github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/wire/msgreject_test.go (about) 1 // Copyright (c) 2014-2015 The btcsuite developers 2 // Copyright (c) 2016 The Dash developers 3 // Use of this source code is governed by an ISC 4 // license that can be found in the LICENSE file. 5 6 package wire_test 7 8 import ( 9 "bytes" 10 "io" 11 "reflect" 12 "testing" 13 14 "github.com/dashpay/godash/wire" 15 "github.com/davecgh/go-spew/spew" 16 ) 17 18 // TestRejectCodeStringer tests the stringized output for the reject code type. 19 func TestRejectCodeStringer(t *testing.T) { 20 tests := []struct { 21 in wire.RejectCode 22 want string 23 }{ 24 {wire.RejectMalformed, "REJECT_MALFORMED"}, 25 {wire.RejectInvalid, "REJECT_INVALID"}, 26 {wire.RejectObsolete, "REJECT_OBSOLETE"}, 27 {wire.RejectDuplicate, "REJECT_DUPLICATE"}, 28 {wire.RejectNonstandard, "REJECT_NONSTANDARD"}, 29 {wire.RejectDust, "REJECT_DUST"}, 30 {wire.RejectInsufficientFee, "REJECT_INSUFFICIENTFEE"}, 31 {wire.RejectCheckpoint, "REJECT_CHECKPOINT"}, 32 {0xff, "Unknown RejectCode (255)"}, 33 } 34 35 t.Logf("Running %d tests", len(tests)) 36 for i, test := range tests { 37 result := test.in.String() 38 if result != test.want { 39 t.Errorf("String #%d\n got: %s want: %s", i, result, 40 test.want) 41 continue 42 } 43 } 44 45 } 46 47 // TestRejectLatest tests the MsgPong API against the latest protocol version. 48 func TestRejectLatest(t *testing.T) { 49 pver := wire.ProtocolVersion 50 51 // Create reject message data. 52 rejCommand := (&wire.MsgBlock{}).Command() 53 rejCode := wire.RejectDuplicate 54 rejReason := "duplicate block" 55 rejHash := mainNetGenesisHash 56 57 // Ensure we get the correct data back out. 58 msg := wire.NewMsgReject(rejCommand, rejCode, rejReason) 59 msg.Hash = rejHash 60 if msg.Cmd != rejCommand { 61 t.Errorf("NewMsgReject: wrong rejected command - got %v, "+ 62 "want %v", msg.Cmd, rejCommand) 63 } 64 if msg.Code != rejCode { 65 t.Errorf("NewMsgReject: wrong rejected code - got %v, "+ 66 "want %v", msg.Code, rejCode) 67 } 68 if msg.Reason != rejReason { 69 t.Errorf("NewMsgReject: wrong rejected reason - got %v, "+ 70 "want %v", msg.Reason, rejReason) 71 } 72 73 // Ensure the command is expected value. 74 wantCmd := "reject" 75 if cmd := msg.Command(); cmd != wantCmd { 76 t.Errorf("NewMsgReject: wrong command - got %v want %v", 77 cmd, wantCmd) 78 } 79 80 // Ensure max payload is expected value for latest protocol version. 81 wantPayload := uint32(wire.MaxMessagePayload) 82 maxPayload := msg.MaxPayloadLength(pver) 83 if maxPayload != wantPayload { 84 t.Errorf("MaxPayloadLength: wrong max payload length for "+ 85 "protocol version %d - got %v, want %v", pver, 86 maxPayload, wantPayload) 87 } 88 89 // Test encode with latest protocol version. 90 var buf bytes.Buffer 91 err := msg.BtcEncode(&buf, pver) 92 if err != nil { 93 t.Errorf("encode of MsgReject failed %v err <%v>", msg, err) 94 } 95 96 // Test decode with latest protocol version. 97 readMsg := wire.MsgReject{} 98 err = readMsg.BtcDecode(&buf, pver) 99 if err != nil { 100 t.Errorf("decode of MsgReject failed %v err <%v>", buf.Bytes(), 101 err) 102 } 103 104 // Ensure decoded data is the same. 105 if msg.Cmd != readMsg.Cmd { 106 t.Errorf("Should get same reject command - got %v, want %v", 107 readMsg.Cmd, msg.Cmd) 108 } 109 if msg.Code != readMsg.Code { 110 t.Errorf("Should get same reject code - got %v, want %v", 111 readMsg.Code, msg.Code) 112 } 113 if msg.Reason != readMsg.Reason { 114 t.Errorf("Should get same reject reason - got %v, want %v", 115 readMsg.Reason, msg.Reason) 116 } 117 if msg.Hash != readMsg.Hash { 118 t.Errorf("Should get same reject hash - got %v, want %v", 119 readMsg.Hash, msg.Hash) 120 } 121 } 122 123 // TestRejectBeforeAdded tests the MsgReject API against a protocol version 124 // before the version which introduced it (RejectVersion). 125 func TestRejectBeforeAdded(t *testing.T) { 126 // Use the protocol version just prior to RejectVersion. 127 pver := wire.RejectVersion - 1 128 129 // Create reject message data. 130 rejCommand := (&wire.MsgBlock{}).Command() 131 rejCode := wire.RejectDuplicate 132 rejReason := "duplicate block" 133 rejHash := mainNetGenesisHash 134 135 msg := wire.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) 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 := wire.MsgReject{} 155 err = readMsg.BtcDecode(&buf, pver) 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 := (&wire.MsgBlock{}).Command() 187 rejCode := wire.RejectDuplicate 188 rejReason := "duplicate block" 189 rejHash := mainNetGenesisHash 190 191 msg := wire.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, wire.ProtocolVersion) 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 := wire.MsgReject{} 203 err = readMsg.BtcDecode(&buf, wire.RejectVersion-1) 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 wire.MsgReject // Message to encode 231 buf []byte // Wire encoding 232 pver uint32 // Protocol version for wire encoding 233 }{ 234 // Latest protocol version rejected command version (no hash). 235 { 236 wire.MsgReject{ 237 Cmd: "version", 238 Code: wire.RejectDuplicate, 239 Reason: "duplicate version", 240 }, 241 []byte{ 242 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, // "version" 243 0x12, // wire.RejectDuplicate 244 0x11, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 245 0x74, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 246 0x6f, 0x6e, // "duplicate version" 247 }, 248 wire.ProtocolVersion, 249 }, 250 // Latest protocol version rejected command block (has hash). 251 { 252 wire.MsgReject{ 253 Cmd: "block", 254 Code: wire.RejectDuplicate, 255 Reason: "duplicate block", 256 Hash: mainNetGenesisHash, 257 }, 258 []byte{ 259 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "block" 260 0x12, // wire.RejectDuplicate 261 0x0f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 262 0x74, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "duplicate block" 263 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 264 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 265 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, 266 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // mainNetGenesisHash 267 }, 268 wire.ProtocolVersion, 269 }, 270 } 271 272 t.Logf("Running %d tests", len(tests)) 273 for i, test := range tests { 274 // Encode the message to wire format. 275 var buf bytes.Buffer 276 err := test.msg.BtcEncode(&buf, test.pver) 277 if err != nil { 278 t.Errorf("BtcEncode #%d error %v", i, err) 279 continue 280 } 281 if !bytes.Equal(buf.Bytes(), test.buf) { 282 t.Errorf("BtcEncode #%d\n got: %s want: %s", i, 283 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 284 continue 285 } 286 287 // Decode the message from wire format. 288 var msg wire.MsgReject 289 rbuf := bytes.NewReader(test.buf) 290 err = msg.BtcDecode(rbuf, test.pver) 291 if err != nil { 292 t.Errorf("BtcDecode #%d error %v", i, err) 293 continue 294 } 295 if !reflect.DeepEqual(msg, test.msg) { 296 t.Errorf("BtcDecode #%d\n got: %s want: %s", i, 297 spew.Sdump(msg), spew.Sdump(test.msg)) 298 continue 299 } 300 } 301 } 302 303 // TestRejectWireErrors performs negative tests against wire encode and decode 304 // of MsgReject to confirm error paths work correctly. 305 func TestRejectWireErrors(t *testing.T) { 306 pver := wire.ProtocolVersion 307 pverNoReject := wire.RejectVersion - 1 308 wireErr := &wire.MessageError{} 309 310 baseReject := wire.NewMsgReject("block", wire.RejectDuplicate, 311 "duplicate block") 312 baseReject.Hash = mainNetGenesisHash 313 baseRejectEncoded := []byte{ 314 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "block" 315 0x12, // wire.RejectDuplicate 316 0x0f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 317 0x74, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "duplicate block" 318 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 319 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 320 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, 321 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // mainNetGenesisHash 322 } 323 324 tests := []struct { 325 in *wire.MsgReject // Value to encode 326 buf []byte // Wire encoding 327 pver uint32 // Protocol version for wire encoding 328 max int // Max size of fixed buffer to induce errors 329 writeErr error // Expected write error 330 readErr error // Expected read error 331 }{ 332 // Latest protocol version with intentional read/write errors. 333 // Force error in reject command. 334 {baseReject, baseRejectEncoded, pver, 0, io.ErrShortWrite, io.EOF}, 335 // Force error in reject code. 336 {baseReject, baseRejectEncoded, pver, 6, io.ErrShortWrite, io.EOF}, 337 // Force error in reject reason. 338 {baseReject, baseRejectEncoded, pver, 7, io.ErrShortWrite, io.EOF}, 339 // Force error in reject hash. 340 {baseReject, baseRejectEncoded, pver, 23, io.ErrShortWrite, io.EOF}, 341 // Force error due to unsupported protocol version. 342 {baseReject, baseRejectEncoded, pverNoReject, 6, wireErr, wireErr}, 343 } 344 345 t.Logf("Running %d tests", len(tests)) 346 for i, test := range tests { 347 // Encode to wire format. 348 w := newFixedWriter(test.max) 349 err := test.in.BtcEncode(w, test.pver) 350 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { 351 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", 352 i, err, test.writeErr) 353 continue 354 } 355 356 // For errors which are not of type wire.MessageError, check 357 // them for equality. 358 if _, ok := err.(*wire.MessageError); !ok { 359 if err != test.writeErr { 360 t.Errorf("BtcEncode #%d wrong error got: %v, "+ 361 "want: %v", i, err, test.writeErr) 362 continue 363 } 364 } 365 366 // Decode from wire format. 367 var msg wire.MsgReject 368 r := newFixedReader(test.max, test.buf) 369 err = msg.BtcDecode(r, test.pver) 370 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { 371 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", 372 i, err, test.readErr) 373 continue 374 } 375 376 // For errors which are not of type wire.MessageError, check 377 // them for equality. 378 if _, ok := err.(*wire.MessageError); !ok { 379 if err != test.readErr { 380 t.Errorf("BtcDecode #%d wrong error got: %v, "+ 381 "want: %v", i, err, test.readErr) 382 continue 383 } 384 } 385 } 386 }