github.com/palcoin-project/palcd@v1.0.0/wire/msgversion_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 "net" 11 "reflect" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/davecgh/go-spew/spew" 17 ) 18 19 // TestVersion tests the MsgVersion API. 20 func TestVersion(t *testing.T) { 21 pver := ProtocolVersion 22 23 // Create version message data. 24 lastBlock := int32(234234) 25 tcpAddrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333} 26 me := NewNetAddress(tcpAddrMe, SFNodeNetwork) 27 tcpAddrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 8333} 28 you := NewNetAddress(tcpAddrYou, SFNodeNetwork) 29 nonce, err := RandomUint64() 30 if err != nil { 31 t.Errorf("RandomUint64: error generating nonce: %v", err) 32 } 33 34 // Ensure we get the correct data back out. 35 msg := NewMsgVersion(me, you, nonce, lastBlock) 36 if msg.ProtocolVersion != int32(pver) { 37 t.Errorf("NewMsgVersion: wrong protocol version - got %v, want %v", 38 msg.ProtocolVersion, pver) 39 } 40 if !reflect.DeepEqual(&msg.AddrMe, me) { 41 t.Errorf("NewMsgVersion: wrong me address - got %v, want %v", 42 spew.Sdump(&msg.AddrMe), spew.Sdump(me)) 43 } 44 if !reflect.DeepEqual(&msg.AddrYou, you) { 45 t.Errorf("NewMsgVersion: wrong you address - got %v, want %v", 46 spew.Sdump(&msg.AddrYou), spew.Sdump(you)) 47 } 48 if msg.Nonce != nonce { 49 t.Errorf("NewMsgVersion: wrong nonce - got %v, want %v", 50 msg.Nonce, nonce) 51 } 52 if msg.UserAgent != DefaultUserAgent { 53 t.Errorf("NewMsgVersion: wrong user agent - got %v, want %v", 54 msg.UserAgent, DefaultUserAgent) 55 } 56 if msg.LastBlock != lastBlock { 57 t.Errorf("NewMsgVersion: wrong last block - got %v, want %v", 58 msg.LastBlock, lastBlock) 59 } 60 if msg.DisableRelayTx { 61 t.Errorf("NewMsgVersion: disable relay tx is not false by "+ 62 "default - got %v, want %v", msg.DisableRelayTx, false) 63 } 64 65 msg.AddUserAgent("myclient", "1.2.3", "optional", "comments") 66 customUserAgent := DefaultUserAgent + "myclient:1.2.3(optional; comments)/" 67 if msg.UserAgent != customUserAgent { 68 t.Errorf("AddUserAgent: wrong user agent - got %s, want %s", 69 msg.UserAgent, customUserAgent) 70 } 71 72 msg.AddUserAgent("mygui", "3.4.5") 73 customUserAgent += "mygui:3.4.5/" 74 if msg.UserAgent != customUserAgent { 75 t.Errorf("AddUserAgent: wrong user agent - got %s, want %s", 76 msg.UserAgent, customUserAgent) 77 } 78 79 // accounting for ":", "/" 80 err = msg.AddUserAgent(strings.Repeat("t", 81 MaxUserAgentLen-len(customUserAgent)-2+1), "") 82 if _, ok := err.(*MessageError); !ok { 83 t.Errorf("AddUserAgent: expected error not received "+ 84 "- got %v, want %T", err, MessageError{}) 85 86 } 87 88 // Version message should not have any services set by default. 89 if msg.Services != 0 { 90 t.Errorf("NewMsgVersion: wrong default services - got %v, want %v", 91 msg.Services, 0) 92 93 } 94 if msg.HasService(SFNodeNetwork) { 95 t.Errorf("HasService: SFNodeNetwork service is set") 96 } 97 98 // Ensure the command is expected value. 99 wantCmd := "version" 100 if cmd := msg.Command(); cmd != wantCmd { 101 t.Errorf("NewMsgVersion: wrong command - got %v want %v", 102 cmd, wantCmd) 103 } 104 105 // Ensure max payload is expected value. 106 // Protocol version 4 bytes + services 8 bytes + timestamp 8 bytes + 107 // remote and local net addresses + nonce 8 bytes + length of user agent 108 // (varInt) + max allowed user agent length + last block 4 bytes + 109 // relay transactions flag 1 byte. 110 wantPayload := uint32(358) 111 maxPayload := msg.MaxPayloadLength(pver) 112 if maxPayload != wantPayload { 113 t.Errorf("MaxPayloadLength: wrong max payload length for "+ 114 "protocol version %d - got %v, want %v", pver, 115 maxPayload, wantPayload) 116 } 117 118 // Ensure adding the full service node flag works. 119 msg.AddService(SFNodeNetwork) 120 if msg.Services != SFNodeNetwork { 121 t.Errorf("AddService: wrong services - got %v, want %v", 122 msg.Services, SFNodeNetwork) 123 } 124 if !msg.HasService(SFNodeNetwork) { 125 t.Errorf("HasService: SFNodeNetwork service not set") 126 } 127 } 128 129 // TestVersionWire tests the MsgVersion wire encode and decode for various 130 // protocol versions. 131 func TestVersionWire(t *testing.T) { 132 // verRelayTxFalse and verRelayTxFalseEncoded is a version message as of 133 // BIP0037Version with the transaction relay disabled. 134 baseVersionBIP0037Copy := *baseVersionBIP0037 135 verRelayTxFalse := &baseVersionBIP0037Copy 136 verRelayTxFalse.DisableRelayTx = true 137 verRelayTxFalseEncoded := make([]byte, len(baseVersionBIP0037Encoded)) 138 copy(verRelayTxFalseEncoded, baseVersionBIP0037Encoded) 139 verRelayTxFalseEncoded[len(verRelayTxFalseEncoded)-1] = 0 140 141 tests := []struct { 142 in *MsgVersion // Message to encode 143 out *MsgVersion // Expected decoded message 144 buf []byte // Wire encoding 145 pver uint32 // Protocol version for wire encoding 146 enc MessageEncoding // Message encoding format 147 }{ 148 // Latest protocol version. 149 { 150 baseVersionBIP0037, 151 baseVersionBIP0037, 152 baseVersionBIP0037Encoded, 153 ProtocolVersion, 154 BaseEncoding, 155 }, 156 157 // Protocol version BIP0037Version with relay transactions field 158 // true. 159 { 160 baseVersionBIP0037, 161 baseVersionBIP0037, 162 baseVersionBIP0037Encoded, 163 BIP0037Version, 164 BaseEncoding, 165 }, 166 167 // Protocol version BIP0037Version with relay transactions field 168 // false. 169 { 170 verRelayTxFalse, 171 verRelayTxFalse, 172 verRelayTxFalseEncoded, 173 BIP0037Version, 174 BaseEncoding, 175 }, 176 177 // Protocol version BIP0035Version. 178 { 179 baseVersion, 180 baseVersion, 181 baseVersionEncoded, 182 BIP0035Version, 183 BaseEncoding, 184 }, 185 186 // Protocol version BIP0031Version. 187 { 188 baseVersion, 189 baseVersion, 190 baseVersionEncoded, 191 BIP0031Version, 192 BaseEncoding, 193 }, 194 195 // Protocol version NetAddressTimeVersion. 196 { 197 baseVersion, 198 baseVersion, 199 baseVersionEncoded, 200 NetAddressTimeVersion, 201 BaseEncoding, 202 }, 203 204 // Protocol version MultipleAddressVersion. 205 { 206 baseVersion, 207 baseVersion, 208 baseVersionEncoded, 209 MultipleAddressVersion, 210 BaseEncoding, 211 }, 212 } 213 214 t.Logf("Running %d tests", len(tests)) 215 for i, test := range tests { 216 // Encode the message to wire format. 217 var buf bytes.Buffer 218 err := test.in.BtcEncode(&buf, test.pver, test.enc) 219 if err != nil { 220 t.Errorf("BtcEncode #%d error %v", i, err) 221 continue 222 } 223 if !bytes.Equal(buf.Bytes(), test.buf) { 224 t.Errorf("BtcEncode #%d\n got: %s want: %s", i, 225 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 226 continue 227 } 228 229 // Decode the message from wire format. 230 var msg MsgVersion 231 rbuf := bytes.NewBuffer(test.buf) 232 err = msg.BtcDecode(rbuf, test.pver, test.enc) 233 if err != nil { 234 t.Errorf("BtcDecode #%d error %v", i, err) 235 continue 236 } 237 if !reflect.DeepEqual(&msg, test.out) { 238 t.Errorf("BtcDecode #%d\n got: %s want: %s", i, 239 spew.Sdump(msg), spew.Sdump(test.out)) 240 continue 241 } 242 } 243 } 244 245 // TestVersionWireErrors performs negative tests against wire encode and 246 // decode of MsgGetHeaders to confirm error paths work correctly. 247 func TestVersionWireErrors(t *testing.T) { 248 // Use protocol version 60002 specifically here instead of the latest 249 // because the test data is using bytes encoded with that protocol 250 // version. 251 pver := uint32(60002) 252 enc := BaseEncoding 253 wireErr := &MessageError{} 254 255 // Ensure calling MsgVersion.BtcDecode with a non *bytes.Buffer returns 256 // error. 257 fr := newFixedReader(0, []byte{}) 258 if err := baseVersion.BtcDecode(fr, pver, enc); err == nil { 259 t.Errorf("Did not received error when calling " + 260 "MsgVersion.BtcDecode with non *bytes.Buffer") 261 } 262 263 // Copy the base version and change the user agent to exceed max limits. 264 bvc := *baseVersion 265 exceedUAVer := &bvc 266 newUA := "/" + strings.Repeat("t", MaxUserAgentLen-8+1) + ":0.0.1/" 267 exceedUAVer.UserAgent = newUA 268 269 // Encode the new UA length as a varint. 270 var newUAVarIntBuf bytes.Buffer 271 err := WriteVarInt(&newUAVarIntBuf, pver, uint64(len(newUA))) 272 if err != nil { 273 t.Errorf("WriteVarInt: error %v", err) 274 } 275 276 // Make a new buffer big enough to hold the base version plus the new 277 // bytes for the bigger varint to hold the new size of the user agent 278 // and the new user agent string. Then stich it all together. 279 newLen := len(baseVersionEncoded) - len(baseVersion.UserAgent) 280 newLen = newLen + len(newUAVarIntBuf.Bytes()) - 1 + len(newUA) 281 exceedUAVerEncoded := make([]byte, newLen) 282 copy(exceedUAVerEncoded, baseVersionEncoded[0:80]) 283 copy(exceedUAVerEncoded[80:], newUAVarIntBuf.Bytes()) 284 copy(exceedUAVerEncoded[83:], []byte(newUA)) 285 copy(exceedUAVerEncoded[83+len(newUA):], baseVersionEncoded[97:100]) 286 287 tests := []struct { 288 in *MsgVersion // Value to encode 289 buf []byte // Wire encoding 290 pver uint32 // Protocol version for wire encoding 291 enc MessageEncoding // Message encoding format 292 max int // Max size of fixed buffer to induce errors 293 writeErr error // Expected write error 294 readErr error // Expected read error 295 }{ 296 // Force error in protocol version. 297 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, 298 // Force error in services. 299 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF}, 300 // Force error in timestamp. 301 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 12, io.ErrShortWrite, io.EOF}, 302 // Force error in remote address. 303 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 20, io.ErrShortWrite, io.EOF}, 304 // Force error in local address. 305 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 47, io.ErrShortWrite, io.ErrUnexpectedEOF}, 306 // Force error in nonce. 307 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 73, io.ErrShortWrite, io.ErrUnexpectedEOF}, 308 // Force error in user agent length. 309 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF}, 310 // Force error in user agent. 311 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 82, io.ErrShortWrite, io.ErrUnexpectedEOF}, 312 // Force error in last block. 313 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 98, io.ErrShortWrite, io.ErrUnexpectedEOF}, 314 // Force error in relay tx - no read error should happen since 315 // it's optional. 316 { 317 baseVersionBIP0037, baseVersionBIP0037Encoded, 318 BIP0037Version, BaseEncoding, 101, io.ErrShortWrite, nil, 319 }, 320 // Force error due to user agent too big 321 {exceedUAVer, exceedUAVerEncoded, pver, BaseEncoding, newLen, wireErr, wireErr}, 322 } 323 324 t.Logf("Running %d tests", len(tests)) 325 for i, test := range tests { 326 // Encode to wire format. 327 w := newFixedWriter(test.max) 328 err := test.in.BtcEncode(w, test.pver, test.enc) 329 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { 330 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", 331 i, err, test.writeErr) 332 continue 333 } 334 335 // For errors which are not of type MessageError, check them for 336 // equality. 337 if _, ok := err.(*MessageError); !ok { 338 if err != test.writeErr { 339 t.Errorf("BtcEncode #%d wrong error got: %v, "+ 340 "want: %v", i, err, test.writeErr) 341 continue 342 } 343 } 344 345 // Decode from wire format. 346 var msg MsgVersion 347 buf := bytes.NewBuffer(test.buf[0:test.max]) 348 err = msg.BtcDecode(buf, test.pver, test.enc) 349 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { 350 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", 351 i, err, test.readErr) 352 continue 353 } 354 355 // For errors which are not of type MessageError, check them for 356 // equality. 357 if _, ok := err.(*MessageError); !ok { 358 if err != test.readErr { 359 t.Errorf("BtcDecode #%d wrong error got: %v, "+ 360 "want: %v", i, err, test.readErr) 361 continue 362 } 363 } 364 } 365 } 366 367 // TestVersionOptionalFields performs tests to ensure that an encoded version 368 // messages that omit optional fields are handled correctly. 369 func TestVersionOptionalFields(t *testing.T) { 370 // onlyRequiredVersion is a version message that only contains the 371 // required versions and all other values set to their default values. 372 onlyRequiredVersion := MsgVersion{ 373 ProtocolVersion: 60002, 374 Services: SFNodeNetwork, 375 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST) 376 AddrYou: NetAddress{ 377 Timestamp: time.Time{}, // Zero value -- no timestamp in version 378 Services: SFNodeNetwork, 379 IP: net.ParseIP("192.168.0.1"), 380 Port: 8333, 381 }, 382 } 383 onlyRequiredVersionEncoded := make([]byte, len(baseVersionEncoded)-55) 384 copy(onlyRequiredVersionEncoded, baseVersionEncoded) 385 386 // addrMeVersion is a version message that contains all fields through 387 // the AddrMe field. 388 addrMeVersion := onlyRequiredVersion 389 addrMeVersion.AddrMe = NetAddress{ 390 Timestamp: time.Time{}, // Zero value -- no timestamp in version 391 Services: SFNodeNetwork, 392 IP: net.ParseIP("127.0.0.1"), 393 Port: 8333, 394 } 395 addrMeVersionEncoded := make([]byte, len(baseVersionEncoded)-29) 396 copy(addrMeVersionEncoded, baseVersionEncoded) 397 398 // nonceVersion is a version message that contains all fields through 399 // the Nonce field. 400 nonceVersion := addrMeVersion 401 nonceVersion.Nonce = 123123 // 0x1e0f3 402 nonceVersionEncoded := make([]byte, len(baseVersionEncoded)-21) 403 copy(nonceVersionEncoded, baseVersionEncoded) 404 405 // uaVersion is a version message that contains all fields through 406 // the UserAgent field. 407 uaVersion := nonceVersion 408 uaVersion.UserAgent = "/btcdtest:0.0.1/" 409 uaVersionEncoded := make([]byte, len(baseVersionEncoded)-4) 410 copy(uaVersionEncoded, baseVersionEncoded) 411 412 // lastBlockVersion is a version message that contains all fields 413 // through the LastBlock field. 414 lastBlockVersion := uaVersion 415 lastBlockVersion.LastBlock = 234234 // 0x392fa 416 lastBlockVersionEncoded := make([]byte, len(baseVersionEncoded)) 417 copy(lastBlockVersionEncoded, baseVersionEncoded) 418 419 tests := []struct { 420 msg *MsgVersion // Expected message 421 buf []byte // Wire encoding 422 pver uint32 // Protocol version for wire encoding 423 enc MessageEncoding // Message encoding format 424 }{ 425 { 426 &onlyRequiredVersion, 427 onlyRequiredVersionEncoded, 428 ProtocolVersion, 429 BaseEncoding, 430 }, 431 { 432 &addrMeVersion, 433 addrMeVersionEncoded, 434 ProtocolVersion, 435 BaseEncoding, 436 }, 437 { 438 &nonceVersion, 439 nonceVersionEncoded, 440 ProtocolVersion, 441 BaseEncoding, 442 }, 443 { 444 &uaVersion, 445 uaVersionEncoded, 446 ProtocolVersion, 447 BaseEncoding, 448 }, 449 { 450 &lastBlockVersion, 451 lastBlockVersionEncoded, 452 ProtocolVersion, 453 BaseEncoding, 454 }, 455 } 456 457 for i, test := range tests { 458 // Decode the message from wire format. 459 var msg MsgVersion 460 rbuf := bytes.NewBuffer(test.buf) 461 err := msg.BtcDecode(rbuf, test.pver, test.enc) 462 if err != nil { 463 t.Errorf("BtcDecode #%d error %v", i, err) 464 continue 465 } 466 if !reflect.DeepEqual(&msg, test.msg) { 467 t.Errorf("BtcDecode #%d\n got: %s want: %s", i, 468 spew.Sdump(msg), spew.Sdump(test.msg)) 469 continue 470 } 471 } 472 } 473 474 // baseVersion is used in the various tests as a baseline MsgVersion. 475 var baseVersion = &MsgVersion{ 476 ProtocolVersion: 60002, 477 Services: SFNodeNetwork, 478 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST) 479 AddrYou: NetAddress{ 480 Timestamp: time.Time{}, // Zero value -- no timestamp in version 481 Services: SFNodeNetwork, 482 IP: net.ParseIP("192.168.0.1"), 483 Port: 8333, 484 }, 485 AddrMe: NetAddress{ 486 Timestamp: time.Time{}, // Zero value -- no timestamp in version 487 Services: SFNodeNetwork, 488 IP: net.ParseIP("127.0.0.1"), 489 Port: 8333, 490 }, 491 Nonce: 123123, // 0x1e0f3 492 UserAgent: "/btcdtest:0.0.1/", 493 LastBlock: 234234, // 0x392fa 494 } 495 496 // baseVersionEncoded is the wire encoded bytes for baseVersion using protocol 497 // version 60002 and is used in the various tests. 498 var baseVersionEncoded = []byte{ 499 0x62, 0xea, 0x00, 0x00, // Protocol version 60002 500 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 501 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // 64-bit Timestamp 502 // AddrYou -- No timestamp for NetAddress in version message 503 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 505 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1 506 0x20, 0x8d, // Port 8333 in big-endian 507 // AddrMe -- No timestamp for NetAddress in version message 508 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 509 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 510 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 511 0x20, 0x8d, // Port 8333 in big-endian 512 0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce 513 0x10, // Varint for user agent length 514 0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73, 515 0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent 516 0xfa, 0x92, 0x03, 0x00, // Last block 517 } 518 519 // baseVersionBIP0037 is used in the various tests as a baseline MsgVersion for 520 // BIP0037. 521 var baseVersionBIP0037 = &MsgVersion{ 522 ProtocolVersion: 70001, 523 Services: SFNodeNetwork, 524 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST) 525 AddrYou: NetAddress{ 526 Timestamp: time.Time{}, // Zero value -- no timestamp in version 527 Services: SFNodeNetwork, 528 IP: net.ParseIP("192.168.0.1"), 529 Port: 8333, 530 }, 531 AddrMe: NetAddress{ 532 Timestamp: time.Time{}, // Zero value -- no timestamp in version 533 Services: SFNodeNetwork, 534 IP: net.ParseIP("127.0.0.1"), 535 Port: 8333, 536 }, 537 Nonce: 123123, // 0x1e0f3 538 UserAgent: "/btcdtest:0.0.1/", 539 LastBlock: 234234, // 0x392fa 540 } 541 542 // baseVersionBIP0037Encoded is the wire encoded bytes for baseVersionBIP0037 543 // using protocol version BIP0037Version and is used in the various tests. 544 var baseVersionBIP0037Encoded = []byte{ 545 0x71, 0x11, 0x01, 0x00, // Protocol version 70001 546 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 547 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // 64-bit Timestamp 548 // AddrYou -- No timestamp for NetAddress in version message 549 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 551 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1 552 0x20, 0x8d, // Port 8333 in big-endian 553 // AddrMe -- No timestamp for NetAddress in version message 554 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 556 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 557 0x20, 0x8d, // Port 8333 in big-endian 558 0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce 559 0x10, // Varint for user agent length 560 0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73, 561 0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent 562 0xfa, 0x92, 0x03, 0x00, // Last block 563 0x01, // Relay tx 564 }