OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / wire / msggetdata_test.go
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.
4
5 package wire
6
7 import (
8         "bytes"
9         "io"
10         "reflect"
11         "testing"
12
13         "github.com/btcsuite/btcd/chaincfg/chainhash"
14         "github.com/davecgh/go-spew/spew"
15 )
16
17 // TestGetData tests the MsgGetData API.
18 func TestGetData(t *testing.T) {
19         pver := ProtocolVersion
20
21         // Ensure the command is expected value.
22         wantCmd := "getdata"
23         msg := NewMsgGetData()
24         if cmd := msg.Command(); cmd != wantCmd {
25                 t.Errorf("NewMsgGetData: wrong command - got %v want %v",
26                         cmd, wantCmd)
27         }
28
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)
37         }
38
39         // Ensure inventory vectors are added properly.
40         hash := chainhash.Hash{}
41         iv := NewInvVect(InvTypeBlock, &hash)
42         err := msg.AddInvVect(iv)
43         if err != nil {
44                 t.Errorf("AddInvVect: %v", err)
45         }
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))
49         }
50
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)
55         }
56         if err == nil {
57                 t.Errorf("AddInvVect: expected error on too many inventory " +
58                         "vectors not received")
59         }
60
61         // Ensure creating the message with a size hint larger than the max
62         // works as expected.
63         msg = NewMsgGetDataSizeHint(MaxInvPerMsg + 1)
64         wantCap := MaxInvPerMsg
65         if cap(msg.InvList) != wantCap {
66                 t.Errorf("NewMsgGetDataSizeHint: wrong cap for size hint - "+
67                         "got %v, want %v", cap(msg.InvList), wantCap)
68         }
69 }
70
71 // TestGetDataWire tests the MsgGetData wire encode and decode for various
72 // numbers of inventory vectors and protocol versions.
73 func TestGetDataWire(t *testing.T) {
74         // Block 203707 hash.
75         hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
76         blockHash, err := chainhash.NewHashFromStr(hashStr)
77         if err != nil {
78                 t.Errorf("NewHashFromStr: %v", err)
79         }
80
81         // Transation 1 of Block 203707 hash.
82         hashStr = "d28a3dc7392bf00a9855ee93dd9a81eff82a2c4fe57fbd42cfe71b487accfaf0"
83         txHash, err := chainhash.NewHashFromStr(hashStr)
84         if err != nil {
85                 t.Errorf("NewHashFromStr: %v", err)
86         }
87
88         iv := NewInvVect(InvTypeBlock, blockHash)
89         iv2 := NewInvVect(InvTypeTx, txHash)
90
91         // Empty MsgGetData message.
92         NoInv := NewMsgGetData()
93         NoInvEncoded := []byte{
94                 0x00, // Varint for number of inventory vectors
95         }
96
97         // MsgGetData message with multiple inventory vectors.
98         MultiInv := NewMsgGetData()
99         MultiInv.AddInvVect(iv)
100         MultiInv.AddInvVect(iv2)
101         MultiInvEncoded := []byte{
102                 0x02,                   // Varint for number of inv vectors
103                 0x02, 0x00, 0x00, 0x00, // InvTypeBlock
104                 0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7,
105                 0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4, 0xa1, 0x0b,
106                 0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b,
107                 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 203707 hash
108                 0x01, 0x00, 0x00, 0x00, // InvTypeTx
109                 0xf0, 0xfa, 0xcc, 0x7a, 0x48, 0x1b, 0xe7, 0xcf,
110                 0x42, 0xbd, 0x7f, 0xe5, 0x4f, 0x2c, 0x2a, 0xf8,
111                 0xef, 0x81, 0x9a, 0xdd, 0x93, 0xee, 0x55, 0x98,
112                 0x0a, 0xf0, 0x2b, 0x39, 0xc7, 0x3d, 0x8a, 0xd2, // Tx 1 of block 203707 hash
113         }
114
115         tests := []struct {
116                 in   *MsgGetData     // Message to encode
117                 out  *MsgGetData     // Expected decoded message
118                 buf  []byte          // Wire encoding
119                 pver uint32          // Protocol version for wire encoding
120                 enc  MessageEncoding // Message encoding format
121         }{
122                 // Latest protocol version with no inv vectors.
123                 {
124                         NoInv,
125                         NoInv,
126                         NoInvEncoded,
127                         ProtocolVersion,
128                         BaseEncoding,
129                 },
130
131                 // Latest protocol version with multiple inv vectors.
132                 {
133                         MultiInv,
134                         MultiInv,
135                         MultiInvEncoded,
136                         ProtocolVersion,
137                         BaseEncoding,
138                 },
139
140                 // Protocol version BIP0035Version no inv vectors.
141                 {
142                         NoInv,
143                         NoInv,
144                         NoInvEncoded,
145                         BIP0035Version,
146                         BaseEncoding,
147                 },
148
149                 // Protocol version BIP0035Version with multiple inv vectors.
150                 {
151                         MultiInv,
152                         MultiInv,
153                         MultiInvEncoded,
154                         BIP0035Version,
155                         BaseEncoding,
156                 },
157
158                 // Protocol version BIP0031Version no inv vectors.
159                 {
160                         NoInv,
161                         NoInv,
162                         NoInvEncoded,
163                         BIP0031Version,
164                         BaseEncoding,
165                 },
166
167                 // Protocol version BIP0031Version with multiple inv vectors.
168                 {
169                         MultiInv,
170                         MultiInv,
171                         MultiInvEncoded,
172                         BIP0031Version,
173                         BaseEncoding,
174                 },
175
176                 // Protocol version NetAddressTimeVersion no inv vectors.
177                 {
178                         NoInv,
179                         NoInv,
180                         NoInvEncoded,
181                         NetAddressTimeVersion,
182                         BaseEncoding,
183                 },
184
185                 // Protocol version NetAddressTimeVersion with multiple inv vectors.
186                 {
187                         MultiInv,
188                         MultiInv,
189                         MultiInvEncoded,
190                         NetAddressTimeVersion,
191                         BaseEncoding,
192                 },
193
194                 // Protocol version MultipleAddressVersion no inv vectors.
195                 {
196                         NoInv,
197                         NoInv,
198                         NoInvEncoded,
199                         MultipleAddressVersion,
200                         BaseEncoding,
201                 },
202
203                 // Protocol version MultipleAddressVersion with multiple inv vectors.
204                 {
205                         MultiInv,
206                         MultiInv,
207                         MultiInvEncoded,
208                         MultipleAddressVersion,
209                         BaseEncoding,
210                 },
211         }
212
213         t.Logf("Running %d tests", len(tests))
214         for i, test := range tests {
215                 // Encode the message to wire format.
216                 var buf bytes.Buffer
217                 err := test.in.BtcEncode(&buf, test.pver, test.enc)
218                 if err != nil {
219                         t.Errorf("BtcEncode #%d error %v", i, err)
220                         continue
221                 }
222                 if !bytes.Equal(buf.Bytes(), test.buf) {
223                         t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
224                                 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
225                         continue
226                 }
227
228                 // Decode the message from wire format.
229                 var msg MsgGetData
230                 rbuf := bytes.NewReader(test.buf)
231                 err = msg.BtcDecode(rbuf, test.pver, test.enc)
232                 if err != nil {
233                         t.Errorf("BtcDecode #%d error %v", i, err)
234                         continue
235                 }
236                 if !reflect.DeepEqual(&msg, test.out) {
237                         t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
238                                 spew.Sdump(msg), spew.Sdump(test.out))
239                         continue
240                 }
241         }
242 }
243
244 // TestGetDataWireErrors performs negative tests against wire encode and decode
245 // of MsgGetData to confirm error paths work correctly.
246 func TestGetDataWireErrors(t *testing.T) {
247         pver := ProtocolVersion
248         wireErr := &MessageError{}
249
250         // Block 203707 hash.
251         hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
252         blockHash, err := chainhash.NewHashFromStr(hashStr)
253         if err != nil {
254                 t.Errorf("NewHashFromStr: %v", err)
255         }
256
257         iv := NewInvVect(InvTypeBlock, blockHash)
258
259         // Base message used to induce errors.
260         baseGetData := NewMsgGetData()
261         baseGetData.AddInvVect(iv)
262         baseGetDataEncoded := []byte{
263                 0x02,                   // Varint for number of inv vectors
264                 0x02, 0x00, 0x00, 0x00, // InvTypeBlock
265                 0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7,
266                 0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4, 0xa1, 0x0b,
267                 0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b,
268                 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 203707 hash
269         }
270
271         // Message that forces an error by having more than the max allowed inv
272         // vectors.
273         maxGetData := NewMsgGetData()
274         for i := 0; i < MaxInvPerMsg; i++ {
275                 maxGetData.AddInvVect(iv)
276         }
277         maxGetData.InvList = append(maxGetData.InvList, iv)
278         maxGetDataEncoded := []byte{
279                 0xfd, 0x51, 0xc3, // Varint for number of inv vectors (50001)
280         }
281
282         tests := []struct {
283                 in       *MsgGetData     // Value to encode
284                 buf      []byte          // Wire encoding
285                 pver     uint32          // Protocol version for wire encoding
286                 enc      MessageEncoding // Message encoding format
287                 max      int             // Max size of fixed buffer to induce errors
288                 writeErr error           // Expected write error
289                 readErr  error           // Expected read error
290         }{
291                 // Latest protocol version with intentional read/write errors.
292                 // Force error in inventory vector count
293                 {baseGetData, baseGetDataEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
294                 // Force error in inventory list.
295                 {baseGetData, baseGetDataEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF},
296                 // Force error with greater than max inventory vectors.
297                 {maxGetData, maxGetDataEncoded, pver, BaseEncoding, 3, wireErr, wireErr},
298         }
299
300         t.Logf("Running %d tests", len(tests))
301         for i, test := range tests {
302                 // Encode to wire format.
303                 w := newFixedWriter(test.max)
304                 err := test.in.BtcEncode(w, test.pver, test.enc)
305                 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
306                         t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
307                                 i, err, test.writeErr)
308                         continue
309                 }
310
311                 // For errors which are not of type MessageError, check them for
312                 // equality.
313                 if _, ok := err.(*MessageError); !ok {
314                         if err != test.writeErr {
315                                 t.Errorf("BtcEncode #%d wrong error got: %v, "+
316                                         "want: %v", i, err, test.writeErr)
317                                 continue
318                         }
319                 }
320
321                 // Decode from wire format.
322                 var msg MsgGetData
323                 r := newFixedReader(test.max, test.buf)
324                 err = msg.BtcDecode(r, test.pver, test.enc)
325                 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
326                         t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
327                                 i, err, test.readErr)
328                         continue
329                 }
330
331                 // For errors which are not of type MessageError, check them for
332                 // equality.
333                 if _, ok := err.(*MessageError); !ok {
334                         if err != test.readErr {
335                                 t.Errorf("BtcDecode #%d wrong error got: %v, "+
336                                         "want: %v", i, err, test.readErr)
337                                 continue
338                         }
339                 }
340         }
341 }