diff --git a/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java b/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java index 4d48eb43..3c337e38 100644 --- a/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java +++ b/core/src/test/java/org/bitcoinj/core/BitcoinSerializerTest.java @@ -30,10 +30,10 @@ import static org.bitcoinj.core.Utils.HEX; import static org.junit.Assert.*; public class BitcoinSerializerTest { - private final byte[] addrMessage = HEX.decode("f9beb4d96164647200000000000000001f000000" + + private static final byte[] ADDRESS_MESSAGE_BYTES = HEX.decode("f9beb4d96164647200000000000000001f000000" + "ed52399b01e215104d010000000000000000000000000000000000ffff0a000001208d"); - private final byte[] txMessage = HEX.withSeparator(" ", 2).decode( + private static final byte[] TRANSACTION_MESSAGE_BYTES = HEX.withSeparator(" ", 2).decode( "f9 be b4 d9 74 78 00 00 00 00 00 00 00 00 00 00" + "02 01 00 00 e2 93 cd be 01 00 00 00 01 6d bd db" + "08 5b 1d 8a f7 51 84 f0 bc 01 fa d5 8d 12 66 e9" + @@ -55,21 +55,21 @@ public class BitcoinSerializerTest { @Test public void testAddr() throws Exception { - MessageSerializer bs = MainNetParams.get().getDefaultSerializer(); + MessageSerializer serializer = MainNetParams.get().getDefaultSerializer(); // the actual data from https://en.bitcoin.it/wiki/Protocol_specification#addr - AddressMessage a = (AddressMessage)bs.deserialize(ByteBuffer.wrap(addrMessage)); - assertEquals(1, a.getAddresses().size()); - PeerAddress pa = a.getAddresses().get(0); - assertEquals(8333, pa.getPort()); - assertEquals("10.0.0.1", pa.getAddr().getHostAddress()); - ByteArrayOutputStream bos = new ByteArrayOutputStream(addrMessage.length); - bs.serialize(a, bos); + AddressMessage addressMessage = (AddressMessage) serializer.deserialize(ByteBuffer.wrap(ADDRESS_MESSAGE_BYTES)); + assertEquals(1, addressMessage.getAddresses().size()); + PeerAddress peerAddress = addressMessage.getAddresses().get(0); + assertEquals(8333, peerAddress.getPort()); + assertEquals("10.0.0.1", peerAddress.getAddr().getHostAddress()); + ByteArrayOutputStream bos = new ByteArrayOutputStream(ADDRESS_MESSAGE_BYTES.length); + serializer.serialize(addressMessage, bos); - assertEquals(31, a.getMessageSize()); - a.addAddress(new PeerAddress(InetAddress.getLocalHost())); - assertEquals(61, a.getMessageSize()); - a.removeAddress(0); - assertEquals(31, a.getMessageSize()); + assertEquals(31, addressMessage.getMessageSize()); + addressMessage.addAddress(new PeerAddress(InetAddress.getLocalHost())); + assertEquals(61, addressMessage.getMessageSize()); + addressMessage.removeAddress(0); + assertEquals(31, addressMessage.getMessageSize()); //this wont be true due to dynamic timestamps. //assertTrue(LazyParseByteCacheTest.arrayContains(bos.toByteArray(), addrMessage)); @@ -77,56 +77,56 @@ public class BitcoinSerializerTest { @Test public void testCachedParsing() throws Exception { - MessageSerializer bs = MainNetParams.get().getSerializer(true); + MessageSerializer serializer = MainNetParams.get().getSerializer(true); // first try writing to a fields to ensure uncaching and children are not affected - Transaction tx = (Transaction)bs.deserialize(ByteBuffer.wrap(txMessage)); - assertNotNull(tx); - assertEquals(true, tx.isCached()); + Transaction transaction = (Transaction) serializer.deserialize(ByteBuffer.wrap(TRANSACTION_MESSAGE_BYTES)); + assertNotNull(transaction); + assertTrue(transaction.isCached()); - tx.setLockTime(1); + transaction.setLockTime(1); // parent should have been uncached - assertEquals(false, tx.isCached()); + assertFalse(transaction.isCached()); // child should remain cached. - assertEquals(true, tx.getInputs().get(0).isCached()); + assertTrue(transaction.getInputs().get(0).isCached()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); - bs.serialize(tx, bos); - assertEquals(true, !Arrays.equals(txMessage, bos.toByteArray())); + serializer.serialize(transaction, bos); + assertFalse(Arrays.equals(TRANSACTION_MESSAGE_BYTES, bos.toByteArray())); // now try writing to a child to ensure uncaching is propagated up to parent but not to siblings - tx = (Transaction)bs.deserialize(ByteBuffer.wrap(txMessage)); - assertNotNull(tx); - assertEquals(true, tx.isCached()); + transaction = (Transaction) serializer.deserialize(ByteBuffer.wrap(TRANSACTION_MESSAGE_BYTES)); + assertNotNull(transaction); + assertTrue(transaction.isCached()); - tx.getInputs().get(0).setSequenceNumber(1); + transaction.getInputs().get(0).setSequenceNumber(1); // parent should have been uncached - assertEquals(false, tx.isCached()); + assertFalse(transaction.isCached()); // so should child - assertEquals(false, tx.getInputs().get(0).isCached()); + assertFalse(transaction.getInputs().get(0).isCached()); bos = new ByteArrayOutputStream(); - bs.serialize(tx, bos); - assertEquals(true, !Arrays.equals(txMessage, bos.toByteArray())); + serializer.serialize(transaction, bos); + assertFalse(Arrays.equals(TRANSACTION_MESSAGE_BYTES, bos.toByteArray())); // deserialize/reserialize to check for equals. - tx = (Transaction)bs.deserialize(ByteBuffer.wrap(txMessage)); - assertNotNull(tx); - assertEquals(true, tx.isCached()); + transaction = (Transaction) serializer.deserialize(ByteBuffer.wrap(TRANSACTION_MESSAGE_BYTES)); + assertNotNull(transaction); + assertTrue(transaction.isCached()); bos = new ByteArrayOutputStream(); - bs.serialize(tx, bos); - assertEquals(true, Arrays.equals(txMessage, bos.toByteArray())); + serializer.serialize(transaction, bos); + assertTrue(Arrays.equals(TRANSACTION_MESSAGE_BYTES, bos.toByteArray())); // deserialize/reserialize to check for equals. Set a field to it's existing value to trigger uncache - tx = (Transaction)bs.deserialize(ByteBuffer.wrap(txMessage)); - assertNotNull(tx); - assertEquals(true, tx.isCached()); + transaction = (Transaction) serializer.deserialize(ByteBuffer.wrap(TRANSACTION_MESSAGE_BYTES)); + assertNotNull(transaction); + assertTrue(transaction.isCached()); - tx.getInputs().get(0).setSequenceNumber(tx.getInputs().get(0).getSequenceNumber()); + transaction.getInputs().get(0).setSequenceNumber(transaction.getInputs().get(0).getSequenceNumber()); bos = new ByteArrayOutputStream(); - bs.serialize(tx, bos); - assertEquals(true, Arrays.equals(txMessage, bos.toByteArray())); + serializer.serialize(transaction, bos); + assertTrue(Arrays.equals(TRANSACTION_MESSAGE_BYTES, bos.toByteArray())); } /** @@ -134,43 +134,35 @@ public class BitcoinSerializerTest { */ @Test public void testHeaders1() throws Exception { - MessageSerializer bs = MainNetParams.get().getDefaultSerializer(); + MessageSerializer serializer = MainNetParams.get().getDefaultSerializer(); - String headersMessageBytesHex = "f9beb4d9686561" + + byte[] headersMessageBytes = HEX.decode("f9beb4d9686561" + "646572730000000000520000005d4fab8101010000006fe28c0ab6f1b372c1a6a246ae6" + "3f74f931e8365e15a089c68d6190000000000982051fd1e4ba744bbbe680e1fee14677b" + - "a1a3c3540bf7b1cdb606e857233e0e61bc6649ffff001d01e3629900"; - byte[] headersMessageBytes = HEX.decode(headersMessageBytesHex); - HeadersMessage hm = (HeadersMessage) bs.deserialize(ByteBuffer.wrap(headersMessageBytes)); + "a1a3c3540bf7b1cdb606e857233e0e61bc6649ffff001d01e3629900"); + HeadersMessage headersMessage = (HeadersMessage) serializer.deserialize(ByteBuffer.wrap(headersMessageBytes)); // The first block after the genesis // http://blockexplorer.com/b/1 - Block block = hm.getBlockHeaders().get(0); - String hash = block.getHashAsString(); - assertEquals(hash, "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"); - + Block block = headersMessage.getBlockHeaders().get(0); + assertEquals("00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048", block.getHashAsString()); assertNotNull(block.transactions); - - assertEquals(Utils.HEX.encode(block.getMerkleRoot().getBytes()), - "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"); + assertEquals("0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098", Utils.HEX.encode(block.getMerkleRoot().getBytes())); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - bs.serialize(hm, byteArrayOutputStream); + serializer.serialize(headersMessage, byteArrayOutputStream); byte[] serializedBytes = byteArrayOutputStream.toByteArray(); - String serializedBytesHex = HEX.encode(serializedBytes); - assertEquals(headersMessageBytes.length, serializedBytes.length); - assertEquals(true, Arrays.equals(headersMessageBytes, serializedBytes)); + assertArrayEquals(headersMessageBytes, serializedBytes); } - - @Test /** * Get 6 headers of blocks 1-6 in the chain */ + @Test public void testHeaders2() throws Exception { - MessageSerializer bs = MainNetParams.get().getDefaultSerializer(); + MessageSerializer serializer = MainNetParams.get().getDefaultSerializer(); - String headersMessageBytesHex = "f9beb4d96865616465" + + byte[] headersMessageBytes = HEX.decode("f9beb4d96865616465" + "72730000000000e701000085acd4ea06010000006fe28c0ab6f1b372c1a6a246ae63f74f931e" + "8365e15a089c68d6190000000000982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1c" + "db606e857233e0e61bc6649ffff001d01e3629900010000004860eb18bf1b1620e37e9490fc8a" + @@ -183,91 +175,63 @@ public class BitcoinSerializerTest { "a88d221c8bd6c059da090e88f8a2c99690ee55dbba4e00000000e11c48fecdd9e72510ca84f023" + "370c9a38bf91ac5cae88019bee94d24528526344c36649ffff001d1d03e4770001000000fc33f5" + "96f822a0a1951ffdbf2a897b095636ad871707bf5d3162729b00000000379dfb96a5ea8c81700ea4" + - "ac6b97ae9a9312b2d4301a29580e924ee6761a2520adc46649ffff001d189c4c9700"; - byte[] headersMessageBytes = HEX.decode(headersMessageBytesHex); - HeadersMessage hm = (HeadersMessage) bs.deserialize(ByteBuffer.wrap(headersMessageBytes)); + "ac6b97ae9a9312b2d4301a29580e924ee6761a2520adc46649ffff001d189c4c9700"); + HeadersMessage headersMessage = (HeadersMessage) serializer.deserialize(ByteBuffer.wrap(headersMessageBytes)); - int nBlocks = hm.getBlockHeaders().size(); - assertEquals(nBlocks, 6); + assertEquals(6, headersMessage.getBlockHeaders().size()); // index 0 block is the number 1 block in the block chain // http://blockexplorer.com/b/1 - Block zeroBlock = hm.getBlockHeaders().get(0); - String zeroBlockHash = zeroBlock.getHashAsString(); - + Block zeroBlock = headersMessage.getBlockHeaders().get(0); assertEquals("00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048", - zeroBlockHash); - assertEquals(zeroBlock.getNonce(), 2573394689L); - - - Block thirdBlock = hm.getBlockHeaders().get(3); - String thirdBlockHash = thirdBlock.getHashAsString(); + zeroBlock.getHashAsString()); + assertEquals(2573394689L, zeroBlock.getNonce()); // index 3 block is the number 4 block in the block chain // http://blockexplorer.com/b/4 + Block thirdBlock = headersMessage.getBlockHeaders().get(3); assertEquals("000000004ebadb55ee9096c9a2f8880e09da59c0d68b1c228da88e48844a1485", - thirdBlockHash); - assertEquals(thirdBlock.getNonce(), 2850094635L); + thirdBlock.getHashAsString()); + assertEquals(2850094635L, thirdBlock.getNonce()); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - bs.serialize(hm, byteArrayOutputStream); + serializer.serialize(headersMessage, byteArrayOutputStream); byte[] serializedBytes = byteArrayOutputStream.toByteArray(); - assertEquals(headersMessageBytes.length, serializedBytes.length); - assertEquals(true, Arrays.equals(headersMessageBytes, serializedBytes)); + assertArrayEquals(headersMessageBytes, serializedBytes); } - @Test - public void testBitcoinPacketHeader() { - try { - new BitcoinSerializer.BitcoinPacketHeader(ByteBuffer.wrap(new byte[]{0})); - fail(); - } catch (BufferUnderflowException e) { - } + @Test(expected = BufferUnderflowException.class) + public void testBitcoinPacketHeaderTooShort() { + new BitcoinSerializer.BitcoinPacketHeader(ByteBuffer.wrap(new byte[] { 0 })); + } + @Test(expected = ProtocolException.class) + public void testBitcoinPacketHeaderTooLong() { // Message with a Message size which is 1 too big, in little endian format. byte[] wrongMessageLength = HEX.decode("000000000000000000000000010000020000000000"); - try { - new BitcoinSerializer.BitcoinPacketHeader(ByteBuffer.wrap(wrongMessageLength)); - fail(); - } catch (ProtocolException e) { - // expected - } + new BitcoinSerializer.BitcoinPacketHeader(ByteBuffer.wrap(wrongMessageLength)); } - @Test + @Test(expected = BufferUnderflowException.class) public void testSeekPastMagicBytes() { // Fail in another way, there is data in the stream but no magic bytes. byte[] brokenMessage = HEX.decode("000000"); - try { - MainNetParams.get().getDefaultSerializer().seekPastMagicBytes(ByteBuffer.wrap(brokenMessage)); - fail(); - } catch (BufferUnderflowException e) { - // expected - } + MainNetParams.get().getDefaultSerializer().seekPastMagicBytes(ByteBuffer.wrap(brokenMessage)); } - @Test /** * Tests serialization of an unknown message. */ - public void testSerializeUnknownMessage() { - MessageSerializer bs = MainNetParams.get().getDefaultSerializer(); + @Test(expected = Error.class) + public void testSerializeUnknownMessage() throws Exception { + MessageSerializer serializer = MainNetParams.get().getDefaultSerializer(); - UnknownMessage a = new UnknownMessage(); - ByteArrayOutputStream bos = new ByteArrayOutputStream(addrMessage.length); - try { - bs.serialize(a, bos); - fail(); - } catch (Throwable e) { - } - } - - /** - * Unknown message for testSerializeUnknownMessage. - */ - class UnknownMessage extends Message { - @Override - protected void parse() throws ProtocolException { - } + Message unknownMessage = new Message() { + @Override + protected void parse() throws ProtocolException { + } + }; + ByteArrayOutputStream bos = new ByteArrayOutputStream(ADDRESS_MESSAGE_BYTES.length); + serializer.serialize(unknownMessage, bos); } }