diff --git a/ethereumj-core/src/main/java/org/ethereum/net/dht/Bucket.java b/ethereumj-core/src/main/java/org/ethereum/net/dht/Bucket.java index 5c7e06b1..eb791c7d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/dht/Bucket.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/dht/Bucket.java @@ -15,7 +15,7 @@ public class Bucket { String name; - List peerIds = new ArrayList<>(); + List peers = new ArrayList<>(); public Bucket(String name) { @@ -23,23 +23,23 @@ public class Bucket { } - public void add(PeerId peerId) { + public void add(Peer peer) { - if (peerId == null) throw new Error("Not a leaf"); + if (peer == null) throw new Error("Not a leaf"); - if ( peerIds == null){ + if ( peers == null){ - if (peerId.nextBit(name) == 1) - left.add(peerId); + if (peer.nextBit(name) == 1) + left.add(peer); else - right.add(peerId); + right.add(peer); return; } - peerIds.add(peerId); + peers.add(peer); - if (peerIds.size() > MAX_KADEMLIA_K) + if (peers.size() > MAX_KADEMLIA_K) splitBucket(); } @@ -47,14 +47,14 @@ public class Bucket { left = new Bucket(name + "1"); right = new Bucket(name + "0"); - for (PeerId id : peerIds) { + for (Peer id : peers) { if (id.nextBit(name) == 1) left.add(id); else right.add(id); } - this.peerIds = null; + this.peers = null; } @@ -74,9 +74,9 @@ public class Bucket { sb.append(name).append("\n"); - if (peerIds == null) return sb.toString(); + if (peers == null) return sb.toString(); - for (PeerId id : peerIds) + for (Peer id : peers) sb.append(id.toBinaryString()).append("\n"); return sb.toString(); @@ -108,7 +108,7 @@ public class Bucket { @Override public void call(Bucket bucket) { - if (bucket.peerIds != null) leafs.add(bucket); + if (bucket.peers != null) leafs.add(bucket); } public List getLeafs() { @@ -124,7 +124,7 @@ public class Bucket { return name; } - public List getPeerIds() { - return peerIds; + public List getPeers() { + return peers; } } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/dht/PeerId.java b/ethereumj-core/src/main/java/org/ethereum/net/dht/Peer.java similarity index 50% rename from ethereumj-core/src/main/java/org/ethereum/net/dht/PeerId.java rename to ethereumj-core/src/main/java/org/ethereum/net/dht/Peer.java index 183a2b9f..72a0f0d0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/dht/PeerId.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/dht/Peer.java @@ -1,19 +1,28 @@ package org.ethereum.net.dht; +import com.sun.javafx.binding.StringFormatter; import org.ethereum.crypto.HashUtil; import org.spongycastle.util.BigIntegers; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; -public class PeerId { - byte[] data; +public class Peer { + byte[] id; + String host = "127.0.0.1"; + int port = 0; - public PeerId(byte[] data) { - this.data = data; + public Peer(byte[] id, String host, int port) { + this.id = id; + this.host = host; + this.port = port; } - public PeerId() { + public Peer(byte[] ip) { + this.id= ip; + } + + public Peer() { HashUtil.randomPeerId(); } @@ -25,34 +34,32 @@ public class PeerId { return 0; } - public byte[] calcDistance(PeerId toPeerId) { + public byte[] calcDistance(Peer toPeer) { - BigInteger aPeer = new BigInteger(data); - BigInteger bPeer = new BigInteger(toPeerId.data); + BigInteger aPeer = new BigInteger(getId()); + BigInteger bPeer = new BigInteger(toPeer.getId()); BigInteger distance = aPeer.xor(bPeer); return BigIntegers.asUnsignedByteArray(distance); } - public byte[] getData() { - return data; + public byte[] getId() { + return id; } - public void setData(byte[] data) { - this.data = data; + public void setId(byte[] ip) { + this.id = id; } @Override public String toString() { - return "PeerId{" + - "data=" + Hex.toHexString(data) + - '}'; + return String.format("Peer {\n id=%s, \n host=%s, \n port=%d\n}", Hex.toHexString(id), host, port); } public String toBinaryString() { - BigInteger bi = new BigInteger(1, data); + BigInteger bi = new BigInteger(1, id); String out = String.format("%512s", bi.toString(2)); out = out.replace(' ', '0'); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/FindNodeMessage.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/FindNodeMessage.java index 4ed20bb6..f514a5e2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/FindNodeMessage.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/FindNodeMessage.java @@ -1,37 +1,71 @@ package org.ethereum.net.rlpx; import org.ethereum.crypto.ECKey; +import org.ethereum.util.ByteUtil; import org.ethereum.util.RLP; +import org.ethereum.util.RLPItem; +import org.ethereum.util.RLPList; +import org.spongycastle.util.encoders.Hex; -import static org.ethereum.util.ByteUtil.longToBytes; -import static org.ethereum.util.ByteUtil.stripLeadingZeroes; +import static org.ethereum.util.ByteUtil.longToBytesNoLeadZeroes; public class FindNodeMessage extends Message { - public static Message create(byte[] target, ECKey privKey) { + byte[] target; + long expires; + + @Override + public void parse(byte[] data) { + + RLPList list = RLP.decode2(data); + list = (RLPList) list.get(0); + + RLPItem target = (RLPItem) list.get(0); + RLPItem expires = (RLPItem) list.get(1); + + this.target = target.getRLPData(); + this.expires = ByteUtil.byteArrayToLong(expires.getRLPData()); + } + + + public static FindNodeMessage create(byte[] target, ECKey privKey) { long expiration = 3 + System.currentTimeMillis() / 1000; - /* RLP Encode data */ byte[] rlpToken = RLP.encodeElement(target); - byte[] tmpExp = longToBytes(expiration); - byte[] rlpExp = RLP.encodeElement(stripLeadingZeroes(tmpExp)); + byte[] rlpExp = longToBytesNoLeadZeroes(expiration); + rlpExp = RLP.encodeElement(rlpExp); byte[] type = new byte[]{3}; byte[] data = RLP.encodeList(rlpToken, rlpExp); FindNodeMessage findNode = new FindNodeMessage(); findNode.encode(type, data, privKey); + findNode.target = target; + findNode.expires = expiration; return findNode; } + public byte[] getTarget() { + return target; + } + + public long getExpires() { + return expires; + } @Override public String toString() { - return "FindNodeMessage: " + super.toString(); + + long currTime = System.currentTimeMillis() / 1000; + + String out = String.format("[FindNodeMessage] \n target: %s \n expires in %d seconds \n %s\n", + Hex.toHexString(target), (expires - currTime), super.toString()); + + return out; } } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/Message.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/Message.java index 968a106d..bece2831 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/Message.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/Message.java @@ -10,7 +10,7 @@ import java.security.SignatureException; import static org.ethereum.crypto.HashUtil.sha3; import static org.ethereum.util.ByteUtil.merge; -public class Message { +public abstract class Message { byte[] wire; @@ -54,6 +54,8 @@ public class Message { msg.data = data; msg.wire = wire; + msg.parse(data); + return msg; } @@ -134,6 +136,8 @@ public class Message { return data; } + public abstract void parse(byte[] data); + @Override public String toString() { return "{" + diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/NeighborsMessage.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/NeighborsMessage.java index 77b698a2..945d010f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/NeighborsMessage.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/NeighborsMessage.java @@ -3,19 +3,46 @@ package org.ethereum.net.rlpx; import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; import org.ethereum.util.RLP; +import org.ethereum.util.RLPItem; +import org.ethereum.util.RLPList; +import org.spongycastle.util.encoders.Hex; +import java.util.ArrayList; import java.util.List; +import static org.ethereum.util.ByteUtil.longToBytesNoLeadZeroes; + public class NeighborsMessage extends Message { - public static Message create(List nodes, ECKey privKey) { + List nodes; + long expires; - long expiration = System.currentTimeMillis(); + @Override + public void parse(byte[] data) { + RLPList list = RLP.decode2(data); + + RLPList nodesRLP = (RLPList) ((RLPList) list.get(0)).get(0); + RLPItem expires = (RLPItem) ((RLPList) list.get(0)).get(1); + + nodes = new ArrayList<>(); + + for (int i = 0; i < nodesRLP.size(); ++i) { + RLPList nodeRLP = (RLPList) nodesRLP.get(i); + Node node = new Node(nodeRLP.getRLPData()); + nodes.add(node); + } + this.expires = ByteUtil.byteArrayToLong(expires.getRLPData()); + } + + + public static NeighborsMessage create(List nodes, ECKey privKey) { + + long expiration = System.currentTimeMillis() / 1000; byte[][] nodeRLPs = null; if (nodes != null) { - nodeRLPs = new byte[nodes.size()][]; + nodeRLPs = new byte[nodes.size()][]; int i = 0; for (Node node : nodes) { nodeRLPs[i] = node.getRLP(); @@ -24,19 +51,39 @@ public class NeighborsMessage extends Message { } byte[] rlpListNodes = RLP.encodeList(nodeRLPs); - byte[] rlpExp = RLP.encodeElement(ByteUtil.longToBytes(expiration)); + byte[] rlpExp = longToBytesNoLeadZeroes(expiration); + rlpExp = RLP.encodeElement(rlpExp); byte[] type = new byte[]{4}; byte[] data = RLP.encodeList(rlpListNodes, rlpExp); NeighborsMessage neighborsMessage = new NeighborsMessage(); neighborsMessage.encode(type, data, privKey); + neighborsMessage.nodes = nodes; + neighborsMessage.expires = expiration; return neighborsMessage; } + public List getNodes() { + return nodes; + } + + public long getExpires() { + return expires; + } + + @Override public String toString() { - return "NeighborsMessage: " + super.toString(); + + long currTime = System.currentTimeMillis() / 1000; + + String out = String.format("[NeighborsMessage] \n nodes [%d]: %s \n expires in %d seconds \n %s\n", + this.getNodes().size(), this.getNodes(), (expires - currTime), super.toString()); + + return out; } + + } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/Node.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/Node.java index ee60f07f..c11dfdd5 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/Node.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/Node.java @@ -1,22 +1,44 @@ package org.ethereum.net.rlpx; -import org.ethereum.util.ByteUtil; import org.ethereum.util.RLP; +import org.ethereum.util.RLPList; +import org.spongycastle.util.encoders.Hex; import java.nio.charset.Charset; +import static org.ethereum.util.ByteUtil.byteArrayToInt; +import static org.ethereum.util.ByteUtil.intToBytesNoLeadZeroes; + public class Node { byte[] id; - String ip; - int port; + String host; + int port; - public Node(byte[] id, String ip, int port) { + public Node(byte[] id, String host, int port) { this.id = id; - this.ip = ip; + this.host = host; this.port = port; } + public Node(byte[] rlp) { + + RLPList nodeRLP = RLP.decode2(rlp); + nodeRLP = (RLPList) nodeRLP.get(0); + + byte[] hostB = nodeRLP.get(0).getRLPData(); + byte[] portB = nodeRLP.get(1).getRLPData(); + byte[] idB = nodeRLP.get(2).getRLPData(); + + String host = new String(hostB, Charset.forName("UTF-8")); + int port = byteArrayToInt(portB); + + this.host = host; + this.port = port; + this.id = idB; + } + + public byte[] getId() { return id; } @@ -25,12 +47,12 @@ public class Node { this.id = id; } - public String getIp() { - return ip; + public String getHost() { + return host; } - public void setIp(String ip) { - this.ip = ip; + public void setHost(String host) { + this.host = host; } public int getPort() { @@ -41,14 +63,22 @@ public class Node { this.port = port; } - public byte[] getRLP(){ + public byte[] getRLP() { - byte[] rlpId = RLP.encodeElement(id); - byte[] rlpIp = RLP.encodeElement(ip.getBytes(Charset.forName("UTF-8"))); - byte[] rlpPort = RLP.encodeElement(ByteUtil.longToBytes(port)); + byte[] rlphost = RLP.encodeElement(host.getBytes(Charset.forName("UTF-8"))); + byte[] rlpPort = RLP.encodeElement(intToBytesNoLeadZeroes(port)); + byte[] rlpId = RLP.encodeElement(id); - byte[] data = RLP.encodeList(rlpId, rlpIp, rlpPort); + byte[] data = RLP.encodeList(rlphost, rlpPort, rlpId); return data; } + @Override + public String toString() { + return "Node{" + + " host='" + host + '\'' + + ", port=" + port + + ", id=" + Hex.toHexString(id) + + '}'; + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/PingMessage.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/PingMessage.java index 915c373f..f7e15f88 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/PingMessage.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/PingMessage.java @@ -1,25 +1,35 @@ package org.ethereum.net.rlpx; import org.ethereum.crypto.ECKey; +import org.ethereum.util.ByteUtil; import org.ethereum.util.RLP; +import org.ethereum.util.RLPItem; +import org.ethereum.util.RLPList; +import org.spongycastle.util.encoders.Hex; + +import java.nio.charset.Charset; import static org.ethereum.util.ByteUtil.longToBytes; import static org.ethereum.util.ByteUtil.stripLeadingZeroes; public class PingMessage extends Message { - public static Message create(String ip, int port, ECKey privKey){ + String host; + int port; + long expires; + + public static PingMessage create(String host, int port, ECKey privKey) { long expiration = 3 + System.currentTimeMillis() / 1000; /* RLP Encode data */ - byte[] rlpIp = RLP.encodeElement(ip.getBytes()); + byte[] rlpIp = RLP.encodeElement(host.getBytes()); byte[] tmpPort = longToBytes(port); - byte[] rlpPort = RLP.encodeElement(stripLeadingZeroes(tmpPort)); + byte[] rlpPort = RLP.encodeElement(stripLeadingZeroes(tmpPort)); - byte[] tmpExp = longToBytes(expiration); - byte[] rlpExp = RLP.encodeElement(stripLeadingZeroes(tmpExp)); + byte[] tmpExp = longToBytes(expiration); + byte[] rlpExp = RLP.encodeElement(stripLeadingZeroes(tmpExp)); byte[] type = new byte[]{1}; byte[] data = RLP.encodeList(rlpIp, rlpPort, rlpExp); @@ -27,11 +37,49 @@ public class PingMessage extends Message { PingMessage ping = new PingMessage(); ping.encode(type, data, privKey); + ping.expires = expiration; + ping.host = host; + ping.port = port; + return ping; } + @Override + public void parse(byte[] data) { + + RLPList list = RLP.decode2(data); + list = (RLPList) list.get(0); + + byte[] ipB = list.get(0).getRLPData(); + this.host = new String(ipB, Charset.forName("UTF-8")); + + this.port = ByteUtil.byteArrayToInt(list.get(1).getRLPData()); + + RLPItem expires = (RLPItem) list.get(2); + this.expires = ByteUtil.byteArrayToLong(expires.getRLPData()); + } + + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } + + public long getExpires() { + return expires; + } + @Override public String toString() { - return "PingMessage: " + super.toString(); + + long currTime = System.currentTimeMillis() / 1000; + + String out = String.format("[PingMessage] \n host: %s port: %d \n expires in %d seconds \n %s\n", + host, port, (expires - currTime), super.toString()); + + return out; } } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/PongMessage.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/PongMessage.java index d731e468..6b4e3add 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/PongMessage.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/PongMessage.java @@ -3,12 +3,21 @@ package org.ethereum.net.rlpx; import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; import org.ethereum.util.RLP; +import org.ethereum.util.RLPItem; +import org.ethereum.util.RLPList; +import org.spongycastle.util.encoders.Hex; + +import java.nio.charset.Charset; public class PongMessage extends Message { - public static Message create(byte[] token, ECKey privKey) { + byte[] token; // token is the MDC of the ping + long expires; - long expiration = System.currentTimeMillis(); + + public static PongMessage create(byte[] token, ECKey privKey) { + + long expiration = 3 + System.currentTimeMillis() / 1000; /* RLP Encode data */ byte[] rlpToken = RLP.encodeElement(token); @@ -20,14 +29,39 @@ public class PongMessage extends Message { PongMessage pong = new PongMessage(); pong.encode(type, data, privKey); + pong.token = token; + pong.expires = expiration; + return pong; } @Override - public String toString() { - return "PongMessage: " + super.toString(); + public void parse(byte[] data) { + RLPList list = RLP.decode2(data); + list = (RLPList) list.get(0); + + this.token = list.get(0).getRLPData(); + RLPItem expires = (RLPItem) list.get(1); + this.expires = ByteUtil.byteArrayToLong(expires.getRLPData()); } + public byte[] getToken() { + return token; + } + + public long getExpires() { + return expires; + } + + @Override + public String toString() { + long currTime = System.currentTimeMillis() / 1000; + + String out = String.format("[PongMessage] \n token: %s \n expires in %d seconds \n %s\n", + Hex.toHexString(token), (expires - currTime), super.toString()); + + return out; + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/util/ByteUtil.java b/ethereumj-core/src/main/java/org/ethereum/util/ByteUtil.java index 163afc15..a061bf52 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/ByteUtil.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/ByteUtil.java @@ -99,6 +99,33 @@ public class ByteUtil { return ByteBuffer.allocate(8).putLong(val).array(); } + /** + * Converts a long value into a byte array. + * + * @param val - long value to convert + * @return decimal value with leading byte that are zeroes striped + */ + public static byte[] longToBytesNoLeadZeroes(long val) { + + // todo: improve performance by while strip numbers until (long >> 8 == 0) + byte[] data = ByteBuffer.allocate(8).putLong(val).array(); + + return stripLeadingZeroes(data); + } + + + /** + * Converts a int value into a byte array. + * + * @param val - int value to convert + * @return decimal value with leading byte that are zeroes striped + */ + public static byte[] intToBytesNoLeadZeroes(int val) { + return longToBytesNoLeadZeroes((long)val); + } + + + /** * Convert a byte-array into a hex String.
* Works similar to {@link Hex#toHexString} diff --git a/ethereumj-core/src/test/java/test/ethereum/net/RLPXTest.java b/ethereumj-core/src/test/java/test/ethereum/net/RLPXTest.java index 030c013b..8461605e 100644 --- a/ethereumj-core/src/test/java/test/ethereum/net/RLPXTest.java +++ b/ethereumj-core/src/test/java/test/ethereum/net/RLPXTest.java @@ -2,9 +2,12 @@ package test.ethereum.net; import org.ethereum.crypto.ECKey; import org.ethereum.net.rlpx.*; +import org.ethereum.util.RLP; +import org.ethereum.util.RLPList; import org.junit.Assert; import org.junit.Test; import org.slf4j.LoggerFactory; +import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; import java.nio.charset.Charset; @@ -14,13 +17,14 @@ import java.util.List; import static org.ethereum.crypto.HashUtil.sha3; import static org.ethereum.util.ByteUtil.merge; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class RLPXTest { private static final org.slf4j.Logger logger = LoggerFactory.getLogger("test"); @Test // ping test - public void test1(){ + public void test1() { String ip = "85.65.19.231"; int port = 30303; @@ -30,7 +34,7 @@ public class RLPXTest { logger.info("{}", ping); byte[] wire = ping.getPacket(); - PingMessage ping2 = (PingMessage)Message.decode(wire); + PingMessage ping2 = (PingMessage) Message.decode(wire); logger.info("{}", ping2); assertEquals(ping.toString(), ping2.toString()); @@ -40,7 +44,7 @@ public class RLPXTest { } @Test // pong test - public void test2(){ + public void test2() { byte[] token = sha3("+++".getBytes(Charset.forName("UTF-8"))); ECKey key = ECKey.fromPrivate(BigInteger.TEN); @@ -49,7 +53,7 @@ public class RLPXTest { logger.info("{}", pong); byte[] wire = pong.getPacket(); - PongMessage pong2 = (PongMessage)Message.decode(wire); + PongMessage pong2 = (PongMessage) Message.decode(wire); logger.info("{}", pong); assertEquals(pong.toString(), pong2.toString()); @@ -59,7 +63,7 @@ public class RLPXTest { } @Test // neighbors message - public void test3(){ + public void test3() { String ip = "85.65.19.231"; int port = 30303; @@ -77,7 +81,7 @@ public class RLPXTest { logger.info("{}", neighbors); byte[] wire = neighbors.getPacket(); - NeighborsMessage neighbors2 = (NeighborsMessage)Message.decode(wire); + NeighborsMessage neighbors2 = (NeighborsMessage) Message.decode(wire); logger.info("{}", neighbors2); assertEquals(neighbors.toString(), neighbors2.toString()); @@ -87,7 +91,7 @@ public class RLPXTest { } @Test // find node message - public void test4(){ + public void test4() { byte[] id = sha3("+++".getBytes(Charset.forName("UTF-8"))); ECKey key = ECKey.fromPrivate(BigInteger.TEN); @@ -96,7 +100,7 @@ public class RLPXTest { logger.info("{}", findNode); byte[] wire = findNode.getPacket(); - FindNodeMessage findNode2 = (FindNodeMessage)Message.decode(wire); + FindNodeMessage findNode2 = (FindNodeMessage) Message.decode(wire); logger.info("{}", findNode2); assertEquals(findNode.toString(), findNode2.toString()); @@ -106,8 +110,8 @@ public class RLPXTest { } - @Test (expected = Error.class)// failure on MDC - public void test5(){ + @Test(expected = Error.class)// failure on MDC + public void test5() { byte[] id = sha3("+++".getBytes(Charset.forName("UTF-8"))); ECKey key = ECKey.fromPrivate(BigInteger.TEN); @@ -118,10 +122,123 @@ public class RLPXTest { byte[] wire = findNode.getPacket(); wire[64] = 0; - FindNodeMessage findNode2 = (FindNodeMessage)Message.decode(wire); + FindNodeMessage findNode2 = (FindNodeMessage) Message.decode(wire); logger.info("{}", findNode2); assertEquals(findNode.toString(), findNode2.toString()); } + + @Test + public void test6() { + + byte[] id_1 = sha3("+++".getBytes(Charset.forName("UTF-8"))); + String host_1 = "85.65.19.231"; + int port_1 = 30303; + + Node node_1 = new Node(id_1, host_1 , port_1); + Node node_2 = new Node(node_1.getRLP()); + + byte[] id_2 = node_2.getId(); + String host_2 = node_2.getHost(); + int port_2 = node_2.getPort(); + + assertEquals(Hex.toHexString(id_1), Hex.toHexString(id_2)); + assertEquals(host_1, host_2); + assertTrue(port_1 == port_2); + } + + + + @Test // Neighbors parse data + public void test7() { + + byte[] wire = + Hex.decode("d5106e888eeca1e0b4a93bf17c325f912b43ca4176a000966619aa6a96ac9d5a60e66c73ed5629c13d4d0c806a3127379541e8d90d7fcb52c33c5e36557ad92dfed9619fcd3b92e42683aed89bd3c6eef6b59bd0237c36d83ebb0075a59903f50104f90200f901f8f8528c38352e36352e31392e32333182f310b840aeb2dd107edd996adf1bbf835fb3f9a11aabb7ed3dfef84c7a3c8767482bff522906a11e8cddee969153bf5944e64e37943db509bb4cc714c217f20483802ec0f8528c38352e36352e31392e32333182e5b4b840b70cdf8f23024a65afbf12110ca06fa5c37bd9fe4f6234a0120cdaaf16e8bb96d090d0164c316aaa18158d346e9b0a29ad9bfa0404ab4ee9906adfbacb01c21bf8528c38352e36352e31392e32333182df38b840ed8e01b5f5468f32de23a7524af1b35605ffd7cdb79af4eacd522c94f8ed849bb81dfed4992c179caeef0952ecad2d868503164a434c300356b369a33c159289f8528c38352e36352e31392e32333182df38b840136996f11c2c80f231987fc4f0cbd061cb021c63afaf5dd879e7c851a57be8d023af14bc201be81588ecab7971693b3f689a4854df74ad2e2334e88ae76aa122f8528c38352e36352e31392e32333182f303b840742eac32e1e2343b89c03a20fc051854ea6a3ff28ca918d1994fe1e32d6d77ab63352131db3ed0e7d6cc057d859c114b102f49052daee3d1c5f5fdaab972e655f8528c38352e36352e31392e32333182f310b8407d9e1f9ceb66fc21787b830554d604f933be203be9366710fb33355975e874a72b87837cf28b1b9ae171826b64e3c5d178326cbf71f89b3dec614816a1a40ce38454f6b578"); + + NeighborsMessage msg1 = (NeighborsMessage) NeighborsMessage.decode(wire); + + ECKey key = ECKey.fromPrivate(BigInteger.TEN); + NeighborsMessage msg2 = (NeighborsMessage) NeighborsMessage.create(msg1.getNodes(), key); + + NeighborsMessage msg3 = (NeighborsMessage) NeighborsMessage.decode(msg2.getPacket()); + + for (int i = 0; i < msg1.getNodes().size(); ++i) { + + Node node_1 = msg1.getNodes().get(i); + Node node_3 = msg3.getNodes().get(i); + + assertEquals(node_1.toString(), node_3.toString()); + } + + System.out.println(msg1); + + } + + + @Test // FindNodeMessage parse data + public void test8() { + + byte[] wire = + Hex.decode("3770d98825a42cb69edf70ffdf8d6d2b28a8c5499a7e3350e4a42c94652339cac3f8e9c3b5a181c8dd13e491ad9229f6a8bd018d786e1fb9e5264f43bbd6ce93af9bc85b468dee651bcd518561f83cb166da7aef7e506057dc2fbb2ea582bcc00003f847b84083fba54f6bb80ce31f6d5d1ec0a9a2e4685bc185115b01da6dcb70cd13116a6bd08b86ffe60b7d7ea56c6498848e3741113f8e70b9f0d12dbfe895680d03fd658454f6e772"); + + FindNodeMessage msg1 = (FindNodeMessage) FindNodeMessage.decode(wire); + + ECKey key = ECKey.fromPrivate(BigInteger.TEN); + FindNodeMessage msg2 = FindNodeMessage.create(msg1.getTarget(), key); + + FindNodeMessage msg3 = (FindNodeMessage) FindNodeMessage.decode(msg2.getPacket()); + + Assert.assertEquals(Hex.toHexString(msg1.getTarget()), Hex.toHexString(msg3.getTarget())); + } + + @Test // Ping parse data + public void test9() { +// wire: 4c62e1b75f4003ef77032006a142bbf31772936a1e5098566b28a04a5c71c73f1f2c9f539a85458c50a554de12da9d7e69fb2507f7c0788885508d385bbe7a9538fa675712aa1eaad29902bb46eee4531d00a10fd81179e4151929f60fec4dc50001ce87302e302e302e30808454f8483c +// PingMessage: {mdc=4c62e1b75f4003ef77032006a142bbf31772936a1e5098566b28a04a5c71c73f, signature=1f2c9f539a85458c50a554de12da9d7e69fb2507f7c0788885508d385bbe7a9538fa675712aa1eaad29902bb46eee4531d00a10fd81179e4151929f60fec4dc500, type=01, data=ce87302e302e302e30808454f8483c} + + byte[] wire = + Hex.decode("4c62e1b75f4003ef77032006a142bbf31772936a1e5098566b28a04a5c71c73f1f2c9f539a85458c50a554de12da9d7e69fb2507f7c0788885508d385bbe7a9538fa675712aa1eaad29902bb46eee4531d00a10fd81179e4151929f60fec4dc50001ce87302e302e302e30808454f8483c"); + + PingMessage msg1 = (PingMessage)Message.decode(wire); + + ECKey key = ECKey.fromPrivate(BigInteger.TEN); + PingMessage msg2 = PingMessage.create(msg1.getHost(), msg1.getPort(), key); + PingMessage msg3 = (PingMessage)Message.decode(msg2.getPacket()); + + assertEquals(msg1.getHost(), msg3.getHost()); + } + + + @Test // Pong parse data + public void test10(){ +// wire: 84db9bf6a1f7a3444f4d4946155da16c63a51abdd6822ac683d8243f260b99b265601b769acebfe3c76ddeb6e83e924f2bac2beca0c802ff0745d349bd58bc6662d62d38c2a3bb3e167a333d7d099496ebd35e096c5c1ee1587e9bd11f20e3d80002e6a079d49bdba3a7acfc9a2881d768d1aa246c2486ab166f0305a863bd47c5d21e0e8454f8483c +// PongMessage: {mdc=84db9bf6a1f7a3444f4d4946155da16c63a51abdd6822ac683d8243f260b99b2, signature=65601b769acebfe3c76ddeb6e83e924f2bac2beca0c802ff0745d349bd58bc6662d62d38c2a3bb3e167a333d7d099496ebd35e096c5c1ee1587e9bd11f20e3d800, type=02, data=e6a079d49bdba3a7acfc9a2881d768d1aa246c2486ab166f0305a863bd47c5d21e0e8454f8483c} + + byte[] wire = + Hex.decode("84db9bf6a1f7a3444f4d4946155da16c63a51abdd6822ac683d8243f260b99b265601b769acebfe3c76ddeb6e83e924f2bac2beca0c802ff0745d349bd58bc6662d62d38c2a3bb3e167a333d7d099496ebd35e096c5c1ee1587e9bd11f20e3d80002e6a079d49bdba3a7acfc9a2881d768d1aa246c2486ab166f0305a863bd47c5d21e0e8454f8483c"); + + PongMessage msg1 = (PongMessage)Message.decode(wire); + + ECKey key = ECKey.fromPrivate(BigInteger.TEN); + PongMessage msg2 = PongMessage.create(msg1.getToken(), key); + + PongMessage msg3 = (PongMessage)Message.decode(msg2.getPacket()); + assertEquals( Hex.toHexString(msg1.getToken()), Hex.toHexString(msg3.getToken())); + } + + + + + } + + + + + + + + + +