diff --git a/wire/bench_test.go b/wire/bench_test.go index 517fafa4..c329a347 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -394,7 +394,7 @@ func BenchmarkDecodeGetHeaders(b *testing.B) { // Serialize it so the bytes are available to test the decode below. var bb bytes.Buffer - if err := m.BtcEncode(&bb, pver); err != nil { + if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { b.Fatalf("MsgGetHeaders.BtcEncode: unexpected error: %v", err) } buf := bb.Bytes() @@ -404,7 +404,7 @@ func BenchmarkDecodeGetHeaders(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { r.Seek(0, 0) - msg.BtcDecode(r, pver) + msg.BtcDecode(r, pver, LatestEncoding) } } @@ -424,7 +424,7 @@ func BenchmarkDecodeHeaders(b *testing.B) { // Serialize it so the bytes are available to test the decode below. var bb bytes.Buffer - if err := m.BtcEncode(&bb, pver); err != nil { + if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { b.Fatalf("MsgHeaders.BtcEncode: unexpected error: %v", err) } buf := bb.Bytes() @@ -434,7 +434,7 @@ func BenchmarkDecodeHeaders(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { r.Seek(0, 0) - msg.BtcDecode(r, pver) + msg.BtcDecode(r, pver, LatestEncoding) } } @@ -454,7 +454,7 @@ func BenchmarkDecodeGetBlocks(b *testing.B) { // Serialize it so the bytes are available to test the decode below. var bb bytes.Buffer - if err := m.BtcEncode(&bb, pver); err != nil { + if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { b.Fatalf("MsgGetBlocks.BtcEncode: unexpected error: %v", err) } buf := bb.Bytes() @@ -464,7 +464,7 @@ func BenchmarkDecodeGetBlocks(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { r.Seek(0, 0) - msg.BtcDecode(r, pver) + msg.BtcDecode(r, pver, LatestEncoding) } } @@ -481,7 +481,7 @@ func BenchmarkDecodeAddr(b *testing.B) { // Serialize it so the bytes are available to test the decode below. var bb bytes.Buffer - if err := ma.BtcEncode(&bb, pver); err != nil { + if err := ma.BtcEncode(&bb, pver, LatestEncoding); err != nil { b.Fatalf("MsgAddr.BtcEncode: unexpected error: %v", err) } buf := bb.Bytes() @@ -491,7 +491,7 @@ func BenchmarkDecodeAddr(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { r.Seek(0, 0) - msg.BtcDecode(r, pver) + msg.BtcDecode(r, pver, LatestEncoding) } } @@ -511,7 +511,7 @@ func BenchmarkDecodeInv(b *testing.B) { // Serialize it so the bytes are available to test the decode below. var bb bytes.Buffer - if err := m.BtcEncode(&bb, pver); err != nil { + if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { b.Fatalf("MsgInv.BtcEncode: unexpected error: %v", err) } buf := bb.Bytes() @@ -521,7 +521,7 @@ func BenchmarkDecodeInv(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { r.Seek(0, 0) - msg.BtcDecode(r, pver) + msg.BtcDecode(r, pver, LatestEncoding) } } @@ -541,7 +541,7 @@ func BenchmarkDecodeNotFound(b *testing.B) { // Serialize it so the bytes are available to test the decode below. var bb bytes.Buffer - if err := m.BtcEncode(&bb, pver); err != nil { + if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { b.Fatalf("MsgNotFound.BtcEncode: unexpected error: %v", err) } buf := bb.Bytes() @@ -551,7 +551,7 @@ func BenchmarkDecodeNotFound(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { r.Seek(0, 0) - msg.BtcDecode(r, pver) + msg.BtcDecode(r, pver, LatestEncoding) } } @@ -579,7 +579,7 @@ func BenchmarkDecodeMerkleBlock(b *testing.B) { // Serialize it so the bytes are available to test the decode below. var bb bytes.Buffer - if err := m.BtcEncode(&bb, pver); err != nil { + if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { b.Fatalf("MsgMerkleBlock.BtcEncode: unexpected error: %v", err) } buf := bb.Bytes() @@ -589,7 +589,7 @@ func BenchmarkDecodeMerkleBlock(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { r.Seek(0, 0) - msg.BtcDecode(r, pver) + msg.BtcDecode(r, pver, LatestEncoding) } } diff --git a/wire/blockheader.go b/wire/blockheader.go index c2c0ae03..892cf3ca 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -60,7 +60,7 @@ func (h *BlockHeader) BlockHash() chainhash.Hash { // This is part of the Message interface implementation. // See Deserialize for decoding block headers stored to disk, such as in a // database, as opposed to decoding block headers from the wire. -func (h *BlockHeader) BtcDecode(r io.Reader, pver uint32) error { +func (h *BlockHeader) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { return readBlockHeader(r, pver, h) } @@ -68,7 +68,7 @@ func (h *BlockHeader) BtcDecode(r io.Reader, pver uint32) error { // This is part of the Message interface implementation. // See Serialize for encoding block headers to be stored to disk, such as in a // database, as opposed to encoding block headers for the wire. -func (h *BlockHeader) BtcEncode(w io.Writer, pver uint32) error { +func (h *BlockHeader) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { return writeBlockHeader(w, pver, h) } diff --git a/wire/blockheader_test.go b/wire/blockheader_test.go index 2035b1aa..fef06967 100644 --- a/wire/blockheader_test.go +++ b/wire/blockheader_test.go @@ -79,10 +79,11 @@ func TestBlockHeaderWire(t *testing.T) { } tests := []struct { - in *BlockHeader // Data to encode - out *BlockHeader // Expected decoded data - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *BlockHeader // Data to encode + out *BlockHeader // Expected decoded data + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding variant to use }{ // Latest protocol version. { @@ -90,6 +91,7 @@ func TestBlockHeaderWire(t *testing.T) { baseBlockHdr, baseBlockHdrEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version. @@ -98,6 +100,7 @@ func TestBlockHeaderWire(t *testing.T) { baseBlockHdr, baseBlockHdrEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version. @@ -106,6 +109,7 @@ func TestBlockHeaderWire(t *testing.T) { baseBlockHdr, baseBlockHdrEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion. @@ -114,6 +118,7 @@ func TestBlockHeaderWire(t *testing.T) { baseBlockHdr, baseBlockHdrEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion. @@ -122,6 +127,7 @@ func TestBlockHeaderWire(t *testing.T) { baseBlockHdr, baseBlockHdrEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -141,7 +147,7 @@ func TestBlockHeaderWire(t *testing.T) { } buf.Reset() - err = test.in.BtcEncode(&buf, pver) + err = test.in.BtcEncode(&buf, pver, 0) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -167,7 +173,7 @@ func TestBlockHeaderWire(t *testing.T) { } rbuf = bytes.NewReader(test.buf) - err = bh.BtcDecode(rbuf, pver) + err = bh.BtcDecode(rbuf, pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue diff --git a/wire/fakemessage_test.go b/wire/fakemessage_test.go index 17f38c57..e3a2342d 100644 --- a/wire/fakemessage_test.go +++ b/wire/fakemessage_test.go @@ -15,15 +15,16 @@ type fakeMessage struct { forceLenErr bool } -// BtcDecode doesn't do anything. It just satisfies the Message interface. -func (msg *fakeMessage) BtcDecode(r io.Reader, pver uint32) error { +// BtcDecode doesn't do anything. It just satisfies the wire.Message +// interface. +func (msg *fakeMessage) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { return nil } // BtcEncode writes the payload field of the fake message or forces an error // if the forceEncodeErr flag of the fake message is set. It also satisfies the -// Message interface. -func (msg *fakeMessage) BtcEncode(w io.Writer, pver uint32) error { +// wire.Message interface. +func (msg *fakeMessage) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { if msg.forceEncodeErr { err := &MessageError{ Func: "fakeMessage.BtcEncode", diff --git a/wire/message.go b/wire/message.go index c2edcdac..84ffef9b 100644 --- a/wire/message.go +++ b/wire/message.go @@ -53,13 +53,31 @@ const ( CmdFeeFilter = "feefilter" ) +// WireEncoding represents the wire message encoding format to be used. +type MessageEncoding uint32 + +const ( + // BaseEncoding encodes all messages in the default format specified + // for the Bitcoin wire protocol. + BaseEncoding MessageEncoding = 1 << iota + + // WitnessEncoding encodes all messages other than transaction messages + // using the default Bitcoin wire protocol specification. For transaction + // messages, the new encoding format detailed in BIP0144 will be used. + WitnessEncoding +) + +// LatestEncoding is the most recently specified encoding for the Bitcoin wire +// protocol. +var LatestEncoding = WitnessEncoding + // Message is an interface that describes a bitcoin message. A type that // implements Message has complete control over the representation of its data // and may therefore contain additional or fewer fields than those which // are used directly in the protocol encoded message. type Message interface { - BtcDecode(io.Reader, uint32) error - BtcEncode(io.Writer, uint32) error + BtcDecode(io.Reader, uint32, MessageEncoding) error + BtcEncode(io.Writer, uint32, MessageEncoding) error Command() string MaxPayloadLength(uint32) uint32 } @@ -200,6 +218,27 @@ func discardInput(r io.Reader, n uint32) { // information and returns the number of bytes written. This function is the // same as WriteMessage except it also returns the number of bytes written. func WriteMessageN(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) (int, error) { + return WriteMessageWithEncodingN(w, msg, pver, btcnet, BaseEncoding) +} + +// WriteMessage writes a bitcoin Message to w including the necessary header +// information. This function is the same as WriteMessageN except it doesn't +// doesn't return the number of bytes written. This function is mainly provided +// for backwards compatibility with the original API, but it's also useful for +// callers that don't care about byte counts. +func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) error { + _, err := WriteMessageN(w, msg, pver, btcnet) + return err +} + +// WriteMessageWithEncodingN writes a bitcoin Message to w including the +// necessary header information and returns the number of bytes written. +// This function is the same as WriteMessageN except it also allows the caller +// to specify the message encoding format to be used when serializing wire +// messages. +func WriteMessageWithEncodingN(w io.Writer, msg Message, pver uint32, + btcnet BitcoinNet, encoding MessageEncoding) (int, error) { + totalBytes := 0 // Enforce max command size. @@ -214,7 +253,7 @@ func WriteMessageN(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) (in // Encode the message payload. var bw bytes.Buffer - err := msg.BtcEncode(&bw, pver) + err := msg.BtcEncode(&bw, pver, encoding) if err != nil { return totalBytes, err } @@ -264,22 +303,15 @@ func WriteMessageN(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) (in return totalBytes, err } -// WriteMessage writes a bitcoin Message to w including the necessary header -// information. This function is the same as WriteMessageN except it doesn't -// doesn't return the number of bytes written. This function is mainly provided -// for backwards compatibility with the original API, but it's also useful for -// callers that don't care about byte counts. -func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) error { - _, err := WriteMessageN(w, msg, pver, btcnet) - return err -} +// ReadMessageWithEncodingN reads, validates, and parses the next bitcoin Message +// from r for the provided protocol version and bitcoin network. It returns the +// number of bytes read in addition to the parsed Message and raw bytes which +// comprise the message. This function is the same as ReadMessageN except it +// allows the caller to specify which message encoding is to to consult when +// decoding wire messages. +func ReadMessageWithEncodingN(r io.Reader, pver uint32, btcnet BitcoinNet, + enc MessageEncoding) (int, Message, []byte, error) { -// ReadMessageN reads, validates, and parses the next bitcoin Message from r for -// the provided protocol version and bitcoin network. It returns the number of -// bytes read in addition to the parsed Message and raw bytes which comprise the -// message. This function is the same as ReadMessage except it also returns the -// number of bytes read. -func ReadMessageN(r io.Reader, pver uint32, btcnet BitcoinNet) (int, Message, []byte, error) { totalBytes := 0 n, hdr, err := readMessageHeader(r) totalBytes += n @@ -351,7 +383,7 @@ func ReadMessageN(r io.Reader, pver uint32, btcnet BitcoinNet) (int, Message, [] // Unmarshal message. NOTE: This must be a *bytes.Buffer since the // MsgVersion BtcDecode function requires it. pr := bytes.NewBuffer(payload) - err = msg.BtcDecode(pr, pver) + err = msg.BtcDecode(pr, pver, enc) if err != nil { return totalBytes, nil, nil, err } @@ -359,6 +391,15 @@ func ReadMessageN(r io.Reader, pver uint32, btcnet BitcoinNet) (int, Message, [] return totalBytes, msg, payload, nil } +// ReadMessageN reads, validates, and parses the next bitcoin Message from r for +// the provided protocol version and bitcoin network. It returns the number of +// bytes read in addition to the parsed Message and raw bytes which comprise the +// message. This function is the same as ReadMessage except it also returns the +// number of bytes read. +func ReadMessageN(r io.Reader, pver uint32, btcnet BitcoinNet) (int, Message, []byte, error) { + return ReadMessageWithEncodingN(r, pver, btcnet, BaseEncoding) +} + // ReadMessage reads, validates, and parses the next bitcoin Message from r for // the provided protocol version and bitcoin network. It returns the parsed // Message and raw bytes which comprise the message. This function only differs diff --git a/wire/msgaddr.go b/wire/msgaddr.go index f64f9267..ce945c8c 100644 --- a/wire/msgaddr.go +++ b/wire/msgaddr.go @@ -57,7 +57,7 @@ func (msg *MsgAddr) ClearAddresses() { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { count, err := ReadVarInt(r, pver) if err != nil { return err @@ -85,7 +85,7 @@ func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgAddr) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgAddr) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { // Protocol versions before MultipleAddressVersion only allowed 1 address // per message. count := len(msg.AddrList) diff --git a/wire/msgaddr_test.go b/wire/msgaddr_test.go index fc466e03..7516d324 100644 --- a/wire/msgaddr_test.go +++ b/wire/msgaddr_test.go @@ -139,10 +139,11 @@ func TestAddrWire(t *testing.T) { } tests := []struct { - in *MsgAddr // Message to encode - out *MsgAddr // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgAddr // Message to encode + out *MsgAddr // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version with no addresses. { @@ -150,6 +151,7 @@ func TestAddrWire(t *testing.T) { noAddr, noAddrEncoded, ProtocolVersion, + BaseEncoding, }, // Latest protocol version with multiple addresses. @@ -158,6 +160,7 @@ func TestAddrWire(t *testing.T) { multiAddr, multiAddrEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion-1 with no addresses. @@ -166,6 +169,7 @@ func TestAddrWire(t *testing.T) { noAddr, noAddrEncoded, MultipleAddressVersion - 1, + BaseEncoding, }, } @@ -173,7 +177,7 @@ func TestAddrWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -187,7 +191,7 @@ func TestAddrWire(t *testing.T) { // Decode the message from wire format. var msg MsgAddr rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -251,30 +255,31 @@ func TestAddrWireErrors(t *testing.T) { } tests := []struct { - in *MsgAddr // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgAddr // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Latest protocol version with intentional read/write errors. // Force error in addresses count - {baseAddr, baseAddrEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {baseAddr, baseAddrEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in address list. - {baseAddr, baseAddrEncoded, pver, 1, io.ErrShortWrite, io.EOF}, + {baseAddr, baseAddrEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF}, // Force error with greater than max inventory vectors. - {maxAddr, maxAddrEncoded, pver, 3, wireErr, wireErr}, + {maxAddr, maxAddrEncoded, pver, BaseEncoding, 3, wireErr, wireErr}, // Force error with greater than max inventory vectors for // protocol versions before multiple addresses were allowed. - {maxAddr, maxAddrEncoded, pverMA - 1, 3, wireErr, wireErr}, + {maxAddr, maxAddrEncoded, pverMA - 1, BaseEncoding, 3, wireErr, wireErr}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -294,7 +299,7 @@ func TestAddrWireErrors(t *testing.T) { // Decode from wire format. var msg MsgAddr r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msgalert.go b/wire/msgalert.go index 8bddae19..71c4e220 100644 --- a/wire/msgalert.go +++ b/wire/msgalert.go @@ -333,7 +333,7 @@ type MsgAlert struct { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgAlert) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgAlert) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { var err error msg.SerializedPayload, err = ReadVarBytes(r, pver, MaxMessagePayload, @@ -354,7 +354,7 @@ func (msg *MsgAlert) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgAlert) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgAlert) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { var err error var serializedpayload []byte if msg.Payload != nil { diff --git a/wire/msgalert_test.go b/wire/msgalert_test.go index 82c3ccce..7c34419d 100644 --- a/wire/msgalert_test.go +++ b/wire/msgalert_test.go @@ -16,6 +16,7 @@ import ( // TestMsgAlert tests the MsgAlert API. func TestMsgAlert(t *testing.T) { pver := ProtocolVersion + encoding := BaseEncoding serializedpayload := []byte("some message") signature := []byte("some sig") @@ -48,7 +49,7 @@ func TestMsgAlert(t *testing.T) { // Test BtcEncode with Payload == nil var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) + err := msg.BtcEncode(&buf, pver, encoding) if err != nil { t.Error(err.Error()) } @@ -65,7 +66,7 @@ func TestMsgAlert(t *testing.T) { // note: Payload is an empty Alert but not nil msg.Payload = new(Alert) buf = *new(bytes.Buffer) - err = msg.BtcEncode(&buf, pver) + err = msg.BtcEncode(&buf, pver, encoding) if err != nil { t.Error(err.Error()) } @@ -94,10 +95,11 @@ func TestMsgAlertWire(t *testing.T) { } tests := []struct { - in *MsgAlert // Message to encode - out *MsgAlert // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgAlert // Message to encode + out *MsgAlert // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version. { @@ -105,6 +107,7 @@ func TestMsgAlertWire(t *testing.T) { baseMsgAlert, baseMsgAlertEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version. @@ -113,6 +116,7 @@ func TestMsgAlertWire(t *testing.T) { baseMsgAlert, baseMsgAlertEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version. @@ -121,6 +125,7 @@ func TestMsgAlertWire(t *testing.T) { baseMsgAlert, baseMsgAlertEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion. @@ -129,6 +134,7 @@ func TestMsgAlertWire(t *testing.T) { baseMsgAlert, baseMsgAlertEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion. @@ -137,6 +143,7 @@ func TestMsgAlertWire(t *testing.T) { baseMsgAlert, baseMsgAlertEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -144,7 +151,7 @@ func TestMsgAlertWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -158,7 +165,7 @@ func TestMsgAlertWire(t *testing.T) { // Decode the message from wire format. var msg MsgAlert rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -175,6 +182,7 @@ func TestMsgAlertWire(t *testing.T) { // of MsgAlert to confirm error paths work correctly. func TestMsgAlertWireErrors(t *testing.T) { pver := ProtocolVersion + encoding := BaseEncoding baseMsgAlert := NewMsgAlert([]byte("some payload"), []byte("somesig")) baseMsgAlertEncoded := []byte{ @@ -186,28 +194,29 @@ func TestMsgAlertWireErrors(t *testing.T) { } tests := []struct { - in *MsgAlert // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgAlert // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Force error in payload length. - {baseMsgAlert, baseMsgAlertEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in payload. - {baseMsgAlert, baseMsgAlertEncoded, pver, 1, io.ErrShortWrite, io.EOF}, + {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF}, // Force error in signature length. - {baseMsgAlert, baseMsgAlertEncoded, pver, 13, io.ErrShortWrite, io.EOF}, + {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 13, io.ErrShortWrite, io.EOF}, // Force error in signature. - {baseMsgAlert, baseMsgAlertEncoded, pver, 14, io.ErrShortWrite, io.EOF}, + {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 14, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -227,7 +236,7 @@ func TestMsgAlertWireErrors(t *testing.T) { // Decode from wire format. var msg MsgAlert r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) @@ -248,7 +257,7 @@ func TestMsgAlertWireErrors(t *testing.T) { // Test Error on empty Payload baseMsgAlert.SerializedPayload = []byte{} w := new(bytes.Buffer) - err := baseMsgAlert.BtcEncode(w, pver) + err := baseMsgAlert.BtcEncode(w, pver, encoding) if _, ok := err.(*MessageError); !ok { t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T", err, MessageError{}) @@ -259,7 +268,7 @@ func TestMsgAlertWireErrors(t *testing.T) { baseMsgAlert.Payload = new(Alert) baseMsgAlert.Payload.SetCancel = make([]int32, maxCountSetCancel+1) buf := *new(bytes.Buffer) - err = baseMsgAlert.BtcEncode(&buf, pver) + err = baseMsgAlert.BtcEncode(&buf, pver, encoding) if _, ok := err.(*MessageError); !ok { t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T", err, MessageError{}) @@ -269,7 +278,7 @@ func TestMsgAlertWireErrors(t *testing.T) { baseMsgAlert.Payload = new(Alert) baseMsgAlert.Payload.SetSubVer = make([]string, maxCountSetSubVer+1) buf = *new(bytes.Buffer) - err = baseMsgAlert.BtcEncode(&buf, pver) + err = baseMsgAlert.BtcEncode(&buf, pver, encoding) if _, ok := err.(*MessageError); !ok { t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T", err, MessageError{}) diff --git a/wire/msgblock.go b/wire/msgblock.go index 058baa88..73c264a5 100644 --- a/wire/msgblock.go +++ b/wire/msgblock.go @@ -60,7 +60,7 @@ func (msg *MsgBlock) ClearTransactions() { // This is part of the Message interface implementation. // See Deserialize for decoding blocks stored to disk, such as in a database, as // opposed to decoding blocks from the wire. -func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { err := readBlockHeader(r, pver, &msg.Header) if err != nil { return err @@ -83,7 +83,7 @@ func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32) error { msg.Transactions = make([]*MsgTx, 0, txCount) for i := uint64(0); i < txCount; i++ { tx := MsgTx{} - err := tx.BtcDecode(r, pver) + err := tx.BtcDecode(r, pver, enc) if err != nil { return err } @@ -106,7 +106,19 @@ func (msg *MsgBlock) Deserialize(r io.Reader) error { // At the current time, there is no difference between the wire encoding // at protocol version 0 and the stable long-term storage format. As // a result, make use of BtcDecode. - return msg.BtcDecode(r, 0) + // + // Passing an encoding type of WitnessEncoding to BtcEncode for the + // MessageEncoding parameter indicates that the transactions within the + // block are expected to be serialized according to the new + // serialization structure defined in BIP0141. + return msg.BtcDecode(r, 0, WitnessEncoding) +} + +// DeserializeWitness decodes a block from r into the receiver similar to +// Deserialize, however DeserializeWitness strips all (if any) witness data +// from the transactions within the block before encoding them. +func (msg *MsgBlock) DeserializeNoWitness(r io.Reader) error { + return msg.BtcDecode(r, 0, BaseEncoding) } // DeserializeTxLoc decodes r in the same manner Deserialize does, but it takes @@ -160,7 +172,7 @@ func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) { // This is part of the Message interface implementation. // See Serialize for encoding blocks to be stored to disk, such as in a // database, as opposed to encoding blocks for the wire. -func (msg *MsgBlock) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgBlock) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { err := writeBlockHeader(w, pver, &msg.Header) if err != nil { return err @@ -172,7 +184,7 @@ func (msg *MsgBlock) BtcEncode(w io.Writer, pver uint32) error { } for _, tx := range msg.Transactions { - err = tx.BtcEncode(w, pver) + err = tx.BtcEncode(w, pver, enc) if err != nil { return err } @@ -194,7 +206,20 @@ func (msg *MsgBlock) Serialize(w io.Writer) error { // At the current time, there is no difference between the wire encoding // at protocol version 0 and the stable long-term storage format. As // a result, make use of BtcEncode. - return msg.BtcEncode(w, 0) + // + // Passing WitnessEncoding as the encoding type here indicates that + // each of the transactions should be serialized using the witness + // serialization structure defined in BIP0141. + return msg.BtcEncode(w, 0, WitnessEncoding) +} + +// SerializeWitness encodes a block to w using an identical format to Serialize, +// with all (if any) witness data stripped from all transactions. +// This method is provided in additon to the regular Serialize, in order to +// allow one to selectively encode transaction witness data to non-upgraded +// peers which are unaware of the new encoding. +func (msg *MsgBlock) SerializeNoWitness(w io.Writer) error { + return msg.BtcEncode(w, 0, BaseEncoding) } // SerializeSize returns the number of bytes it would take to serialize the diff --git a/wire/msgblock_test.go b/wire/msgblock_test.go index b861ff51..2a861b20 100644 --- a/wire/msgblock_test.go +++ b/wire/msgblock_test.go @@ -36,7 +36,7 @@ func TestBlock(t *testing.T) { // Ensure max payload is expected value for latest protocol version. // Num addresses (varInt) + max allowed addresses. - wantPayload := uint32(1000000) + wantPayload := uint32(4000000) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ @@ -110,11 +110,12 @@ func TestBlockHash(t *testing.T) { // of transaction inputs and outputs and protocol versions. func TestBlockWire(t *testing.T) { tests := []struct { - in *MsgBlock // Message to encode - out *MsgBlock // Expected decoded message - buf []byte // Wire encoding - txLocs []TxLoc // Expected transaction locations - pver uint32 // Protocol version for wire encoding + in *MsgBlock // Message to encode + out *MsgBlock // Expected decoded message + buf []byte // Wire encoding + txLocs []TxLoc // Expected transaction locations + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version. { @@ -123,6 +124,7 @@ func TestBlockWire(t *testing.T) { blockOneBytes, blockOneTxLocs, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version. @@ -132,6 +134,7 @@ func TestBlockWire(t *testing.T) { blockOneBytes, blockOneTxLocs, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version. @@ -141,6 +144,7 @@ func TestBlockWire(t *testing.T) { blockOneBytes, blockOneTxLocs, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion. @@ -150,6 +154,7 @@ func TestBlockWire(t *testing.T) { blockOneBytes, blockOneTxLocs, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion. @@ -159,14 +164,16 @@ func TestBlockWire(t *testing.T) { blockOneBytes, blockOneTxLocs, MultipleAddressVersion, + BaseEncoding, }, + // TODO(roasbeef): add case for witnessy block } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -180,7 +187,7 @@ func TestBlockWire(t *testing.T) { // Decode the message from wire format. var msg MsgBlock rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -202,36 +209,37 @@ func TestBlockWireErrors(t *testing.T) { pver := uint32(60002) tests := []struct { - in *MsgBlock // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgBlock // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Force error in version. - {&blockOne, blockOneBytes, pver, 0, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in prev block hash. - {&blockOne, blockOneBytes, pver, 4, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF}, // Force error in merkle root. - {&blockOne, blockOneBytes, pver, 36, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 36, io.ErrShortWrite, io.EOF}, // Force error in timestamp. - {&blockOne, blockOneBytes, pver, 68, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 68, io.ErrShortWrite, io.EOF}, // Force error in difficulty bits. - {&blockOne, blockOneBytes, pver, 72, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 72, io.ErrShortWrite, io.EOF}, // Force error in header nonce. - {&blockOne, blockOneBytes, pver, 76, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 76, io.ErrShortWrite, io.EOF}, // Force error in transaction count. - {&blockOne, blockOneBytes, pver, 80, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 80, io.ErrShortWrite, io.EOF}, // Force error in transactions. - {&blockOne, blockOneBytes, pver, 81, io.ErrShortWrite, io.EOF}, + {&blockOne, blockOneBytes, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if err != test.writeErr { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -241,7 +249,7 @@ func TestBlockWireErrors(t *testing.T) { // Decode from wire format. var msg MsgBlock r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if err != test.readErr { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) @@ -388,9 +396,10 @@ func TestBlockOverflowErrors(t *testing.T) { pver := uint32(70001) tests := []struct { - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - err error // Expected error + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + err error // Expected error }{ // Block that claims to have ~uint64(0) transactions. { @@ -409,7 +418,7 @@ func TestBlockOverflowErrors(t *testing.T) { 0x01, 0xe3, 0x62, 0x99, // Nonce 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // TxnCount - }, pver, &MessageError{}, + }, pver, BaseEncoding, &MessageError{}, }, } @@ -418,7 +427,7 @@ func TestBlockOverflowErrors(t *testing.T) { // Decode from wire format. var msg MsgBlock r := bytes.NewReader(test.buf) - err := msg.BtcDecode(r, test.pver) + err := msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.err) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, reflect.TypeOf(test.err)) diff --git a/wire/msgfeefilter.go b/wire/msgfeefilter.go index 0162f838..754647a2 100644 --- a/wire/msgfeefilter.go +++ b/wire/msgfeefilter.go @@ -21,7 +21,7 @@ type MsgFeeFilter struct { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgFeeFilter) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgFeeFilter) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { if pver < FeeFilterVersion { str := fmt.Sprintf("feefilter message invalid for protocol "+ "version %d", pver) @@ -33,7 +33,7 @@ func (msg *MsgFeeFilter) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgFeeFilter) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgFeeFilter) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { if pver < FeeFilterVersion { str := fmt.Sprintf("feefilter message invalid for protocol "+ "version %d", pver) diff --git a/wire/msgfeefilter_test.go b/wire/msgfeefilter_test.go index 02946240..ccea45b4 100644 --- a/wire/msgfeefilter_test.go +++ b/wire/msgfeefilter_test.go @@ -43,14 +43,14 @@ func TestFeeFilterLatest(t *testing.T) { // Test encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) + err := msg.BtcEncode(&buf, pver, BaseEncoding) if err != nil { t.Errorf("encode of MsgFeeFilter failed %v err <%v>", msg, err) } // Test decode with latest protocol version. readmsg := NewMsgFeeFilter(0) - err = readmsg.BtcDecode(&buf, pver) + err = readmsg.BtcDecode(&buf, pver, BaseEncoding) if err != nil { t.Errorf("decode of MsgFeeFilter failed [%v] err <%v>", buf, err) } @@ -91,7 +91,7 @@ func TestFeeFilterWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, BaseEncoding) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -105,7 +105,7 @@ func TestFeeFilterWire(t *testing.T) { // Decode the message from wire format. var msg MsgFeeFilter rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, BaseEncoding) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -149,7 +149,7 @@ func TestFeeFilterWireErrors(t *testing.T) { for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, BaseEncoding) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -169,7 +169,7 @@ func TestFeeFilterWireErrors(t *testing.T) { // Decode from wire format. var msg MsgFeeFilter r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, BaseEncoding) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msgfilteradd.go b/wire/msgfilteradd.go index b9e8a869..21b67cab 100644 --- a/wire/msgfilteradd.go +++ b/wire/msgfilteradd.go @@ -27,7 +27,7 @@ type MsgFilterAdd struct { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgFilterAdd) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgFilterAdd) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { if pver < BIP0037Version { str := fmt.Sprintf("filteradd message invalid for protocol "+ "version %d", pver) @@ -42,7 +42,7 @@ func (msg *MsgFilterAdd) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgFilterAdd) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgFilterAdd) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { if pver < BIP0037Version { str := fmt.Sprintf("filteradd message invalid for protocol "+ "version %d", pver) diff --git a/wire/msgfilteradd_test.go b/wire/msgfilteradd_test.go index 67144301..6099b0fc 100644 --- a/wire/msgfilteradd_test.go +++ b/wire/msgfilteradd_test.go @@ -14,6 +14,7 @@ import ( // TestFilterAddLatest tests the MsgFilterAdd API against the latest protocol // version. func TestFilterAddLatest(t *testing.T) { + enc := BaseEncoding pver := ProtocolVersion data := []byte{0x01, 0x02} @@ -37,14 +38,14 @@ func TestFilterAddLatest(t *testing.T) { // Test encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) + err := msg.BtcEncode(&buf, pver, enc) if err != nil { t.Errorf("encode of MsgFilterAdd failed %v err <%v>", msg, err) } // Test decode with latest protocol version. var readmsg MsgFilterAdd - err = readmsg.BtcDecode(&buf, pver) + err = readmsg.BtcDecode(&buf, pver, enc) if err != nil { t.Errorf("decode of MsgFilterAdd failed [%v] err <%v>", buf, err) } @@ -61,14 +62,14 @@ func TestFilterAddCrossProtocol(t *testing.T) { // Encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, ProtocolVersion) + err := msg.BtcEncode(&buf, ProtocolVersion, LatestEncoding) if err != nil { t.Errorf("encode of MsgFilterAdd failed %v err <%v>", msg, err) } // Decode with old protocol version. var readmsg MsgFilterAdd - err = readmsg.BtcDecode(&buf, BIP0031Version) + err = readmsg.BtcDecode(&buf, BIP0031Version, LatestEncoding) if err == nil { t.Errorf("decode of MsgFilterAdd succeeded when it shouldn't "+ "have %v", msg) @@ -89,7 +90,7 @@ func TestFilterAddMaxDataSize(t *testing.T) { // Encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, ProtocolVersion) + err := msg.BtcEncode(&buf, ProtocolVersion, LatestEncoding) if err == nil { t.Errorf("encode of MsgFilterAdd succeeded when it shouldn't "+ "have %v", msg) @@ -97,7 +98,7 @@ func TestFilterAddMaxDataSize(t *testing.T) { // Decode with latest protocol version. readbuf := bytes.NewReader(data) - err = msg.BtcDecode(readbuf, ProtocolVersion) + err = msg.BtcDecode(readbuf, ProtocolVersion, LatestEncoding) if err == nil { t.Errorf("decode of MsgFilterAdd succeeded when it shouldn't "+ "have %v", msg) @@ -116,27 +117,28 @@ func TestFilterAddWireErrors(t *testing.T) { baseFilterAddEncoded := append([]byte{0x04}, baseData...) tests := []struct { - in *MsgFilterAdd // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgFilterAdd // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Latest protocol version with intentional read/write errors. // Force error in data size. { - baseFilterAdd, baseFilterAddEncoded, pver, 0, + baseFilterAdd, baseFilterAddEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF, }, // Force error in data. { - baseFilterAdd, baseFilterAddEncoded, pver, 1, + baseFilterAdd, baseFilterAddEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF, }, // Force error due to unsupported protocol version. { - baseFilterAdd, baseFilterAddEncoded, pverNoFilterAdd, 5, + baseFilterAdd, baseFilterAddEncoded, pverNoFilterAdd, BaseEncoding, 5, wireErr, wireErr, }, } @@ -145,7 +147,7 @@ func TestFilterAddWireErrors(t *testing.T) { for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -165,7 +167,7 @@ func TestFilterAddWireErrors(t *testing.T) { // Decode from wire format. var msg MsgFilterAdd r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msgfilterclear.go b/wire/msgfilterclear.go index b82d6b85..7562fe2c 100644 --- a/wire/msgfilterclear.go +++ b/wire/msgfilterclear.go @@ -18,7 +18,7 @@ type MsgFilterClear struct{} // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgFilterClear) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgFilterClear) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { if pver < BIP0037Version { str := fmt.Sprintf("filterclear message invalid for protocol "+ "version %d", pver) @@ -30,7 +30,7 @@ func (msg *MsgFilterClear) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgFilterClear) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgFilterClear) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { if pver < BIP0037Version { str := fmt.Sprintf("filterclear message invalid for protocol "+ "version %d", pver) diff --git a/wire/msgfilterclear_test.go b/wire/msgfilterclear_test.go index 8e4c6002..23adea56 100644 --- a/wire/msgfilterclear_test.go +++ b/wire/msgfilterclear_test.go @@ -43,14 +43,14 @@ func TestFilterClearCrossProtocol(t *testing.T) { // Encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, ProtocolVersion) + err := msg.BtcEncode(&buf, ProtocolVersion, LatestEncoding) if err != nil { t.Errorf("encode of MsgFilterClear failed %v err <%v>", msg, err) } // Decode with old protocol version. var readmsg MsgFilterClear - err = readmsg.BtcDecode(&buf, BIP0031Version) + err = readmsg.BtcDecode(&buf, BIP0031Version, LatestEncoding) if err == nil { t.Errorf("decode of MsgFilterClear succeeded when it "+ "shouldn't have %v", msg) @@ -68,6 +68,7 @@ func TestFilterClearWire(t *testing.T) { out *MsgFilterClear // Expected decoded message buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version. { @@ -75,6 +76,7 @@ func TestFilterClearWire(t *testing.T) { msgFilterClear, msgFilterClearEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0037Version + 1. @@ -83,6 +85,7 @@ func TestFilterClearWire(t *testing.T) { msgFilterClear, msgFilterClearEncoded, BIP0037Version + 1, + BaseEncoding, }, // Protocol version BIP0037Version. @@ -91,6 +94,7 @@ func TestFilterClearWire(t *testing.T) { msgFilterClear, msgFilterClearEncoded, BIP0037Version, + BaseEncoding, }, } @@ -98,7 +102,7 @@ func TestFilterClearWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -112,7 +116,7 @@ func TestFilterClearWire(t *testing.T) { // Decode the message from wire format. var msg MsgFilterClear rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -138,6 +142,7 @@ func TestFilterClearWireErrors(t *testing.T) { in *MsgFilterClear // Value to encode buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format max int // Max size of fixed buffer to induce errors writeErr error // Expected write error readErr error // Expected read error @@ -145,7 +150,7 @@ func TestFilterClearWireErrors(t *testing.T) { // Force error due to unsupported protocol version. { baseFilterClear, baseFilterClearEncoded, - pverNoFilterClear, 4, wireErr, wireErr, + pverNoFilterClear, BaseEncoding, 4, wireErr, wireErr, }, } @@ -153,7 +158,7 @@ func TestFilterClearWireErrors(t *testing.T) { for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -173,7 +178,7 @@ func TestFilterClearWireErrors(t *testing.T) { // Decode from wire format. var msg MsgFilterClear r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msgfilterload.go b/wire/msgfilterload.go index 80374194..dbda7376 100644 --- a/wire/msgfilterload.go +++ b/wire/msgfilterload.go @@ -51,7 +51,7 @@ type MsgFilterLoad struct { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgFilterLoad) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgFilterLoad) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { if pver < BIP0037Version { str := fmt.Sprintf("filterload message invalid for protocol "+ "version %d", pver) @@ -81,7 +81,7 @@ func (msg *MsgFilterLoad) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgFilterLoad) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgFilterLoad) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { if pver < BIP0037Version { str := fmt.Sprintf("filterload message invalid for protocol "+ "version %d", pver) diff --git a/wire/msgfilterload_test.go b/wire/msgfilterload_test.go index bfa7a4fe..fb045ffa 100644 --- a/wire/msgfilterload_test.go +++ b/wire/msgfilterload_test.go @@ -15,6 +15,7 @@ import ( // version. func TestFilterLoadLatest(t *testing.T) { pver := ProtocolVersion + enc := BaseEncoding data := []byte{0x01, 0x02} msg := NewMsgFilterLoad(data, 10, 0, 0) @@ -37,14 +38,14 @@ func TestFilterLoadLatest(t *testing.T) { // Test encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) + err := msg.BtcEncode(&buf, pver, enc) if err != nil { t.Errorf("encode of MsgFilterLoad failed %v err <%v>", msg, err) } // Test decode with latest protocol version. readmsg := MsgFilterLoad{} - err = readmsg.BtcDecode(&buf, pver) + err = readmsg.BtcDecode(&buf, pver, enc) if err != nil { t.Errorf("decode of MsgFilterLoad failed [%v] err <%v>", buf, err) } @@ -58,7 +59,7 @@ func TestFilterLoadCrossProtocol(t *testing.T) { // Encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, ProtocolVersion) + err := msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding) if err != nil { t.Errorf("encode of NewMsgFilterLoad failed %v err <%v>", msg, err) @@ -66,7 +67,7 @@ func TestFilterLoadCrossProtocol(t *testing.T) { // Decode with old protocol version. var readmsg MsgFilterLoad - err = readmsg.BtcDecode(&buf, BIP0031Version) + err = readmsg.BtcDecode(&buf, BIP0031Version, BaseEncoding) if err == nil { t.Errorf("decode of MsgFilterLoad succeeded when it shouldn't have %v", msg) @@ -80,7 +81,7 @@ func TestFilterLoadMaxFilterSize(t *testing.T) { // Encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, ProtocolVersion) + err := msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding) if err == nil { t.Errorf("encode of MsgFilterLoad succeeded when it shouldn't "+ "have %v", msg) @@ -88,7 +89,7 @@ func TestFilterLoadMaxFilterSize(t *testing.T) { // Decode with latest protocol version. readbuf := bytes.NewReader(data) - err = msg.BtcDecode(readbuf, ProtocolVersion) + err = msg.BtcDecode(readbuf, ProtocolVersion, BaseEncoding) if err == nil { t.Errorf("decode of MsgFilterLoad succeeded when it shouldn't "+ "have %v", msg) @@ -102,7 +103,7 @@ func TestFilterLoadMaxHashFuncsSize(t *testing.T) { // Encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, ProtocolVersion) + err := msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding) if err == nil { t.Errorf("encode of MsgFilterLoad succeeded when it shouldn't have %v", msg) @@ -117,7 +118,7 @@ func TestFilterLoadMaxHashFuncsSize(t *testing.T) { } // Decode with latest protocol version. readbuf := bytes.NewReader(newBuf) - err = msg.BtcDecode(readbuf, ProtocolVersion) + err = msg.BtcDecode(readbuf, ProtocolVersion, BaseEncoding) if err == nil { t.Errorf("decode of MsgFilterLoad succeeded when it shouldn't have %v", msg) @@ -140,42 +141,43 @@ func TestFilterLoadWireErrors(t *testing.T) { 0x00) // Flags tests := []struct { - in *MsgFilterLoad // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgFilterLoad // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Latest protocol version with intentional read/write errors. // Force error in filter size. { - baseFilterLoad, baseFilterLoadEncoded, pver, 0, + baseFilterLoad, baseFilterLoadEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF, }, // Force error in filter. { - baseFilterLoad, baseFilterLoadEncoded, pver, 1, + baseFilterLoad, baseFilterLoadEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF, }, // Force error in hash funcs. { - baseFilterLoad, baseFilterLoadEncoded, pver, 5, + baseFilterLoad, baseFilterLoadEncoded, pver, BaseEncoding, 5, io.ErrShortWrite, io.EOF, }, // Force error in tweak. { - baseFilterLoad, baseFilterLoadEncoded, pver, 9, + baseFilterLoad, baseFilterLoadEncoded, pver, BaseEncoding, 9, io.ErrShortWrite, io.EOF, }, // Force error in flags. { - baseFilterLoad, baseFilterLoadEncoded, pver, 13, + baseFilterLoad, baseFilterLoadEncoded, pver, BaseEncoding, 13, io.ErrShortWrite, io.EOF, }, // Force error due to unsupported protocol version. { - baseFilterLoad, baseFilterLoadEncoded, pverNoFilterLoad, + baseFilterLoad, baseFilterLoadEncoded, pverNoFilterLoad, BaseEncoding, 10, wireErr, wireErr, }, } @@ -184,7 +186,7 @@ func TestFilterLoadWireErrors(t *testing.T) { for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -204,7 +206,7 @@ func TestFilterLoadWireErrors(t *testing.T) { // Decode from wire format. var msg MsgFilterLoad r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msggetaddr.go b/wire/msggetaddr.go index 0a4bf57a..2af8018f 100644 --- a/wire/msggetaddr.go +++ b/wire/msggetaddr.go @@ -18,13 +18,13 @@ type MsgGetAddr struct{} // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { return nil } // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { return nil } diff --git a/wire/msggetaddr_test.go b/wire/msggetaddr_test.go index a5427322..6a6f0f9c 100644 --- a/wire/msggetaddr_test.go +++ b/wire/msggetaddr_test.go @@ -42,10 +42,11 @@ func TestGetAddrWire(t *testing.T) { msgGetAddrEncoded := []byte{} tests := []struct { - in *MsgGetAddr // Message to encode - out *MsgGetAddr // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgGetAddr // Message to encode + out *MsgGetAddr // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding variant. }{ // Latest protocol version. { @@ -53,6 +54,7 @@ func TestGetAddrWire(t *testing.T) { msgGetAddr, msgGetAddrEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version. @@ -61,6 +63,7 @@ func TestGetAddrWire(t *testing.T) { msgGetAddr, msgGetAddrEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version. @@ -69,6 +72,7 @@ func TestGetAddrWire(t *testing.T) { msgGetAddr, msgGetAddrEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion. @@ -77,6 +81,7 @@ func TestGetAddrWire(t *testing.T) { msgGetAddr, msgGetAddrEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion. @@ -85,6 +90,7 @@ func TestGetAddrWire(t *testing.T) { msgGetAddr, msgGetAddrEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -92,7 +98,7 @@ func TestGetAddrWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -106,7 +112,7 @@ func TestGetAddrWire(t *testing.T) { // Decode the message from wire format. var msg MsgGetAddr rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue diff --git a/wire/msggetblocks.go b/wire/msggetblocks.go index 8201ff41..caf4400c 100644 --- a/wire/msggetblocks.go +++ b/wire/msggetblocks.go @@ -50,7 +50,7 @@ func (msg *MsgGetBlocks) AddBlockLocatorHash(hash *chainhash.Hash) error { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { err := readElement(r, &msg.ProtocolVersion) if err != nil { return err @@ -85,7 +85,7 @@ func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgGetBlocks) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgGetBlocks) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { count := len(msg.BlockLocatorHashes) if count > MaxBlockLocatorsPerMsg { str := fmt.Sprintf("too many block locator hashes for message "+ diff --git a/wire/msggetblocks_test.go b/wire/msggetblocks_test.go index c7568259..376f7338 100644 --- a/wire/msggetblocks_test.go +++ b/wire/msggetblocks_test.go @@ -142,10 +142,11 @@ func TestGetBlocksWire(t *testing.T) { } tests := []struct { - in *MsgGetBlocks // Message to encode - out *MsgGetBlocks // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgGetBlocks // Message to encode + out *MsgGetBlocks // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version with no block locators. { @@ -153,6 +154,7 @@ func TestGetBlocksWire(t *testing.T) { noLocators, noLocatorsEncoded, ProtocolVersion, + BaseEncoding, }, // Latest protocol version with multiple block locators. @@ -161,6 +163,7 @@ func TestGetBlocksWire(t *testing.T) { multiLocators, multiLocatorsEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version with no block locators. @@ -169,6 +172,7 @@ func TestGetBlocksWire(t *testing.T) { noLocators, noLocatorsEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0035Version with multiple block locators. @@ -177,6 +181,7 @@ func TestGetBlocksWire(t *testing.T) { multiLocators, multiLocatorsEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version with no block locators. @@ -185,6 +190,7 @@ func TestGetBlocksWire(t *testing.T) { noLocators, noLocatorsEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version BIP0031Versionwith multiple block locators. @@ -193,6 +199,7 @@ func TestGetBlocksWire(t *testing.T) { multiLocators, multiLocatorsEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion with no block locators. @@ -201,6 +208,7 @@ func TestGetBlocksWire(t *testing.T) { noLocators, noLocatorsEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version NetAddressTimeVersion multiple block locators. @@ -209,6 +217,7 @@ func TestGetBlocksWire(t *testing.T) { multiLocators, multiLocatorsEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion with no block locators. @@ -217,6 +226,7 @@ func TestGetBlocksWire(t *testing.T) { noLocators, noLocatorsEncoded, MultipleAddressVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion multiple block locators. @@ -225,6 +235,7 @@ func TestGetBlocksWire(t *testing.T) { multiLocators, multiLocatorsEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -232,7 +243,7 @@ func TestGetBlocksWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -246,7 +257,7 @@ func TestGetBlocksWire(t *testing.T) { // Decode the message from wire format. var msg MsgGetBlocks rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -325,30 +336,31 @@ func TestGetBlocksWireErrors(t *testing.T) { } tests := []struct { - in *MsgGetBlocks // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgGetBlocks // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Force error in protocol version. - {baseGetBlocks, baseGetBlocksEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in block locator hash count. - {baseGetBlocks, baseGetBlocksEncoded, pver, 4, io.ErrShortWrite, io.EOF}, + {baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF}, // Force error in block locator hashes. - {baseGetBlocks, baseGetBlocksEncoded, pver, 5, io.ErrShortWrite, io.EOF}, + {baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 5, io.ErrShortWrite, io.EOF}, // Force error in stop hash. - {baseGetBlocks, baseGetBlocksEncoded, pver, 69, io.ErrShortWrite, io.EOF}, + {baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 69, io.ErrShortWrite, io.EOF}, // Force error with greater than max block locator hashes. - {maxGetBlocks, maxGetBlocksEncoded, pver, 7, wireErr, wireErr}, + {maxGetBlocks, maxGetBlocksEncoded, pver, BaseEncoding, 7, wireErr, wireErr}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -368,7 +380,7 @@ func TestGetBlocksWireErrors(t *testing.T) { // Decode from wire format. var msg MsgGetBlocks r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msggetdata.go b/wire/msggetdata.go index b646c46c..5837fac5 100644 --- a/wire/msggetdata.go +++ b/wire/msggetdata.go @@ -37,7 +37,7 @@ func (msg *MsgGetData) AddInvVect(iv *InvVect) error { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgGetData) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgGetData) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { count, err := ReadVarInt(r, pver) if err != nil { return err @@ -67,7 +67,7 @@ func (msg *MsgGetData) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgGetData) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgGetData) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { // Limit to max inventory vectors per message. count := len(msg.InvList) if count > MaxInvPerMsg { diff --git a/wire/msggetdata_test.go b/wire/msggetdata_test.go index a4bf1827..ea11262e 100644 --- a/wire/msggetdata_test.go +++ b/wire/msggetdata_test.go @@ -113,10 +113,11 @@ func TestGetDataWire(t *testing.T) { } tests := []struct { - in *MsgGetData // Message to encode - out *MsgGetData // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgGetData // Message to encode + out *MsgGetData // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version with no inv vectors. { @@ -124,6 +125,7 @@ func TestGetDataWire(t *testing.T) { NoInv, NoInvEncoded, ProtocolVersion, + BaseEncoding, }, // Latest protocol version with multiple inv vectors. @@ -132,6 +134,7 @@ func TestGetDataWire(t *testing.T) { MultiInv, MultiInvEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version no inv vectors. @@ -140,6 +143,7 @@ func TestGetDataWire(t *testing.T) { NoInv, NoInvEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0035Version with multiple inv vectors. @@ -148,6 +152,7 @@ func TestGetDataWire(t *testing.T) { MultiInv, MultiInvEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version no inv vectors. @@ -156,6 +161,7 @@ func TestGetDataWire(t *testing.T) { NoInv, NoInvEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version BIP0031Version with multiple inv vectors. @@ -164,6 +170,7 @@ func TestGetDataWire(t *testing.T) { MultiInv, MultiInvEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion no inv vectors. @@ -172,6 +179,7 @@ func TestGetDataWire(t *testing.T) { NoInv, NoInvEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version NetAddressTimeVersion with multiple inv vectors. @@ -180,6 +188,7 @@ func TestGetDataWire(t *testing.T) { MultiInv, MultiInvEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion no inv vectors. @@ -188,6 +197,7 @@ func TestGetDataWire(t *testing.T) { NoInv, NoInvEncoded, MultipleAddressVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion with multiple inv vectors. @@ -196,6 +206,7 @@ func TestGetDataWire(t *testing.T) { MultiInv, MultiInvEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -203,7 +214,7 @@ func TestGetDataWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -217,7 +228,7 @@ func TestGetDataWire(t *testing.T) { // Decode the message from wire format. var msg MsgGetData rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -269,27 +280,28 @@ func TestGetDataWireErrors(t *testing.T) { } tests := []struct { - in *MsgGetData // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgGetData // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Latest protocol version with intentional read/write errors. // Force error in inventory vector count - {baseGetData, baseGetDataEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {baseGetData, baseGetDataEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in inventory list. - {baseGetData, baseGetDataEncoded, pver, 1, io.ErrShortWrite, io.EOF}, + {baseGetData, baseGetDataEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF}, // Force error with greater than max inventory vectors. - {maxGetData, maxGetDataEncoded, pver, 3, wireErr, wireErr}, + {maxGetData, maxGetDataEncoded, pver, BaseEncoding, 3, wireErr, wireErr}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -309,7 +321,7 @@ func TestGetDataWireErrors(t *testing.T) { // Decode from wire format. var msg MsgGetData r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msggetheaders.go b/wire/msggetheaders.go index 00755f3c..0bbe42cb 100644 --- a/wire/msggetheaders.go +++ b/wire/msggetheaders.go @@ -47,7 +47,7 @@ func (msg *MsgGetHeaders) AddBlockLocatorHash(hash *chainhash.Hash) error { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { err := readElement(r, &msg.ProtocolVersion) if err != nil { return err @@ -82,7 +82,7 @@ func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgGetHeaders) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgGetHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { // Limit to max block locator hashes per message. count := len(msg.BlockLocatorHashes) if count > MaxBlockLocatorsPerMsg { diff --git a/wire/msggetheaders_test.go b/wire/msggetheaders_test.go index 545deb3c..34a24ae3 100644 --- a/wire/msggetheaders_test.go +++ b/wire/msggetheaders_test.go @@ -132,10 +132,11 @@ func TestGetHeadersWire(t *testing.T) { } tests := []struct { - in *MsgGetHeaders // Message to encode - out *MsgGetHeaders // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgGetHeaders // Message to encode + out *MsgGetHeaders // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version with no block locators. { @@ -143,6 +144,7 @@ func TestGetHeadersWire(t *testing.T) { noLocators, noLocatorsEncoded, ProtocolVersion, + BaseEncoding, }, // Latest protocol version with multiple block locators. @@ -151,6 +153,7 @@ func TestGetHeadersWire(t *testing.T) { multiLocators, multiLocatorsEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version with no block locators. @@ -159,6 +162,7 @@ func TestGetHeadersWire(t *testing.T) { noLocators, noLocatorsEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0035Version with multiple block locators. @@ -167,6 +171,7 @@ func TestGetHeadersWire(t *testing.T) { multiLocators, multiLocatorsEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version with no block locators. @@ -175,6 +180,7 @@ func TestGetHeadersWire(t *testing.T) { noLocators, noLocatorsEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version BIP0031Versionwith multiple block locators. @@ -183,6 +189,7 @@ func TestGetHeadersWire(t *testing.T) { multiLocators, multiLocatorsEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion with no block locators. @@ -191,6 +198,7 @@ func TestGetHeadersWire(t *testing.T) { noLocators, noLocatorsEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version NetAddressTimeVersion multiple block locators. @@ -199,6 +207,7 @@ func TestGetHeadersWire(t *testing.T) { multiLocators, multiLocatorsEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion with no block locators. @@ -207,6 +216,7 @@ func TestGetHeadersWire(t *testing.T) { noLocators, noLocatorsEncoded, MultipleAddressVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion multiple block locators. @@ -215,6 +225,7 @@ func TestGetHeadersWire(t *testing.T) { multiLocators, multiLocatorsEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -222,7 +233,7 @@ func TestGetHeadersWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -236,7 +247,7 @@ func TestGetHeadersWire(t *testing.T) { // Decode the message from wire format. var msg MsgGetHeaders rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -316,30 +327,31 @@ func TestGetHeadersWireErrors(t *testing.T) { } tests := []struct { - in *MsgGetHeaders // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgGetHeaders // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Force error in protocol version. - {baseGetHeaders, baseGetHeadersEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {baseGetHeaders, baseGetHeadersEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in block locator hash count. - {baseGetHeaders, baseGetHeadersEncoded, pver, 4, io.ErrShortWrite, io.EOF}, + {baseGetHeaders, baseGetHeadersEncoded, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF}, // Force error in block locator hashes. - {baseGetHeaders, baseGetHeadersEncoded, pver, 5, io.ErrShortWrite, io.EOF}, + {baseGetHeaders, baseGetHeadersEncoded, pver, BaseEncoding, 5, io.ErrShortWrite, io.EOF}, // Force error in stop hash. - {baseGetHeaders, baseGetHeadersEncoded, pver, 69, io.ErrShortWrite, io.EOF}, + {baseGetHeaders, baseGetHeadersEncoded, pver, BaseEncoding, 69, io.ErrShortWrite, io.EOF}, // Force error with greater than max block locator hashes. - {maxGetHeaders, maxGetHeadersEncoded, pver, 7, wireErr, wireErr}, + {maxGetHeaders, maxGetHeadersEncoded, pver, BaseEncoding, 7, wireErr, wireErr}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -359,7 +371,7 @@ func TestGetHeadersWireErrors(t *testing.T) { // Decode from wire format. var msg MsgGetHeaders r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msgheaders.go b/wire/msgheaders.go index 588b8be5..7d18d930 100644 --- a/wire/msgheaders.go +++ b/wire/msgheaders.go @@ -36,7 +36,7 @@ func (msg *MsgHeaders) AddBlockHeader(bh *BlockHeader) error { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { count, err := ReadVarInt(r, pver) if err != nil { return err @@ -79,7 +79,7 @@ func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgHeaders) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { // Limit to max block headers per message. count := len(msg.Headers) if count > MaxBlockHeadersPerMsg { diff --git a/wire/msgheaders_test.go b/wire/msgheaders_test.go index 1e44c56d..9b94545b 100644 --- a/wire/msgheaders_test.go +++ b/wire/msgheaders_test.go @@ -95,10 +95,11 @@ func TestHeadersWire(t *testing.T) { } tests := []struct { - in *MsgHeaders // Message to encode - out *MsgHeaders // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgHeaders // Message to encode + out *MsgHeaders // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version with no headers. { @@ -106,6 +107,7 @@ func TestHeadersWire(t *testing.T) { noHeaders, noHeadersEncoded, ProtocolVersion, + BaseEncoding, }, // Latest protocol version with one header. @@ -114,6 +116,7 @@ func TestHeadersWire(t *testing.T) { oneHeader, oneHeaderEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version with no headers. @@ -122,6 +125,7 @@ func TestHeadersWire(t *testing.T) { noHeaders, noHeadersEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0035Version with one header. @@ -130,6 +134,7 @@ func TestHeadersWire(t *testing.T) { oneHeader, oneHeaderEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version with no headers. @@ -138,6 +143,7 @@ func TestHeadersWire(t *testing.T) { noHeaders, noHeadersEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version BIP0031Version with one header. @@ -146,6 +152,7 @@ func TestHeadersWire(t *testing.T) { oneHeader, oneHeaderEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion with no headers. { @@ -153,6 +160,7 @@ func TestHeadersWire(t *testing.T) { noHeaders, noHeadersEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version NetAddressTimeVersion with one header. @@ -161,6 +169,7 @@ func TestHeadersWire(t *testing.T) { oneHeader, oneHeaderEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion with no headers. @@ -169,6 +178,7 @@ func TestHeadersWire(t *testing.T) { noHeaders, noHeadersEncoded, MultipleAddressVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion with one header. @@ -177,6 +187,7 @@ func TestHeadersWire(t *testing.T) { oneHeader, oneHeaderEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -184,7 +195,7 @@ func TestHeadersWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -198,7 +209,7 @@ func TestHeadersWire(t *testing.T) { // Decode the message from wire format. var msg MsgHeaders rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -282,31 +293,32 @@ func TestHeadersWireErrors(t *testing.T) { } tests := []struct { - in *MsgHeaders // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgHeaders // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Latest protocol version with intentional read/write errors. // Force error in header count. - {oneHeader, oneHeaderEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {oneHeader, oneHeaderEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in block header. - {oneHeader, oneHeaderEncoded, pver, 5, io.ErrShortWrite, io.EOF}, + {oneHeader, oneHeaderEncoded, pver, BaseEncoding, 5, io.ErrShortWrite, io.EOF}, // Force error with greater than max headers. - {maxHeaders, maxHeadersEncoded, pver, 3, wireErr, wireErr}, + {maxHeaders, maxHeadersEncoded, pver, BaseEncoding, 3, wireErr, wireErr}, // Force error with number of transactions. - {transHeader, transHeaderEncoded, pver, 81, io.ErrShortWrite, io.EOF}, + {transHeader, transHeaderEncoded, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF}, // Force error with included transactions. - {transHeader, transHeaderEncoded, pver, len(transHeaderEncoded), nil, wireErr}, + {transHeader, transHeaderEncoded, pver, BaseEncoding, len(transHeaderEncoded), nil, wireErr}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -326,7 +338,7 @@ func TestHeadersWireErrors(t *testing.T) { // Decode from wire format. var msg MsgHeaders r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msginv.go b/wire/msginv.go index 34db4bb0..5377b179 100644 --- a/wire/msginv.go +++ b/wire/msginv.go @@ -45,7 +45,7 @@ func (msg *MsgInv) AddInvVect(iv *InvVect) error { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { count, err := ReadVarInt(r, pver) if err != nil { return err @@ -75,7 +75,7 @@ func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgInv) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgInv) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { // Limit to max inventory vectors per message. count := len(msg.InvList) if count > MaxInvPerMsg { diff --git a/wire/msginv_test.go b/wire/msginv_test.go index d1f99572..ea01fc11 100644 --- a/wire/msginv_test.go +++ b/wire/msginv_test.go @@ -113,10 +113,11 @@ func TestInvWire(t *testing.T) { } tests := []struct { - in *MsgInv // Message to encode - out *MsgInv // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgInv // Message to encode + out *MsgInv // Expected decoded message + buf []byte // Wire encoding pver uint32 + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encodinf format }{ // Latest protocol version with no inv vectors. { @@ -124,6 +125,7 @@ func TestInvWire(t *testing.T) { NoInv, NoInvEncoded, ProtocolVersion, + BaseEncoding, }, // Latest protocol version with multiple inv vectors. @@ -132,6 +134,7 @@ func TestInvWire(t *testing.T) { MultiInv, MultiInvEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version no inv vectors. @@ -140,6 +143,7 @@ func TestInvWire(t *testing.T) { NoInv, NoInvEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0035Version with multiple inv vectors. @@ -148,6 +152,7 @@ func TestInvWire(t *testing.T) { MultiInv, MultiInvEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version no inv vectors. @@ -156,6 +161,7 @@ func TestInvWire(t *testing.T) { NoInv, NoInvEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version BIP0031Version with multiple inv vectors. @@ -164,6 +170,7 @@ func TestInvWire(t *testing.T) { MultiInv, MultiInvEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion no inv vectors. @@ -172,6 +179,7 @@ func TestInvWire(t *testing.T) { NoInv, NoInvEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version NetAddressTimeVersion with multiple inv vectors. @@ -180,6 +188,7 @@ func TestInvWire(t *testing.T) { MultiInv, MultiInvEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion no inv vectors. @@ -188,6 +197,7 @@ func TestInvWire(t *testing.T) { NoInv, NoInvEncoded, MultipleAddressVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion with multiple inv vectors. @@ -196,6 +206,7 @@ func TestInvWire(t *testing.T) { MultiInv, MultiInvEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -203,7 +214,7 @@ func TestInvWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -217,7 +228,7 @@ func TestInvWire(t *testing.T) { // Decode the message from wire format. var msg MsgInv rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -269,27 +280,28 @@ func TestInvWireErrors(t *testing.T) { } tests := []struct { - in *MsgInv // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgInv // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Latest protocol version with intentional read/write errors. // Force error in inventory vector count - {baseInv, baseInvEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {baseInv, baseInvEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in inventory list. - {baseInv, baseInvEncoded, pver, 1, io.ErrShortWrite, io.EOF}, + {baseInv, baseInvEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF}, // Force error with greater than max inventory vectors. - {maxInv, maxInvEncoded, pver, 3, wireErr, wireErr}, + {maxInv, maxInvEncoded, pver, BaseEncoding, 3, wireErr, wireErr}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -309,7 +321,7 @@ func TestInvWireErrors(t *testing.T) { // Decode from wire format. var msg MsgInv r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msgmempool.go b/wire/msgmempool.go index f6b08c2e..25760c52 100644 --- a/wire/msgmempool.go +++ b/wire/msgmempool.go @@ -19,7 +19,7 @@ type MsgMemPool struct{} // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgMemPool) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgMemPool) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { if pver < BIP0035Version { str := fmt.Sprintf("mempool message invalid for protocol "+ "version %d", pver) @@ -31,7 +31,7 @@ func (msg *MsgMemPool) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgMemPool) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgMemPool) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { if pver < BIP0035Version { str := fmt.Sprintf("mempool message invalid for protocol "+ "version %d", pver) diff --git a/wire/msgmempool_test.go b/wire/msgmempool_test.go index 5d05e721..04652eb4 100644 --- a/wire/msgmempool_test.go +++ b/wire/msgmempool_test.go @@ -11,6 +11,7 @@ import ( func TestMemPool(t *testing.T) { pver := ProtocolVersion + enc := BaseEncoding // Ensure the command is expected value. wantCmd := "mempool" @@ -31,7 +32,7 @@ func TestMemPool(t *testing.T) { // Test encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) + err := msg.BtcEncode(&buf, pver, enc) if err != nil { t.Errorf("encode of MsgMemPool failed %v err <%v>", msg, err) } @@ -39,7 +40,7 @@ func TestMemPool(t *testing.T) { // Older protocol versions should fail encode since message didn't // exist yet. oldPver := BIP0035Version - 1 - err = msg.BtcEncode(&buf, oldPver) + err = msg.BtcEncode(&buf, oldPver, enc) if err == nil { s := "encode of MsgMemPool passed for old protocol version %v err <%v>" t.Errorf(s, msg, err) @@ -47,14 +48,14 @@ func TestMemPool(t *testing.T) { // Test decode with latest protocol version. readmsg := NewMsgMemPool() - err = readmsg.BtcDecode(&buf, pver) + err = readmsg.BtcDecode(&buf, pver, enc) if err != nil { t.Errorf("decode of MsgMemPool failed [%v] err <%v>", buf, err) } // Older protocol versions should fail decode since message didn't // exist yet. - err = readmsg.BtcDecode(&buf, oldPver) + err = readmsg.BtcDecode(&buf, oldPver, enc) if err == nil { s := "decode of MsgMemPool passed for old protocol version %v err <%v>" t.Errorf(s, msg, err) diff --git a/wire/msgmerkleblock.go b/wire/msgmerkleblock.go index 74707028..d2ee4721 100644 --- a/wire/msgmerkleblock.go +++ b/wire/msgmerkleblock.go @@ -42,7 +42,7 @@ func (msg *MsgMerkleBlock) AddTxHash(hash *chainhash.Hash) error { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { if pver < BIP0037Version { str := fmt.Sprintf("merkleblock message invalid for protocol "+ "version %d", pver) @@ -90,7 +90,7 @@ func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgMerkleBlock) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgMerkleBlock) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { if pver < BIP0037Version { str := fmt.Sprintf("merkleblock message invalid for protocol "+ "version %d", pver) diff --git a/wire/msgmerkleblock_test.go b/wire/msgmerkleblock_test.go index 417d2ee1..430c1fbb 100644 --- a/wire/msgmerkleblock_test.go +++ b/wire/msgmerkleblock_test.go @@ -19,6 +19,7 @@ import ( // TestMerkleBlock tests the MsgMerkleBlock API. func TestMerkleBlock(t *testing.T) { pver := ProtocolVersion + enc := BaseEncoding // Block 1 header. prevHash := &blockOne.Header.PrevBlock @@ -37,7 +38,7 @@ func TestMerkleBlock(t *testing.T) { // Ensure max payload is expected value for latest protocol version. // Num addresses (varInt) + max allowed addresses. - wantPayload := uint32(1000000) + wantPayload := uint32(4000000) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ @@ -76,21 +77,21 @@ func TestMerkleBlock(t *testing.T) { // Test encode with latest protocol version. var buf bytes.Buffer - err = msg.BtcEncode(&buf, pver) + err = msg.BtcEncode(&buf, pver, enc) if err != nil { t.Errorf("encode of MsgMerkleBlock failed %v err <%v>", msg, err) } // Test decode with latest protocol version. readmsg := MsgMerkleBlock{} - err = readmsg.BtcDecode(&buf, pver) + err = readmsg.BtcDecode(&buf, pver, enc) if err != nil { t.Errorf("decode of MsgMerkleBlock failed [%v] err <%v>", buf, err) } // Force extra hash to test maxTxPerBlock. msg.Hashes = append(msg.Hashes, hash) - err = msg.BtcEncode(&buf, pver) + err = msg.BtcEncode(&buf, pver, enc) if err == nil { t.Errorf("encode of MsgMerkleBlock succeeded with too many " + "tx hashes when it should have failed") @@ -101,7 +102,7 @@ func TestMerkleBlock(t *testing.T) { // Reset the number of hashes back to a valid value. msg.Hashes = msg.Hashes[len(msg.Hashes)-1:] msg.Flags = make([]byte, maxFlagsPerMerkleBlock+1) - err = msg.BtcEncode(&buf, pver) + err = msg.BtcEncode(&buf, pver, enc) if err == nil { t.Errorf("encode of MsgMerkleBlock succeeded with too many " + "flag bytes when it should have failed") @@ -123,7 +124,7 @@ func TestMerkleBlockCrossProtocol(t *testing.T) { // Encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, ProtocolVersion) + err := msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding) if err != nil { t.Errorf("encode of NewMsgFilterLoad failed %v err <%v>", msg, err) @@ -131,7 +132,7 @@ func TestMerkleBlockCrossProtocol(t *testing.T) { // Decode with old protocol version. var readmsg MsgFilterLoad - err = readmsg.BtcDecode(&buf, BIP0031Version) + err = readmsg.BtcDecode(&buf, BIP0031Version, BaseEncoding) if err == nil { t.Errorf("decode of MsgFilterLoad succeeded when it shouldn't have %v", msg) @@ -146,17 +147,18 @@ func TestMerkleBlockWire(t *testing.T) { out *MsgMerkleBlock // Expected decoded message buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version. { &merkleBlockOne, &merkleBlockOne, merkleBlockOneBytes, - ProtocolVersion, + ProtocolVersion, BaseEncoding, }, // Protocol version BIP0037Version. { &merkleBlockOne, &merkleBlockOne, merkleBlockOneBytes, - BIP0037Version, + BIP0037Version, BaseEncoding, }, } @@ -164,7 +166,7 @@ func TestMerkleBlockWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -178,7 +180,7 @@ func TestMerkleBlockWire(t *testing.T) { // Decode the message from wire format. var msg MsgMerkleBlock rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -205,69 +207,70 @@ func TestMerkleBlockWireErrors(t *testing.T) { in *MsgMerkleBlock // Value to encode buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format max int // Max size of fixed buffer to induce errors writeErr error // Expected write error readErr error // Expected read error }{ // Force error in version. { - &merkleBlockOne, merkleBlockOneBytes, pver, 0, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF, }, // Force error in prev block hash. { - &merkleBlockOne, merkleBlockOneBytes, pver, 4, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF, }, // Force error in merkle root. { - &merkleBlockOne, merkleBlockOneBytes, pver, 36, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 36, io.ErrShortWrite, io.EOF, }, // Force error in timestamp. { - &merkleBlockOne, merkleBlockOneBytes, pver, 68, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 68, io.ErrShortWrite, io.EOF, }, // Force error in difficulty bits. { - &merkleBlockOne, merkleBlockOneBytes, pver, 72, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 72, io.ErrShortWrite, io.EOF, }, // Force error in header nonce. { - &merkleBlockOne, merkleBlockOneBytes, pver, 76, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 76, io.ErrShortWrite, io.EOF, }, // Force error in transaction count. { - &merkleBlockOne, merkleBlockOneBytes, pver, 80, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 80, io.ErrShortWrite, io.EOF, }, // Force error in num hashes. { - &merkleBlockOne, merkleBlockOneBytes, pver, 84, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 84, io.ErrShortWrite, io.EOF, }, // Force error in hashes. { - &merkleBlockOne, merkleBlockOneBytes, pver, 85, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 85, io.ErrShortWrite, io.EOF, }, // Force error in num flag bytes. { - &merkleBlockOne, merkleBlockOneBytes, pver, 117, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 117, io.ErrShortWrite, io.EOF, }, // Force error in flag bytes. { - &merkleBlockOne, merkleBlockOneBytes, pver, 118, + &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 118, io.ErrShortWrite, io.EOF, }, // Force error due to unsupported protocol version. { &merkleBlockOne, merkleBlockOneBytes, pverNoMerkleBlock, - 119, wireErr, wireErr, + BaseEncoding, 119, wireErr, wireErr, }, } @@ -275,7 +278,7 @@ func TestMerkleBlockWireErrors(t *testing.T) { for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -295,7 +298,7 @@ func TestMerkleBlockWireErrors(t *testing.T) { // Decode from wire format. var msg MsgMerkleBlock r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) @@ -343,14 +346,15 @@ func TestMerkleBlockOverflowErrors(t *testing.T) { exceedMaxFlagBytes = append(exceedMaxFlagBytes, buf.Bytes()...) tests := []struct { - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - err error // Expected error + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + err error // Expected error }{ // Block that claims to have more than max allowed hashes. - {exceedMaxHashes, pver, &MessageError{}}, + {exceedMaxHashes, pver, BaseEncoding, &MessageError{}}, // Block that claims to have more than max allowed flag bytes. - {exceedMaxFlagBytes, pver, &MessageError{}}, + {exceedMaxFlagBytes, pver, BaseEncoding, &MessageError{}}, } t.Logf("Running %d tests", len(tests)) @@ -358,7 +362,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) { // Decode from wire format. var msg MsgMerkleBlock r := bytes.NewReader(test.buf) - err := msg.BtcDecode(r, test.pver) + err := msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.err) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, reflect.TypeOf(test.err)) diff --git a/wire/msgnotfound.go b/wire/msgnotfound.go index 0c95020d..e8676816 100644 --- a/wire/msgnotfound.go +++ b/wire/msgnotfound.go @@ -34,7 +34,7 @@ func (msg *MsgNotFound) AddInvVect(iv *InvVect) error { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { count, err := ReadVarInt(r, pver) if err != nil { return err @@ -64,7 +64,7 @@ func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { // Limit to max inventory vectors per message. count := len(msg.InvList) if count > MaxInvPerMsg { diff --git a/wire/msgnotfound_test.go b/wire/msgnotfound_test.go index 2a0886c8..07da74e8 100644 --- a/wire/msgnotfound_test.go +++ b/wire/msgnotfound_test.go @@ -104,10 +104,11 @@ func TestNotFoundWire(t *testing.T) { } tests := []struct { - in *MsgNotFound // Message to encode - out *MsgNotFound // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgNotFound // Message to encode + out *MsgNotFound // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version with no inv vectors. { @@ -115,6 +116,7 @@ func TestNotFoundWire(t *testing.T) { NoInv, NoInvEncoded, ProtocolVersion, + BaseEncoding, }, // Latest protocol version with multiple inv vectors. @@ -123,6 +125,7 @@ func TestNotFoundWire(t *testing.T) { MultiInv, MultiInvEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version no inv vectors. @@ -131,6 +134,7 @@ func TestNotFoundWire(t *testing.T) { NoInv, NoInvEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0035Version with multiple inv vectors. @@ -139,6 +143,7 @@ func TestNotFoundWire(t *testing.T) { MultiInv, MultiInvEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version no inv vectors. @@ -147,6 +152,7 @@ func TestNotFoundWire(t *testing.T) { NoInv, NoInvEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version BIP0031Version with multiple inv vectors. @@ -155,6 +161,7 @@ func TestNotFoundWire(t *testing.T) { MultiInv, MultiInvEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion no inv vectors. @@ -163,6 +170,7 @@ func TestNotFoundWire(t *testing.T) { NoInv, NoInvEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version NetAddressTimeVersion with multiple inv vectors. @@ -171,6 +179,7 @@ func TestNotFoundWire(t *testing.T) { MultiInv, MultiInvEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion no inv vectors. @@ -179,6 +188,7 @@ func TestNotFoundWire(t *testing.T) { NoInv, NoInvEncoded, MultipleAddressVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion with multiple inv vectors. @@ -187,6 +197,7 @@ func TestNotFoundWire(t *testing.T) { MultiInv, MultiInvEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -194,7 +205,7 @@ func TestNotFoundWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -208,7 +219,7 @@ func TestNotFoundWire(t *testing.T) { // Decode the message from wire format. var msg MsgNotFound rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -260,26 +271,27 @@ func TestNotFoundWireErrors(t *testing.T) { } tests := []struct { - in *MsgNotFound // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgNotFound // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Force error in inventory vector count - {baseNotFound, baseNotFoundEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {baseNotFound, baseNotFoundEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in inventory list. - {baseNotFound, baseNotFoundEncoded, pver, 1, io.ErrShortWrite, io.EOF}, + {baseNotFound, baseNotFoundEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF}, // Force error with greater than max inventory vectors. - {maxNotFound, maxNotFoundEncoded, pver, 3, wireErr, wireErr}, + {maxNotFound, maxNotFoundEncoded, pver, BaseEncoding, 3, wireErr, wireErr}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -299,7 +311,7 @@ func TestNotFoundWireErrors(t *testing.T) { // Decode from wire format. var msg MsgNotFound r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msgping.go b/wire/msgping.go index c9e3f646..b2f346e0 100644 --- a/wire/msgping.go +++ b/wire/msgping.go @@ -27,7 +27,7 @@ type MsgPing struct { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { // There was no nonce for BIP0031Version and earlier. // NOTE: > is not a mistake here. The BIP0031 was defined as AFTER // the version unlike most others. @@ -43,7 +43,7 @@ func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgPing) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgPing) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { // There was no nonce for BIP0031Version and earlier. // NOTE: > is not a mistake here. The BIP0031 was defined as AFTER // the version unlike most others. diff --git a/wire/msgping_test.go b/wire/msgping_test.go index 7a00dafc..511325cb 100644 --- a/wire/msgping_test.go +++ b/wire/msgping_test.go @@ -50,6 +50,7 @@ func TestPing(t *testing.T) { func TestPingBIP0031(t *testing.T) { // Use the protocol version just prior to BIP0031Version changes. pver := BIP0031Version + enc := BaseEncoding nonce, err := RandomUint64() if err != nil { @@ -72,14 +73,14 @@ func TestPingBIP0031(t *testing.T) { // Test encode with old protocol version. var buf bytes.Buffer - err = msg.BtcEncode(&buf, pver) + err = msg.BtcEncode(&buf, pver, enc) if err != nil { t.Errorf("encode of MsgPing failed %v err <%v>", msg, err) } // Test decode with old protocol version. readmsg := NewMsgPing(0) - err = readmsg.BtcDecode(&buf, pver) + err = readmsg.BtcDecode(&buf, pver, enc) if err != nil { t.Errorf("decode of MsgPing failed [%v] err <%v>", buf, err) } @@ -106,14 +107,14 @@ func TestPingCrossProtocol(t *testing.T) { // Encode with latest protocol version. var buf bytes.Buffer - err = msg.BtcEncode(&buf, ProtocolVersion) + err = msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding) if err != nil { t.Errorf("encode of MsgPing failed %v err <%v>", msg, err) } // Decode with old protocol version. readmsg := NewMsgPing(0) - err = readmsg.BtcDecode(&buf, BIP0031Version) + err = readmsg.BtcDecode(&buf, BIP0031Version, BaseEncoding) if err != nil { t.Errorf("decode of MsgPing failed [%v] err <%v>", buf, err) } @@ -129,10 +130,11 @@ func TestPingCrossProtocol(t *testing.T) { // versions. func TestPingWire(t *testing.T) { tests := []struct { - in MsgPing // Message to encode - out MsgPing // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in MsgPing // Message to encode + out MsgPing // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version. { @@ -140,6 +142,7 @@ func TestPingWire(t *testing.T) { MsgPing{Nonce: 123123}, // 0x1e0f3 []byte{0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0031Version+1 @@ -148,6 +151,7 @@ func TestPingWire(t *testing.T) { MsgPing{Nonce: 456456}, // 0x6f708 []byte{0x08, 0xf7, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00}, BIP0031Version + 1, + BaseEncoding, }, // Protocol version BIP0031Version @@ -156,6 +160,7 @@ func TestPingWire(t *testing.T) { MsgPing{Nonce: 0}, // No nonce for pver []byte{}, // No nonce for pver BIP0031Version, + BaseEncoding, }, } @@ -163,7 +168,7 @@ func TestPingWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -177,7 +182,7 @@ func TestPingWire(t *testing.T) { // Decode the message from wire format. var msg MsgPing rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -196,18 +201,20 @@ func TestPingWireErrors(t *testing.T) { pver := ProtocolVersion tests := []struct { - in *MsgPing // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgPing // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Latest protocol version with intentional read/write errors. { &MsgPing{Nonce: 123123}, // 0x1e0f3 []byte{0xf3, 0xe0, 0x01, 0x00}, pver, + BaseEncoding, 2, io.ErrShortWrite, io.ErrUnexpectedEOF, @@ -218,7 +225,7 @@ func TestPingWireErrors(t *testing.T) { for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if err != test.writeErr { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -228,7 +235,7 @@ func TestPingWireErrors(t *testing.T) { // Decode from wire format. var msg MsgPing r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if err != test.readErr { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msgpong.go b/wire/msgpong.go index 9fd02721..eec80d8d 100644 --- a/wire/msgpong.go +++ b/wire/msgpong.go @@ -22,7 +22,7 @@ type MsgPong struct { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgPong) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgPong) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { // NOTE: <= is not a mistake here. The BIP0031 was defined as AFTER // the version unlike most others. if pver <= BIP0031Version { @@ -36,7 +36,7 @@ func (msg *MsgPong) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgPong) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgPong) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { // NOTE: <= is not a mistake here. The BIP0031 was defined as AFTER // the version unlike most others. if pver <= BIP0031Version { diff --git a/wire/msgpong_test.go b/wire/msgpong_test.go index a6684c08..148a46a0 100644 --- a/wire/msgpong_test.go +++ b/wire/msgpong_test.go @@ -15,6 +15,7 @@ import ( // TestPongLatest tests the MsgPong API against the latest protocol version. func TestPongLatest(t *testing.T) { + enc := BaseEncoding pver := ProtocolVersion nonce, err := RandomUint64() @@ -45,14 +46,14 @@ func TestPongLatest(t *testing.T) { // Test encode with latest protocol version. var buf bytes.Buffer - err = msg.BtcEncode(&buf, pver) + err = msg.BtcEncode(&buf, pver, enc) if err != nil { t.Errorf("encode of MsgPong failed %v err <%v>", msg, err) } // Test decode with latest protocol version. readmsg := NewMsgPong(0) - err = readmsg.BtcDecode(&buf, pver) + err = readmsg.BtcDecode(&buf, pver, enc) if err != nil { t.Errorf("decode of MsgPong failed [%v] err <%v>", buf, err) } @@ -68,6 +69,7 @@ func TestPongLatest(t *testing.T) { func TestPongBIP0031(t *testing.T) { // Use the protocol version just prior to BIP0031Version changes. pver := BIP0031Version + enc := BaseEncoding nonce, err := RandomUint64() if err != nil { @@ -87,7 +89,7 @@ func TestPongBIP0031(t *testing.T) { // Test encode with old protocol version. var buf bytes.Buffer - err = msg.BtcEncode(&buf, pver) + err = msg.BtcEncode(&buf, pver, enc) if err == nil { t.Errorf("encode of MsgPong succeeded when it shouldn't have %v", msg) @@ -95,7 +97,7 @@ func TestPongBIP0031(t *testing.T) { // Test decode with old protocol version. readmsg := NewMsgPong(0) - err = readmsg.BtcDecode(&buf, pver) + err = readmsg.BtcDecode(&buf, pver, enc) if err == nil { t.Errorf("decode of MsgPong succeeded when it shouldn't have %v", spew.Sdump(buf)) @@ -122,14 +124,14 @@ func TestPongCrossProtocol(t *testing.T) { // Encode with latest protocol version. var buf bytes.Buffer - err = msg.BtcEncode(&buf, ProtocolVersion) + err = msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding) if err != nil { t.Errorf("encode of MsgPong failed %v err <%v>", msg, err) } // Decode with old protocol version. readmsg := NewMsgPong(0) - err = readmsg.BtcDecode(&buf, BIP0031Version) + err = readmsg.BtcDecode(&buf, BIP0031Version, BaseEncoding) if err == nil { t.Errorf("encode of MsgPong succeeded when it shouldn't have %v", msg) @@ -146,10 +148,11 @@ func TestPongCrossProtocol(t *testing.T) { // versions. func TestPongWire(t *testing.T) { tests := []struct { - in MsgPong // Message to encode - out MsgPong // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in MsgPong // Message to encode + out MsgPong // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version. { @@ -157,6 +160,7 @@ func TestPongWire(t *testing.T) { MsgPong{Nonce: 123123}, // 0x1e0f3 []byte{0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0031Version+1 @@ -165,6 +169,7 @@ func TestPongWire(t *testing.T) { MsgPong{Nonce: 456456}, // 0x6f708 []byte{0x08, 0xf7, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00}, BIP0031Version + 1, + BaseEncoding, }, } @@ -172,7 +177,7 @@ func TestPongWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -186,7 +191,7 @@ func TestPongWire(t *testing.T) { // Decode the message from wire format. var msg MsgPong rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -212,25 +217,26 @@ func TestPongWireErrors(t *testing.T) { } tests := []struct { - in *MsgPong // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgPong // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Latest protocol version with intentional read/write errors. // Force error in nonce. - {basePong, basePongEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {basePong, basePongEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error due to unsupported protocol version. - {basePong, basePongEncoded, pverNoPong, 4, wireErr, wireErr}, + {basePong, basePongEncoded, pverNoPong, BaseEncoding, 4, wireErr, wireErr}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -250,7 +256,7 @@ func TestPongWireErrors(t *testing.T) { // Decode from wire format. var msg MsgPong r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msgreject.go b/wire/msgreject.go index 4fe94ba6..a00eeff6 100644 --- a/wire/msgreject.go +++ b/wire/msgreject.go @@ -73,7 +73,7 @@ type MsgReject struct { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { if pver < RejectVersion { str := fmt.Sprintf("reject message invalid for protocol "+ "version %d", pver) @@ -115,7 +115,7 @@ func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { if pver < RejectVersion { str := fmt.Sprintf("reject message invalid for protocol "+ "version %d", pver) diff --git a/wire/msgreject_test.go b/wire/msgreject_test.go index 610801a8..0285c501 100644 --- a/wire/msgreject_test.go +++ b/wire/msgreject_test.go @@ -45,6 +45,7 @@ func TestRejectCodeStringer(t *testing.T) { // TestRejectLatest tests the MsgPong API against the latest protocol version. func TestRejectLatest(t *testing.T) { pver := ProtocolVersion + enc := BaseEncoding // Create reject message data. rejCommand := (&MsgBlock{}).Command() @@ -86,14 +87,14 @@ func TestRejectLatest(t *testing.T) { // Test encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) + err := msg.BtcEncode(&buf, pver, enc) if err != nil { t.Errorf("encode of MsgReject failed %v err <%v>", msg, err) } // Test decode with latest protocol version. readMsg := MsgReject{} - err = readMsg.BtcDecode(&buf, pver) + err = readMsg.BtcDecode(&buf, pver, enc) if err != nil { t.Errorf("decode of MsgReject failed %v err <%v>", buf.Bytes(), err) @@ -123,6 +124,7 @@ func TestRejectLatest(t *testing.T) { func TestRejectBeforeAdded(t *testing.T) { // Use the protocol version just prior to RejectVersion. pver := RejectVersion - 1 + enc := BaseEncoding // Create reject message data. rejCommand := (&MsgBlock{}).Command() @@ -142,7 +144,7 @@ func TestRejectBeforeAdded(t *testing.T) { // Test encode with old protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) + err := msg.BtcEncode(&buf, pver, enc) if err == nil { t.Errorf("encode of MsgReject succeeded when it shouldn't "+ "have %v", msg) @@ -150,7 +152,7 @@ func TestRejectBeforeAdded(t *testing.T) { // // Test decode with old protocol version. readMsg := MsgReject{} - err = readMsg.BtcDecode(&buf, pver) + err = readMsg.BtcDecode(&buf, pver, enc) if err == nil { t.Errorf("decode of MsgReject succeeded when it shouldn't "+ "have %v", spew.Sdump(buf.Bytes())) @@ -191,14 +193,14 @@ func TestRejectCrossProtocol(t *testing.T) { // Encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, ProtocolVersion) + err := msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding) if err != nil { t.Errorf("encode of MsgReject failed %v err <%v>", msg, err) } // Decode with old protocol version. readMsg := MsgReject{} - err = readMsg.BtcDecode(&buf, RejectVersion-1) + err = readMsg.BtcDecode(&buf, RejectVersion-1, BaseEncoding) if err == nil { t.Errorf("encode of MsgReject succeeded when it shouldn't "+ "have %v", msg) @@ -225,9 +227,10 @@ func TestRejectCrossProtocol(t *testing.T) { // protocol versions. func TestRejectWire(t *testing.T) { tests := []struct { - msg MsgReject // Message to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + msg MsgReject // Message to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version rejected command version (no hash). { @@ -244,6 +247,7 @@ func TestRejectWire(t *testing.T) { 0x6f, 0x6e, // "duplicate version" }, ProtocolVersion, + BaseEncoding, }, // Latest protocol version rejected command block (has hash). { @@ -264,6 +268,7 @@ func TestRejectWire(t *testing.T) { 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // mainNetGenesisHash }, ProtocolVersion, + BaseEncoding, }, } @@ -271,7 +276,7 @@ func TestRejectWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.msg.BtcEncode(&buf, test.pver) + err := test.msg.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -285,7 +290,7 @@ func TestRejectWire(t *testing.T) { // Decode the message from wire format. var msg MsgReject rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -319,31 +324,32 @@ func TestRejectWireErrors(t *testing.T) { } tests := []struct { - in *MsgReject // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgReject // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Latest protocol version with intentional read/write errors. // Force error in reject command. - {baseReject, baseRejectEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {baseReject, baseRejectEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in reject code. - {baseReject, baseRejectEncoded, pver, 6, io.ErrShortWrite, io.EOF}, + {baseReject, baseRejectEncoded, pver, BaseEncoding, 6, io.ErrShortWrite, io.EOF}, // Force error in reject reason. - {baseReject, baseRejectEncoded, pver, 7, io.ErrShortWrite, io.EOF}, + {baseReject, baseRejectEncoded, pver, BaseEncoding, 7, io.ErrShortWrite, io.EOF}, // Force error in reject hash. - {baseReject, baseRejectEncoded, pver, 23, io.ErrShortWrite, io.EOF}, + {baseReject, baseRejectEncoded, pver, BaseEncoding, 23, io.ErrShortWrite, io.EOF}, // Force error due to unsupported protocol version. - {baseReject, baseRejectEncoded, pverNoReject, 6, wireErr, wireErr}, + {baseReject, baseRejectEncoded, pverNoReject, BaseEncoding, 6, wireErr, wireErr}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -363,7 +369,7 @@ func TestRejectWireErrors(t *testing.T) { // Decode from wire format. var msg MsgReject r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) diff --git a/wire/msgsendheaders.go b/wire/msgsendheaders.go index 532e4aa1..19505351 100644 --- a/wire/msgsendheaders.go +++ b/wire/msgsendheaders.go @@ -19,7 +19,7 @@ type MsgSendHeaders struct{} // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgSendHeaders) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgSendHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { if pver < SendHeadersVersion { str := fmt.Sprintf("sendheaders message invalid for protocol "+ "version %d", pver) @@ -31,7 +31,7 @@ func (msg *MsgSendHeaders) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgSendHeaders) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgSendHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { if pver < SendHeadersVersion { str := fmt.Sprintf("sendheaders message invalid for protocol "+ "version %d", pver) diff --git a/wire/msgsendheaders_test.go b/wire/msgsendheaders_test.go index ed650509..bd510fba 100644 --- a/wire/msgsendheaders_test.go +++ b/wire/msgsendheaders_test.go @@ -16,6 +16,7 @@ import ( // version. func TestSendHeaders(t *testing.T) { pver := ProtocolVersion + enc := BaseEncoding // Ensure the command is expected value. wantCmd := "sendheaders" @@ -36,7 +37,7 @@ func TestSendHeaders(t *testing.T) { // Test encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) + err := msg.BtcEncode(&buf, pver, enc) if err != nil { t.Errorf("encode of MsgSendHeaders failed %v err <%v>", msg, err) @@ -45,7 +46,7 @@ func TestSendHeaders(t *testing.T) { // Older protocol versions should fail encode since message didn't // exist yet. oldPver := SendHeadersVersion - 1 - err = msg.BtcEncode(&buf, oldPver) + err = msg.BtcEncode(&buf, oldPver, enc) if err == nil { s := "encode of MsgSendHeaders passed for old protocol " + "version %v err <%v>" @@ -54,7 +55,7 @@ func TestSendHeaders(t *testing.T) { // Test decode with latest protocol version. readmsg := NewMsgSendHeaders() - err = readmsg.BtcDecode(&buf, pver) + err = readmsg.BtcDecode(&buf, pver, enc) if err != nil { t.Errorf("decode of MsgSendHeaders failed [%v] err <%v>", buf, err) @@ -62,7 +63,7 @@ func TestSendHeaders(t *testing.T) { // Older protocol versions should fail decode since message didn't // exist yet. - err = readmsg.BtcDecode(&buf, oldPver) + err = readmsg.BtcDecode(&buf, oldPver, enc) if err == nil { s := "decode of MsgSendHeaders passed for old protocol " + "version %v err <%v>" @@ -75,12 +76,13 @@ func TestSendHeaders(t *testing.T) { func TestSendHeadersBIP0130(t *testing.T) { // Use the protocol version just prior to SendHeadersVersion changes. pver := SendHeadersVersion - 1 + enc := BaseEncoding msg := NewMsgSendHeaders() // Test encode with old protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) + err := msg.BtcEncode(&buf, pver, enc) if err == nil { t.Errorf("encode of MsgSendHeaders succeeded when it should " + "have failed") @@ -88,7 +90,7 @@ func TestSendHeadersBIP0130(t *testing.T) { // Test decode with old protocol version. readmsg := NewMsgSendHeaders() - err = readmsg.BtcDecode(&buf, pver) + err = readmsg.BtcDecode(&buf, pver, enc) if err == nil { t.Errorf("decode of MsgSendHeaders succeeded when it should " + "have failed") @@ -98,11 +100,12 @@ func TestSendHeadersBIP0130(t *testing.T) { // TestSendHeadersCrossProtocol tests the MsgSendHeaders API when encoding with // the latest protocol version and decoding with SendHeadersVersion. func TestSendHeadersCrossProtocol(t *testing.T) { + enc := BaseEncoding msg := NewMsgSendHeaders() // Encode with latest protocol version. var buf bytes.Buffer - err := msg.BtcEncode(&buf, ProtocolVersion) + err := msg.BtcEncode(&buf, ProtocolVersion, enc) if err != nil { t.Errorf("encode of MsgSendHeaders failed %v err <%v>", msg, err) @@ -110,7 +113,7 @@ func TestSendHeadersCrossProtocol(t *testing.T) { // Decode with old protocol version. readmsg := NewMsgSendHeaders() - err = readmsg.BtcDecode(&buf, SendHeadersVersion) + err = readmsg.BtcDecode(&buf, SendHeadersVersion, enc) if err != nil { t.Errorf("decode of MsgSendHeaders failed [%v] err <%v>", buf, err) @@ -128,6 +131,7 @@ func TestSendHeadersWire(t *testing.T) { out *MsgSendHeaders // Expected decoded message buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version. { @@ -135,6 +139,7 @@ func TestSendHeadersWire(t *testing.T) { msgSendHeaders, msgSendHeadersEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version SendHeadersVersion+1 @@ -143,6 +148,7 @@ func TestSendHeadersWire(t *testing.T) { msgSendHeaders, msgSendHeadersEncoded, SendHeadersVersion + 1, + BaseEncoding, }, // Protocol version SendHeadersVersion @@ -151,6 +157,7 @@ func TestSendHeadersWire(t *testing.T) { msgSendHeaders, msgSendHeadersEncoded, SendHeadersVersion, + BaseEncoding, }, } @@ -158,7 +165,7 @@ func TestSendHeadersWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -172,7 +179,7 @@ func TestSendHeadersWire(t *testing.T) { // Decode the message from wire format. var msg MsgSendHeaders rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue diff --git a/wire/msgtx.go b/wire/msgtx.go index c4a8b320..144f27aa 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -334,7 +334,7 @@ func (msg *MsgTx) Copy() *MsgTx { // This is part of the Message interface implementation. // See Deserialize for decoding transactions stored to disk, such as in a // database, as opposed to decoding transactions from the wire. -func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { version, err := binarySerializer.Uint32(r, littleEndian) if err != nil { return err @@ -498,14 +498,22 @@ func (msg *MsgTx) Deserialize(r io.Reader) error { // At the current time, there is no difference between the wire encoding // at protocol version 0 and the stable long-term storage format. As // a result, make use of BtcDecode. - return msg.BtcDecode(r, 0) + return msg.BtcDecode(r, 0, WitnessEncoding) +} + +// DeserializeNoWitness decodes a transaction from r into the receiver, where +// the transaction encoding format within r MUST NOT utilize the new +// serialization format created to encode transaction bearing witness data +// within inputs. +func (msg *MsgTx) DeserializeNoWitness(r io.Reader) error { + return msg.BtcDecode(r, 0, BaseEncoding) } // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. // See Serialize for encoding transactions to be stored to disk, such as in a // database, as opposed to encoding transactions for the wire. -func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { err := binarySerializer.PutUint32(w, littleEndian, uint32(msg.Version)) if err != nil { return err @@ -554,8 +562,19 @@ func (msg *MsgTx) Serialize(w io.Writer) error { // At the current time, there is no difference between the wire encoding // at protocol version 0 and the stable long-term storage format. As // a result, make use of BtcEncode. - return msg.BtcEncode(w, 0) + // + // Passing a encoding type of WitnessEncoding to BtcEncode for MsgTx + // indicates that the transaction's witnesses (if any) should be + // serialized according to the new serialization structure defined in + // BIP0144. + return msg.BtcEncode(w, 0, WitnessEncoding) +} +// SerializeWitness encodes the transaction to w in an identical manner to +// Serialize, however even if the source transaction has inputs with witness +// data, the old serialization format will still be used. +func (msg *MsgTx) SerializeNoWitness(w io.Writer) error { + return msg.BtcEncode(w, 0, BaseEncoding) } // SerializeSize returns the number of bytes it would take to serialize the diff --git a/wire/msgtx_test.go b/wire/msgtx_test.go index b771fe40..ae669008 100644 --- a/wire/msgtx_test.go +++ b/wire/msgtx_test.go @@ -174,6 +174,83 @@ func TestTxHash(t *testing.T) { } } +// TestTxSha tests the ability to generate the wtxid, and txid of a transaction +// with witness inputs accurately. +func TestWTxSha(t *testing.T) { + hashStrTxid := "0f167d1385a84d1518cfee208b653fc9163b605ccf1b75347e2850b3e2eb19f3" + wantHashTxid, err := chainhash.NewHashFromStr(hashStrTxid) + if err != nil { + t.Errorf("NewShaHashFromStr: %v", err) + return + } + hashStrWTxid := "0858eab78e77b6b033da30f46699996396cf48fcf625a783c85a51403e175e74" + wantHashWTxid, err := chainhash.NewHashFromStr(hashStrWTxid) + if err != nil { + t.Errorf("NewShaHashFromStr: %v", err) + return + } + + // From block 23157 in a past version of segnet. + msgTx := NewMsgTx(1) + txIn := TxIn{ + PreviousOutPoint: OutPoint{ + Hash: chainhash.Hash{ + 0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0, + 0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2, + 0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8, + 0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, + }, + Index: 19, + }, + Witness: [][]byte{ + []byte{ // 70-byte signature + 0x30, 0x43, 0x02, 0x1f, 0x4d, 0x23, 0x81, 0xdc, + 0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51, + 0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd, + 0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36, + 0x58, 0xda, 0x19, 0x02, 0x20, 0x60, 0x8b, 0x5c, + 0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e, + 0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b, + 0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7, + 0x56, 0x9a, 0x18, 0x19, 0x70, 0x01, + }, + []byte{ // 33-byte serialize pub key + 0x03, 0x07, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7, + 0x63, 0x46, 0xdf, 0x69, 0x77, 0x00, 0x0c, 0x89, + 0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61, + 0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x06, 0x6a, + 0x8f, + }, + }, + Sequence: 0xffffffff, + } + txOut := TxOut{ + Value: 395019, + PkScript: []byte{ + 0x00, // Version 0 witness program + 0x14, // OP_DATA_20 + 0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39, + 0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89, + 0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash + }, + } + msgTx.AddTxIn(&txIn) + msgTx.AddTxOut(&txOut) + msgTx.LockTime = 0 + + // Ensure the correct txid, and wtxid is produced as expected. + txid := msgTx.TxHash() + if !txid.IsEqual(wantHashTxid) { + t.Errorf("TxSha: wrong hash - got %v, want %v", + spew.Sprint(txid), spew.Sprint(wantHashTxid)) + } + wtxid := msgTx.WitnessHash() + if !wtxid.IsEqual(wantHashWTxid) { + t.Errorf("WTxSha: wrong hash - got %v, want %v", + spew.Sprint(wtxid), spew.Sprint(wantHashWTxid)) + } +} + // TestTxWire tests the MsgTx wire encode and decode for various numbers // of transaction inputs and outputs and protocol versions. func TestTxWire(t *testing.T) { @@ -188,17 +265,18 @@ func TestTxWire(t *testing.T) { } tests := []struct { - in *MsgTx // Message to encode - out *MsgTx // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgTx // Message to encode + out *MsgTx // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version with no transactions. { noTx, - noTx, - noTxEncoded, + noTx, noTxEncoded, ProtocolVersion, + BaseEncoding, }, // Latest protocol version with multiple transactions. @@ -207,6 +285,7 @@ func TestTxWire(t *testing.T) { multiTx, multiTxEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version with no transactions. @@ -215,6 +294,7 @@ func TestTxWire(t *testing.T) { noTx, noTxEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0035Version with multiple transactions. @@ -223,6 +303,7 @@ func TestTxWire(t *testing.T) { multiTx, multiTxEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version with no transactions. @@ -231,6 +312,7 @@ func TestTxWire(t *testing.T) { noTx, noTxEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version BIP0031Version with multiple transactions. @@ -239,6 +321,7 @@ func TestTxWire(t *testing.T) { multiTx, multiTxEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion with no transactions. @@ -247,6 +330,7 @@ func TestTxWire(t *testing.T) { noTx, noTxEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version NetAddressTimeVersion with multiple transactions. @@ -255,6 +339,7 @@ func TestTxWire(t *testing.T) { multiTx, multiTxEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion with no transactions. @@ -263,6 +348,7 @@ func TestTxWire(t *testing.T) { noTx, noTxEncoded, MultipleAddressVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion with multiple transactions. @@ -271,6 +357,7 @@ func TestTxWire(t *testing.T) { multiTx, multiTxEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -278,7 +365,7 @@ func TestTxWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -292,7 +379,7 @@ func TestTxWire(t *testing.T) { // Decode the message from wire format. var msg MsgTx rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -314,44 +401,45 @@ func TestTxWireErrors(t *testing.T) { pver := uint32(60002) tests := []struct { - in *MsgTx // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgTx // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Force error in version. - {multiTx, multiTxEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in number of transaction inputs. - {multiTx, multiTxEncoded, pver, 4, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF}, // Force error in transaction input previous block hash. - {multiTx, multiTxEncoded, pver, 5, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 5, io.ErrShortWrite, io.EOF}, // Force error in transaction input previous block output index. - {multiTx, multiTxEncoded, pver, 37, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 37, io.ErrShortWrite, io.EOF}, // Force error in transaction input signature script length. - {multiTx, multiTxEncoded, pver, 41, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 41, io.ErrShortWrite, io.EOF}, // Force error in transaction input signature script. - {multiTx, multiTxEncoded, pver, 42, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 42, io.ErrShortWrite, io.EOF}, // Force error in transaction input sequence. - {multiTx, multiTxEncoded, pver, 49, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 49, io.ErrShortWrite, io.EOF}, // Force error in number of transaction outputs. - {multiTx, multiTxEncoded, pver, 53, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 53, io.ErrShortWrite, io.EOF}, // Force error in transaction output value. - {multiTx, multiTxEncoded, pver, 54, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 54, io.ErrShortWrite, io.EOF}, // Force error in transaction output pk script length. - {multiTx, multiTxEncoded, pver, 62, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 62, io.ErrShortWrite, io.EOF}, // Force error in transaction output pk script. - {multiTx, multiTxEncoded, pver, 63, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 63, io.ErrShortWrite, io.EOF}, // Force error in transaction output lock time. - {multiTx, multiTxEncoded, pver, 206, io.ErrShortWrite, io.EOF}, + {multiTx, multiTxEncoded, pver, BaseEncoding, 206, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if err != test.writeErr { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -361,7 +449,7 @@ func TestTxWireErrors(t *testing.T) { // Decode from wire format. var msg MsgTx r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) + err = msg.BtcDecode(r, test.pver, test.enc) if err != test.readErr { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) @@ -386,6 +474,7 @@ func TestTxSerialize(t *testing.T) { out *MsgTx // Expected decoded message buf []byte // Serialized data pkScriptLocs []int // Expected output script locations + witness bool // Serialize using the witness encoding }{ // No transactions. { @@ -393,6 +482,7 @@ func TestTxSerialize(t *testing.T) { noTx, noTxEncoded, nil, + false, }, // Multiple transactions. @@ -401,6 +491,7 @@ func TestTxSerialize(t *testing.T) { multiTx, multiTxEncoded, multiTxPkScriptLocs, + false, }, } @@ -525,10 +616,11 @@ func TestTxOverflowErrors(t *testing.T) { txVer := uint32(1) tests := []struct { - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - version uint32 // Transaction version - err error // Expected error + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + version uint32 // Transaction version + err error // Expected error }{ // Transaction that claims to have ~uint64(0) inputs. { @@ -536,7 +628,7 @@ func TestTxOverflowErrors(t *testing.T) { 0x00, 0x00, 0x00, 0x01, // Version 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Varint for number of input transactions - }, pver, txVer, &MessageError{}, + }, pver, BaseEncoding, txVer, &MessageError{}, }, // Transaction that claims to have ~uint64(0) outputs. @@ -546,7 +638,7 @@ func TestTxOverflowErrors(t *testing.T) { 0x00, // Varint for number of input transactions 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Varint for number of output transactions - }, pver, txVer, &MessageError{}, + }, pver, BaseEncoding, txVer, &MessageError{}, }, // Transaction that has an input with a signature script that @@ -562,7 +654,7 @@ func TestTxOverflowErrors(t *testing.T) { 0xff, 0xff, 0xff, 0xff, // Prevous output index 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Varint for length of signature script - }, pver, txVer, &MessageError{}, + }, pver, BaseEncoding, txVer, &MessageError{}, }, // Transaction that has an output with a public key script @@ -582,7 +674,7 @@ func TestTxOverflowErrors(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Transaction amount 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Varint for length of public key script - }, pver, txVer, &MessageError{}, + }, pver, BaseEncoding, txVer, &MessageError{}, }, } @@ -591,7 +683,7 @@ func TestTxOverflowErrors(t *testing.T) { // Decode from wire format. var msg MsgTx r := bytes.NewReader(test.buf) - err := msg.BtcDecode(r, test.pver) + err := msg.BtcDecode(r, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.err) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, reflect.TypeOf(test.err)) diff --git a/wire/msgverack.go b/wire/msgverack.go index 6d89e61a..60342b56 100644 --- a/wire/msgverack.go +++ b/wire/msgverack.go @@ -17,13 +17,13 @@ type MsgVerAck struct{} // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgVerAck) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgVerAck) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { return nil } // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgVerAck) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgVerAck) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { return nil } diff --git a/wire/msgverack_test.go b/wire/msgverack_test.go index 05066f5b..7a144912 100644 --- a/wire/msgverack_test.go +++ b/wire/msgverack_test.go @@ -41,10 +41,11 @@ func TestVerAckWire(t *testing.T) { msgVerAckEncoded := []byte{} tests := []struct { - in *MsgVerAck // Message to encode - out *MsgVerAck // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgVerAck // Message to encode + out *MsgVerAck // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version. { @@ -52,6 +53,7 @@ func TestVerAckWire(t *testing.T) { msgVerAck, msgVerAckEncoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0035Version. @@ -60,6 +62,7 @@ func TestVerAckWire(t *testing.T) { msgVerAck, msgVerAckEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version. @@ -68,6 +71,7 @@ func TestVerAckWire(t *testing.T) { msgVerAck, msgVerAckEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion. @@ -76,6 +80,7 @@ func TestVerAckWire(t *testing.T) { msgVerAck, msgVerAckEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion. @@ -84,6 +89,7 @@ func TestVerAckWire(t *testing.T) { msgVerAck, msgVerAckEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -91,7 +97,7 @@ func TestVerAckWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -105,7 +111,7 @@ func TestVerAckWire(t *testing.T) { // Decode the message from wire format. var msg MsgVerAck rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue diff --git a/wire/msgversion.go b/wire/msgversion.go index d6a3061f..3077f127 100644 --- a/wire/msgversion.go +++ b/wire/msgversion.go @@ -76,7 +76,7 @@ func (msg *MsgVersion) AddService(service ServiceFlag) { // *bytes.Buffer so the number of remaining bytes can be ascertained. // // This is part of the Message interface implementation. -func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { buf, ok := r.(*bytes.Buffer) if !ok { return fmt.Errorf("MsgVersion.BtcDecode reader is not a " + @@ -149,7 +149,7 @@ func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { err := validateUserAgent(msg.UserAgent) if err != nil { return err diff --git a/wire/msgversion_test.go b/wire/msgversion_test.go index 9d90a7e8..dc2b6e09 100644 --- a/wire/msgversion_test.go +++ b/wire/msgversion_test.go @@ -139,10 +139,11 @@ func TestVersionWire(t *testing.T) { verRelayTxFalseEncoded[len(verRelayTxFalseEncoded)-1] = 0 tests := []struct { - in *MsgVersion // Message to encode - out *MsgVersion // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + in *MsgVersion // Message to encode + out *MsgVersion // Expected decoded message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ // Latest protocol version. { @@ -150,6 +151,7 @@ func TestVersionWire(t *testing.T) { baseVersionBIP0037, baseVersionBIP0037Encoded, ProtocolVersion, + BaseEncoding, }, // Protocol version BIP0037Version with relay transactions field @@ -159,6 +161,7 @@ func TestVersionWire(t *testing.T) { baseVersionBIP0037, baseVersionBIP0037Encoded, BIP0037Version, + BaseEncoding, }, // Protocol version BIP0037Version with relay transactions field @@ -168,6 +171,7 @@ func TestVersionWire(t *testing.T) { verRelayTxFalse, verRelayTxFalseEncoded, BIP0037Version, + BaseEncoding, }, // Protocol version BIP0035Version. @@ -176,6 +180,7 @@ func TestVersionWire(t *testing.T) { baseVersion, baseVersionEncoded, BIP0035Version, + BaseEncoding, }, // Protocol version BIP0031Version. @@ -184,6 +189,7 @@ func TestVersionWire(t *testing.T) { baseVersion, baseVersionEncoded, BIP0031Version, + BaseEncoding, }, // Protocol version NetAddressTimeVersion. @@ -192,6 +198,7 @@ func TestVersionWire(t *testing.T) { baseVersion, baseVersionEncoded, NetAddressTimeVersion, + BaseEncoding, }, // Protocol version MultipleAddressVersion. @@ -200,6 +207,7 @@ func TestVersionWire(t *testing.T) { baseVersion, baseVersionEncoded, MultipleAddressVersion, + BaseEncoding, }, } @@ -207,7 +215,7 @@ func TestVersionWire(t *testing.T) { for i, test := range tests { // Encode the message to wire format. var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) + err := test.in.BtcEncode(&buf, test.pver, test.enc) if err != nil { t.Errorf("BtcEncode #%d error %v", i, err) continue @@ -221,7 +229,7 @@ func TestVersionWire(t *testing.T) { // Decode the message from wire format. var msg MsgVersion rbuf := bytes.NewBuffer(test.buf) - err = msg.BtcDecode(rbuf, test.pver) + err = msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue @@ -241,12 +249,13 @@ func TestVersionWireErrors(t *testing.T) { // because the test data is using bytes encoded with that protocol // version. pver := uint32(60002) + enc := BaseEncoding wireErr := &MessageError{} // Ensure calling MsgVersion.BtcDecode with a non *bytes.Buffer returns // error. fr := newFixedReader(0, []byte{}) - if err := baseVersion.BtcDecode(fr, pver); err == nil { + if err := baseVersion.BtcDecode(fr, pver, enc); err == nil { t.Errorf("Did not received error when calling " + "MsgVersion.BtcDecode with non *bytes.Buffer") } @@ -276,46 +285,47 @@ func TestVersionWireErrors(t *testing.T) { copy(exceedUAVerEncoded[83+len(newUA):], baseVersionEncoded[97:100]) tests := []struct { - in *MsgVersion // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error + in *MsgVersion // Value to encode + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format + max int // Max size of fixed buffer to induce errors + writeErr error // Expected write error + readErr error // Expected read error }{ // Force error in protocol version. - {baseVersion, baseVersionEncoded, pver, 0, io.ErrShortWrite, io.EOF}, + {baseVersion, baseVersionEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, // Force error in services. - {baseVersion, baseVersionEncoded, pver, 4, io.ErrShortWrite, io.EOF}, + {baseVersion, baseVersionEncoded, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF}, // Force error in timestamp. - {baseVersion, baseVersionEncoded, pver, 12, io.ErrShortWrite, io.EOF}, + {baseVersion, baseVersionEncoded, pver, BaseEncoding, 12, io.ErrShortWrite, io.EOF}, // Force error in remote address. - {baseVersion, baseVersionEncoded, pver, 20, io.ErrShortWrite, io.EOF}, + {baseVersion, baseVersionEncoded, pver, BaseEncoding, 20, io.ErrShortWrite, io.EOF}, // Force error in local address. - {baseVersion, baseVersionEncoded, pver, 47, io.ErrShortWrite, io.ErrUnexpectedEOF}, + {baseVersion, baseVersionEncoded, pver, BaseEncoding, 47, io.ErrShortWrite, io.ErrUnexpectedEOF}, // Force error in nonce. - {baseVersion, baseVersionEncoded, pver, 73, io.ErrShortWrite, io.ErrUnexpectedEOF}, + {baseVersion, baseVersionEncoded, pver, BaseEncoding, 73, io.ErrShortWrite, io.ErrUnexpectedEOF}, // Force error in user agent length. - {baseVersion, baseVersionEncoded, pver, 81, io.ErrShortWrite, io.EOF}, + {baseVersion, baseVersionEncoded, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF}, // Force error in user agent. - {baseVersion, baseVersionEncoded, pver, 82, io.ErrShortWrite, io.ErrUnexpectedEOF}, + {baseVersion, baseVersionEncoded, pver, BaseEncoding, 82, io.ErrShortWrite, io.ErrUnexpectedEOF}, // Force error in last block. - {baseVersion, baseVersionEncoded, pver, 98, io.ErrShortWrite, io.ErrUnexpectedEOF}, + {baseVersion, baseVersionEncoded, pver, BaseEncoding, 98, io.ErrShortWrite, io.ErrUnexpectedEOF}, // Force error in relay tx - no read error should happen since // it's optional. { baseVersionBIP0037, baseVersionBIP0037Encoded, - BIP0037Version, 101, io.ErrShortWrite, nil, + BIP0037Version, BaseEncoding, 101, io.ErrShortWrite, nil, }, // Force error due to user agent too big - {exceedUAVer, exceedUAVerEncoded, pver, newLen, wireErr, wireErr}, + {exceedUAVer, exceedUAVerEncoded, pver, BaseEncoding, newLen, wireErr, wireErr}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) + err := test.in.BtcEncode(w, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", i, err, test.writeErr) @@ -335,7 +345,7 @@ func TestVersionWireErrors(t *testing.T) { // Decode from wire format. var msg MsgVersion buf := bytes.NewBuffer(test.buf[0:test.max]) - err = msg.BtcDecode(buf, test.pver) + err = msg.BtcDecode(buf, test.pver, test.enc) if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", i, err, test.readErr) @@ -407,34 +417,40 @@ func TestVersionOptionalFields(t *testing.T) { copy(lastBlockVersionEncoded, baseVersionEncoded) tests := []struct { - msg *MsgVersion // Expected message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding + msg *MsgVersion // Expected message + buf []byte // Wire encoding + pver uint32 // Protocol version for wire encoding + enc MessageEncoding // Message encoding format }{ { &onlyRequiredVersion, onlyRequiredVersionEncoded, ProtocolVersion, + BaseEncoding, }, { &addrMeVersion, addrMeVersionEncoded, ProtocolVersion, + BaseEncoding, }, { &nonceVersion, nonceVersionEncoded, ProtocolVersion, + BaseEncoding, }, { &uaVersion, uaVersionEncoded, ProtocolVersion, + BaseEncoding, }, { &lastBlockVersion, lastBlockVersionEncoded, ProtocolVersion, + BaseEncoding, }, } @@ -442,7 +458,7 @@ func TestVersionOptionalFields(t *testing.T) { // Decode the message from wire format. var msg MsgVersion rbuf := bytes.NewBuffer(test.buf) - err := msg.BtcDecode(rbuf, test.pver) + err := msg.BtcDecode(rbuf, test.pver, test.enc) if err != nil { t.Errorf("BtcDecode #%d error %v", i, err) continue