github.com/lbryio/lbcd@v0.22.119/wire/msgreject_test.go (about) 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 }