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