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