1#!/usr/bin/env python3 2# Copyright (c) 2010 ArtForz -- public domain half-a-node 3# Copyright (c) 2012 Jeff Garzik 4# Copyright (c) 2010-2019 The Bitcoin Core developers 5# Distributed under the MIT software license, see the accompanying 6# file COPYING or http://www.opensource.org/licenses/mit-license.php. 7"""Bitcoin test framework primitive and message structures 8 9CBlock, CTransaction, CBlockHeader, CTxIn, CTxOut, etc....: 10 data structures that should map to corresponding structures in 11 bitcoin/primitives 12 13msg_block, msg_tx, msg_headers, etc.: 14 data structures that represent network messages 15 16ser_*, deser_*: functions that handle serialization/deserialization. 17 18Classes use __slots__ to ensure extraneous attributes aren't accidentally added 19by tests, compromising their intended effect. 20""" 21from codecs import encode 22import copy 23import hashlib 24from io import BytesIO 25import random 26import socket 27import struct 28import time 29 30from test_framework.siphash import siphash256 31from test_framework.util import hex_str_to_bytes, assert_equal 32from test_framework.qtumconfig import INITIAL_HASH_STATE_ROOT, INITIAL_HASH_UTXO_ROOT, ENABLE_REDUCED_BLOCK_TIME 33 34if ENABLE_REDUCED_BLOCK_TIME: 35 MY_VERSION = 70019 # past bip-31 for ping/pong 36else: 37 MY_VERSION = 70018 # past bip-31 for ping/pong 38 39MIN_VERSION_SUPPORTED = 60001 40MY_SUBVERSION = b"/python-mininode-tester:0.0.3/" 41MY_RELAY = 1 # from version 70001 onwards, fRelay should be appended to version messages (BIP37) 42 43MAX_LOCATOR_SZ = 101 44MAX_BLOCK_BASE_SIZE = 1000000 45 46COIN = 100000000 # 1 btc in satoshis 47MAX_MONEY = 10782240625000000 48 49BIP125_SEQUENCE_NUMBER = 0xfffffffd # Sequence number that is BIP 125 opt-in and BIP 68-opt-out 50 51NODE_NETWORK = (1 << 0) 52NODE_GETUTXO = (1 << 1) 53NODE_BLOOM = (1 << 2) 54NODE_WITNESS = (1 << 3) 55NODE_NETWORK_LIMITED = (1 << 10) 56 57MSG_TX = 1 58MSG_BLOCK = 2 59MSG_FILTERED_BLOCK = 3 60MSG_WITNESS_FLAG = 1 << 30 61MSG_TYPE_MASK = 0xffffffff >> 2 62 63# Serialization/deserialization tools 64def sha256(s): 65 return hashlib.new('sha256', s).digest() 66 67def hash256(s): 68 return sha256(sha256(s)) 69 70def ser_compact_size(l): 71 r = b"" 72 if l < 253: 73 r = struct.pack("B", l) 74 elif l < 0x10000: 75 r = struct.pack("<BH", 253, l) 76 elif l < 0x100000000: 77 r = struct.pack("<BI", 254, l) 78 else: 79 r = struct.pack("<BQ", 255, l) 80 return r 81 82def deser_compact_size(f): 83 nit = struct.unpack("<B", f.read(1))[0] 84 if nit == 253: 85 nit = struct.unpack("<H", f.read(2))[0] 86 elif nit == 254: 87 nit = struct.unpack("<I", f.read(4))[0] 88 elif nit == 255: 89 nit = struct.unpack("<Q", f.read(8))[0] 90 return nit 91 92def deser_string(f): 93 nit = deser_compact_size(f) 94 return f.read(nit) 95 96def ser_string(s): 97 return ser_compact_size(len(s)) + s 98 99def deser_uint256(f): 100 r = 0 101 for i in range(8): 102 t = struct.unpack("<I", f.read(4))[0] 103 r += t << (i * 32) 104 return r 105 106 107def ser_uint256(u): 108 rs = b"" 109 for i in range(8): 110 rs += struct.pack("<I", u & 0xFFFFFFFF) 111 u >>= 32 112 return rs 113 114 115def uint256_from_str(s): 116 r = 0 117 t = struct.unpack("<IIIIIIII", s[:32]) 118 for i in range(8): 119 r += t[i] << (i * 32) 120 return r 121 122 123def uint256_from_compact(c): 124 nbytes = (c >> 24) & 0xFF 125 v = (c & 0xFFFFFF) << (8 * (nbytes - 3)) 126 return v 127 128 129def deser_vector(f, c): 130 nit = deser_compact_size(f) 131 r = [] 132 for i in range(nit): 133 t = c() 134 t.deserialize(f) 135 r.append(t) 136 return r 137 138 139# ser_function_name: Allow for an alternate serialization function on the 140# entries in the vector (we use this for serializing the vector of transactions 141# for a witness block). 142def ser_vector(l, ser_function_name=None): 143 r = ser_compact_size(len(l)) 144 for i in l: 145 if ser_function_name: 146 r += getattr(i, ser_function_name)() 147 else: 148 r += i.serialize() 149 return r 150 151 152def deser_uint256_vector(f): 153 nit = deser_compact_size(f) 154 r = [] 155 for i in range(nit): 156 t = deser_uint256(f) 157 r.append(t) 158 return r 159 160 161def ser_uint256_vector(l): 162 r = ser_compact_size(len(l)) 163 for i in l: 164 r += ser_uint256(i) 165 return r 166 167 168def deser_string_vector(f): 169 nit = deser_compact_size(f) 170 r = [] 171 for i in range(nit): 172 t = deser_string(f) 173 r.append(t) 174 return r 175 176 177def ser_string_vector(l): 178 r = ser_compact_size(len(l)) 179 for sv in l: 180 r += ser_string(sv) 181 return r 182 183 184# Deserialize from a hex string representation (eg from RPC) 185def FromHex(obj, hex_string): 186 obj.deserialize(BytesIO(hex_str_to_bytes(hex_string))) 187 return obj 188 189# Convert a binary-serializable object to hex (eg for submission via RPC) 190def ToHex(obj): 191 return obj.serialize().hex() 192 193# Objects that map to bitcoind objects, which can be serialized/deserialized 194 195 196class CAddress: 197 __slots__ = ("ip", "nServices", "pchReserved", "port", "time") 198 199 def __init__(self): 200 self.time = 0 201 self.nServices = 1 202 self.pchReserved = b"\x00" * 10 + b"\xff" * 2 203 self.ip = "0.0.0.0" 204 self.port = 0 205 206 def deserialize(self, f, with_time=True): 207 if with_time: 208 self.time = struct.unpack("<i", f.read(4))[0] 209 self.nServices = struct.unpack("<Q", f.read(8))[0] 210 self.pchReserved = f.read(12) 211 self.ip = socket.inet_ntoa(f.read(4)) 212 self.port = struct.unpack(">H", f.read(2))[0] 213 214 def serialize(self, with_time=True): 215 r = b"" 216 if with_time: 217 r += struct.pack("<i", self.time) 218 r += struct.pack("<Q", self.nServices) 219 r += self.pchReserved 220 r += socket.inet_aton(self.ip) 221 r += struct.pack(">H", self.port) 222 return r 223 224 def __repr__(self): 225 return "CAddress(nServices=%i ip=%s port=%i)" % (self.nServices, 226 self.ip, self.port) 227 228 229class CInv: 230 __slots__ = ("hash", "type") 231 232 typemap = { 233 0: "Error", 234 MSG_TX: "TX", 235 MSG_BLOCK: "Block", 236 MSG_TX | MSG_WITNESS_FLAG: "WitnessTx", 237 MSG_BLOCK | MSG_WITNESS_FLAG: "WitnessBlock", 238 MSG_FILTERED_BLOCK: "filtered Block", 239 4: "CompactBlock" 240 } 241 242 def __init__(self, t=0, h=0): 243 self.type = t 244 self.hash = h 245 246 def deserialize(self, f): 247 self.type = struct.unpack("<i", f.read(4))[0] 248 self.hash = deser_uint256(f) 249 250 def serialize(self): 251 r = b"" 252 r += struct.pack("<i", self.type) 253 r += ser_uint256(self.hash) 254 return r 255 256 def __repr__(self): 257 return "CInv(type=%s hash=%064x)" \ 258 % (self.typemap[self.type], self.hash) 259 260 261class CBlockLocator: 262 __slots__ = ("nVersion", "vHave") 263 264 def __init__(self): 265 self.nVersion = MY_VERSION 266 self.vHave = [] 267 268 def deserialize(self, f): 269 self.nVersion = struct.unpack("<i", f.read(4))[0] 270 self.vHave = deser_uint256_vector(f) 271 272 def serialize(self): 273 r = b"" 274 r += struct.pack("<i", self.nVersion) 275 r += ser_uint256_vector(self.vHave) 276 return r 277 278 def __repr__(self): 279 return "CBlockLocator(nVersion=%i vHave=%s)" \ 280 % (self.nVersion, repr(self.vHave)) 281 282 283class COutPoint: 284 __slots__ = ("hash", "n") 285 286 def __init__(self, hash=0, n=0): 287 self.hash = hash 288 self.n = n 289 290 def deserialize(self, f): 291 self.hash = deser_uint256(f) 292 self.n = struct.unpack("<I", f.read(4))[0] 293 294 def serialize(self): 295 r = b"" 296 r += ser_uint256(self.hash) 297 r += struct.pack("<I", self.n) 298 return r 299 300 def __repr__(self): 301 return "COutPoint(hash=%064x n=%i)" % (self.hash, self.n) 302 303 304class CTxIn: 305 __slots__ = ("nSequence", "prevout", "scriptSig") 306 307 def __init__(self, outpoint=None, scriptSig=b"", nSequence=0): 308 if outpoint is None: 309 self.prevout = COutPoint() 310 else: 311 self.prevout = outpoint 312 self.scriptSig = scriptSig 313 self.nSequence = nSequence 314 315 def deserialize(self, f): 316 self.prevout = COutPoint() 317 self.prevout.deserialize(f) 318 self.scriptSig = deser_string(f) 319 self.nSequence = struct.unpack("<I", f.read(4))[0] 320 321 def serialize(self): 322 r = b"" 323 r += self.prevout.serialize() 324 r += ser_string(self.scriptSig) 325 r += struct.pack("<I", self.nSequence) 326 return r 327 328 def __repr__(self): 329 return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \ 330 % (repr(self.prevout), self.scriptSig.hex(), 331 self.nSequence) 332 333 334class CTxOut: 335 __slots__ = ("nValue", "scriptPubKey") 336 337 def __init__(self, nValue=0, scriptPubKey=b""): 338 self.nValue = nValue 339 self.scriptPubKey = scriptPubKey 340 341 def deserialize(self, f): 342 self.nValue = struct.unpack("<q", f.read(8))[0] 343 self.scriptPubKey = deser_string(f) 344 345 def serialize(self): 346 r = b"" 347 r += struct.pack("<q", self.nValue) 348 r += ser_string(self.scriptPubKey) 349 return r 350 351 def __repr__(self): 352 return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \ 353 % (self.nValue // COIN, self.nValue % COIN, 354 self.scriptPubKey.hex()) 355 356 357class CScriptWitness: 358 __slots__ = ("stack",) 359 360 def __init__(self): 361 # stack is a vector of strings 362 self.stack = [] 363 364 def __repr__(self): 365 return "CScriptWitness(%s)" % \ 366 (",".join([x.hex() for x in self.stack])) 367 368 def is_null(self): 369 if self.stack: 370 return False 371 return True 372 373 374class CTxInWitness: 375 __slots__ = ("scriptWitness",) 376 377 def __init__(self): 378 self.scriptWitness = CScriptWitness() 379 380 def deserialize(self, f): 381 self.scriptWitness.stack = deser_string_vector(f) 382 383 def serialize(self): 384 return ser_string_vector(self.scriptWitness.stack) 385 386 def __repr__(self): 387 return repr(self.scriptWitness) 388 389 def is_null(self): 390 return self.scriptWitness.is_null() 391 392 393class CTxWitness: 394 __slots__ = ("vtxinwit",) 395 396 def __init__(self): 397 self.vtxinwit = [] 398 399 def deserialize(self, f): 400 for i in range(len(self.vtxinwit)): 401 self.vtxinwit[i].deserialize(f) 402 403 def serialize(self): 404 r = b"" 405 # This is different than the usual vector serialization -- 406 # we omit the length of the vector, which is required to be 407 # the same length as the transaction's vin vector. 408 for x in self.vtxinwit: 409 r += x.serialize() 410 return r 411 412 def __repr__(self): 413 return "CTxWitness(%s)" % \ 414 (';'.join([repr(x) for x in self.vtxinwit])) 415 416 def is_null(self): 417 for x in self.vtxinwit: 418 if not x.is_null(): 419 return False 420 return True 421 422 423class CTransaction: 424 __slots__ = ("hash", "nLockTime", "nVersion", "sha256", "vin", "vout", 425 "wit") 426 427 def __init__(self, tx=None): 428 if tx is None: 429 self.nVersion = 1 430 self.vin = [] 431 self.vout = [] 432 self.wit = CTxWitness() 433 self.nLockTime = 0 434 self.sha256 = None 435 self.hash = None 436 else: 437 self.nVersion = tx.nVersion 438 self.vin = copy.deepcopy(tx.vin) 439 self.vout = copy.deepcopy(tx.vout) 440 self.nLockTime = tx.nLockTime 441 self.sha256 = tx.sha256 442 self.hash = tx.hash 443 self.wit = copy.deepcopy(tx.wit) 444 445 def deserialize(self, f): 446 self.nVersion = struct.unpack("<i", f.read(4))[0] 447 self.vin = deser_vector(f, CTxIn) 448 flags = 0 449 if len(self.vin) == 0: 450 flags = struct.unpack("<B", f.read(1))[0] 451 # Not sure why flags can't be zero, but this 452 # matches the implementation in bitcoind 453 if (flags != 0): 454 self.vin = deser_vector(f, CTxIn) 455 self.vout = deser_vector(f, CTxOut) 456 else: 457 self.vout = deser_vector(f, CTxOut) 458 if flags != 0: 459 self.wit.vtxinwit = [CTxInWitness() for i in range(len(self.vin))] 460 self.wit.deserialize(f) 461 else: 462 self.wit = CTxWitness() 463 self.nLockTime = struct.unpack("<I", f.read(4))[0] 464 self.sha256 = None 465 self.hash = None 466 467 def serialize_without_witness(self): 468 r = b"" 469 r += struct.pack("<i", self.nVersion) 470 r += ser_vector(self.vin) 471 r += ser_vector(self.vout) 472 r += struct.pack("<I", self.nLockTime) 473 return r 474 475 # Only serialize with witness when explicitly called for 476 def serialize_with_witness(self): 477 flags = 0 478 if not self.wit.is_null(): 479 flags |= 1 480 r = b"" 481 r += struct.pack("<i", self.nVersion) 482 if flags: 483 dummy = [] 484 r += ser_vector(dummy) 485 r += struct.pack("<B", flags) 486 r += ser_vector(self.vin) 487 r += ser_vector(self.vout) 488 if flags & 1: 489 if (len(self.wit.vtxinwit) != len(self.vin)): 490 # vtxinwit must have the same length as vin 491 self.wit.vtxinwit = self.wit.vtxinwit[:len(self.vin)] 492 for i in range(len(self.wit.vtxinwit), len(self.vin)): 493 self.wit.vtxinwit.append(CTxInWitness()) 494 r += self.wit.serialize() 495 r += struct.pack("<I", self.nLockTime) 496 return r 497 498 # Regular serialization is with witness -- must explicitly 499 # call serialize_without_witness to exclude witness data. 500 def serialize(self): 501 return self.serialize_with_witness() 502 503 # Recalculate the txid (transaction hash without witness) 504 def rehash(self): 505 self.sha256 = None 506 self.calc_sha256() 507 return self.hash 508 509 # We will only cache the serialization without witness in 510 # self.sha256 and self.hash -- those are expected to be the txid. 511 def calc_sha256(self, with_witness=False): 512 if with_witness: 513 # Don't cache the result, just return it 514 return uint256_from_str(hash256(self.serialize_with_witness())) 515 516 if self.sha256 is None: 517 self.sha256 = uint256_from_str(hash256(self.serialize_without_witness())) 518 self.hash = encode(hash256(self.serialize_without_witness())[::-1], 'hex_codec').decode('ascii') 519 520 def is_valid(self): 521 self.calc_sha256() 522 for tout in self.vout: 523 if tout.nValue < 0 or tout.nValue > 21000000 * COIN: 524 return False 525 return True 526 527 def __repr__(self): 528 return "CTransaction(nVersion=%i vin=%s vout=%s wit=%s nLockTime=%i)" \ 529 % (self.nVersion, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime) 530 531 532class CBlockHeader(object): 533 __slots__ = ("hash", "hashMerkleRoot", "hashPrevBlock", "hashStateRoot", "hashUTXORoot", "prevoutStake", "vchBlockSig", "nBits", "nNonce", 534 "nTime", "nVersion", "sha256") 535 536 def __init__(self, header=None): 537 if header is None: 538 self.set_null() 539 else: 540 self.nVersion = header.nVersion 541 self.hashPrevBlock = header.hashPrevBlock 542 self.hashMerkleRoot = header.hashMerkleRoot 543 self.nTime = header.nTime 544 self.nBits = header.nBits 545 self.nNonce = header.nNonce 546 self.hashStateRoot = header.hashStateRoot 547 self.hashUTXORoot = header.hashUTXORoot 548 self.prevoutStake = header.prevoutStake 549 self.vchBlockSig = header.vchBlockSig 550 551 self.sha256 = header.sha256 552 self.hash = header.hash 553 self.calc_sha256() 554 555 def set_null(self): 556 self.nVersion = 4 557 self.hashPrevBlock = 0 558 self.hashMerkleRoot = 0 559 self.nTime = 0 560 self.nBits = 0 561 self.nNonce = 0 562 self.hashStateRoot = INITIAL_HASH_STATE_ROOT 563 self.hashUTXORoot = INITIAL_HASH_UTXO_ROOT 564 self.prevoutStake = COutPoint(0, 0xffffffff) 565 self.vchBlockSig = b"" 566 567 self.sha256 = None 568 self.hash = None 569 570 def deserialize(self, f): 571 self.nVersion = struct.unpack("<i", f.read(4))[0] 572 self.hashPrevBlock = deser_uint256(f) 573 self.hashMerkleRoot = deser_uint256(f) 574 self.nTime = struct.unpack("<I", f.read(4))[0] 575 self.nBits = struct.unpack("<I", f.read(4))[0] 576 self.nNonce = struct.unpack("<I", f.read(4))[0] 577 self.hashStateRoot = deser_uint256(f) 578 self.hashUTXORoot = deser_uint256(f) 579 self.prevoutStake = COutPoint() 580 self.prevoutStake.deserialize(f) 581 self.vchBlockSig = deser_string(f) 582 583 self.sha256 = None 584 self.hash = None 585 586 def serialize(self): 587 r = b"" 588 r += struct.pack("<i", self.nVersion) 589 r += ser_uint256(self.hashPrevBlock) 590 r += ser_uint256(self.hashMerkleRoot) 591 r += struct.pack("<I", self.nTime) 592 r += struct.pack("<I", self.nBits) 593 r += struct.pack("<I", self.nNonce) 594 r += ser_uint256(self.hashStateRoot) 595 r += ser_uint256(self.hashUTXORoot) 596 r += self.prevoutStake.serialize() if self.prevoutStake else COutPoint(0, 0xffffffff).serialize() 597 r += ser_string(self.vchBlockSig) 598 return r 599 600 def calc_sha256(self): 601 if self.sha256 is None: 602 r = b"" 603 r += struct.pack("<i", self.nVersion) 604 r += ser_uint256(self.hashPrevBlock) 605 r += ser_uint256(self.hashMerkleRoot) 606 r += struct.pack("<I", self.nTime) 607 r += struct.pack("<I", self.nBits) 608 r += struct.pack("<I", self.nNonce) 609 r += ser_uint256(self.hashStateRoot) 610 r += ser_uint256(self.hashUTXORoot) 611 r += self.prevoutStake.serialize() if self.prevoutStake else COutPoint(0, 0xffffffff).serialize() 612 r += ser_string(self.vchBlockSig) 613 self.sha256 = uint256_from_str(hash256(r)) 614 self.hash = encode(hash256(r)[::-1], 'hex_codec').decode('ascii') 615 616 def rehash(self): 617 self.sha256 = None 618 self.calc_sha256() 619 return self.sha256 620 621 def is_pos(self): 622 return self.prevoutStake and (self.prevoutStake.hash != 0 or self.prevoutStake.n != 0xffffffff) 623 624 def solve_stake(self, stakeModifier, prevouts): 625 target = uint256_from_compact(self.nBits) 626 for prevout, nValue, txBlockTime in prevouts: 627 data = b"" 628 data += ser_uint256(stakeModifier) 629 data += struct.pack("<I", txBlockTime) 630 data += prevout.serialize() 631 data += struct.pack("<I", self.nTime) 632 posHash = uint256_from_str(hash256(data)) 633 if posHash <= (target*nValue) & (2**256 - 1): 634 self.prevoutStake = prevout 635 return True 636 return False 637 638 def __repr__(self): 639 return "CBlockHeader(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x)" \ 640 % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, 641 time.ctime(self.nTime), self.nBits, self.nNonce) 642 643# BLOCK_HEADER_SIZE = len(CBlockHeader().serialize()) 644# assert_equal(BLOCK_HEADER_SIZE, 80) 645 646class CBlock(CBlockHeader): 647 __slots__ = ("vtx",) 648 649 def __init__(self, header=None): 650 super(CBlock, self).__init__(header) 651 self.vtx = [] 652 653 def deserialize(self, f): 654 super(CBlock, self).deserialize(f) 655 self.vtx = deser_vector(f, CTransaction) 656 657 def serialize(self, with_witness=True): 658 r = b"" 659 r += super(CBlock, self).serialize() 660 if with_witness: 661 r += ser_vector(self.vtx, "serialize_with_witness") 662 else: 663 r += ser_vector(self.vtx, "serialize_without_witness") 664 return r 665 666 # Calculate the merkle root given a vector of transaction hashes 667 @classmethod 668 def get_merkle_root(cls, hashes): 669 while len(hashes) > 1: 670 newhashes = [] 671 for i in range(0, len(hashes), 2): 672 i2 = min(i+1, len(hashes)-1) 673 newhashes.append(hash256(hashes[i] + hashes[i2])) 674 hashes = newhashes 675 return uint256_from_str(hashes[0]) 676 677 def calc_merkle_root(self): 678 hashes = [] 679 for tx in self.vtx: 680 tx.calc_sha256() 681 hashes.append(ser_uint256(tx.sha256)) 682 return self.get_merkle_root(hashes) 683 684 def calc_witness_merkle_root(self, is_pos=False): 685 # For witness root purposes, the hash of the 686 # coinbase, with witness, is defined to be 0...0 687 if is_pos: 688 hashes = [ser_uint256(0), ser_uint256(0)] 689 hashes_start_index = 2 690 else: 691 hashes = [ser_uint256(0)] 692 hashes_start_index = 1 693 694 for tx in self.vtx[hashes_start_index:]: 695 # Calculate the hashes with witness data 696 hashes.append(ser_uint256(tx.calc_sha256(True))) 697 698 return self.get_merkle_root(hashes) 699 700 def is_valid(self): 701 self.calc_sha256() 702 target = uint256_from_compact(self.nBits) 703 if self.sha256 > target: 704 return False 705 for tx in self.vtx: 706 if not tx.is_valid(): 707 return False 708 if self.calc_merkle_root() != self.hashMerkleRoot: 709 return False 710 return True 711 712 def solve(self): 713 self.rehash() 714 target = uint256_from_compact(self.nBits) 715 while self.sha256 > target: 716 self.nNonce += 1 717 self.rehash() 718 719 def sign_block(self, key, low_s=True, pod=None, der_sig=False): 720 data = b"" 721 data += struct.pack("<i", self.nVersion) 722 data += ser_uint256(self.hashPrevBlock) 723 data += ser_uint256(self.hashMerkleRoot) 724 data += struct.pack("<I", self.nTime) 725 data += struct.pack("<I", self.nBits) 726 data += struct.pack("<I", self.nNonce) 727 data += ser_uint256(self.hashStateRoot) 728 data += ser_uint256(self.hashUTXORoot) 729 data += self.prevoutStake.serialize() 730 if pod != None: 731 data += struct.pack("<b", len(pod)) + pod 732 sha256NoSig = hash256(data) 733 self.vchBlockSig = key.sign_ecdsa(sha256NoSig, low_s=low_s, der_sig=der_sig) 734 735 def __repr__(self): 736 return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" \ 737 % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, 738 time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx)) 739 740 741class PrefilledTransaction: 742 __slots__ = ("index", "tx") 743 744 def __init__(self, index=0, tx = None): 745 self.index = index 746 self.tx = tx 747 748 def deserialize(self, f): 749 self.index = deser_compact_size(f) 750 self.tx = CTransaction() 751 self.tx.deserialize(f) 752 753 def serialize(self, with_witness=True): 754 r = b"" 755 r += ser_compact_size(self.index) 756 if with_witness: 757 r += self.tx.serialize_with_witness() 758 else: 759 r += self.tx.serialize_without_witness() 760 return r 761 762 def serialize_without_witness(self): 763 return self.serialize(with_witness=False) 764 765 def serialize_with_witness(self): 766 return self.serialize(with_witness=True) 767 768 def __repr__(self): 769 return "PrefilledTransaction(index=%d, tx=%s)" % (self.index, repr(self.tx)) 770 771 772# This is what we send on the wire, in a cmpctblock message. 773class P2PHeaderAndShortIDs: 774 __slots__ = ("header", "nonce", "prefilled_txn", "prefilled_txn_length", 775 "shortids", "shortids_length") 776 777 def __init__(self): 778 self.header = CBlockHeader() 779 self.nonce = 0 780 self.shortids_length = 0 781 self.shortids = [] 782 self.prefilled_txn_length = 0 783 self.prefilled_txn = [] 784 785 def deserialize(self, f): 786 self.header.deserialize(f) 787 self.nonce = struct.unpack("<Q", f.read(8))[0] 788 self.shortids_length = deser_compact_size(f) 789 for i in range(self.shortids_length): 790 # shortids are defined to be 6 bytes in the spec, so append 791 # two zero bytes and read it in as an 8-byte number 792 self.shortids.append(struct.unpack("<Q", f.read(6) + b'\x00\x00')[0]) 793 self.prefilled_txn = deser_vector(f, PrefilledTransaction) 794 self.prefilled_txn_length = len(self.prefilled_txn) 795 796 # When using version 2 compact blocks, we must serialize with_witness. 797 def serialize(self, with_witness=False): 798 r = b"" 799 r += self.header.serialize() 800 r += struct.pack("<Q", self.nonce) 801 r += ser_compact_size(self.shortids_length) 802 for x in self.shortids: 803 # We only want the first 6 bytes 804 r += struct.pack("<Q", x)[0:6] 805 if with_witness: 806 r += ser_vector(self.prefilled_txn, "serialize_with_witness") 807 else: 808 r += ser_vector(self.prefilled_txn, "serialize_without_witness") 809 return r 810 811 def __repr__(self): 812 return "P2PHeaderAndShortIDs(header=%s, nonce=%d, shortids_length=%d, shortids=%s, prefilled_txn_length=%d, prefilledtxn=%s" % (repr(self.header), self.nonce, self.shortids_length, repr(self.shortids), self.prefilled_txn_length, repr(self.prefilled_txn)) 813 814 815# P2P version of the above that will use witness serialization (for compact 816# block version 2) 817class P2PHeaderAndShortWitnessIDs(P2PHeaderAndShortIDs): 818 __slots__ = () 819 def serialize(self): 820 return super(P2PHeaderAndShortWitnessIDs, self).serialize(with_witness=True) 821 822# Calculate the BIP 152-compact blocks shortid for a given transaction hash 823def calculate_shortid(k0, k1, tx_hash): 824 expected_shortid = siphash256(k0, k1, tx_hash) 825 expected_shortid &= 0x0000ffffffffffff 826 return expected_shortid 827 828 829# This version gets rid of the array lengths, and reinterprets the differential 830# encoding into indices that can be used for lookup. 831class HeaderAndShortIDs: 832 __slots__ = ("header", "nonce", "prefilled_txn", "shortids", "use_witness") 833 834 def __init__(self, p2pheaders_and_shortids = None): 835 self.header = CBlockHeader() 836 self.nonce = 0 837 self.shortids = [] 838 self.prefilled_txn = [] 839 self.use_witness = False 840 841 if p2pheaders_and_shortids is not None: 842 self.header = p2pheaders_and_shortids.header 843 self.nonce = p2pheaders_and_shortids.nonce 844 self.shortids = p2pheaders_and_shortids.shortids 845 last_index = -1 846 for x in p2pheaders_and_shortids.prefilled_txn: 847 self.prefilled_txn.append(PrefilledTransaction(x.index + last_index + 1, x.tx)) 848 last_index = self.prefilled_txn[-1].index 849 850 def to_p2p(self): 851 if self.use_witness: 852 ret = P2PHeaderAndShortWitnessIDs() 853 else: 854 ret = P2PHeaderAndShortIDs() 855 ret.header = self.header 856 ret.nonce = self.nonce 857 ret.shortids_length = len(self.shortids) 858 ret.shortids = self.shortids 859 ret.prefilled_txn_length = len(self.prefilled_txn) 860 ret.prefilled_txn = [] 861 last_index = -1 862 for x in self.prefilled_txn: 863 ret.prefilled_txn.append(PrefilledTransaction(x.index - last_index - 1, x.tx)) 864 last_index = x.index 865 return ret 866 867 def get_siphash_keys(self): 868 header_nonce = self.header.serialize() 869 header_nonce += struct.pack("<Q", self.nonce) 870 hash_header_nonce_as_str = sha256(header_nonce) 871 key0 = struct.unpack("<Q", hash_header_nonce_as_str[0:8])[0] 872 key1 = struct.unpack("<Q", hash_header_nonce_as_str[8:16])[0] 873 return [ key0, key1 ] 874 875 # Version 2 compact blocks use wtxid in shortids (rather than txid) 876 def initialize_from_block(self, block, nonce=0, prefill_list=None, use_witness=False): 877 if prefill_list is None: 878 prefill_list = [0] 879 self.header = CBlockHeader(block) 880 self.nonce = nonce 881 self.prefilled_txn = [ PrefilledTransaction(i, block.vtx[i]) for i in prefill_list ] 882 self.shortids = [] 883 self.use_witness = use_witness 884 [k0, k1] = self.get_siphash_keys() 885 for i in range(len(block.vtx)): 886 if i not in prefill_list: 887 tx_hash = block.vtx[i].sha256 888 if use_witness: 889 tx_hash = block.vtx[i].calc_sha256(with_witness=True) 890 self.shortids.append(calculate_shortid(k0, k1, tx_hash)) 891 892 def __repr__(self): 893 return "HeaderAndShortIDs(header=%s, nonce=%d, shortids=%s, prefilledtxn=%s" % (repr(self.header), self.nonce, repr(self.shortids), repr(self.prefilled_txn)) 894 895 896class BlockTransactionsRequest: 897 __slots__ = ("blockhash", "indexes") 898 899 def __init__(self, blockhash=0, indexes = None): 900 self.blockhash = blockhash 901 self.indexes = indexes if indexes is not None else [] 902 903 def deserialize(self, f): 904 self.blockhash = deser_uint256(f) 905 indexes_length = deser_compact_size(f) 906 for i in range(indexes_length): 907 self.indexes.append(deser_compact_size(f)) 908 909 def serialize(self): 910 r = b"" 911 r += ser_uint256(self.blockhash) 912 r += ser_compact_size(len(self.indexes)) 913 for x in self.indexes: 914 r += ser_compact_size(x) 915 return r 916 917 # helper to set the differentially encoded indexes from absolute ones 918 def from_absolute(self, absolute_indexes): 919 self.indexes = [] 920 last_index = -1 921 for x in absolute_indexes: 922 self.indexes.append(x-last_index-1) 923 last_index = x 924 925 def to_absolute(self): 926 absolute_indexes = [] 927 last_index = -1 928 for x in self.indexes: 929 absolute_indexes.append(x+last_index+1) 930 last_index = absolute_indexes[-1] 931 return absolute_indexes 932 933 def __repr__(self): 934 return "BlockTransactionsRequest(hash=%064x indexes=%s)" % (self.blockhash, repr(self.indexes)) 935 936 937class BlockTransactions: 938 __slots__ = ("blockhash", "transactions") 939 940 def __init__(self, blockhash=0, transactions = None): 941 self.blockhash = blockhash 942 self.transactions = transactions if transactions is not None else [] 943 944 def deserialize(self, f): 945 self.blockhash = deser_uint256(f) 946 self.transactions = deser_vector(f, CTransaction) 947 948 def serialize(self, with_witness=True): 949 r = b"" 950 r += ser_uint256(self.blockhash) 951 if with_witness: 952 r += ser_vector(self.transactions, "serialize_with_witness") 953 else: 954 r += ser_vector(self.transactions, "serialize_without_witness") 955 return r 956 957 def __repr__(self): 958 return "BlockTransactions(hash=%064x transactions=%s)" % (self.blockhash, repr(self.transactions)) 959 960 961class CPartialMerkleTree: 962 __slots__ = ("nTransactions", "vBits", "vHash") 963 964 def __init__(self): 965 self.nTransactions = 0 966 self.vHash = [] 967 self.vBits = [] 968 969 def deserialize(self, f): 970 self.nTransactions = struct.unpack("<i", f.read(4))[0] 971 self.vHash = deser_uint256_vector(f) 972 vBytes = deser_string(f) 973 self.vBits = [] 974 for i in range(len(vBytes) * 8): 975 self.vBits.append(vBytes[i//8] & (1 << (i % 8)) != 0) 976 977 def serialize(self): 978 r = b"" 979 r += struct.pack("<i", self.nTransactions) 980 r += ser_uint256_vector(self.vHash) 981 vBytesArray = bytearray([0x00] * ((len(self.vBits) + 7)//8)) 982 for i in range(len(self.vBits)): 983 vBytesArray[i // 8] |= self.vBits[i] << (i % 8) 984 r += ser_string(bytes(vBytesArray)) 985 return r 986 987 def __repr__(self): 988 return "CPartialMerkleTree(nTransactions=%d, vHash=%s, vBits=%s)" % (self.nTransactions, repr(self.vHash), repr(self.vBits)) 989 990 991class CMerkleBlock: 992 __slots__ = ("header", "txn") 993 994 def __init__(self): 995 self.header = CBlockHeader() 996 self.txn = CPartialMerkleTree() 997 998 def deserialize(self, f): 999 self.header.deserialize(f) 1000 self.txn.deserialize(f) 1001 1002 def serialize(self): 1003 r = b"" 1004 r += self.header.serialize() 1005 r += self.txn.serialize() 1006 return r 1007 1008 def __repr__(self): 1009 return "CMerkleBlock(header=%s, txn=%s)" % (repr(self.header), repr(self.txn)) 1010 1011 1012# Objects that correspond to messages on the wire 1013class msg_version: 1014 __slots__ = ("addrFrom", "addrTo", "nNonce", "nRelay", "nServices", 1015 "nStartingHeight", "nTime", "nVersion", "strSubVer") 1016 command = b"version" 1017 1018 def __init__(self): 1019 self.nVersion = MY_VERSION 1020 self.nServices = NODE_NETWORK | NODE_WITNESS 1021 self.nTime = int(time.time()) 1022 self.addrTo = CAddress() 1023 self.addrFrom = CAddress() 1024 self.nNonce = random.getrandbits(64) 1025 self.strSubVer = MY_SUBVERSION 1026 self.nStartingHeight = -1 1027 self.nRelay = MY_RELAY 1028 1029 def deserialize(self, f): 1030 self.nVersion = struct.unpack("<i", f.read(4))[0] 1031 self.nServices = struct.unpack("<Q", f.read(8))[0] 1032 self.nTime = struct.unpack("<q", f.read(8))[0] 1033 self.addrTo = CAddress() 1034 self.addrTo.deserialize(f, False) 1035 1036 self.addrFrom = CAddress() 1037 self.addrFrom.deserialize(f, False) 1038 self.nNonce = struct.unpack("<Q", f.read(8))[0] 1039 self.strSubVer = deser_string(f) 1040 1041 self.nStartingHeight = struct.unpack("<i", f.read(4))[0] 1042 1043 if self.nVersion >= 70001: 1044 # Relay field is optional for version 70001 onwards 1045 try: 1046 self.nRelay = struct.unpack("<b", f.read(1))[0] 1047 except: 1048 self.nRelay = 0 1049 else: 1050 self.nRelay = 0 1051 1052 def serialize(self): 1053 r = b"" 1054 r += struct.pack("<i", self.nVersion) 1055 r += struct.pack("<Q", self.nServices) 1056 r += struct.pack("<q", self.nTime) 1057 r += self.addrTo.serialize(False) 1058 r += self.addrFrom.serialize(False) 1059 r += struct.pack("<Q", self.nNonce) 1060 r += ser_string(self.strSubVer) 1061 r += struct.pack("<i", self.nStartingHeight) 1062 r += struct.pack("<b", self.nRelay) 1063 return r 1064 1065 def __repr__(self): 1066 return 'msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i nRelay=%i)' \ 1067 % (self.nVersion, self.nServices, time.ctime(self.nTime), 1068 repr(self.addrTo), repr(self.addrFrom), self.nNonce, 1069 self.strSubVer, self.nStartingHeight, self.nRelay) 1070 1071 1072class msg_verack: 1073 __slots__ = () 1074 command = b"verack" 1075 1076 def __init__(self): 1077 pass 1078 1079 def deserialize(self, f): 1080 pass 1081 1082 def serialize(self): 1083 return b"" 1084 1085 def __repr__(self): 1086 return "msg_verack()" 1087 1088 1089class msg_addr: 1090 __slots__ = ("addrs",) 1091 command = b"addr" 1092 1093 def __init__(self): 1094 self.addrs = [] 1095 1096 def deserialize(self, f): 1097 self.addrs = deser_vector(f, CAddress) 1098 1099 def serialize(self): 1100 return ser_vector(self.addrs) 1101 1102 def __repr__(self): 1103 return "msg_addr(addrs=%s)" % (repr(self.addrs)) 1104 1105 1106class msg_inv: 1107 __slots__ = ("inv",) 1108 command = b"inv" 1109 1110 def __init__(self, inv=None): 1111 if inv is None: 1112 self.inv = [] 1113 else: 1114 self.inv = inv 1115 1116 def deserialize(self, f): 1117 self.inv = deser_vector(f, CInv) 1118 1119 def serialize(self): 1120 return ser_vector(self.inv) 1121 1122 def __repr__(self): 1123 return "msg_inv(inv=%s)" % (repr(self.inv)) 1124 1125 1126class msg_getdata: 1127 __slots__ = ("inv",) 1128 command = b"getdata" 1129 1130 def __init__(self, inv=None): 1131 self.inv = inv if inv is not None else [] 1132 1133 def deserialize(self, f): 1134 self.inv = deser_vector(f, CInv) 1135 1136 def serialize(self): 1137 return ser_vector(self.inv) 1138 1139 def __repr__(self): 1140 return "msg_getdata(inv=%s)" % (repr(self.inv)) 1141 1142 1143class msg_getblocks: 1144 __slots__ = ("locator", "hashstop") 1145 command = b"getblocks" 1146 1147 def __init__(self): 1148 self.locator = CBlockLocator() 1149 self.hashstop = 0 1150 1151 def deserialize(self, f): 1152 self.locator = CBlockLocator() 1153 self.locator.deserialize(f) 1154 self.hashstop = deser_uint256(f) 1155 1156 def serialize(self): 1157 r = b"" 1158 r += self.locator.serialize() 1159 r += ser_uint256(self.hashstop) 1160 return r 1161 1162 def __repr__(self): 1163 return "msg_getblocks(locator=%s hashstop=%064x)" \ 1164 % (repr(self.locator), self.hashstop) 1165 1166 1167class msg_tx: 1168 __slots__ = ("tx",) 1169 command = b"tx" 1170 1171 def __init__(self, tx=CTransaction()): 1172 self.tx = tx 1173 1174 def deserialize(self, f): 1175 self.tx.deserialize(f) 1176 1177 def serialize(self): 1178 return self.tx.serialize_with_witness() 1179 1180 def __repr__(self): 1181 return "msg_tx(tx=%s)" % (repr(self.tx)) 1182 1183 1184class msg_no_witness_tx(msg_tx): 1185 __slots__ = () 1186 1187 def serialize(self): 1188 return self.tx.serialize_without_witness() 1189 1190 1191class msg_block: 1192 __slots__ = ("block",) 1193 command = b"block" 1194 1195 def __init__(self, block=None): 1196 if block is None: 1197 self.block = CBlock() 1198 else: 1199 self.block = block 1200 1201 def deserialize(self, f): 1202 self.block.deserialize(f) 1203 1204 def serialize(self): 1205 return self.block.serialize() 1206 1207 def __repr__(self): 1208 return "msg_block(block=%s)" % (repr(self.block)) 1209 1210 1211# for cases where a user needs tighter control over what is sent over the wire 1212# note that the user must supply the name of the command, and the data 1213class msg_generic: 1214 __slots__ = ("command", "data") 1215 1216 def __init__(self, command, data=None): 1217 self.command = command 1218 self.data = data 1219 1220 def serialize(self): 1221 return self.data 1222 1223 def __repr__(self): 1224 return "msg_generic()" 1225 1226 1227class msg_no_witness_block(msg_block): 1228 __slots__ = () 1229 def serialize(self): 1230 return self.block.serialize(with_witness=False) 1231 1232 1233class msg_getaddr: 1234 __slots__ = () 1235 command = b"getaddr" 1236 1237 def __init__(self): 1238 pass 1239 1240 def deserialize(self, f): 1241 pass 1242 1243 def serialize(self): 1244 return b"" 1245 1246 def __repr__(self): 1247 return "msg_getaddr()" 1248 1249 1250class msg_ping: 1251 __slots__ = ("nonce",) 1252 command = b"ping" 1253 1254 def __init__(self, nonce=0): 1255 self.nonce = nonce 1256 1257 def deserialize(self, f): 1258 self.nonce = struct.unpack("<Q", f.read(8))[0] 1259 1260 def serialize(self): 1261 r = b"" 1262 r += struct.pack("<Q", self.nonce) 1263 return r 1264 1265 def __repr__(self): 1266 return "msg_ping(nonce=%08x)" % self.nonce 1267 1268 1269class msg_pong: 1270 __slots__ = ("nonce",) 1271 command = b"pong" 1272 1273 def __init__(self, nonce=0): 1274 self.nonce = nonce 1275 1276 def deserialize(self, f): 1277 self.nonce = struct.unpack("<Q", f.read(8))[0] 1278 1279 def serialize(self): 1280 r = b"" 1281 r += struct.pack("<Q", self.nonce) 1282 return r 1283 1284 def __repr__(self): 1285 return "msg_pong(nonce=%08x)" % self.nonce 1286 1287 1288class msg_mempool: 1289 __slots__ = () 1290 command = b"mempool" 1291 1292 def __init__(self): 1293 pass 1294 1295 def deserialize(self, f): 1296 pass 1297 1298 def serialize(self): 1299 return b"" 1300 1301 def __repr__(self): 1302 return "msg_mempool()" 1303 1304 1305class msg_notfound: 1306 __slots__ = ("vec", ) 1307 command = b"notfound" 1308 1309 def __init__(self, vec=None): 1310 self.vec = vec or [] 1311 1312 def deserialize(self, f): 1313 self.vec = deser_vector(f, CInv) 1314 1315 def serialize(self): 1316 return ser_vector(self.vec) 1317 1318 def __repr__(self): 1319 return "msg_notfound(vec=%s)" % (repr(self.vec)) 1320 1321 1322class msg_sendheaders: 1323 __slots__ = () 1324 command = b"sendheaders" 1325 1326 def __init__(self): 1327 pass 1328 1329 def deserialize(self, f): 1330 pass 1331 1332 def serialize(self): 1333 return b"" 1334 1335 def __repr__(self): 1336 return "msg_sendheaders()" 1337 1338 1339# getheaders message has 1340# number of entries 1341# vector of hashes 1342# hash_stop (hash of last desired block header, 0 to get as many as possible) 1343class msg_getheaders: 1344 __slots__ = ("hashstop", "locator",) 1345 command = b"getheaders" 1346 1347 def __init__(self): 1348 self.locator = CBlockLocator() 1349 self.hashstop = 0 1350 1351 def deserialize(self, f): 1352 self.locator = CBlockLocator() 1353 self.locator.deserialize(f) 1354 self.hashstop = deser_uint256(f) 1355 1356 def serialize(self): 1357 r = b"" 1358 r += self.locator.serialize() 1359 r += ser_uint256(self.hashstop) 1360 return r 1361 1362 def __repr__(self): 1363 return "msg_getheaders(locator=%s, stop=%064x)" \ 1364 % (repr(self.locator), self.hashstop) 1365 1366 1367# headers message has 1368# <count> <vector of block headers> 1369class msg_headers: 1370 __slots__ = ("headers",) 1371 command = b"headers" 1372 1373 def __init__(self, headers=None): 1374 self.headers = headers if headers is not None else [] 1375 1376 def deserialize(self, f): 1377 # comment in bitcoind indicates these should be deserialized as blocks 1378 blocks = deser_vector(f, CBlock) 1379 for x in blocks: 1380 self.headers.append(CBlockHeader(x)) 1381 1382 def serialize(self): 1383 blocks = [CBlock(x) for x in self.headers] 1384 return ser_vector(blocks) 1385 1386 def __repr__(self): 1387 return "msg_headers(headers=%s)" % repr(self.headers) 1388 1389 1390class msg_merkleblock: 1391 command = b"merkleblock" 1392 1393 def deserialize(self, f): 1394 pass # Placeholder for now 1395 1396 1397class msg_filterload: 1398 __slots__ = ("data", "nHashFuncs", "nTweak", "nFlags") 1399 command = b"filterload" 1400 1401 def __init__(self, data=b'00', nHashFuncs=0, nTweak=0, nFlags=0): 1402 self.data = data 1403 self.nHashFuncs = nHashFuncs 1404 self.nTweak = nTweak 1405 self.nFlags = nFlags 1406 1407 def deserialize(self, f): 1408 self.data = deser_string(f) 1409 self.nHashFuncs = struct.unpack("<I", f.read(4))[0] 1410 self.nTweak = struct.unpack("<I", f.read(4))[0] 1411 self.nFlags = struct.unpack("<B", f.read(1))[0] 1412 1413 def serialize(self): 1414 r = b"" 1415 r += ser_string(self.data) 1416 r += struct.pack("<I", self.nHashFuncs) 1417 r += struct.pack("<I", self.nTweak) 1418 r += struct.pack("<B", self.nFlags) 1419 return r 1420 1421 def __repr__(self): 1422 return "msg_filterload(data={}, nHashFuncs={}, nTweak={}, nFlags={})".format( 1423 self.data, self.nHashFuncs, self.nTweak, self.nFlags) 1424 1425 1426class msg_filteradd: 1427 __slots__ = ("data") 1428 command = b"filteradd" 1429 1430 def __init__(self, data): 1431 self.data = data 1432 1433 def deserialize(self, f): 1434 self.data = deser_string(f) 1435 1436 def serialize(self): 1437 r = b"" 1438 r += ser_string(self.data) 1439 return r 1440 1441 def __repr__(self): 1442 return "msg_filteradd(data={})".format(self.data) 1443 1444 1445class msg_filterclear: 1446 __slots__ = () 1447 command = b"filterclear" 1448 1449 def __init__(self): 1450 pass 1451 1452 def deserialize(self, f): 1453 pass 1454 1455 def serialize(self): 1456 return b"" 1457 1458 def __repr__(self): 1459 return "msg_filterclear()" 1460 1461 1462class msg_feefilter: 1463 __slots__ = ("feerate",) 1464 command = b"feefilter" 1465 1466 def __init__(self, feerate=0): 1467 self.feerate = feerate 1468 1469 def deserialize(self, f): 1470 self.feerate = struct.unpack("<Q", f.read(8))[0] 1471 1472 def serialize(self): 1473 r = b"" 1474 r += struct.pack("<Q", self.feerate) 1475 return r 1476 1477 def __repr__(self): 1478 return "msg_feefilter(feerate=%08x)" % self.feerate 1479 1480 1481class msg_sendcmpct: 1482 __slots__ = ("announce", "version") 1483 command = b"sendcmpct" 1484 1485 def __init__(self): 1486 self.announce = False 1487 self.version = 1 1488 1489 def deserialize(self, f): 1490 self.announce = struct.unpack("<?", f.read(1))[0] 1491 self.version = struct.unpack("<Q", f.read(8))[0] 1492 1493 def serialize(self): 1494 r = b"" 1495 r += struct.pack("<?", self.announce) 1496 r += struct.pack("<Q", self.version) 1497 return r 1498 1499 def __repr__(self): 1500 return "msg_sendcmpct(announce=%s, version=%lu)" % (self.announce, self.version) 1501 1502 1503class msg_cmpctblock: 1504 __slots__ = ("header_and_shortids",) 1505 command = b"cmpctblock" 1506 1507 def __init__(self, header_and_shortids = None): 1508 self.header_and_shortids = header_and_shortids 1509 1510 def deserialize(self, f): 1511 self.header_and_shortids = P2PHeaderAndShortIDs() 1512 self.header_and_shortids.deserialize(f) 1513 1514 def serialize(self): 1515 r = b"" 1516 r += self.header_and_shortids.serialize() 1517 return r 1518 1519 def __repr__(self): 1520 return "msg_cmpctblock(HeaderAndShortIDs=%s)" % repr(self.header_and_shortids) 1521 1522 1523class msg_getblocktxn: 1524 __slots__ = ("block_txn_request",) 1525 command = b"getblocktxn" 1526 1527 def __init__(self): 1528 self.block_txn_request = None 1529 1530 def deserialize(self, f): 1531 self.block_txn_request = BlockTransactionsRequest() 1532 self.block_txn_request.deserialize(f) 1533 1534 def serialize(self): 1535 r = b"" 1536 r += self.block_txn_request.serialize() 1537 return r 1538 1539 def __repr__(self): 1540 return "msg_getblocktxn(block_txn_request=%s)" % (repr(self.block_txn_request)) 1541 1542 1543class msg_blocktxn: 1544 __slots__ = ("block_transactions",) 1545 command = b"blocktxn" 1546 1547 def __init__(self): 1548 self.block_transactions = BlockTransactions() 1549 1550 def deserialize(self, f): 1551 self.block_transactions.deserialize(f) 1552 1553 def serialize(self): 1554 r = b"" 1555 r += self.block_transactions.serialize() 1556 return r 1557 1558 def __repr__(self): 1559 return "msg_blocktxn(block_transactions=%s)" % (repr(self.block_transactions)) 1560 1561 1562class msg_no_witness_blocktxn(msg_blocktxn): 1563 __slots__ = () 1564 1565 def serialize(self): 1566 return self.block_transactions.serialize(with_witness=False) 1567