Coverage Summary for Class: HelloMessage (org.ethereum.net.p2p)

Class Class, % Method, % Line, %
HelloMessage 0% (0/1) 0% (0/15) 0% (0/76)


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.p2p; 21  22 import org.bouncycastle.util.encoders.Hex; 23 import org.ethereum.net.client.Capability; 24 import org.ethereum.util.ByteUtil; 25 import org.ethereum.util.RLP; 26 import org.ethereum.util.RLPElement; 27 import org.ethereum.util.RLPList; 28  29 import java.nio.charset.StandardCharsets; 30 import java.util.ArrayList; 31 import java.util.Collections; 32 import java.util.List; 33 import java.util.stream.Collectors; 34  35 import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY; 36  37 /** 38  * Wrapper around an Ethereum HelloMessage on the network 39  * 40  * @see org.ethereum.net.p2p.P2pMessageCodes#HELLO 41  */ 42 public class HelloMessage extends P2pMessage { 43  44  /** 45  * The implemented version of the P2P protocol. 46  */ 47  private byte p2pVersion; 48  /** 49  * The underlying client. A user-readable string. 50  */ 51  private String clientId; 52  /** 53  * A peer-network capability code, readable ASCII and 3 letters. 54  * Currently only "eth", "shh" and "bzz" are known. 55  */ 56  private List<Capability> capabilities = Collections.emptyList(); 57  /** 58  * The port on which the peer is listening for an incoming connection 59  */ 60  private int listenPort; 61  /** 62  * The identity and public key of the peer 63  */ 64  private String peerId; 65  66  public HelloMessage(byte[] encoded) { 67  super(encoded); 68  } 69  70  public HelloMessage(byte p2pVersion, String clientId, 71  List<Capability> capabilities, int listenPort, String peerId) { 72  this.p2pVersion = p2pVersion; 73  this.clientId = clientId; 74  this.capabilities = capabilities; 75  this.listenPort = listenPort; 76  this.peerId = peerId; 77  this.parsed = true; 78  } 79  80  private void parse() { 81  RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0); 82  83  byte[] p2pVersionBytes = paramsList.get(0).getRLPData(); 84  this.p2pVersion = p2pVersionBytes != null ? p2pVersionBytes[0] : 0; 85  86  byte[] clientIdBytes = paramsList.get(1).getRLPData(); 87  this.clientId = new String(clientIdBytes != null ? clientIdBytes : EMPTY_BYTE_ARRAY); 88  89  RLPList capabilityList = (RLPList) paramsList.get(2); 90  this.capabilities = new ArrayList<>(); 91  92  for (int k = 0; k < capabilityList.size(); k++) { 93  Object aCapabilityList = capabilityList.get(k); 94  95  RLPElement capId = ((RLPList) aCapabilityList).get(0); 96  RLPElement capVersion = ((RLPList) aCapabilityList).get(1); 97  98  String name = new String(capId.getRLPData()); 99  byte version = capVersion.getRLPData() == null ? 0 : capVersion.getRLPData()[0]; 100  101  Capability cap = new Capability(name, version); 102  this.capabilities.add(cap); 103  } 104  105  byte[] peerPortBytes = paramsList.get(3).getRLPData(); 106  this.listenPort = ByteUtil.byteArrayToInt(peerPortBytes); 107  108  byte[] peerIdBytes = paramsList.get(4).getRLPData(); 109  this.peerId = ByteUtil.toHexString(peerIdBytes); 110  this.parsed = true; 111  } 112  113  private void encode() { 114  byte[] p2pVersion = RLP.encodeByte(this.p2pVersion); 115  byte[] clientId = RLP.encodeString(this.clientId); 116  byte[][] capabilities = new byte[this.capabilities.size()][]; 117  for (int i = 0; i < this.capabilities.size(); i++) { 118  Capability capability = this.capabilities.get(i); 119  capabilities[i] = RLP.encodeList( 120  RLP.encodeElement(capability.getName().getBytes(StandardCharsets.UTF_8)), 121  RLP.encodeInt(capability.getVersion())); 122  } 123  byte[] capabilityList = RLP.encodeList(capabilities); 124  byte[] peerPort = RLP.encodeInt(this.listenPort); 125  byte[] peerId = RLP.encodeElement(Hex.decode(this.peerId)); 126  127  this.encoded = RLP.encodeList(p2pVersion, clientId, 128  capabilityList, peerPort, peerId); 129  } 130  131  @Override 132  public byte[] getEncoded() { 133  if (encoded == null) { 134  encode(); 135  } 136  return encoded; 137  } 138  139  public byte getP2PVersion() { 140  if (!parsed) { 141  parse(); 142  } 143  return p2pVersion; 144  } 145  146  public String getClientId() { 147  if (!parsed) { 148  parse(); 149  } 150  return clientId; 151  } 152  153  public List<Capability> getCapabilities() { 154  if (!parsed) { 155  parse(); 156  } 157  return capabilities; 158  } 159  160  public int getListenPort() { 161  if (!parsed) { 162  parse(); 163  } 164  return listenPort; 165  } 166  167  public String getPeerId() { 168  if (!parsed) { 169  parse(); 170  } 171  return peerId; 172  } 173  174  @Override 175  public P2pMessageCodes getCommand() { 176  return P2pMessageCodes.HELLO; 177  } 178  179  public void setPeerId(String peerId) { 180  this.peerId = peerId; 181  } 182  183  public void setP2pVersion(byte p2pVersion) { 184  this.p2pVersion = p2pVersion; 185  } 186  187  @Override 188  public Class<?> getAnswerMessage() { 189  return null; 190  } 191  192  public String toString() { 193  if (!parsed) { 194  parse(); 195  } 196  197  return String.format( 198  "[%s p2pVersion=%s clientId=%s capabilities=[%s] getPeerPort=%d peerId=%s]", 199  this.getCommand().name(), 200  this.p2pVersion, 201  this.clientId, 202  this.capabilities.stream().map(Capability::toString).collect(Collectors.joining(" ")), 203  this.listenPort, 204  this.peerId 205  ); 206  } 207 }