1 // Copyright (c) 2013-2016 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
13 "github.com/btcsuite/btcd/chaincfg/chainhash"
14 "github.com/davecgh/go-spew/spew"
17 // TestNotFound tests the MsgNotFound API.
18 func TestNotFound(t *testing.T) {
19 pver := ProtocolVersion
21 // Ensure the command is expected value.
23 msg := NewMsgNotFound()
24 if cmd := msg.Command(); cmd != wantCmd {
25 t.Errorf("NewMsgNotFound: wrong command - got %v want %v",
29 // Ensure max payload is expected value for latest protocol version.
30 // Num inventory vectors (varInt) + max allowed inventory vectors.
31 wantPayload := uint32(1800009)
32 maxPayload := msg.MaxPayloadLength(pver)
33 if maxPayload != wantPayload {
34 t.Errorf("MaxPayloadLength: wrong max payload length for "+
35 "protocol version %d - got %v, want %v", pver,
36 maxPayload, wantPayload)
39 // Ensure inventory vectors are added properly.
40 hash := chainhash.Hash{}
41 iv := NewInvVect(InvTypeBlock, &hash)
42 err := msg.AddInvVect(iv)
44 t.Errorf("AddInvVect: %v", err)
46 if msg.InvList[0] != iv {
47 t.Errorf("AddInvVect: wrong invvect added - got %v, want %v",
48 spew.Sprint(msg.InvList[0]), spew.Sprint(iv))
51 // Ensure adding more than the max allowed inventory vectors per
52 // message returns an error.
53 for i := 0; i < MaxInvPerMsg; i++ {
54 err = msg.AddInvVect(iv)
57 t.Errorf("AddInvVect: expected error on too many inventory " +
58 "vectors not received")
62 // TestNotFoundWire tests the MsgNotFound wire encode and decode for various
63 // numbers of inventory vectors and protocol versions.
64 func TestNotFoundWire(t *testing.T) {
66 hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
67 blockHash, err := chainhash.NewHashFromStr(hashStr)
69 t.Errorf("NewHashFromStr: %v", err)
72 // Transation 1 of Block 203707 hash.
73 hashStr = "d28a3dc7392bf00a9855ee93dd9a81eff82a2c4fe57fbd42cfe71b487accfaf0"
74 txHash, err := chainhash.NewHashFromStr(hashStr)
76 t.Errorf("NewHashFromStr: %v", err)
79 iv := NewInvVect(InvTypeBlock, blockHash)
80 iv2 := NewInvVect(InvTypeTx, txHash)
82 // Empty notfound message.
83 NoInv := NewMsgNotFound()
84 NoInvEncoded := []byte{
85 0x00, // Varint for number of inventory vectors
88 // NotFound message with multiple inventory vectors.
89 MultiInv := NewMsgNotFound()
90 MultiInv.AddInvVect(iv)
91 MultiInv.AddInvVect(iv2)
92 MultiInvEncoded := []byte{
93 0x02, // Varint for number of inv vectors
94 0x02, 0x00, 0x00, 0x00, // InvTypeBlock
95 0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7,
96 0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4, 0xa1, 0x0b,
97 0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b,
98 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 203707 hash
99 0x01, 0x00, 0x00, 0x00, // InvTypeTx
100 0xf0, 0xfa, 0xcc, 0x7a, 0x48, 0x1b, 0xe7, 0xcf,
101 0x42, 0xbd, 0x7f, 0xe5, 0x4f, 0x2c, 0x2a, 0xf8,
102 0xef, 0x81, 0x9a, 0xdd, 0x93, 0xee, 0x55, 0x98,
103 0x0a, 0xf0, 0x2b, 0x39, 0xc7, 0x3d, 0x8a, 0xd2, // Tx 1 of block 203707 hash
107 in *MsgNotFound // Message to encode
108 out *MsgNotFound // Expected decoded message
109 buf []byte // Wire encoding
110 pver uint32 // Protocol version for wire encoding
111 enc MessageEncoding // Message encoding format
113 // Latest protocol version with no inv vectors.
122 // Latest protocol version with multiple inv vectors.
131 // Protocol version BIP0035Version no inv vectors.
140 // Protocol version BIP0035Version with multiple inv vectors.
149 // Protocol version BIP0031Version no inv vectors.
158 // Protocol version BIP0031Version with multiple inv vectors.
167 // Protocol version NetAddressTimeVersion no inv vectors.
172 NetAddressTimeVersion,
176 // Protocol version NetAddressTimeVersion with multiple inv vectors.
181 NetAddressTimeVersion,
185 // Protocol version MultipleAddressVersion no inv vectors.
190 MultipleAddressVersion,
194 // Protocol version MultipleAddressVersion with multiple inv vectors.
199 MultipleAddressVersion,
204 t.Logf("Running %d tests", len(tests))
205 for i, test := range tests {
206 // Encode the message to wire format.
208 err := test.in.BtcEncode(&buf, test.pver, test.enc)
210 t.Errorf("BtcEncode #%d error %v", i, err)
213 if !bytes.Equal(buf.Bytes(), test.buf) {
214 t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
215 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
219 // Decode the message from wire format.
221 rbuf := bytes.NewReader(test.buf)
222 err = msg.BtcDecode(rbuf, test.pver, test.enc)
224 t.Errorf("BtcDecode #%d error %v", i, err)
227 if !reflect.DeepEqual(&msg, test.out) {
228 t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
229 spew.Sdump(msg), spew.Sdump(test.out))
235 // TestNotFoundWireErrors performs negative tests against wire encode and decode
236 // of MsgNotFound to confirm error paths work correctly.
237 func TestNotFoundWireErrors(t *testing.T) {
238 pver := ProtocolVersion
239 wireErr := &MessageError{}
241 // Block 203707 hash.
242 hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
243 blockHash, err := chainhash.NewHashFromStr(hashStr)
245 t.Errorf("NewHashFromStr: %v", err)
248 iv := NewInvVect(InvTypeBlock, blockHash)
250 // Base message used to induce errors.
251 baseNotFound := NewMsgNotFound()
252 baseNotFound.AddInvVect(iv)
253 baseNotFoundEncoded := []byte{
254 0x02, // Varint for number of inv vectors
255 0x02, 0x00, 0x00, 0x00, // InvTypeBlock
256 0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7,
257 0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4, 0xa1, 0x0b,
258 0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b,
259 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 203707 hash
262 // Message that forces an error by having more than the max allowed inv
264 maxNotFound := NewMsgNotFound()
265 for i := 0; i < MaxInvPerMsg; i++ {
266 maxNotFound.AddInvVect(iv)
268 maxNotFound.InvList = append(maxNotFound.InvList, iv)
269 maxNotFoundEncoded := []byte{
270 0xfd, 0x51, 0xc3, // Varint for number of inv vectors (50001)
274 in *MsgNotFound // Value to encode
275 buf []byte // Wire encoding
276 pver uint32 // Protocol version for wire encoding
277 enc MessageEncoding // Message encoding format
278 max int // Max size of fixed buffer to induce errors
279 writeErr error // Expected write error
280 readErr error // Expected read error
282 // Force error in inventory vector count
283 {baseNotFound, baseNotFoundEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
284 // Force error in inventory list.
285 {baseNotFound, baseNotFoundEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF},
286 // Force error with greater than max inventory vectors.
287 {maxNotFound, maxNotFoundEncoded, pver, BaseEncoding, 3, wireErr, wireErr},
290 t.Logf("Running %d tests", len(tests))
291 for i, test := range tests {
292 // Encode to wire format.
293 w := newFixedWriter(test.max)
294 err := test.in.BtcEncode(w, test.pver, test.enc)
295 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
296 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
297 i, err, test.writeErr)
301 // For errors which are not of type MessageError, check them for
303 if _, ok := err.(*MessageError); !ok {
304 if err != test.writeErr {
305 t.Errorf("BtcEncode #%d wrong error got: %v, "+
306 "want: %v", i, err, test.writeErr)
311 // Decode from wire format.
313 r := newFixedReader(test.max, test.buf)
314 err = msg.BtcDecode(r, test.pver, test.enc)
315 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
316 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
317 i, err, test.readErr)
321 // For errors which are not of type MessageError, check them for
323 if _, ok := err.(*MessageError); !ok {
324 if err != test.readErr {
325 t.Errorf("BtcDecode #%d wrong error got: %v, "+
326 "want: %v", i, err, test.readErr)