OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / wire / msgreject_test.go
1 // Copyright (c) 2014-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/davecgh/go-spew/spew"
14 )
15
16 // TestRejectCodeStringer tests the stringized output for the reject code type.
17 func TestRejectCodeStringer(t *testing.T) {
18         tests := []struct {
19                 in   RejectCode
20                 want string
21         }{
22                 {RejectMalformed, "REJECT_MALFORMED"},
23                 {RejectInvalid, "REJECT_INVALID"},
24                 {RejectObsolete, "REJECT_OBSOLETE"},
25                 {RejectDuplicate, "REJECT_DUPLICATE"},
26                 {RejectNonstandard, "REJECT_NONSTANDARD"},
27                 {RejectDust, "REJECT_DUST"},
28                 {RejectInsufficientFee, "REJECT_INSUFFICIENTFEE"},
29                 {RejectCheckpoint, "REJECT_CHECKPOINT"},
30                 {0xff, "Unknown RejectCode (255)"},
31         }
32
33         t.Logf("Running %d tests", len(tests))
34         for i, test := range tests {
35                 result := test.in.String()
36                 if result != test.want {
37                         t.Errorf("String #%d\n got: %s want: %s", i, result,
38                                 test.want)
39                         continue
40                 }
41         }
42
43 }
44
45 // TestRejectLatest tests the MsgPong API against the latest protocol version.
46 func TestRejectLatest(t *testing.T) {
47         pver := ProtocolVersion
48         enc := BaseEncoding
49
50         // Create reject message data.
51         rejCommand := (&MsgBlock{}).Command()
52         rejCode := RejectDuplicate
53         rejReason := "duplicate block"
54         rejHash := mainNetGenesisHash
55
56         // Ensure we get the correct data back out.
57         msg := NewMsgReject(rejCommand, rejCode, rejReason)
58         msg.Hash = rejHash
59         if msg.Cmd != rejCommand {
60                 t.Errorf("NewMsgReject: wrong rejected command - got %v, "+
61                         "want %v", msg.Cmd, rejCommand)
62         }
63         if msg.Code != rejCode {
64                 t.Errorf("NewMsgReject: wrong rejected code - got %v, "+
65                         "want %v", msg.Code, rejCode)
66         }
67         if msg.Reason != rejReason {
68                 t.Errorf("NewMsgReject: wrong rejected reason - got %v, "+
69                         "want %v", msg.Reason, rejReason)
70         }
71
72         // Ensure the command is expected value.
73         wantCmd := "reject"
74         if cmd := msg.Command(); cmd != wantCmd {
75                 t.Errorf("NewMsgReject: wrong command - got %v want %v",
76                         cmd, wantCmd)
77         }
78
79         // Ensure max payload is expected value for latest protocol version.
80         wantPayload := uint32(MaxMessagePayload)
81         maxPayload := msg.MaxPayloadLength(pver)
82         if maxPayload != wantPayload {
83                 t.Errorf("MaxPayloadLength: wrong max payload length for "+
84                         "protocol version %d - got %v, want %v", pver,
85                         maxPayload, wantPayload)
86         }
87
88         // Test encode with latest protocol version.
89         var buf bytes.Buffer
90         err := msg.BtcEncode(&buf, pver, enc)
91         if err != nil {
92                 t.Errorf("encode of MsgReject failed %v err <%v>", msg, err)
93         }
94
95         // Test decode with latest protocol version.
96         readMsg := MsgReject{}
97         err = readMsg.BtcDecode(&buf, pver, enc)
98         if err != nil {
99                 t.Errorf("decode of MsgReject failed %v err <%v>", buf.Bytes(),
100                         err)
101         }
102
103         // Ensure decoded data is the same.
104         if msg.Cmd != readMsg.Cmd {
105                 t.Errorf("Should get same reject command - got %v, want %v",
106                         readMsg.Cmd, msg.Cmd)
107         }
108         if msg.Code != readMsg.Code {
109                 t.Errorf("Should get same reject code - got %v, want %v",
110                         readMsg.Code, msg.Code)
111         }
112         if msg.Reason != readMsg.Reason {
113                 t.Errorf("Should get same reject reason - got %v, want %v",
114                         readMsg.Reason, msg.Reason)
115         }
116         if msg.Hash != readMsg.Hash {
117                 t.Errorf("Should get same reject hash - got %v, want %v",
118                         readMsg.Hash, msg.Hash)
119         }
120 }
121
122 // TestRejectBeforeAdded tests the MsgReject API against a protocol version
123 // before the version which introduced it (RejectVersion).
124 func TestRejectBeforeAdded(t *testing.T) {
125         // Use the protocol version just prior to RejectVersion.
126         pver := RejectVersion - 1
127         enc := BaseEncoding
128
129         // Create reject message data.
130         rejCommand := (&MsgBlock{}).Command()
131         rejCode := RejectDuplicate
132         rejReason := "duplicate block"
133         rejHash := mainNetGenesisHash
134
135         msg := NewMsgReject(rejCommand, rejCode, rejReason)
136         msg.Hash = rejHash
137
138         // Ensure max payload is expected value for old protocol version.
139         size := msg.MaxPayloadLength(pver)
140         if size != 0 {
141                 t.Errorf("Max length should be 0 for reject protocol version %d.",
142                         pver)
143         }
144
145         // Test encode with old protocol version.
146         var buf bytes.Buffer
147         err := msg.BtcEncode(&buf, pver, enc)
148         if err == nil {
149                 t.Errorf("encode of MsgReject succeeded when it shouldn't "+
150                         "have %v", msg)
151         }
152
153         //      // Test decode with old protocol version.
154         readMsg := MsgReject{}
155         err = readMsg.BtcDecode(&buf, pver, enc)
156         if err == nil {
157                 t.Errorf("decode of MsgReject succeeded when it shouldn't "+
158                         "have %v", spew.Sdump(buf.Bytes()))
159         }
160
161         // Since this protocol version doesn't support reject, make sure various
162         // fields didn't get encoded and decoded back out.
163         if msg.Cmd == readMsg.Cmd {
164                 t.Errorf("Should not get same reject command for protocol "+
165                         "version %d", pver)
166         }
167         if msg.Code == readMsg.Code {
168                 t.Errorf("Should not get same reject code for protocol "+
169                         "version %d", pver)
170         }
171         if msg.Reason == readMsg.Reason {
172                 t.Errorf("Should not get same reject reason for protocol "+
173                         "version %d", pver)
174         }
175         if msg.Hash == readMsg.Hash {
176                 t.Errorf("Should not get same reject hash for protocol "+
177                         "version %d", pver)
178         }
179 }
180
181 // TestRejectCrossProtocol tests the MsgReject API when encoding with the latest
182 // protocol version and decoded with a version before the version which
183 // introduced it (RejectVersion).
184 func TestRejectCrossProtocol(t *testing.T) {
185         // Create reject message data.
186         rejCommand := (&MsgBlock{}).Command()
187         rejCode := RejectDuplicate
188         rejReason := "duplicate block"
189         rejHash := mainNetGenesisHash
190
191         msg := NewMsgReject(rejCommand, rejCode, rejReason)
192         msg.Hash = rejHash
193
194         // Encode with latest protocol version.
195         var buf bytes.Buffer
196         err := msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding)
197         if err != nil {
198                 t.Errorf("encode of MsgReject failed %v err <%v>", msg, err)
199         }
200
201         // Decode with old protocol version.
202         readMsg := MsgReject{}
203         err = readMsg.BtcDecode(&buf, RejectVersion-1, BaseEncoding)
204         if err == nil {
205                 t.Errorf("encode of MsgReject succeeded when it shouldn't "+
206                         "have %v", msg)
207         }
208
209         // Since one of the protocol versions doesn't support the reject
210         // message, make sure the various fields didn't get encoded and decoded
211         // back out.
212         if msg.Cmd == readMsg.Cmd {
213                 t.Errorf("Should not get same reject command for cross protocol")
214         }
215         if msg.Code == readMsg.Code {
216                 t.Errorf("Should not get same reject code for cross protocol")
217         }
218         if msg.Reason == readMsg.Reason {
219                 t.Errorf("Should not get same reject reason for cross protocol")
220         }
221         if msg.Hash == readMsg.Hash {
222                 t.Errorf("Should not get same reject hash for cross protocol")
223         }
224 }
225
226 // TestRejectWire tests the MsgReject wire encode and decode for various
227 // protocol versions.
228 func TestRejectWire(t *testing.T) {
229         tests := []struct {
230                 msg  MsgReject       // Message to encode
231                 buf  []byte          // Wire encoding
232                 pver uint32          // Protocol version for wire encoding
233                 enc  MessageEncoding // Message encoding format
234         }{
235                 // Latest protocol version rejected command version (no hash).
236                 {
237                         MsgReject{
238                                 Cmd:    "version",
239                                 Code:   RejectDuplicate,
240                                 Reason: "duplicate version",
241                         },
242                         []byte{
243                                 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, // "version"
244                                 0x12, // RejectDuplicate
245                                 0x11, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61,
246                                 0x74, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
247                                 0x6f, 0x6e, // "duplicate version"
248                         },
249                         ProtocolVersion,
250                         BaseEncoding,
251                 },
252                 // Latest protocol version rejected command block (has hash).
253                 {
254                         MsgReject{
255                                 Cmd:    "block",
256                                 Code:   RejectDuplicate,
257                                 Reason: "duplicate block",
258                                 Hash:   mainNetGenesisHash,
259                         },
260                         []byte{
261                                 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "block"
262                                 0x12, // RejectDuplicate
263                                 0x0f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61,
264                                 0x74, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "duplicate block"
265                                 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
266                                 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
267                                 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
268                                 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // mainNetGenesisHash
269                         },
270                         ProtocolVersion,
271                         BaseEncoding,
272                 },
273         }
274
275         t.Logf("Running %d tests", len(tests))
276         for i, test := range tests {
277                 // Encode the message to wire format.
278                 var buf bytes.Buffer
279                 err := test.msg.BtcEncode(&buf, test.pver, test.enc)
280                 if err != nil {
281                         t.Errorf("BtcEncode #%d error %v", i, err)
282                         continue
283                 }
284                 if !bytes.Equal(buf.Bytes(), test.buf) {
285                         t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
286                                 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
287                         continue
288                 }
289
290                 // Decode the message from wire format.
291                 var msg MsgReject
292                 rbuf := bytes.NewReader(test.buf)
293                 err = msg.BtcDecode(rbuf, test.pver, test.enc)
294                 if err != nil {
295                         t.Errorf("BtcDecode #%d error %v", i, err)
296                         continue
297                 }
298                 if !reflect.DeepEqual(msg, test.msg) {
299                         t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
300                                 spew.Sdump(msg), spew.Sdump(test.msg))
301                         continue
302                 }
303         }
304 }
305
306 // TestRejectWireErrors performs negative tests against wire encode and decode
307 // of MsgReject to confirm error paths work correctly.
308 func TestRejectWireErrors(t *testing.T) {
309         pver := ProtocolVersion
310         pverNoReject := RejectVersion - 1
311         wireErr := &MessageError{}
312
313         baseReject := NewMsgReject("block", RejectDuplicate, "duplicate block")
314         baseReject.Hash = mainNetGenesisHash
315         baseRejectEncoded := []byte{
316                 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "block"
317                 0x12, // RejectDuplicate
318                 0x0f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61,
319                 0x74, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "duplicate block"
320                 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
321                 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
322                 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
323                 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // mainNetGenesisHash
324         }
325
326         tests := []struct {
327                 in       *MsgReject      // Value to encode
328                 buf      []byte          // Wire encoding
329                 pver     uint32          // Protocol version for wire encoding
330                 enc      MessageEncoding // Message encoding format
331                 max      int             // Max size of fixed buffer to induce errors
332                 writeErr error           // Expected write error
333                 readErr  error           // Expected read error
334         }{
335                 // Latest protocol version with intentional read/write errors.
336                 // Force error in reject command.
337                 {baseReject, baseRejectEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
338                 // Force error in reject code.
339                 {baseReject, baseRejectEncoded, pver, BaseEncoding, 6, io.ErrShortWrite, io.EOF},
340                 // Force error in reject reason.
341                 {baseReject, baseRejectEncoded, pver, BaseEncoding, 7, io.ErrShortWrite, io.EOF},
342                 // Force error in reject hash.
343                 {baseReject, baseRejectEncoded, pver, BaseEncoding, 23, io.ErrShortWrite, io.EOF},
344                 // Force error due to unsupported protocol version.
345                 {baseReject, baseRejectEncoded, pverNoReject, BaseEncoding, 6, wireErr, wireErr},
346         }
347
348         t.Logf("Running %d tests", len(tests))
349         for i, test := range tests {
350                 // Encode to wire format.
351                 w := newFixedWriter(test.max)
352                 err := test.in.BtcEncode(w, test.pver, test.enc)
353                 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
354                         t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
355                                 i, err, test.writeErr)
356                         continue
357                 }
358
359                 // For errors which are not of type MessageError, check them for
360                 // equality.
361                 if _, ok := err.(*MessageError); !ok {
362                         if err != test.writeErr {
363                                 t.Errorf("BtcEncode #%d wrong error got: %v, "+
364                                         "want: %v", i, err, test.writeErr)
365                                 continue
366                         }
367                 }
368
369                 // Decode from wire format.
370                 var msg MsgReject
371                 r := newFixedReader(test.max, test.buf)
372                 err = msg.BtcDecode(r, test.pver, test.enc)
373                 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
374                         t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
375                                 i, err, test.readErr)
376                         continue
377                 }
378
379                 // For errors which are not of type MessageError, check them for
380                 // equality.
381                 if _, ok := err.(*MessageError); !ok {
382                         if err != test.readErr {
383                                 t.Errorf("BtcDecode #%d wrong error got: %v, "+
384                                         "want: %v", i, err, test.readErr)
385                                 continue
386                         }
387                 }
388         }
389 }