github.com/lbryio/lbcd@v0.22.119/wire/msggetblocks_test.go (about) 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/davecgh/go-spew/spew" 14 "github.com/lbryio/lbcd/chaincfg/chainhash" 15 ) 16 17 // TestGetBlocks tests the MsgGetBlocks API. 18 func TestGetBlocks(t *testing.T) { 19 pver := ProtocolVersion 20 21 // Block 99500 hash. 22 hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0" 23 locatorHash, err := chainhash.NewHashFromStr(hashStr) 24 if err != nil { 25 t.Errorf("NewHashFromStr: %v", err) 26 } 27 28 // Block 100000 hash. 29 hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" 30 hashStop, err := chainhash.NewHashFromStr(hashStr) 31 if err != nil { 32 t.Errorf("NewHashFromStr: %v", err) 33 } 34 35 // Ensure we get the same data back out. 36 msg := NewMsgGetBlocks(hashStop) 37 if !msg.HashStop.IsEqual(hashStop) { 38 t.Errorf("NewMsgGetBlocks: wrong stop hash - got %v, want %v", 39 msg.HashStop, hashStop) 40 } 41 42 // Ensure the command is expected value. 43 wantCmd := "getblocks" 44 if cmd := msg.Command(); cmd != wantCmd { 45 t.Errorf("NewMsgGetBlocks: wrong command - got %v want %v", 46 cmd, wantCmd) 47 } 48 49 // Ensure max payload is expected value for latest protocol version. 50 // Protocol version 4 bytes + num hashes (varInt) + max block locator 51 // hashes + hash stop. 52 wantPayload := uint32(16045) 53 maxPayload := msg.MaxPayloadLength(pver) 54 if maxPayload != wantPayload { 55 t.Errorf("MaxPayloadLength: wrong max payload length for "+ 56 "protocol version %d - got %v, want %v", pver, 57 maxPayload, wantPayload) 58 } 59 60 // Ensure block locator hashes are added properly. 61 err = msg.AddBlockLocatorHash(locatorHash) 62 if err != nil { 63 t.Errorf("AddBlockLocatorHash: %v", err) 64 } 65 if msg.BlockLocatorHashes[0] != locatorHash { 66 t.Errorf("AddBlockLocatorHash: wrong block locator added - "+ 67 "got %v, want %v", 68 spew.Sprint(msg.BlockLocatorHashes[0]), 69 spew.Sprint(locatorHash)) 70 } 71 72 // Ensure adding more than the max allowed block locator hashes per 73 // message returns an error. 74 for i := 0; i < MaxBlockLocatorsPerMsg; i++ { 75 err = msg.AddBlockLocatorHash(locatorHash) 76 } 77 if err == nil { 78 t.Errorf("AddBlockLocatorHash: expected error on too many " + 79 "block locator hashes not received") 80 } 81 } 82 83 // TestGetBlocksWire tests the MsgGetBlocks wire encode and decode for various 84 // numbers of block locator hashes and protocol versions. 85 func TestGetBlocksWire(t *testing.T) { 86 // Set protocol inside getblocks message. 87 pver := uint32(60002) 88 89 // Block 99499 hash. 90 hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535" 91 hashLocator, err := chainhash.NewHashFromStr(hashStr) 92 if err != nil { 93 t.Errorf("NewHashFromStr: %v", err) 94 } 95 96 // Block 99500 hash. 97 hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0" 98 hashLocator2, err := chainhash.NewHashFromStr(hashStr) 99 if err != nil { 100 t.Errorf("NewHashFromStr: %v", err) 101 } 102 103 // Block 100000 hash. 104 hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" 105 hashStop, err := chainhash.NewHashFromStr(hashStr) 106 if err != nil { 107 t.Errorf("NewHashFromStr: %v", err) 108 } 109 110 // MsgGetBlocks message with no block locators or stop hash. 111 noLocators := NewMsgGetBlocks(&chainhash.Hash{}) 112 noLocators.ProtocolVersion = pver 113 noLocatorsEncoded := []byte{ 114 0x62, 0xea, 0x00, 0x00, // Protocol version 60002 115 0x00, // Varint for number of block locator hashes 116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Hash stop 120 } 121 122 // MsgGetBlocks message with multiple block locators and a stop hash. 123 multiLocators := NewMsgGetBlocks(hashStop) 124 multiLocators.AddBlockLocatorHash(hashLocator2) 125 multiLocators.AddBlockLocatorHash(hashLocator) 126 multiLocators.ProtocolVersion = pver 127 multiLocatorsEncoded := []byte{ 128 0x62, 0xea, 0x00, 0x00, // Protocol version 60002 129 0x02, // Varint for number of block locator hashes 130 0xe0, 0xde, 0x06, 0x44, 0x68, 0x13, 0x2c, 0x63, 131 0xd2, 0x20, 0xcc, 0x69, 0x12, 0x83, 0xcb, 0x65, 132 0xbc, 0xaa, 0xe4, 0x79, 0x94, 0xef, 0x9e, 0x7b, 133 0xad, 0xe7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 99500 hash 134 0x35, 0x75, 0x95, 0xb7, 0xf6, 0x8c, 0xb1, 0x60, 135 0xcc, 0xba, 0x2c, 0x9a, 0xc5, 0x42, 0x5f, 0xd9, 136 0x6f, 0x0a, 0x01, 0x3d, 0xc9, 0x7e, 0xc8, 0x40, 137 0x0f, 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 99499 hash 138 0x06, 0xe5, 0x33, 0xfd, 0x1a, 0xda, 0x86, 0x39, 139 0x1f, 0x3f, 0x6c, 0x34, 0x32, 0x04, 0xb0, 0xd2, 140 0x78, 0xd4, 0xaa, 0xec, 0x1c, 0x0b, 0x20, 0xaa, 141 0x27, 0xba, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // Hash stop 142 } 143 144 tests := []struct { 145 in *MsgGetBlocks // Message to encode 146 out *MsgGetBlocks // Expected decoded message 147 buf []byte // Wire encoding 148 pver uint32 // Protocol version for wire encoding 149 enc MessageEncoding // Message encoding format 150 }{ 151 // Latest protocol version with no block locators. 152 { 153 noLocators, 154 noLocators, 155 noLocatorsEncoded, 156 ProtocolVersion, 157 BaseEncoding, 158 }, 159 160 // Latest protocol version with multiple block locators. 161 { 162 multiLocators, 163 multiLocators, 164 multiLocatorsEncoded, 165 ProtocolVersion, 166 BaseEncoding, 167 }, 168 169 // Protocol version BIP0035Version with no block locators. 170 { 171 noLocators, 172 noLocators, 173 noLocatorsEncoded, 174 BIP0035Version, 175 BaseEncoding, 176 }, 177 178 // Protocol version BIP0035Version with multiple block locators. 179 { 180 multiLocators, 181 multiLocators, 182 multiLocatorsEncoded, 183 BIP0035Version, 184 BaseEncoding, 185 }, 186 187 // Protocol version BIP0031Version with no block locators. 188 { 189 noLocators, 190 noLocators, 191 noLocatorsEncoded, 192 BIP0031Version, 193 BaseEncoding, 194 }, 195 196 // Protocol version BIP0031Versionwith multiple block locators. 197 { 198 multiLocators, 199 multiLocators, 200 multiLocatorsEncoded, 201 BIP0031Version, 202 BaseEncoding, 203 }, 204 205 // Protocol version NetAddressTimeVersion with no block locators. 206 { 207 noLocators, 208 noLocators, 209 noLocatorsEncoded, 210 NetAddressTimeVersion, 211 BaseEncoding, 212 }, 213 214 // Protocol version NetAddressTimeVersion multiple block locators. 215 { 216 multiLocators, 217 multiLocators, 218 multiLocatorsEncoded, 219 NetAddressTimeVersion, 220 BaseEncoding, 221 }, 222 223 // Protocol version MultipleAddressVersion with no block locators. 224 { 225 noLocators, 226 noLocators, 227 noLocatorsEncoded, 228 MultipleAddressVersion, 229 BaseEncoding, 230 }, 231 232 // Protocol version MultipleAddressVersion multiple block locators. 233 { 234 multiLocators, 235 multiLocators, 236 multiLocatorsEncoded, 237 MultipleAddressVersion, 238 BaseEncoding, 239 }, 240 } 241 242 t.Logf("Running %d tests", len(tests)) 243 for i, test := range tests { 244 // Encode the message to wire format. 245 var buf bytes.Buffer 246 err := test.in.BtcEncode(&buf, test.pver, test.enc) 247 if err != nil { 248 t.Errorf("BtcEncode #%d error %v", i, err) 249 continue 250 } 251 if !bytes.Equal(buf.Bytes(), test.buf) { 252 t.Errorf("BtcEncode #%d\n got: %s want: %s", i, 253 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 254 continue 255 } 256 257 // Decode the message from wire format. 258 var msg MsgGetBlocks 259 rbuf := bytes.NewReader(test.buf) 260 err = msg.BtcDecode(rbuf, test.pver, test.enc) 261 if err != nil { 262 t.Errorf("BtcDecode #%d error %v", i, err) 263 continue 264 } 265 if !reflect.DeepEqual(&msg, test.out) { 266 t.Errorf("BtcDecode #%d\n got: %s want: %s", i, 267 spew.Sdump(&msg), spew.Sdump(test.out)) 268 continue 269 } 270 } 271 } 272 273 // TestGetBlocksWireErrors performs negative tests against wire encode and 274 // decode of MsgGetBlocks to confirm error paths work correctly. 275 func TestGetBlocksWireErrors(t *testing.T) { 276 // Set protocol inside getheaders message. Use protocol version 60002 277 // specifically here instead of the latest because the test data is 278 // using bytes encoded with that protocol version. 279 pver := uint32(60002) 280 wireErr := &MessageError{} 281 282 // Block 99499 hash. 283 hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535" 284 hashLocator, err := chainhash.NewHashFromStr(hashStr) 285 if err != nil { 286 t.Errorf("NewHashFromStr: %v", err) 287 } 288 289 // Block 99500 hash. 290 hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0" 291 hashLocator2, err := chainhash.NewHashFromStr(hashStr) 292 if err != nil { 293 t.Errorf("NewHashFromStr: %v", err) 294 } 295 296 // Block 100000 hash. 297 hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" 298 hashStop, err := chainhash.NewHashFromStr(hashStr) 299 if err != nil { 300 t.Errorf("NewHashFromStr: %v", err) 301 } 302 303 // MsgGetBlocks message with multiple block locators and a stop hash. 304 baseGetBlocks := NewMsgGetBlocks(hashStop) 305 baseGetBlocks.ProtocolVersion = pver 306 baseGetBlocks.AddBlockLocatorHash(hashLocator2) 307 baseGetBlocks.AddBlockLocatorHash(hashLocator) 308 baseGetBlocksEncoded := []byte{ 309 0x62, 0xea, 0x00, 0x00, // Protocol version 60002 310 0x02, // Varint for number of block locator hashes 311 0xe0, 0xde, 0x06, 0x44, 0x68, 0x13, 0x2c, 0x63, 312 0xd2, 0x20, 0xcc, 0x69, 0x12, 0x83, 0xcb, 0x65, 313 0xbc, 0xaa, 0xe4, 0x79, 0x94, 0xef, 0x9e, 0x7b, 314 0xad, 0xe7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 99500 hash 315 0x35, 0x75, 0x95, 0xb7, 0xf6, 0x8c, 0xb1, 0x60, 316 0xcc, 0xba, 0x2c, 0x9a, 0xc5, 0x42, 0x5f, 0xd9, 317 0x6f, 0x0a, 0x01, 0x3d, 0xc9, 0x7e, 0xc8, 0x40, 318 0x0f, 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 99499 hash 319 0x06, 0xe5, 0x33, 0xfd, 0x1a, 0xda, 0x86, 0x39, 320 0x1f, 0x3f, 0x6c, 0x34, 0x32, 0x04, 0xb0, 0xd2, 321 0x78, 0xd4, 0xaa, 0xec, 0x1c, 0x0b, 0x20, 0xaa, 322 0x27, 0xba, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // Hash stop 323 } 324 325 // Message that forces an error by having more than the max allowed 326 // block locator hashes. 327 maxGetBlocks := NewMsgGetBlocks(hashStop) 328 for i := 0; i < MaxBlockLocatorsPerMsg; i++ { 329 maxGetBlocks.AddBlockLocatorHash(&mainNetGenesisHash) 330 } 331 maxGetBlocks.BlockLocatorHashes = append(maxGetBlocks.BlockLocatorHashes, 332 &mainNetGenesisHash) 333 maxGetBlocksEncoded := []byte{ 334 0x62, 0xea, 0x00, 0x00, // Protocol version 60002 335 0xfd, 0xf5, 0x01, // Varint for number of block loc hashes (501) 336 } 337 338 tests := []struct { 339 in *MsgGetBlocks // Value to encode 340 buf []byte // Wire encoding 341 pver uint32 // Protocol version for wire encoding 342 enc MessageEncoding // Message encoding format 343 max int // Max size of fixed buffer to induce errors 344 writeErr error // Expected write error 345 readErr error // Expected read error 346 }{ 347 // Force error in protocol version. 348 {baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, 349 // Force error in block locator hash count. 350 {baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF}, 351 // Force error in block locator hashes. 352 {baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 5, io.ErrShortWrite, io.EOF}, 353 // Force error in stop hash. 354 {baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 69, io.ErrShortWrite, io.EOF}, 355 // Force error with greater than max block locator hashes. 356 {maxGetBlocks, maxGetBlocksEncoded, pver, BaseEncoding, 7, wireErr, wireErr}, 357 } 358 359 t.Logf("Running %d tests", len(tests)) 360 for i, test := range tests { 361 // Encode to wire format. 362 w := newFixedWriter(test.max) 363 err := test.in.BtcEncode(w, test.pver, test.enc) 364 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { 365 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", 366 i, err, test.writeErr) 367 continue 368 } 369 370 // For errors which are not of type MessageError, check them for 371 // equality. 372 if _, ok := err.(*MessageError); !ok { 373 if err != test.writeErr { 374 t.Errorf("BtcEncode #%d wrong error got: %v, "+ 375 "want: %v", i, err, test.writeErr) 376 continue 377 } 378 } 379 380 // Decode from wire format. 381 var msg MsgGetBlocks 382 r := newFixedReader(test.max, test.buf) 383 err = msg.BtcDecode(r, test.pver, test.enc) 384 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { 385 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", 386 i, err, test.readErr) 387 continue 388 } 389 390 // For errors which are not of type MessageError, check them for 391 // equality. 392 if _, ok := err.(*MessageError); !ok { 393 if err != test.readErr { 394 t.Errorf("BtcDecode #%d wrong error got: %v, "+ 395 "want: %v", i, err, test.readErr) 396 continue 397 } 398 } 399 } 400 }