diff --git a/common_test.go b/common_test.go index 29a65d41..20ffbdcd 100644 --- a/common_test.go +++ b/common_test.go @@ -32,6 +32,121 @@ func (r *fakeRandReader) Read(p []byte) (int, error) { return n, r.err } +// TestElementWire tests wire encode and decode for various element types. This +// is mainly to test the "fast" paths in readElement and writeElement which use +// type assertions to avoid reflection when possible. +func TestElementWire(t *testing.T) { + type writeElementReflect int32 + + tests := []struct { + in interface{} // Value to encode + buf []byte // Wire encoding + }{ + {int32(1), []byte{0x01, 0x00, 0x00, 0x00}}, + {uint32(256), []byte{0x00, 0x01, 0x00, 0x00}}, + { + int64(65536), + []byte{0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, + }, + { + uint64(4294967296), + []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, + }, + { + [4]byte{0x01, 0x02, 0x03, 0x04}, + []byte{0x01, 0x02, 0x03, 0x04}, + }, + { + [btcwire.CommandSize]byte{ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + }, + []byte{ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + }, + }, + { + [16]byte{ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + }, + []byte{ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + }, + }, + { + (*btcwire.ShaHash)(&[btcwire.HashSize]byte{ // Make go vet happy. + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + }), + []byte{ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + }, + }, + { + btcwire.ServiceFlag(btcwire.SFNodeNetwork), + []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }, + { + btcwire.InvType(btcwire.InvTypeTx), + []byte{0x01, 0x00, 0x00, 0x00}, + }, + { + btcwire.BitcoinNet(btcwire.MainNet), + []byte{0xf9, 0xbe, 0xb4, 0xd9}, + }, + // Type not supported by the "fast" path and requires reflection. + { + writeElementReflect(1), + []byte{0x01, 0x00, 0x00, 0x00}, + }, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + // Write to wire format. + var buf bytes.Buffer + err := btcwire.TstWriteElement(&buf, test.in) + if err != nil { + t.Errorf("writeElement #%d error %v", i, err) + continue + } + if !bytes.Equal(buf.Bytes(), test.buf) { + t.Errorf("writeElement #%d\n got: %s want: %s", i, + spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) + continue + } + + // Read from wire format. + rbuf := bytes.NewBuffer(test.buf) + val := test.in + if reflect.ValueOf(test.in).Kind() != reflect.Ptr { + val = reflect.New(reflect.TypeOf(test.in)).Interface() + } + err = btcwire.TstReadElement(rbuf, val) + if err != nil { + t.Errorf("readElement #%d error %v", i, err) + continue + } + ival := val + if reflect.ValueOf(test.in).Kind() != reflect.Ptr { + ival = reflect.Indirect(reflect.ValueOf(val)).Interface() + } + if !reflect.DeepEqual(ival, test.in) { + t.Errorf("readElement #%d\n got: %s want: %s", i, + spew.Sdump(ival), spew.Sdump(test.in)) + continue + } + } +} + // TestVarIntWire tests wire encode and decode for variable length integers. func TestVarIntWire(t *testing.T) { pver := btcwire.ProtocolVersion diff --git a/internal_test.go b/internal_test.go index e8ec3535..e18e147d 100644 --- a/internal_test.go +++ b/internal_test.go @@ -19,12 +19,28 @@ import ( // the test package. const MaxMessagePayload uint32 = maxMessagePayload +// CommandSize makes the internal commandSize constant available to the test +// package. +const CommandSize = commandSize + // TstRandomUint64 makes the internal randomUint64 function available to the // test package. func TstRandomUint64(r io.Reader) (uint64, error) { return randomUint64(r) } +// TstReadElement makes the internal readElement function available to the +// test package. +func TstReadElement(r io.Reader, element interface{}) error { + return readElement(r, element) +} + +// TstWriteElement makes the internal writeElement function available to the +// test package. +func TstWriteElement(w io.Writer, element interface{}) error { + return writeElement(w, element) +} + // TstReadVarInt makes the internal readVarInt function available to the // test package. func TstReadVarInt(r io.Reader, pver uint32) (uint64, error) { diff --git a/test_coverage.txt b/test_coverage.txt index e2d163a3..b4ef5880 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -1,96 +1,94 @@ github.com/conformal/btcwire/message.go ReadMessage 100.00% (37/37) -github.com/conformal/btcwire/msgtx.go MsgTx.BtcDecode 100.00% (33/33) +github.com/conformal/btcwire/msgtx.go MsgTx.BtcDecode 100.00% (36/36) github.com/conformal/btcwire/message.go WriteMessage 100.00% (31/31) +github.com/conformal/btcwire/msgtx.go MsgTx.BtcEncode 100.00% (26/26) github.com/conformal/btcwire/msgversion.go MsgVersion.BtcDecode 100.00% (25/25) github.com/conformal/btcwire/msgtx.go MsgTx.Copy 100.00% (24/24) -github.com/conformal/btcwire/msgtx.go MsgTx.BtcEncode 100.00% (23/23) +github.com/conformal/btcwire/msgtx.go readTxIn 100.00% (22/22) github.com/conformal/btcwire/msgversion.go MsgVersion.BtcEncode 100.00% (22/22) github.com/conformal/btcwire/common.go readVarInt 100.00% (21/21) +github.com/conformal/btcwire/netaddress.go readNetAddress 100.00% (20/20) github.com/conformal/btcwire/common.go writeVarInt 100.00% (20/20) -github.com/conformal/btcwire/msgtx.go readTxIn 100.00% (20/20) +github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.BtcDecode 100.00% (20/20) github.com/conformal/btcwire/message.go makeEmptyMessage 100.00% (20/20) github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.BtcDecode 100.00% (20/20) -github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.BtcDecode 100.00% (20/20) -github.com/conformal/btcwire/netaddress.go readNetAddress 100.00% (20/20) github.com/conformal/btcwire/msgblock.go MsgBlock.DeserializeTxLoc 100.00% (19/19) github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.BtcEncode 100.00% (18/18) github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.BtcEncode 100.00% (18/18) github.com/conformal/btcwire/msgheaders.go MsgHeaders.BtcDecode 100.00% (17/17) +github.com/conformal/btcwire/msgtx.go readTxOut 100.00% (17/17) +github.com/conformal/btcwire/msgtx.go writeTxIn 100.00% (16/16) +github.com/conformal/btcwire/msgaddr.go MsgAddr.BtcEncode 100.00% (15/15) github.com/conformal/btcwire/msgblock.go MsgBlock.BtcDecode 100.00% (15/15) github.com/conformal/btcwire/shahash.go NewShaHashFromStr 100.00% (15/15) -github.com/conformal/btcwire/msgaddr.go MsgAddr.BtcEncode 100.00% (15/15) -github.com/conformal/btcwire/msgtx.go readTxOut 100.00% (15/15) -github.com/conformal/btcwire/msgtx.go writeTxIn 100.00% (15/15) github.com/conformal/btcwire/msgheaders.go MsgHeaders.BtcEncode 100.00% (15/15) github.com/conformal/btcwire/msggetdata.go MsgGetData.BtcDecode 100.00% (14/14) -github.com/conformal/btcwire/msginv.go MsgInv.BtcDecode 100.00% (14/14) github.com/conformal/btcwire/netaddress.go writeNetAddress 100.00% (14/14) github.com/conformal/btcwire/msgnotfound.go MsgNotFound.BtcDecode 100.00% (14/14) +github.com/conformal/btcwire/msginv.go MsgInv.BtcDecode 100.00% (14/14) github.com/conformal/btcwire/msgaddr.go MsgAddr.BtcDecode 100.00% (14/14) +github.com/conformal/btcwire/msgtx.go writeTxOut 100.00% (13/13) +github.com/conformal/btcwire/msginv.go MsgInv.BtcEncode 100.00% (12/12) github.com/conformal/btcwire/msggetdata.go MsgGetData.BtcEncode 100.00% (12/12) github.com/conformal/btcwire/protocol.go ServiceFlag.String 100.00% (12/12) github.com/conformal/btcwire/msgnotfound.go MsgNotFound.BtcEncode 100.00% (12/12) -github.com/conformal/btcwire/msginv.go MsgInv.BtcEncode 100.00% (12/12) github.com/conformal/btcwire/common.go readVarString 100.00% (11/11) -github.com/conformal/btcwire/msgtx.go writeTxOut 100.00% (11/11) -github.com/conformal/btcwire/message.go discardInput 100.00% (10/10) github.com/conformal/btcwire/blockheader.go readBlockHeader 100.00% (10/10) -github.com/conformal/btcwire/msgtx.go writeOutPoint 100.00% (9/9) +github.com/conformal/btcwire/message.go discardInput 100.00% (10/10) github.com/conformal/btcwire/msgblock.go MsgBlock.BtcEncode 100.00% (9/9) github.com/conformal/btcwire/msgtx.go readOutPoint 100.00% (9/9) +github.com/conformal/btcwire/msgtx.go writeOutPoint 100.00% (9/9) +github.com/conformal/btcwire/msgalert.go MsgAlert.BtcDecode 100.00% (8/8) github.com/conformal/btcwire/blockheader.go writeBlockHeader 100.00% (8/8) github.com/conformal/btcwire/msgalert.go MsgAlert.BtcEncode 100.00% (8/8) -github.com/conformal/btcwire/msgalert.go MsgAlert.BtcDecode 100.00% (8/8) -github.com/conformal/btcwire/message.go readMessageHeader 100.00% (7/7) +github.com/conformal/btcwire/common.go varIntSerializeSize 100.00% (7/7) +github.com/conformal/btcwire/msgversion.go NewMsgVersionFromConn 100.00% (7/7) github.com/conformal/btcwire/msgpong.go MsgPong.BtcEncode 100.00% (7/7) github.com/conformal/btcwire/msgpong.go MsgPong.BtcDecode 100.00% (7/7) +github.com/conformal/btcwire/message.go readMessageHeader 100.00% (7/7) github.com/conformal/btcwire/common.go writeVarString 100.00% (7/7) -github.com/conformal/btcwire/common.go varIntSerializeSize 100.00% (7/7) github.com/conformal/btcwire/common.go randomUint64 100.00% (7/7) -github.com/conformal/btcwire/msgversion.go NewMsgVersionFromConn 100.00% (7/7) github.com/conformal/btcwire/msgtx.go MsgTx.SerializeSize 100.00% (6/6) github.com/conformal/btcwire/common.go DoubleSha256 100.00% (6/6) +github.com/conformal/btcwire/msgping.go MsgPing.BtcEncode 100.00% (5/5) +github.com/conformal/btcwire/shahash.go ShaHash.SetBytes 100.00% (5/5) +github.com/conformal/btcwire/msgnotfound.go MsgNotFound.AddInvVect 100.00% (5/5) +github.com/conformal/btcwire/common.go writeElements 100.00% (5/5) +github.com/conformal/btcwire/msgblock.go MsgBlock.TxShas 100.00% (5/5) github.com/conformal/btcwire/msgtx.go MsgTx.TxSha 100.00% (5/5) +github.com/conformal/btcwire/blockheader.go BlockHeader.BlockSha 100.00% (5/5) +github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.AddBlockLocatorHash 100.00% (5/5) +github.com/conformal/btcwire/msgping.go MsgPing.BtcDecode 100.00% (5/5) +github.com/conformal/btcwire/msggetdata.go MsgGetData.AddInvVect 100.00% (5/5) +github.com/conformal/btcwire/netaddress.go NewNetAddress 100.00% (5/5) +github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.AddBlockLocatorHash 100.00% (5/5) +github.com/conformal/btcwire/msgaddr.go MsgAddr.AddAddress 100.00% (5/5) github.com/conformal/btcwire/msgaddr.go MsgAddr.AddAddresses 100.00% (5/5) github.com/conformal/btcwire/msgheaders.go MsgHeaders.AddBlockHeader 100.00% (5/5) -github.com/conformal/btcwire/msgping.go MsgPing.BtcEncode 100.00% (5/5) -github.com/conformal/btcwire/msgblock.go MsgBlock.TxShas 100.00% (5/5) -github.com/conformal/btcwire/common.go readElements 100.00% (5/5) -github.com/conformal/btcwire/blockheader.go BlockHeader.BlockSha 100.00% (5/5) -github.com/conformal/btcwire/msgnotfound.go MsgNotFound.AddInvVect 100.00% (5/5) -github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.AddBlockLocatorHash 100.00% (5/5) -github.com/conformal/btcwire/msggetdata.go MsgGetData.AddInvVect 100.00% (5/5) -github.com/conformal/btcwire/msginv.go MsgInv.AddInvVect 100.00% (5/5) github.com/conformal/btcwire/shahash.go NewShaHash 100.00% (5/5) -github.com/conformal/btcwire/msgping.go MsgPing.BtcDecode 100.00% (5/5) -github.com/conformal/btcwire/common.go writeElements 100.00% (5/5) -github.com/conformal/btcwire/msgaddr.go MsgAddr.AddAddress 100.00% (5/5) -github.com/conformal/btcwire/shahash.go ShaHash.SetBytes 100.00% (5/5) -github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.AddBlockLocatorHash 100.00% (5/5) -github.com/conformal/btcwire/netaddress.go NewNetAddress 100.00% (5/5) -github.com/conformal/btcwire/msgmempool.go MsgMemPool.BtcEncode 100.00% (4/4) -github.com/conformal/btcwire/msgping.go MsgPing.MaxPayloadLength 100.00% (4/4) -github.com/conformal/btcwire/msgpong.go MsgPong.MaxPayloadLength 100.00% (4/4) -github.com/conformal/btcwire/invvect.go readInvVect 100.00% (4/4) -github.com/conformal/btcwire/invvect.go writeInvVect 100.00% (4/4) -github.com/conformal/btcwire/netaddress.go maxNetAddressPayload 100.00% (4/4) -github.com/conformal/btcwire/shahash.go ShaHash.String 100.00% (4/4) +github.com/conformal/btcwire/msginv.go MsgInv.AddInvVect 100.00% (5/5) +github.com/conformal/btcwire/common.go readElements 100.00% (5/5) github.com/conformal/btcwire/msgmempool.go MsgMemPool.BtcDecode 100.00% (4/4) -github.com/conformal/btcwire/shahash.go ShaHash.Bytes 100.00% (3/3) -github.com/conformal/btcwire/error.go MessageError.Error 100.00% (3/3) -github.com/conformal/btcwire/msgaddr.go MsgAddr.MaxPayloadLength 100.00% (3/3) -github.com/conformal/btcwire/msgblock.go MsgBlock.AddTransaction 100.00% (3/3) -github.com/conformal/btcwire/netaddress.go NetAddress.HasService 100.00% (3/3) +github.com/conformal/btcwire/msgmempool.go MsgMemPool.BtcEncode 100.00% (4/4) +github.com/conformal/btcwire/msgpong.go MsgPong.MaxPayloadLength 100.00% (4/4) +github.com/conformal/btcwire/shahash.go ShaHash.String 100.00% (4/4) +github.com/conformal/btcwire/netaddress.go maxNetAddressPayload 100.00% (4/4) +github.com/conformal/btcwire/invvect.go writeInvVect 100.00% (4/4) +github.com/conformal/btcwire/invvect.go readInvVect 100.00% (4/4) +github.com/conformal/btcwire/msgping.go MsgPing.MaxPayloadLength 100.00% (4/4) github.com/conformal/btcwire/msgversion.go MsgVersion.HasService 100.00% (3/3) +github.com/conformal/btcwire/msgblock.go MsgBlock.AddTransaction 100.00% (3/3) github.com/conformal/btcwire/invvect.go InvType.String 100.00% (3/3) +github.com/conformal/btcwire/error.go MessageError.Error 100.00% (3/3) +github.com/conformal/btcwire/shahash.go ShaHash.Bytes 100.00% (3/3) +github.com/conformal/btcwire/netaddress.go NetAddress.HasService 100.00% (3/3) +github.com/conformal/btcwire/msgaddr.go MsgAddr.MaxPayloadLength 100.00% (3/3) github.com/conformal/btcwire/netaddress.go NetAddress.SetAddress 100.00% (2/2) github.com/conformal/btcwire/netaddress.go NewNetAddressIPPort 100.00% (2/2) github.com/conformal/btcwire/msgblock.go MsgBlock.ClearTransactions 100.00% (2/2) github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.Command 100.00% (1/1) github.com/conformal/btcwire/blockheader.go NewBlockHeader 100.00% (1/1) -github.com/conformal/btcwire/common.go readElement 100.00% (1/1) -github.com/conformal/btcwire/common.go writeElement 100.00% (1/1) github.com/conformal/btcwire/common.go RandomUint64 100.00% (1/1) github.com/conformal/btcwire/error.go messageError 100.00% (1/1) github.com/conformal/btcwire/msgaddr.go MsgAddr.ClearAddresses 100.00% (1/1) @@ -158,5 +156,7 @@ github.com/conformal/btcwire/msgversion.go NewMsgVersion 100.00% (1/1) github.com/conformal/btcwire/netaddress.go NetAddress.AddService 100.00% (1/1) github.com/conformal/btcwire/shahash.go ShaHash.IsEqual 100.00% (1/1) github.com/conformal/btcwire/invvect.go NewInvVect 100.00% (1/1) -github.com/conformal/btcwire --------------------------------- 100.00% (990/990) +github.com/conformal/btcwire/common.go writeElement 96.77% (60/62) +github.com/conformal/btcwire/common.go readElement 96.72% (59/61) +github.com/conformal/btcwire --------------------------------- 99.64% (1120/1124)