diff --git a/core/src/main/java/org/bitcoinj/core/AddressMessage.java b/core/src/main/java/org/bitcoinj/core/AddressMessage.java index 3c041f94c..d96319f5a 100644 --- a/core/src/main/java/org/bitcoinj/core/AddressMessage.java +++ b/core/src/main/java/org/bitcoinj/core/AddressMessage.java @@ -16,11 +16,8 @@ package org.bitcoinj.core; -import org.bitcoinj.base.VarInt; import org.bitcoinj.net.discovery.PeerDiscovery; -import java.io.IOException; -import java.io.OutputStream; import java.nio.ByteBuffer; import java.util.Collections; import java.util.List; @@ -38,16 +35,6 @@ public abstract class AddressMessage extends Message { super(payload); } - @Override - protected void bitcoinSerializeToStream(OutputStream stream) throws IOException { - if (addresses == null) - return; - stream.write(VarInt.of(addresses.size()).serialize()); - for (PeerAddress addr : addresses) { - addr.bitcoinSerializeToStream(stream); - } - } - public abstract void addAddress(PeerAddress address); public void removeAddress(int index) { diff --git a/core/src/main/java/org/bitcoinj/core/AddressV1Message.java b/core/src/main/java/org/bitcoinj/core/AddressV1Message.java index 2310cca72..ab850b136 100644 --- a/core/src/main/java/org/bitcoinj/core/AddressV1Message.java +++ b/core/src/main/java/org/bitcoinj/core/AddressV1Message.java @@ -21,9 +21,14 @@ import org.bitcoinj.base.VarInt; import org.bitcoinj.base.internal.InternalUtils; import org.bitcoinj.net.discovery.PeerDiscovery; +import java.io.IOException; +import java.io.OutputStream; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Objects; + +import static org.bitcoinj.base.internal.Preconditions.checkArgument; /** * Represents an "addr" message on the P2P network, which contains broadcast IP addresses of other peers. This is @@ -49,10 +54,8 @@ public class AddressV1Message extends AddressMessage { if (numAddresses > MAX_ADDRESSES) throw new ProtocolException("Address message too large."); addresses = new ArrayList<>(numAddresses); - MessageSerializer serializer = new DummySerializer(1); for (int i = 0; i < numAddresses; i++) { - PeerAddress addr = new PeerAddress(payload, serializer); - addresses.add(addr); + addresses.add(PeerAddress.read(payload, 1)); } } @@ -60,6 +63,16 @@ public class AddressV1Message extends AddressMessage { addresses.add(address); } + @Override + protected void bitcoinSerializeToStream(OutputStream stream) throws IOException { + if (addresses == null) + return; + stream.write(VarInt.of(addresses.size()).serialize()); + for (PeerAddress addr : addresses) { + stream.write(addr.serialize(1)); + } + } + @Override public String toString() { return "addr: " + InternalUtils.SPACE_JOINER.join(addresses); diff --git a/core/src/main/java/org/bitcoinj/core/AddressV2Message.java b/core/src/main/java/org/bitcoinj/core/AddressV2Message.java index c5d4ef93c..a9ca6cb47 100644 --- a/core/src/main/java/org/bitcoinj/core/AddressV2Message.java +++ b/core/src/main/java/org/bitcoinj/core/AddressV2Message.java @@ -20,10 +20,14 @@ import org.bitcoinj.base.VarInt; import org.bitcoinj.base.internal.InternalUtils; import org.bitcoinj.net.discovery.PeerDiscovery; +import java.io.IOException; +import java.io.OutputStream; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.ArrayList; +import static org.bitcoinj.base.internal.Preconditions.checkArgument; + /** * Represents an "addrv2" message on the P2P network, which contains broadcast addresses of other peers. This is * one of the ways peers can find each other without using the {@link PeerDiscovery} mechanism. @@ -49,10 +53,8 @@ public class AddressV2Message extends AddressMessage { if (numAddresses > MAX_ADDRESSES) throw new ProtocolException("Address message too large."); addresses = new ArrayList<>(numAddresses); - MessageSerializer serializer = new DummySerializer(2); for (int i = 0; i < numAddresses; i++) { - PeerAddress addr = new PeerAddress(payload, serializer); - addresses.add(addr); + addresses.add(PeerAddress.read(payload, 2)); } } @@ -60,6 +62,16 @@ public class AddressV2Message extends AddressMessage { addresses.add(address); } + @Override + protected void bitcoinSerializeToStream(OutputStream stream) throws IOException { + if (addresses == null) + return; + stream.write(VarInt.of(addresses.size()).serialize()); + for (PeerAddress addr : addresses) { + stream.write(addr.serialize(2)); + } + } + @Override public String toString() { return "addrv2: " + InternalUtils.SPACE_JOINER.join(addresses); diff --git a/core/src/main/java/org/bitcoinj/core/PeerAddress.java b/core/src/main/java/org/bitcoinj/core/PeerAddress.java index 7cbc9e8e3..0d21c7b95 100644 --- a/core/src/main/java/org/bitcoinj/core/PeerAddress.java +++ b/core/src/main/java/org/bitcoinj/core/PeerAddress.java @@ -20,21 +20,18 @@ package org.bitcoinj.core; import com.google.common.io.BaseEncoding; import org.bitcoinj.base.VarInt; import org.bitcoinj.base.internal.Buffers; -import org.bitcoinj.base.internal.TimeUtils; import org.bitcoinj.crypto.internal.CryptoUtils; import org.bitcoinj.base.internal.ByteUtils; -import java.io.IOException; -import java.io.OutputStream; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; +import java.nio.BufferOverflowException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.time.Instant; -import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.Locale; import java.util.Objects; @@ -44,17 +41,14 @@ import java.util.stream.Stream; import static org.bitcoinj.base.internal.Preconditions.checkArgument; /** - *

A PeerAddress holds an IP address and port number representing the network location of - * a peer in the Bitcoin P2P network. It exists primarily for serialization purposes.

- * - *

This class abuses the protocol version contained in its serializer. It can only contain - * 1 ({@link AddressV1Message}) or 2 ({@link AddressV2Message}).

- * - *

Instances of this class are not safe for use by multiple threads.

+ * A PeerAddress holds an IP address and port number representing the network location of + * a peer in the Bitcoin P2P network. It exists primarily for serialization purposes. + *

+ * Instances of this class are not safe for use by multiple threads. */ -public class PeerAddress extends Message { - private InetAddress addr; // Used for IPV4, IPV6, null otherwise or if not-yet-parsed - private String hostname; // Used for (.onion addresses) TORV2, TORV3, null otherwise or if not-yet-parsed +public class PeerAddress { + private InetAddress addr; // Used for IPV4, IPV6, null otherwise + private String hostname; // Used for (.onion addresses) TORV2, TORV3, null otherwise private int port; private Services services; private Instant time; @@ -85,141 +79,23 @@ public class PeerAddress extends Message { } /** - * Construct a peer address from a serialized payload. - * @param payload Bitcoin protocol formatted byte array containing message content. - * @param serializer the serializer to use for this message. - * @throws ProtocolException + * Deserialize this peer address from a given payload, using a given protocol variant. The variant can be + * 1 ({@link AddressV1Message}) or 2 ({@link AddressV2Message}). + * + * @param payload payload to deserialize from + * @param protocolVariant variant of protocol to use for parsing + * @return read message + * @throws BufferUnderflowException if the read message extends beyond the remaining bytes of the payload */ - public PeerAddress(ByteBuffer payload, MessageSerializer serializer) throws ProtocolException { - super(payload, serializer); - } + public static PeerAddress read(ByteBuffer payload, int protocolVariant) throws BufferUnderflowException, ProtocolException { + if (protocolVariant < 0 || protocolVariant > 2) + throw new IllegalStateException("invalid protocolVariant: " + protocolVariant); - /** - * Construct a peer address from a memorized or hardcoded address. - */ - public PeerAddress(InetAddress addr, int port, Services services, MessageSerializer serializer) { - super(serializer); - this.addr = Objects.requireNonNull(addr); - this.port = port; - this.services = services; - this.time = TimeUtils.currentTime().truncatedTo(ChronoUnit.SECONDS); - } - - /** - * Constructs a peer address from the given IP address, port and services. Version number is default for the given parameters. - */ - public PeerAddress(InetAddress addr, int port, Services services) { - this(addr, port, services, new DummySerializer(0)); - } - - /** - * Constructs a peer address from the given IP address and port. Version number is default for the given parameters. - */ - public PeerAddress(InetAddress addr, int port) { - this(addr, port, Services.none()); - } - - /** - * Constructs a peer address from an {@link InetSocketAddress}. An InetSocketAddress can take in as parameters an - * InetAddress or a String hostname. If you want to connect to a .onion, set the hostname to the .onion address. - */ - public PeerAddress(InetSocketAddress addr) { - this(addr.getAddress(), addr.getPort()); - } - - /** - * Constructs a peer address from a stringified hostname+port. Use this if you want to connect to a Tor .onion address. - */ - public PeerAddress(String hostname, int port) { - super(); - this.hostname = hostname; - this.port = port; - this.services = Services.none(); - this.time = TimeUtils.currentTime().truncatedTo(ChronoUnit.SECONDS); - } - - public static PeerAddress localhost(NetworkParameters params) { - return new PeerAddress(InetAddress.getLoopbackAddress(), params.getPort()); - } - - @Override - protected void bitcoinSerializeToStream(OutputStream stream) throws IOException { - int protocolVersion = serializer.getProtocolVersion(); - if (protocolVersion < 1 || protocolVersion > 2) - throw new IllegalStateException("invalid protocolVersion: " + protocolVersion); - - ByteUtils.writeInt32LE(time.getEpochSecond(), stream); - if (protocolVersion == 2) { - stream.write(VarInt.of(services.bits()).serialize()); - if (addr != null) { - if (addr instanceof Inet4Address) { - stream.write(0x01); - stream.write(VarInt.of(4).serialize()); - stream.write(addr.getAddress()); - } else if (addr instanceof Inet6Address) { - stream.write(0x02); - stream.write(VarInt.of(16).serialize()); - stream.write(addr.getAddress()); - } else { - throw new IllegalStateException(); - } - } else if (addr == null && hostname != null && hostname.toLowerCase(Locale.ROOT).endsWith(".onion")) { - byte[] onionAddress = BASE32.decode(hostname.substring(0, hostname.length() - 6)); - if (onionAddress.length == 10) { - // TORv2 - stream.write(0x03); - stream.write(VarInt.of(10).serialize()); - stream.write(onionAddress); - } else if (onionAddress.length == 32 + 2 + 1) { - // TORv3 - stream.write(0x04); - stream.write(VarInt.of(32).serialize()); - byte[] pubkey = Arrays.copyOfRange(onionAddress, 0, 32); - byte[] checksum = Arrays.copyOfRange(onionAddress, 32, 34); - byte torVersion = onionAddress[34]; - if (torVersion != 0x03) - throw new IllegalStateException("version"); - if (!Arrays.equals(checksum, CryptoUtils.onionChecksum(pubkey, torVersion))) - throw new IllegalStateException("checksum"); - stream.write(pubkey); - } else { - throw new IllegalStateException(); - } - } else { - throw new IllegalStateException(); - } - } else { - stream.write(services.serialize()); - if (addr != null) { - // Java does not provide any utility to map an IPv4 address into IPv6 space, so we have to do it by - // hand. - byte[] ipBytes = addr.getAddress(); - stream.write(mapIntoIPv6(ipBytes)); - } else if (hostname != null && hostname.toLowerCase(Locale.ROOT).endsWith(".onion")) { - byte[] onionAddress = BASE32.decode(hostname.substring(0, hostname.length() - 6)); - if (onionAddress.length == 10) { - // TORv2 - stream.write(ONIONCAT_PREFIX); - stream.write(onionAddress); - } else { - throw new IllegalStateException(); - } - } else { - throw new IllegalStateException(); - } - } - // And write out the port. Unlike the rest of the protocol, address and port is in big endian byte order. - ByteUtils.writeInt16BE(port, stream); - } - - @Override - protected void parse(ByteBuffer payload) throws BufferUnderflowException, ProtocolException { - int protocolVersion = serializer.getProtocolVersion(); - if (protocolVersion < 1 || protocolVersion > 2) - throw new IllegalStateException("invalid protocolVersion: " + protocolVersion); - - time = Instant.ofEpochSecond(ByteUtils.readUint32(payload)); - if (protocolVersion == 2) { + Instant time = Instant.ofEpochSecond(ByteUtils.readUint32(payload)); + Services services; + InetAddress addr = null; + String hostname = null; + if (protocolVariant == 2) { services = Services.of(VarInt.read(payload).longValue()); int networkId = payload.get(); byte[] addrBytes = Buffers.readLengthPrefixedBytes(payload); @@ -279,7 +155,184 @@ public class PeerAddress extends Message { hostname = null; } } - port = ByteUtils.readUint16BE(payload); + int port = ByteUtils.readUint16BE(payload); + return new PeerAddress(addr, hostname, port, services, time); + } + + /** + * Constructs a peer address from the given IP address, port and services. + */ + public PeerAddress(InetAddress addr, int port, Services services, Instant time) { + this(addr, null, port, services, Objects.requireNonNull(time)); + } + + /** + * Constructs a peer address from the given IP address, port and services. + */ + public PeerAddress(InetAddress addr, int port, Services services) { + this(addr, null, port, services, null); + } + + /** + * Constructs a peer address from the given IP address and port. + */ + public PeerAddress(InetAddress addr, int port) { + this(addr, null, port, Services.none(), null); + } + + /** + * Constructs a peer address from an {@link InetSocketAddress}. An InetSocketAddress can take in as parameters an + * InetAddress or a String hostname. If you want to connect to a .onion, set the hostname to the .onion address. + */ + public PeerAddress(InetSocketAddress addr) { + this(addr.getAddress(), null, addr.getPort(), Services.none(), null); + } + + private PeerAddress(InetAddress addr, String hostname, int port, Services services, Instant time) { + this.addr = addr; + this.hostname = hostname; + this.port = port; + this.services = services; + this.time = time; + } + + public static PeerAddress localhost(NetworkParameters params) { + return new PeerAddress(InetAddress.getLoopbackAddress(), params.getPort()); + } + + /** + * Write this peer address into the given buffer, using a given protocol variant. The variant can be + * 1 ({@link AddressV1Message}) or 2 ({@link AddressV2Message}).. + * + * @param buf buffer to write into + * @param protocolVariant variant of protocol used + * @return the buffer + * @throws BufferOverflowException if the peer addressdoesn't fit the remaining buffer + */ + public ByteBuffer write(ByteBuffer buf, int protocolVariant) throws BufferOverflowException { + if (protocolVariant < 1 || protocolVariant > 2) + throw new IllegalStateException("invalid protocolVariant: " + protocolVariant); + + ByteUtils.writeInt32LE(time.getEpochSecond(), buf); + if (protocolVariant == 2) { + VarInt.of(services.bits()).write(buf); + if (addr != null) { + if (addr instanceof Inet4Address) { + buf.put((byte) 0x01); + VarInt.of(4).write(buf); + buf.put(addr.getAddress()); + } else if (addr instanceof Inet6Address) { + buf.put((byte) 0x02); + VarInt.of(16).write(buf); + buf.put(addr.getAddress()); + } else { + throw new IllegalStateException(); + } + } else if (addr == null && hostname != null && hostname.toLowerCase(Locale.ROOT).endsWith(".onion")) { + byte[] onionAddress = BASE32.decode(hostname.substring(0, hostname.length() - 6)); + if (onionAddress.length == 10) { + // TORv2 + buf.put((byte) 0x03); + VarInt.of(10).write(buf); + buf.put(onionAddress); + } else if (onionAddress.length == 32 + 2 + 1) { + // TORv3 + buf.put((byte) 0x04); + VarInt.of(32).write(buf); + byte[] pubkey = Arrays.copyOfRange(onionAddress, 0, 32); + byte[] checksum = Arrays.copyOfRange(onionAddress, 32, 34); + byte torVersion = onionAddress[34]; + if (torVersion != 0x03) + throw new IllegalStateException("version"); + if (!Arrays.equals(checksum, CryptoUtils.onionChecksum(pubkey, torVersion))) + throw new IllegalStateException("checksum"); + buf.put(pubkey); + } else { + throw new IllegalStateException(); + } + } else { + throw new IllegalStateException(); + } + } else { + services.write(buf); + if (addr != null) { + // Java does not provide any utility to map an IPv4 address into IPv6 space, so we have to do it by + // hand. + byte[] ipBytes = addr.getAddress(); + buf.put(mapIntoIPv6(ipBytes)); + } else if (hostname != null && hostname.toLowerCase(Locale.ROOT).endsWith(".onion")) { + byte[] onionAddress = BASE32.decode(hostname.substring(0, hostname.length() - 6)); + if (onionAddress.length == 10) { + // TORv2 + buf.put(ONIONCAT_PREFIX); + buf.put(onionAddress); + } else { + throw new IllegalStateException(); + } + } else { + throw new IllegalStateException(); + } + } + // And write out the port. Unlike the rest of the protocol, address and port is in big endian byte order. + ByteUtils.writeInt16BE(port, buf); + return buf; + } + + /** + * Allocates a byte array and writes this peer address into it, using a given protocol variant. The variant can be + * 1 ({@link AddressV1Message}) or 2 ({@link AddressV2Message}). + * + * @param protocolVariant variant of protocol used + * @return byte array containing the peer address + */ + public byte[] serialize(int protocolVariant) { + return write(ByteBuffer.allocate(getMessageSize(protocolVariant)), protocolVariant).array(); + } + + /** + * Return the size of the serialized message, using a given protocol variant. The variant can be + * 1 ({@link AddressV1Message}) or 2 ({@link AddressV2Message}).. Note that if the message was deserialized from + * a payload, this size can differ from the size of the original payload. + * + * @param protocolVariant variant of protocol used + * @return size of the serialized message in bytes + */ + public int getMessageSize(int protocolVariant) { + if (protocolVariant < 1 || protocolVariant > 2) + throw new IllegalStateException("invalid protocolVariant: " + protocolVariant); + int size = 0; + size += 4; // time + if (protocolVariant == 2) { + size += VarInt.sizeOf(services.bits()); + size += 1; // network id + if (addr != null) { + if (addr instanceof Inet4Address) { + size += VarInt.sizeOf(4) + 4; + } else if (addr instanceof Inet6Address) { + size += VarInt.sizeOf(16) + 16; + } else { + throw new IllegalStateException(); + } + } else if (addr == null && hostname != null && hostname.toLowerCase(Locale.ROOT).endsWith(".onion")) { + byte[] onionAddress = BASE32.decode(hostname.substring(0, hostname.length() - 6)); + if (onionAddress.length == 10) { + // TORv2 + size += VarInt.sizeOf(10) + 10; + } else if (onionAddress.length == 32 + 2 + 1) { + // TORv3 + size += VarInt.sizeOf(32) + 32; + } else { + throw new IllegalStateException(); + } + } else { + throw new IllegalStateException(); + } + } else { + size += Services.BYTES; + size += 16; // ip + } + size += 2; // port + return size; } public static InetAddress getByAddress(byte[] addrBytes) { diff --git a/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java b/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java index ea20ec0b7..c8fbd703f 100644 --- a/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java +++ b/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java @@ -19,6 +19,7 @@ package org.bitcoinj.core; import com.google.common.io.BaseEncoding; import org.bitcoinj.base.internal.ByteUtils; +import org.bitcoinj.base.internal.TimeUtils; import org.bitcoinj.params.MainNetParams; import org.bitcoinj.params.TestNet3Params; import org.junit.Test; @@ -28,6 +29,7 @@ import java.math.BigInteger; import java.net.InetAddress; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; +import java.time.temporal.ChronoUnit; import java.util.Arrays; import static org.junit.Assert.assertArrayEquals; @@ -76,7 +78,7 @@ public class BitcoinSerializerTest { assertEquals(31, addressMessage.getMessageSize()); addressMessage.addAddress(new PeerAddress(InetAddress.getLocalHost(), MAINNET.getPort(), - Services.none(), new DummySerializer(1))); + Services.none(), TimeUtils.currentTime().truncatedTo(ChronoUnit.SECONDS))); bos = new ByteArrayOutputStream(61); serializer.serialize(addressMessage, bos); assertEquals(61, addressMessage.getMessageSize()); diff --git a/core/src/test/java/org/bitcoinj/core/PeerAddressTest.java b/core/src/test/java/org/bitcoinj/core/PeerAddressTest.java index 4fd4b314c..61be27b35 100644 --- a/core/src/test/java/org/bitcoinj/core/PeerAddressTest.java +++ b/core/src/test/java/org/bitcoinj/core/PeerAddressTest.java @@ -44,7 +44,7 @@ public class PeerAddressTest { public void equalsContract() { EqualsVerifier.forClass(PeerAddress.class) .suppress(Warning.NONFINAL_FIELDS) - .withIgnoredFields("time", "serializer") + .withIgnoredFields("time") .usingGetClass() .verify(); } @@ -52,10 +52,9 @@ public class PeerAddressTest { @Test public void roundtrip_ipv4_addressV2Variant() throws Exception { Instant time = TimeUtils.currentTime().truncatedTo(ChronoUnit.SECONDS); - MessageSerializer serializer = new DummySerializer(2); - PeerAddress pa = new PeerAddress(InetAddress.getByName("1.2.3.4"), 1234, Services.none(), serializer); - byte[] serialized = pa.bitcoinSerialize(); - PeerAddress pa2 = new PeerAddress(ByteBuffer.wrap(serialized), serializer); + PeerAddress pa = new PeerAddress(InetAddress.getByName("1.2.3.4"), 1234, Services.none(), time); + byte[] serialized = pa.serialize(2); + PeerAddress pa2 = PeerAddress.read(ByteBuffer.wrap(serialized), 2); assertEquals("1.2.3.4", pa2.getAddr().getHostAddress()); assertEquals(1234, pa2.getPort()); assertEquals(Services.none(), pa2.getServices()); @@ -65,10 +64,9 @@ public class PeerAddressTest { @Test public void roundtrip_ipv4_addressVariant() throws Exception { Instant time = TimeUtils.currentTime().truncatedTo(ChronoUnit.SECONDS); - MessageSerializer serializer = new DummySerializer(1); - PeerAddress pa = new PeerAddress(InetAddress.getByName("1.2.3.4"), 1234, Services.none(), serializer); - byte[] serialized = pa.bitcoinSerialize(); - PeerAddress pa2 = new PeerAddress(ByteBuffer.wrap(serialized), serializer); + PeerAddress pa = new PeerAddress(InetAddress.getByName("1.2.3.4"), 1234, Services.none(), time); + byte[] serialized = pa.serialize(1); + PeerAddress pa2 = PeerAddress.read(ByteBuffer.wrap(serialized), 1); assertEquals("1.2.3.4", pa2.getAddr().getHostAddress()); assertEquals(1234, pa2.getPort()); assertEquals(Services.none(), pa2.getServices()); @@ -78,11 +76,10 @@ public class PeerAddressTest { @Test public void roundtrip_ipv6_addressV2Variant() throws Exception { Instant time = TimeUtils.currentTime().truncatedTo(ChronoUnit.SECONDS); - MessageSerializer serializer = new DummySerializer(2); PeerAddress pa = new PeerAddress(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334"), 1234, - Services.none(), serializer); - byte[] serialized = pa.bitcoinSerialize(); - PeerAddress pa2 = new PeerAddress(ByteBuffer.wrap(serialized), serializer); + Services.none(), time); + byte[] serialized = pa.serialize(2); + PeerAddress pa2 = PeerAddress.read(ByteBuffer.wrap(serialized), 2); assertEquals("2001:db8:85a3:0:0:8a2e:370:7334", pa2.getAddr().getHostAddress()); assertEquals(1234, pa2.getPort()); assertEquals(Services.none(), pa2.getServices()); @@ -92,11 +89,10 @@ public class PeerAddressTest { @Test public void roundtrip_ipv6_addressVariant() throws Exception { Instant time = TimeUtils.currentTime().truncatedTo(ChronoUnit.SECONDS); - MessageSerializer serializer = new DummySerializer(1); PeerAddress pa = new PeerAddress(InetAddress.getByName("2001:db8:85a3:0:0:8a2e:370:7334"), 1234, - Services.none(), serializer); - byte[] serialized = pa.bitcoinSerialize(); - PeerAddress pa2 = new PeerAddress(ByteBuffer.wrap(serialized), serializer); + Services.none(), time); + byte[] serialized = pa.serialize(1); + PeerAddress pa2 = PeerAddress.read(ByteBuffer.wrap(serialized), 1); assertEquals("2001:db8:85a3:0:0:8a2e:370:7334", pa2.getAddr().getHostAddress()); assertEquals(1234, pa2.getPort()); assertEquals(Services.none(), pa2.getServices()); @@ -106,8 +102,7 @@ public class PeerAddressTest { @Test @Parameters(method = "deserializeToStringValues") public void deserializeToString(int version, String expectedToString, String hex) { - MessageSerializer serializer = new DummySerializer(version); - PeerAddress pa = new PeerAddress(ByteBuffer.wrap(ByteUtils.parseHex(hex)), serializer); + PeerAddress pa = PeerAddress.read(ByteBuffer.wrap(ByteUtils.parseHex(hex)), version); assertEquals(expectedToString, pa.toString()); }