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.
13 "github.com/davecgh/go-spew/spew"
16 // TestRejectCodeStringer tests the stringized output for the reject code type.
17 func TestRejectCodeStringer(t *testing.T) {
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)"},
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,
45 // TestRejectLatest tests the MsgPong API against the latest protocol version.
46 func TestRejectLatest(t *testing.T) {
47 pver := ProtocolVersion
50 // Create reject message data.
51 rejCommand := (&MsgBlock{}).Command()
52 rejCode := RejectDuplicate
53 rejReason := "duplicate block"
54 rejHash := mainNetGenesisHash
56 // Ensure we get the correct data back out.
57 msg := NewMsgReject(rejCommand, rejCode, rejReason)
59 if msg.Cmd != rejCommand {
60 t.Errorf("NewMsgReject: wrong rejected command - got %v, "+
61 "want %v", msg.Cmd, rejCommand)
63 if msg.Code != rejCode {
64 t.Errorf("NewMsgReject: wrong rejected code - got %v, "+
65 "want %v", msg.Code, rejCode)
67 if msg.Reason != rejReason {
68 t.Errorf("NewMsgReject: wrong rejected reason - got %v, "+
69 "want %v", msg.Reason, rejReason)
72 // Ensure the command is expected value.
74 if cmd := msg.Command(); cmd != wantCmd {
75 t.Errorf("NewMsgReject: wrong command - got %v want %v",
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)
88 // Test encode with latest protocol version.
90 err := msg.BtcEncode(&buf, pver, enc)
92 t.Errorf("encode of MsgReject failed %v err <%v>", msg, err)
95 // Test decode with latest protocol version.
96 readMsg := MsgReject{}
97 err = readMsg.BtcDecode(&buf, pver, enc)
99 t.Errorf("decode of MsgReject failed %v err <%v>", buf.Bytes(),
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)
108 if msg.Code != readMsg.Code {
109 t.Errorf("Should get same reject code - got %v, want %v",
110 readMsg.Code, msg.Code)
112 if msg.Reason != readMsg.Reason {
113 t.Errorf("Should get same reject reason - got %v, want %v",
114 readMsg.Reason, msg.Reason)
116 if msg.Hash != readMsg.Hash {
117 t.Errorf("Should get same reject hash - got %v, want %v",
118 readMsg.Hash, msg.Hash)
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
129 // Create reject message data.
130 rejCommand := (&MsgBlock{}).Command()
131 rejCode := RejectDuplicate
132 rejReason := "duplicate block"
133 rejHash := mainNetGenesisHash
135 msg := NewMsgReject(rejCommand, rejCode, rejReason)
138 // Ensure max payload is expected value for old protocol version.
139 size := msg.MaxPayloadLength(pver)
141 t.Errorf("Max length should be 0 for reject protocol version %d.",
145 // Test encode with old protocol version.
147 err := msg.BtcEncode(&buf, pver, enc)
149 t.Errorf("encode of MsgReject succeeded when it shouldn't "+
153 // // Test decode with old protocol version.
154 readMsg := MsgReject{}
155 err = readMsg.BtcDecode(&buf, pver, enc)
157 t.Errorf("decode of MsgReject succeeded when it shouldn't "+
158 "have %v", spew.Sdump(buf.Bytes()))
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 "+
167 if msg.Code == readMsg.Code {
168 t.Errorf("Should not get same reject code for protocol "+
171 if msg.Reason == readMsg.Reason {
172 t.Errorf("Should not get same reject reason for protocol "+
175 if msg.Hash == readMsg.Hash {
176 t.Errorf("Should not get same reject hash for protocol "+
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
191 msg := NewMsgReject(rejCommand, rejCode, rejReason)
194 // Encode with latest protocol version.
196 err := msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding)
198 t.Errorf("encode of MsgReject failed %v err <%v>", msg, err)
201 // Decode with old protocol version.
202 readMsg := MsgReject{}
203 err = readMsg.BtcDecode(&buf, RejectVersion-1, BaseEncoding)
205 t.Errorf("encode of MsgReject succeeded when it shouldn't "+
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
212 if msg.Cmd == readMsg.Cmd {
213 t.Errorf("Should not get same reject command for cross protocol")
215 if msg.Code == readMsg.Code {
216 t.Errorf("Should not get same reject code for cross protocol")
218 if msg.Reason == readMsg.Reason {
219 t.Errorf("Should not get same reject reason for cross protocol")
221 if msg.Hash == readMsg.Hash {
222 t.Errorf("Should not get same reject hash for cross protocol")
226 // TestRejectWire tests the MsgReject wire encode and decode for various
227 // protocol versions.
228 func TestRejectWire(t *testing.T) {
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
235 // Latest protocol version rejected command version (no hash).
239 Code: RejectDuplicate,
240 Reason: "duplicate version",
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"
252 // Latest protocol version rejected command block (has hash).
256 Code: RejectDuplicate,
257 Reason: "duplicate block",
258 Hash: mainNetGenesisHash,
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
275 t.Logf("Running %d tests", len(tests))
276 for i, test := range tests {
277 // Encode the message to wire format.
279 err := test.msg.BtcEncode(&buf, test.pver, test.enc)
281 t.Errorf("BtcEncode #%d error %v", i, err)
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))
290 // Decode the message from wire format.
292 rbuf := bytes.NewReader(test.buf)
293 err = msg.BtcDecode(rbuf, test.pver, test.enc)
295 t.Errorf("BtcDecode #%d error %v", i, err)
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))
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{}
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
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
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},
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)
359 // For errors which are not of type MessageError, check them for
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)
369 // Decode from wire format.
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)
379 // For errors which are not of type MessageError, check them for
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)