public static VersionMessage read(ByteBuffer payload) throws BufferUnderflowException, ProtocolException {
        int clientVersion = (int) ByteUtils.readUint32(payload);
        check(clientVersion >= ProtocolVersion.MINIMUM.intValue(),
                ProtocolException::new);
        Services localServices = Services.read(payload);
        Instant time = Instant.ofEpochSecond(ByteUtils.readInt64(payload));
        Services receivingServices = Services.read(payload);
        InetAddress receivingInetAddress = PeerAddress.getByAddress(Buffers.readBytes(payload, 16));
        int receivingPort = ByteUtils.readUint16BE(payload);
        InetSocketAddress receivingAddr = new InetSocketAddress(receivingInetAddress, receivingPort);
        Buffers.skipBytes(payload, NETADDR_BYTES); // addr_from
        // uint64 localHostNonce (random data)
        // We don't care about the localhost nonce. It's used to detect connecting back to yourself in cases where
        // there are NATs and proxies in the way. However we don't listen for inbound connections so it's
        // irrelevant.
        Buffers.skipBytes(payload, 8);
        // string subVer (currently "")
        String subVer = Buffers.readLengthPrefixedString(payload);
        // int bestHeight (size of known block chain).
        long bestHeight = ByteUtils.readUint32(payload);
        boolean relayTxesBeforeFilter = clientVersion >= ProtocolVersion.BLOOM_FILTER.intValue() ?
                payload.get() != 0 :
                true;
        return new VersionMessage(clientVersion, localServices, time, receivingServices, receivingAddr, subVer,
                bestHeight, relayTxesBeforeFilter);
    }
@Test
    public void roundTrip_ipv4() throws Exception {
        VersionMessage ver = new VersionMessage(TESTNET, 1234);
        ver.time = Instant.ofEpochSecond(23456);
        ver.subVer = "/bitcoinj/";
        ver.localServices = Services.of(1);
        ver.receivingAddr = new InetSocketAddress(InetAddress.getByName("4.3.2.1"), 8333);
        byte[] serialized = ver.serialize();
        VersionMessage ver2 = VersionMessage.read(ByteBuffer.wrap(serialized));
        assertEquals(1234, ver2.bestHeight);
        assertEquals(Instant.ofEpochSecond(23456), ver2.time);
        assertEquals("/bitcoinj/", ver2.subVer);
        assertEquals(ProtocolVersion.CURRENT.intValue(), ver2.clientVersion);
        assertEquals(1, ver2.localServices.bits());
        assertEquals("4.3.2.1", ver2.receivingAddr.getHostName());
        assertEquals(8333, ver2.receivingAddr.getPort());
    }