Coverage Summary for Class: Channel (org.ethereum.net.server)

Class Class, % Method, % Line, %
Channel 0% (0/1) 0% (0/31) 0% (0/77)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2017 RSK Labs Ltd. 4  * (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>) 5  * 6  * This program is free software: you can redistribute it and/or modify 7  * it under the terms of the GNU Lesser General Public License as published by 8  * the Free Software Foundation, either version 3 of the License, or 9  * (at your option) any later version. 10  * 11  * This program is distributed in the hope that it will be useful, 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14  * GNU Lesser General Public License for more details. 15  * 16  * You should have received a copy of the GNU Lesser General Public License 17  * along with this program. If not, see <http://www.gnu.org/licenses/>. 18  */ 19  20 package org.ethereum.net.server; 21  22 import co.rsk.net.Peer; 23 import co.rsk.net.NodeID; 24 import co.rsk.net.eth.RskMessage; 25 import co.rsk.net.eth.RskWireProtocol; 26 import co.rsk.net.messages.Message; 27 import co.rsk.net.messages.MessageType; 28 import io.netty.buffer.ByteBuf; 29 import io.netty.channel.ChannelHandlerContext; 30 import org.ethereum.net.MessageQueue; 31 import org.ethereum.net.NodeManager; 32 import org.ethereum.net.NodeStatistics; 33 import org.ethereum.net.client.Capability; 34 import org.ethereum.net.eth.EthVersion; 35 import org.ethereum.net.eth.handler.Eth; 36 import org.ethereum.net.eth.handler.EthAdapter; 37 import org.ethereum.net.eth.message.Eth62MessageFactory; 38 import org.ethereum.net.message.ReasonCode; 39 import org.ethereum.net.message.StaticMessages; 40 import org.ethereum.net.p2p.HelloMessage; 41 import org.ethereum.net.p2p.P2pHandler; 42 import org.ethereum.net.rlpx.FrameCodec; 43 import org.ethereum.net.rlpx.MessageCodec; 44 import org.ethereum.net.rlpx.Node; 45 import org.ethereum.sync.SyncStatistics; 46 import org.slf4j.Logger; 47 import org.slf4j.LoggerFactory; 48  49 import java.io.IOException; 50 import java.math.BigInteger; 51 import java.net.InetAddress; 52 import java.net.InetSocketAddress; 53 import java.util.List; 54 import java.util.Objects; 55  56 public class Channel implements Peer { 57  58  private static final Logger logger = LoggerFactory.getLogger("net"); 59  60  private final MessageQueue msgQueue; 61  private final MessageCodec messageCodec; 62  private final NodeManager nodeManager; 63  private final RskWireProtocol.Factory rskWireProtocolFactory; 64  private final Eth62MessageFactory eth62MessageFactory; 65  private final StaticMessages staticMessages; 66  private final boolean isActive; 67  68  private Eth eth = new EthAdapter(); 69  70  private InetSocketAddress inetSocketAddress; 71  72  private Node node; 73  private NodeStatistics nodeStatistics; 74  75  private final PeerStatistics peerStats = new PeerStatistics(); 76  77  private Stats stats; 78  79  public Channel(MessageQueue msgQueue, 80  MessageCodec messageCodec, 81  NodeManager nodeManager, 82  RskWireProtocol.Factory rskWireProtocolFactory, 83  Eth62MessageFactory eth62MessageFactory, 84  StaticMessages staticMessages, 85  String remoteId) { 86  this.msgQueue = msgQueue; 87  this.messageCodec = messageCodec; 88  this.nodeManager = nodeManager; 89  this.rskWireProtocolFactory = rskWireProtocolFactory; 90  this.eth62MessageFactory = eth62MessageFactory; 91  this.staticMessages = staticMessages; 92  this.isActive = remoteId != null && !remoteId.isEmpty(); 93  this.stats = new Stats(); 94  } 95  96  public void sendHelloMessage(ChannelHandlerContext ctx, FrameCodec frameCodec, String nodeId, 97  HelloMessage inboundHelloMessage) throws IOException, InterruptedException { 98  99  // in discovery mode we are supplying fake port along with fake nodeID to not receive 100  // incoming connections with fake public key 101  HelloMessage helloMessage = staticMessages.createHelloMessage(nodeId); 102  103  if (inboundHelloMessage != null && P2pHandler.isProtocolVersionSupported(inboundHelloMessage.getP2PVersion())) { 104  // the p2p version can be downgraded if requested by peer and supported by us 105  helloMessage.setP2pVersion(inboundHelloMessage.getP2PVersion()); 106  } 107  108  byte[] payload = helloMessage.getEncoded(); 109  110  ByteBuf byteBufMsg = ctx.alloc().buffer(); 111  frameCodec.writeFrame(new FrameCodec.Frame(helloMessage.getCode(), payload), byteBufMsg); 112  ctx.writeAndFlush(byteBufMsg).sync(); 113  114  if (logger.isInfoEnabled()) { 115  logger.info("To: \t{} \tSend: \t{}", ctx.channel().remoteAddress(), helloMessage); 116  } 117  getNodeStatistics().rlpxOutHello.add(); 118  } 119  120  public void activateEth(ChannelHandlerContext ctx, EthVersion version) { 121  if (version != EthVersion.V62) { 122  throw new IllegalArgumentException(String.format("Eth version %s is not supported", version)); 123  } 124  125  messageCodec.setEthVersion(version); 126  messageCodec.setEthMessageFactory(eth62MessageFactory); 127  128  RskWireProtocol handler = rskWireProtocolFactory.newInstance(msgQueue, this); 129  logger.info("Eth{} [ address = {} | id = {} ]", handler.getVersion(), inetSocketAddress, getPeerId()); 130  131  ctx.pipeline().addLast(Capability.RSK, handler); 132  133  handler.activate(); 134  135  eth = handler; 136  } 137  138  public void setInetSocketAddress(InetSocketAddress inetSocketAddress) { 139  this.inetSocketAddress = inetSocketAddress; 140  } 141  142  public NodeStatistics getNodeStatistics() { 143  return nodeStatistics; 144  } 145  146  public void setNode(byte[] nodeId) { 147  node = new Node(nodeId, inetSocketAddress.getHostName(), inetSocketAddress.getPort()); 148  nodeStatistics = nodeManager.getNodeStatistics(node); 149  } 150  151  public Node getNode() { 152  return node; 153  } 154  155  public void initMessageCodes(List<Capability> caps) { 156  messageCodec.initMessageCodes(caps); 157  } 158  159  public boolean isProtocolsInitialized() { 160  return eth.isUsingNewProtocol() || eth.hasStatusPassed(); 161  } 162  163  public boolean isUsingNewProtocol() { 164  return eth.isUsingNewProtocol(); 165  } 166  167  public void onDisconnect() { 168  } 169  170  public String getPeerId() { 171  return node == null ? "<null>" : node.getHexId(); 172  } 173  174  /** 175  * Indicates whether this connection was initiated by our peer 176  */ 177  public boolean isActive() { 178  return isActive; 179  } 180  181  public NodeID getNodeId() { 182  return node == null ? null : node.getId(); 183  } 184  185  public void disconnect(ReasonCode reason) { 186  msgQueue.disconnect(reason); 187  } 188  189  public InetSocketAddress getInetSocketAddress() { 190  return inetSocketAddress; 191  } 192  193  public PeerStatistics getPeerStats() { 194  return peerStats; 195  } 196  197  // RSK sub protocol 198  199  public boolean hasEthStatusSucceeded() { 200  return eth.hasStatusSucceeded(); 201  } 202  203  public BigInteger getTotalDifficulty() { 204  return nodeStatistics.getEthTotalDifficulty(); 205  } 206  207  public SyncStatistics getSyncStats() { 208  return eth.getStats(); 209  } 210  211  public void dropConnection() { 212  eth.dropConnection(); 213  } 214  215  public void sendMessage(Message message) { 216  eth.sendMessage(new RskMessage(message)); 217  } 218  219  @Override 220  public NodeID getPeerNodeID() { 221  return node.getId(); 222  } 223  224  @Override 225  public InetAddress getAddress() { 226  return inetSocketAddress.getAddress(); 227  } 228  229  public Stats getStats() { 230  return stats; 231  } 232  233  @Override 234  public boolean equals(Object o) { 235  if (this == o) { 236  return true; 237  } 238  if (o == null || getClass() != o.getClass()) { 239  return false; 240  } 241  242  Channel channel = (Channel) o; 243  244  return Objects.equals(inetSocketAddress, channel.inetSocketAddress) && 245  Objects.equals(node, channel.node); 246  247  } 248  249  @Override 250  public int hashCode() { 251  int result = inetSocketAddress != null ? inetSocketAddress.hashCode() : 0; 252  result = 31 * result + (node != null ? node.hashCode() : 0); 253  return result; 254  } 255  256  @Override 257  public double score(long currentTime, MessageType type) { 258  return stats.update(currentTime, type); 259  } 260  261  @Override 262  public void imported(boolean best) { 263  stats.imported(best); 264  } 265  266  @Override 267  public String toString() { 268  return String.format("%s | %s", getPeerId(), inetSocketAddress); 269  } 270 }