messages.py raw
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-present 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
9 CBlock, CTransaction, CBlockHeader, CTxIn, CTxOut, etc....:
10 data structures that should map to corresponding structures in
11 bitcoin/primitives
12
13 msg_block, msg_tx, msg_headers, etc.:
14 data structures that represent network messages
15
16 ser_*, deser_*: functions that handle serialization/deserialization.
17
18 Classes use __slots__ to ensure extraneous attributes aren't accidentally added
19 by tests, compromising their intended effect.
20 """
21 from base64 import b32decode, b32encode
22 import copy
23 import hashlib
24 from io import BytesIO
25 import math
26 import random
27 import socket
28 import time
29 import unittest
30
31 from test_framework.crypto.siphash import siphash256
32 from test_framework.util import (
33 assert_equal,
34 assert_not_equal,
35 )
36
37 MAX_LOCATOR_SZ = 101
38 MAX_BLOCK_WEIGHT = 4000000
39 MAX_BLOCK_SIGOPS_COST = 80000
40 DEFAULT_BLOCK_RESERVED_WEIGHT = 8000
41 MINIMUM_BLOCK_RESERVED_WEIGHT = 2000
42 MAX_BLOOM_FILTER_SIZE = 36000
43 MAX_BLOOM_HASH_FUNCS = 50
44
45 COIN = 100000000 # 1 btc in satoshis
46 MAX_MONEY = 21000000 * COIN
47
48 MAX_BIP125_RBF_SEQUENCE = 0xfffffffd # Sequence number that is rbf-opt-in (BIP 125) and csv-opt-out (BIP 68)
49 MAX_SEQUENCE_NONFINAL = 0xfffffffe # Sequence number that is csv-opt-out (BIP 68)
50 SEQUENCE_FINAL = 0xffffffff # Sequence number that disables nLockTime if set for every input of a tx
51
52 MAX_PROTOCOL_MESSAGE_LENGTH = 4000000 # Maximum length of incoming protocol messages
53 MAX_HEADERS_RESULTS = 2000 # Number of headers sent in one getheaders result
54 MAX_INV_SIZE = 50000 # Maximum number of entries in an 'inv' protocol message
55
56 NODE_NONE = 0
57 NODE_NETWORK = (1 << 0)
58 NODE_BLOOM = (1 << 2)
59 NODE_WITNESS = (1 << 3)
60 NODE_COMPACT_FILTERS = (1 << 6)
61 NODE_NETWORK_LIMITED = (1 << 10)
62 NODE_P2P_V2 = (1 << 11)
63
64 MSG_TX = 1
65 MSG_BLOCK = 2
66 MSG_FILTERED_BLOCK = 3
67 MSG_CMPCT_BLOCK = 4
68 MSG_WTX = 5
69 MSG_WITNESS_FLAG = 1 << 30
70 MSG_TYPE_MASK = 0xffffffff >> 2
71 MSG_WITNESS_TX = MSG_TX | MSG_WITNESS_FLAG
72
73 FILTER_TYPE_BASIC = 0
74
75 WITNESS_SCALE_FACTOR = 4
76
77 DEFAULT_ANCESTOR_LIMIT = 25 # default max number of in-mempool ancestors
78 DEFAULT_DESCENDANT_LIMIT = 25 # default max number of in-mempool descendants
79 DEFAULT_CLUSTER_LIMIT = 64 # default max number of transactions in a cluster
80
81
82 # Default setting for -datacarriersize.
83 MAX_OP_RETURN_RELAY = 100_000
84
85
86 DEFAULT_MEMPOOL_EXPIRY_HOURS = 336 # hours
87
88 TX_MIN_STANDARD_VERSION = 1
89 TX_MAX_STANDARD_VERSION = 3
90
91 MAGIC_BYTES = {
92 "mainnet": b"\xf9\xbe\xb4\xd9",
93 "testnet4": b"\x1c\x16\x3f\x28",
94 "regtest": b"\xfa\xbf\xb5\xda",
95 "signet": b"\x0a\x03\xcf\x40",
96 }
97
98 def sha256(s):
99 return hashlib.sha256(s).digest()
100
101
102 def sha3(s):
103 return hashlib.sha3_256(s).digest()
104
105
106 def hash256(s):
107 return sha256(sha256(s))
108
109
110 def ser_compact_size(l):
111 r = b""
112 if l < 253:
113 r = l.to_bytes(1, "little")
114 elif l < 0x10000:
115 r = (253).to_bytes(1, "little") + l.to_bytes(2, "little")
116 elif l < 0x100000000:
117 r = (254).to_bytes(1, "little") + l.to_bytes(4, "little")
118 else:
119 r = (255).to_bytes(1, "little") + l.to_bytes(8, "little")
120 return r
121
122
123 def deser_compact_size(f):
124 nit = int.from_bytes(f.read(1), "little")
125 if nit == 253:
126 nit = int.from_bytes(f.read(2), "little")
127 elif nit == 254:
128 nit = int.from_bytes(f.read(4), "little")
129 elif nit == 255:
130 nit = int.from_bytes(f.read(8), "little")
131 return nit
132
133
134 def ser_varint(l):
135 r = b""
136 while True:
137 r = bytes([(l & 0x7f) | (0x80 if len(r) > 0 else 0x00)]) + r
138 if l <= 0x7f:
139 return r
140 l = (l >> 7) - 1
141
142
143 def deser_varint(f):
144 n = 0
145 while True:
146 dat = f.read(1)[0]
147 n = (n << 7) | (dat & 0x7f)
148 if (dat & 0x80) > 0:
149 n += 1
150 else:
151 return n
152
153
154 def deser_string(f):
155 nit = deser_compact_size(f)
156 return f.read(nit)
157
158
159 def ser_string(s):
160 return ser_compact_size(len(s)) + s
161
162
163 def deser_uint256(f):
164 return int.from_bytes(f.read(32), 'little')
165
166
167 def ser_uint256(u):
168 return u.to_bytes(32, 'little')
169
170
171 def uint256_from_str(s):
172 return int.from_bytes(s[:32], 'little')
173
174
175 def uint256_from_compact(c):
176 nbytes = (c >> 24) & 0xFF
177 v = (c & 0xFFFFFF) << (8 * (nbytes - 3))
178 return v
179
180
181 # deser_function_name: Allow for an alternate deserialization function on the
182 # entries in the vector.
183 def deser_vector(f, c, deser_function_name=None):
184 nit = deser_compact_size(f)
185 r = []
186 for _ in range(nit):
187 t = c()
188 if deser_function_name:
189 getattr(t, deser_function_name)(f)
190 else:
191 t.deserialize(f)
192 r.append(t)
193 return r
194
195
196 # ser_function_name: Allow for an alternate serialization function on the
197 # entries in the vector (we use this for serializing the vector of transactions
198 # for a witness block).
199 def ser_vector(l, ser_function_name=None):
200 r = ser_compact_size(len(l))
201 for i in l:
202 if ser_function_name:
203 r += getattr(i, ser_function_name)()
204 else:
205 r += i.serialize()
206 return r
207
208
209 def deser_uint256_vector(f):
210 nit = deser_compact_size(f)
211 r = []
212 for _ in range(nit):
213 t = deser_uint256(f)
214 r.append(t)
215 return r
216
217
218 def ser_uint256_vector(l):
219 r = ser_compact_size(len(l))
220 for i in l:
221 r += ser_uint256(i)
222 return r
223
224
225 def deser_string_vector(f):
226 nit = deser_compact_size(f)
227 r = []
228 for _ in range(nit):
229 t = deser_string(f)
230 r.append(t)
231 return r
232
233
234 def ser_string_vector(l):
235 r = ser_compact_size(len(l))
236 for sv in l:
237 r += ser_string(sv)
238 return r
239
240
241 def deser_block_spent_outputs(f):
242 nit = deser_compact_size(f)
243 return [deser_vector(f, CTxOut) for _ in range(nit)]
244
245
246 def from_hex(obj, hex_string):
247 """Deserialize from a hex string representation (e.g. from RPC)
248
249 Note that there is no complementary helper like e.g. `to_hex` for the
250 inverse operation. To serialize a message object to a hex string, simply
251 use obj.serialize().hex()"""
252 obj.deserialize(BytesIO(bytes.fromhex(hex_string)))
253 return obj
254
255
256 def tx_from_hex(hex_string):
257 """Deserialize from hex string to a transaction object"""
258 return from_hex(CTransaction(), hex_string)
259
260
261 def malleate_tx_to_invalid_witness(tx):
262 """
263 Create a malleated version of the tx where the witness is replaced with garbage data.
264 Returns a CTransaction object.
265 """
266 tx_bad_wit = tx_from_hex(tx["hex"])
267 tx_bad_wit.wit.vtxinwit = [CTxInWitness()]
268 # Add garbage data to witness 0. We cannot simply strip the witness, as the node would
269 # classify it as a transaction in which the witness was missing rather than wrong.
270 tx_bad_wit.wit.vtxinwit[0].scriptWitness.stack = [b'garbage']
271
272 assert_equal(tx["txid"], tx_bad_wit.txid_hex)
273 assert_not_equal(tx["wtxid"], tx_bad_wit.wtxid_hex)
274
275 return tx_bad_wit
276
277
278 # like from_hex, but without the hex part
279 def from_binary(cls, stream):
280 """deserialize a binary stream (or bytes object) into an object"""
281 # handle bytes object by turning it into a stream
282 was_bytes = isinstance(stream, bytes)
283 if was_bytes:
284 stream = BytesIO(stream)
285 obj = cls()
286 obj.deserialize(stream)
287 if was_bytes:
288 assert_equal(len(stream.read()), 0)
289 return obj
290
291
292 # Objects that map to bitcoind objects, which can be serialized/deserialized
293
294
295 class CAddress:
296 __slots__ = ("net", "ip", "nServices", "port", "time")
297
298 # see https://github.com/bitcoin/bips/blob/master/bip-0155.mediawiki
299 NET_IPV4 = 1
300 NET_IPV6 = 2
301 NET_TORV3 = 4
302 NET_I2P = 5
303 NET_CJDNS = 6
304
305 ADDRV2_NET_NAME = {
306 NET_IPV4: "IPv4",
307 NET_IPV6: "IPv6",
308 NET_TORV3: "TorV3",
309 NET_I2P: "I2P",
310 NET_CJDNS: "CJDNS"
311 }
312
313 ADDRV2_ADDRESS_LENGTH = {
314 NET_IPV4: 4,
315 NET_IPV6: 16,
316 NET_TORV3: 32,
317 NET_I2P: 32,
318 NET_CJDNS: 16
319 }
320
321 I2P_PAD = "===="
322
323 def __init__(self):
324 self.time = 0
325 self.nServices = 1
326 self.net = self.NET_IPV4
327 self.ip = "0.0.0.0"
328 self.port = 0
329
330 def __eq__(self, other):
331 return self.net == other.net and self.ip == other.ip and self.nServices == other.nServices and self.port == other.port and self.time == other.time
332
333 def deserialize(self, f, *, with_time=True):
334 """Deserialize from addrv1 format (pre-BIP155)"""
335 if with_time:
336 # VERSION messages serialize CAddress objects without time
337 self.time = int.from_bytes(f.read(4), "little")
338 self.nServices = int.from_bytes(f.read(8), "little")
339 # We only support IPv4 which means skip 12 bytes and read the next 4 as IPv4 address.
340 f.read(12)
341 self.net = self.NET_IPV4
342 self.ip = socket.inet_ntoa(f.read(4))
343 self.port = int.from_bytes(f.read(2), "big")
344
345 def serialize(self, *, with_time=True):
346 """Serialize in addrv1 format (pre-BIP155)"""
347 assert_equal(self.net, self.NET_IPV4)
348 r = b""
349 if with_time:
350 # VERSION messages serialize CAddress objects without time
351 r += self.time.to_bytes(4, "little")
352 r += self.nServices.to_bytes(8, "little")
353 r += b"\x00" * 10 + b"\xff" * 2
354 r += socket.inet_aton(self.ip)
355 r += self.port.to_bytes(2, "big")
356 return r
357
358 def deserialize_v2(self, f):
359 """Deserialize from addrv2 format (BIP155)"""
360 self.time = int.from_bytes(f.read(4), "little")
361
362 self.nServices = deser_compact_size(f)
363
364 self.net = int.from_bytes(f.read(1), "little")
365 assert self.net in self.ADDRV2_NET_NAME
366
367 address_length = deser_compact_size(f)
368 assert_equal(address_length, self.ADDRV2_ADDRESS_LENGTH[self.net])
369
370 addr_bytes = f.read(address_length)
371 if self.net == self.NET_IPV4:
372 self.ip = socket.inet_ntoa(addr_bytes)
373 elif self.net == self.NET_IPV6:
374 self.ip = socket.inet_ntop(socket.AF_INET6, addr_bytes)
375 elif self.net == self.NET_TORV3:
376 prefix = b".onion checksum"
377 version = bytes([3])
378 checksum = sha3(prefix + addr_bytes + version)[:2]
379 self.ip = b32encode(addr_bytes + checksum + version).decode("ascii").lower() + ".onion"
380 elif self.net == self.NET_I2P:
381 self.ip = b32encode(addr_bytes)[0:-len(self.I2P_PAD)].decode("ascii").lower() + ".b32.i2p"
382 elif self.net == self.NET_CJDNS:
383 self.ip = socket.inet_ntop(socket.AF_INET6, addr_bytes)
384 else:
385 raise Exception("Address type not supported")
386
387 self.port = int.from_bytes(f.read(2), "big")
388
389 def serialize_v2(self):
390 """Serialize in addrv2 format (BIP155)"""
391 assert self.net in self.ADDRV2_NET_NAME
392 r = b""
393 r += self.time.to_bytes(4, "little")
394 r += ser_compact_size(self.nServices)
395 r += self.net.to_bytes(1, "little")
396 r += ser_compact_size(self.ADDRV2_ADDRESS_LENGTH[self.net])
397 if self.net == self.NET_IPV4:
398 r += socket.inet_aton(self.ip)
399 elif self.net == self.NET_IPV6:
400 r += socket.inet_pton(socket.AF_INET6, self.ip)
401 elif self.net == self.NET_TORV3:
402 sfx = ".onion"
403 assert self.ip.endswith(sfx)
404 r += b32decode(self.ip[0:-len(sfx)], True)[0:32]
405 elif self.net == self.NET_I2P:
406 sfx = ".b32.i2p"
407 assert self.ip.endswith(sfx)
408 r += b32decode(self.ip[0:-len(sfx)] + self.I2P_PAD, True)
409 elif self.net == self.NET_CJDNS:
410 r += socket.inet_pton(socket.AF_INET6, self.ip)
411 else:
412 raise Exception("Address type not supported")
413 r += self.port.to_bytes(2, "big")
414 return r
415
416 def __repr__(self):
417 return ("CAddress(nServices=%i net=%s addr=%s port=%i)"
418 % (self.nServices, self.ADDRV2_NET_NAME[self.net], self.ip, self.port))
419
420
421 class CInv:
422 __slots__ = ("hash", "type")
423
424 typemap = {
425 0: "Error",
426 MSG_TX: "TX",
427 MSG_BLOCK: "Block",
428 MSG_TX | MSG_WITNESS_FLAG: "WitnessTx",
429 MSG_BLOCK | MSG_WITNESS_FLAG: "WitnessBlock",
430 MSG_FILTERED_BLOCK: "filtered Block",
431 MSG_CMPCT_BLOCK: "CompactBlock",
432 MSG_WTX: "WTX",
433 }
434
435 def __init__(self, t=0, h=0):
436 self.type = t
437 self.hash = h
438
439 def deserialize(self, f):
440 self.type = int.from_bytes(f.read(4), "little")
441 self.hash = deser_uint256(f)
442
443 def serialize(self):
444 r = b""
445 r += self.type.to_bytes(4, "little")
446 r += ser_uint256(self.hash)
447 return r
448
449 def __repr__(self):
450 return "CInv(type=%s hash=%064x)" \
451 % (self.typemap[self.type], self.hash)
452
453 def __eq__(self, other):
454 return isinstance(other, CInv) and self.hash == other.hash and self.type == other.type
455
456
457 class CBlockLocator:
458 __slots__ = ("nVersion", "vHave")
459
460 def __init__(self):
461 self.vHave = []
462
463 def deserialize(self, f):
464 int.from_bytes(f.read(4), "little", signed=True) # Ignore version field.
465 self.vHave = deser_uint256_vector(f)
466
467 def serialize(self):
468 r = b""
469 r += (0).to_bytes(4, "little", signed=True) # Bitcoin Core ignores the version field. Set it to 0.
470 r += ser_uint256_vector(self.vHave)
471 return r
472
473 def __repr__(self):
474 return "CBlockLocator(vHave=%s)" % (repr(self.vHave))
475
476
477 class COutPoint:
478 __slots__ = ("hash", "n")
479
480 def __init__(self, hash=0, n=0):
481 self.hash = hash
482 self.n = n
483
484 def deserialize(self, f):
485 self.hash = deser_uint256(f)
486 self.n = int.from_bytes(f.read(4), "little")
487
488 def serialize(self):
489 r = b""
490 r += ser_uint256(self.hash)
491 r += self.n.to_bytes(4, "little")
492 return r
493
494 def __repr__(self):
495 return "COutPoint(hash=%064x n=%i)" % (self.hash, self.n)
496
497
498 class CTxIn:
499 __slots__ = ("nSequence", "prevout", "scriptSig")
500
501 def __init__(self, outpoint=None, scriptSig=b"", nSequence=0):
502 if outpoint is None:
503 self.prevout = COutPoint()
504 else:
505 self.prevout = outpoint
506 self.scriptSig = scriptSig
507 self.nSequence = nSequence
508
509 def deserialize(self, f):
510 self.prevout = COutPoint()
511 self.prevout.deserialize(f)
512 self.scriptSig = deser_string(f)
513 self.nSequence = int.from_bytes(f.read(4), "little")
514
515 def serialize(self):
516 r = b""
517 r += self.prevout.serialize()
518 r += ser_string(self.scriptSig)
519 r += self.nSequence.to_bytes(4, "little")
520 return r
521
522 def __repr__(self):
523 return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \
524 % (repr(self.prevout), self.scriptSig.hex(),
525 self.nSequence)
526
527
528 class CTxOut:
529 __slots__ = ("nValue", "scriptPubKey")
530
531 def __init__(self, nValue=0, scriptPubKey=b""):
532 self.nValue = nValue
533 self.scriptPubKey = scriptPubKey
534
535 def deserialize(self, f):
536 self.nValue = int.from_bytes(f.read(8), "little", signed=True)
537 self.scriptPubKey = deser_string(f)
538
539 def serialize(self):
540 r = b""
541 r += self.nValue.to_bytes(8, "little", signed=True)
542 r += ser_string(self.scriptPubKey)
543 return r
544
545 def __repr__(self):
546 return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \
547 % (self.nValue // COIN, self.nValue % COIN,
548 self.scriptPubKey.hex())
549
550
551 class CScriptWitness:
552 __slots__ = ("stack",)
553
554 def __init__(self):
555 # stack is a vector of strings
556 self.stack = []
557
558 def __repr__(self):
559 return "CScriptWitness(%s)" % \
560 (",".join([x.hex() for x in self.stack]))
561
562 def is_null(self):
563 if self.stack:
564 return False
565 return True
566
567
568 class CTxInWitness:
569 __slots__ = ("scriptWitness",)
570
571 def __init__(self):
572 self.scriptWitness = CScriptWitness()
573
574 def deserialize(self, f):
575 self.scriptWitness.stack = deser_string_vector(f)
576
577 def serialize(self):
578 return ser_string_vector(self.scriptWitness.stack)
579
580 def __repr__(self):
581 return repr(self.scriptWitness)
582
583 def is_null(self):
584 return self.scriptWitness.is_null()
585
586
587 class CTxWitness:
588 __slots__ = ("vtxinwit",)
589
590 def __init__(self):
591 self.vtxinwit = []
592
593 def deserialize(self, f):
594 for i in range(len(self.vtxinwit)):
595 self.vtxinwit[i].deserialize(f)
596
597 def serialize(self):
598 r = b""
599 # This is different than the usual vector serialization --
600 # we omit the length of the vector, which is required to be
601 # the same length as the transaction's vin vector.
602 for x in self.vtxinwit:
603 r += x.serialize()
604 return r
605
606 def __repr__(self):
607 return "CTxWitness(%s)" % \
608 (';'.join([repr(x) for x in self.vtxinwit]))
609
610 def is_null(self):
611 for x in self.vtxinwit:
612 if not x.is_null():
613 return False
614 return True
615
616
617 class CTransaction:
618 __slots__ = ("nLockTime", "version", "vin", "vout", "wit")
619
620 def __init__(self, tx=None):
621 if tx is None:
622 self.version = 2
623 self.vin = []
624 self.vout = []
625 self.wit = CTxWitness()
626 self.nLockTime = 0
627 else:
628 self.version = tx.version
629 self.vin = copy.deepcopy(tx.vin)
630 self.vout = copy.deepcopy(tx.vout)
631 self.nLockTime = tx.nLockTime
632 self.wit = copy.deepcopy(tx.wit)
633
634 def deserialize(self, f):
635 self.version = int.from_bytes(f.read(4), "little")
636 self.vin = deser_vector(f, CTxIn)
637 flags = 0
638 if len(self.vin) == 0:
639 flags = int.from_bytes(f.read(1), "little")
640 # Not sure why flags can't be zero, but this
641 # matches the implementation in bitcoind
642 if (flags != 0):
643 self.vin = deser_vector(f, CTxIn)
644 self.vout = deser_vector(f, CTxOut)
645 else:
646 self.vout = deser_vector(f, CTxOut)
647 if flags != 0:
648 self.wit.vtxinwit = [CTxInWitness() for _ in range(len(self.vin))]
649 self.wit.deserialize(f)
650 else:
651 self.wit = CTxWitness()
652 self.nLockTime = int.from_bytes(f.read(4), "little")
653
654 def serialize_without_witness(self):
655 r = b""
656 r += self.version.to_bytes(4, "little")
657 r += ser_vector(self.vin)
658 r += ser_vector(self.vout)
659 r += self.nLockTime.to_bytes(4, "little")
660 return r
661
662 # Only serialize with witness when explicitly called for
663 def serialize_with_witness(self):
664 flags = 0
665 if not self.wit.is_null():
666 flags |= 1
667 r = b""
668 r += self.version.to_bytes(4, "little")
669 if flags:
670 dummy = []
671 r += ser_vector(dummy)
672 r += flags.to_bytes(1, "little")
673 r += ser_vector(self.vin)
674 r += ser_vector(self.vout)
675 if flags & 1:
676 if (len(self.wit.vtxinwit) != len(self.vin)):
677 # vtxinwit must have the same length as vin
678 self.wit.vtxinwit = self.wit.vtxinwit[:len(self.vin)]
679 for _ in range(len(self.wit.vtxinwit), len(self.vin)):
680 self.wit.vtxinwit.append(CTxInWitness())
681 r += self.wit.serialize()
682 r += self.nLockTime.to_bytes(4, "little")
683 return r
684
685 # Regular serialization is with witness -- must explicitly
686 # call serialize_without_witness to exclude witness data.
687 def serialize(self):
688 return self.serialize_with_witness()
689
690 @property
691 def wtxid(self):
692 """Return wtxid (transaction hash with witness) as little-endian bytes."""
693 return hash256(self.serialize_with_witness())
694
695 @property
696 def wtxid_hex(self):
697 """Return wtxid (transaction hash with witness) as hex string."""
698 return self.wtxid[::-1].hex()
699
700 @property
701 def wtxid_int(self):
702 """Return wtxid (transaction hash with witness) as integer."""
703 return uint256_from_str(self.wtxid)
704
705 @property
706 def txid(self):
707 """Return txid (transaction hash without witness) as little-endian bytes."""
708 return hash256(self.serialize_without_witness())
709
710 @property
711 def txid_hex(self):
712 """Return txid (transaction hash without witness) as hex string."""
713 return self.txid[::-1].hex()
714
715 @property
716 def txid_int(self):
717 """Return txid (transaction hash without witness) as integer."""
718 return uint256_from_str(self.txid)
719
720 def is_valid(self):
721 for tout in self.vout:
722 if tout.nValue < 0 or tout.nValue > 21000000 * COIN:
723 return False
724 return True
725
726 # Calculate the transaction weight using witness and non-witness
727 # serialization size (does NOT use sigops).
728 def get_weight(self):
729 with_witness_size = len(self.serialize_with_witness())
730 without_witness_size = len(self.serialize_without_witness())
731 return (WITNESS_SCALE_FACTOR - 1) * without_witness_size + with_witness_size
732
733 def get_vsize(self):
734 return math.ceil(self.get_weight() / WITNESS_SCALE_FACTOR)
735
736 def __repr__(self):
737 return "CTransaction(version=%i vin=%s vout=%s wit=%s nLockTime=%i)" \
738 % (self.version, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime)
739
740
741 class CBlockHeader:
742 __slots__ = ("hashMerkleRoot", "hashPrevBlock", "nBits", "nNonce",
743 "nTime", "nVersion")
744
745 def __init__(self, header=None):
746 if header is None:
747 self.set_null()
748 else:
749 self.nVersion = header.nVersion
750 self.hashPrevBlock = header.hashPrevBlock
751 self.hashMerkleRoot = header.hashMerkleRoot
752 self.nTime = header.nTime
753 self.nBits = header.nBits
754 self.nNonce = header.nNonce
755
756 def set_null(self):
757 self.nVersion = 4
758 self.hashPrevBlock = 0
759 self.hashMerkleRoot = 0
760 self.nTime = 0
761 self.nBits = 0
762 self.nNonce = 0
763
764 def deserialize(self, f):
765 self.nVersion = int.from_bytes(f.read(4), "little", signed=True)
766 self.hashPrevBlock = deser_uint256(f)
767 self.hashMerkleRoot = deser_uint256(f)
768 self.nTime = int.from_bytes(f.read(4), "little")
769 self.nBits = int.from_bytes(f.read(4), "little")
770 self.nNonce = int.from_bytes(f.read(4), "little")
771
772 def serialize(self):
773 return self._serialize_header()
774
775 def _serialize_header(self):
776 r = b""
777 r += self.nVersion.to_bytes(4, "little", signed=True)
778 r += ser_uint256(self.hashPrevBlock)
779 r += ser_uint256(self.hashMerkleRoot)
780 r += self.nTime.to_bytes(4, "little")
781 r += self.nBits.to_bytes(4, "little")
782 r += self.nNonce.to_bytes(4, "little")
783 return r
784
785 @property
786 def hash_hex(self):
787 """Return block header hash as hex string."""
788 return hash256(self._serialize_header())[::-1].hex()
789
790 @property
791 def hash_int(self):
792 """Return block header hash as integer."""
793 return uint256_from_str(hash256(self._serialize_header()))
794
795 def __repr__(self):
796 return "CBlockHeader(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x)" \
797 % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot,
798 time.ctime(self.nTime), self.nBits, self.nNonce)
799
800 BLOCK_HEADER_SIZE = len(CBlockHeader().serialize())
801 assert_equal(BLOCK_HEADER_SIZE, 80)
802
803 class CBlock(CBlockHeader):
804 __slots__ = ("vtx",)
805
806 def __init__(self, header=None):
807 super().__init__(header)
808 self.vtx = []
809
810 def deserialize(self, f):
811 super().deserialize(f)
812 self.vtx = deser_vector(f, CTransaction)
813
814 def serialize(self, with_witness=True):
815 r = b""
816 r += super().serialize()
817 if with_witness:
818 r += ser_vector(self.vtx, "serialize_with_witness")
819 else:
820 r += ser_vector(self.vtx, "serialize_without_witness")
821 return r
822
823 # Calculate the merkle root given a vector of transaction hashes
824 @classmethod
825 def get_merkle_root(cls, hashes):
826 while len(hashes) > 1:
827 newhashes = []
828 for i in range(0, len(hashes), 2):
829 i2 = min(i+1, len(hashes)-1)
830 newhashes.append(hash256(hashes[i] + hashes[i2]))
831 hashes = newhashes
832 return uint256_from_str(hashes[0])
833
834 def calc_merkle_root(self):
835 hashes = []
836 for tx in self.vtx:
837 hashes.append(ser_uint256(tx.txid_int))
838 return self.get_merkle_root(hashes)
839
840 def calc_witness_merkle_root(self):
841 # For witness root purposes, the hash of the
842 # coinbase, with witness, is defined to be 0...0
843 hashes = [ser_uint256(0)]
844
845 for tx in self.vtx[1:]:
846 # Calculate the hashes with witness data
847 hashes.append(ser_uint256(tx.wtxid_int))
848
849 return self.get_merkle_root(hashes)
850
851 def is_valid(self):
852 target = uint256_from_compact(self.nBits)
853 if self.hash_int > target:
854 return False
855 for tx in self.vtx:
856 if not tx.is_valid():
857 return False
858 if self.calc_merkle_root() != self.hashMerkleRoot:
859 return False
860 return True
861
862 def solve(self):
863 target = uint256_from_compact(self.nBits)
864 while self.hash_int > target:
865 self.nNonce += 1
866
867 # Calculate the block weight using witness and non-witness
868 # serialization size (does NOT use sigops).
869 def get_weight(self):
870 with_witness_size = len(self.serialize(with_witness=True))
871 without_witness_size = len(self.serialize(with_witness=False))
872 return (WITNESS_SCALE_FACTOR - 1) * without_witness_size + with_witness_size
873
874 def __repr__(self):
875 return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" \
876 % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot,
877 time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx))
878
879
880 class PrefilledTransaction:
881 __slots__ = ("index", "tx")
882
883 def __init__(self, index=0, tx = None):
884 self.index = index
885 self.tx = tx
886
887 def deserialize(self, f):
888 self.index = deser_compact_size(f)
889 self.tx = CTransaction()
890 self.tx.deserialize(f)
891
892 def serialize(self, with_witness=True):
893 r = b""
894 r += ser_compact_size(self.index)
895 if with_witness:
896 r += self.tx.serialize_with_witness()
897 else:
898 r += self.tx.serialize_without_witness()
899 return r
900
901 def serialize_without_witness(self):
902 return self.serialize(with_witness=False)
903
904 def serialize_with_witness(self):
905 return self.serialize(with_witness=True)
906
907 def __repr__(self):
908 return "PrefilledTransaction(index=%d, tx=%s)" % (self.index, repr(self.tx))
909
910
911 # This is what we send on the wire, in a cmpctblock message.
912 class P2PHeaderAndShortIDs:
913 __slots__ = ("header", "nonce", "prefilled_txn", "prefilled_txn_length",
914 "shortids", "shortids_length")
915
916 def __init__(self):
917 self.header = CBlockHeader()
918 self.nonce = 0
919 self.shortids_length = 0
920 self.shortids = []
921 self.prefilled_txn_length = 0
922 self.prefilled_txn = []
923
924 def deserialize(self, f):
925 self.header.deserialize(f)
926 self.nonce = int.from_bytes(f.read(8), "little")
927 self.shortids_length = deser_compact_size(f)
928 for _ in range(self.shortids_length):
929 # shortids are defined to be 6 bytes in the spec, so append
930 # two zero bytes and read it in as an 8-byte number
931 self.shortids.append(int.from_bytes(f.read(6) + b'\x00\x00', "little"))
932 self.prefilled_txn = deser_vector(f, PrefilledTransaction)
933 self.prefilled_txn_length = len(self.prefilled_txn)
934
935 # When using version 2 compact blocks, we must serialize with_witness.
936 def serialize(self, with_witness=False):
937 r = b""
938 r += self.header.serialize()
939 r += self.nonce.to_bytes(8, "little")
940 r += ser_compact_size(self.shortids_length)
941 for x in self.shortids:
942 # We only want the first 6 bytes
943 r += x.to_bytes(8, "little")[0:6]
944 if with_witness:
945 r += ser_vector(self.prefilled_txn, "serialize_with_witness")
946 else:
947 r += ser_vector(self.prefilled_txn, "serialize_without_witness")
948 return r
949
950 def __repr__(self):
951 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))
952
953
954 # P2P version of the above that will use witness serialization (for compact
955 # block version 2)
956 class P2PHeaderAndShortWitnessIDs(P2PHeaderAndShortIDs):
957 __slots__ = ()
958 def serialize(self):
959 return super().serialize(with_witness=True)
960
961 # Calculate the BIP 152-compact blocks shortid for a given transaction hash
962 def calculate_shortid(k0, k1, tx_hash):
963 expected_shortid = siphash256(k0, k1, tx_hash)
964 expected_shortid &= 0x0000ffffffffffff
965 return expected_shortid
966
967
968 # This version gets rid of the array lengths, and reinterprets the differential
969 # encoding into indices that can be used for lookup.
970 class HeaderAndShortIDs:
971 __slots__ = ("header", "nonce", "prefilled_txn", "shortids", "use_witness")
972
973 def __init__(self, p2pheaders_and_shortids = None):
974 self.header = CBlockHeader()
975 self.nonce = 0
976 self.shortids = []
977 self.prefilled_txn = []
978 self.use_witness = False
979
980 if p2pheaders_and_shortids is not None:
981 self.header = p2pheaders_and_shortids.header
982 self.nonce = p2pheaders_and_shortids.nonce
983 self.shortids = p2pheaders_and_shortids.shortids
984 last_index = -1
985 for x in p2pheaders_and_shortids.prefilled_txn:
986 self.prefilled_txn.append(PrefilledTransaction(x.index + last_index + 1, x.tx))
987 last_index = self.prefilled_txn[-1].index
988
989 def to_p2p(self):
990 if self.use_witness:
991 ret = P2PHeaderAndShortWitnessIDs()
992 else:
993 ret = P2PHeaderAndShortIDs()
994 ret.header = self.header
995 ret.nonce = self.nonce
996 ret.shortids_length = len(self.shortids)
997 ret.shortids = self.shortids
998 ret.prefilled_txn_length = len(self.prefilled_txn)
999 ret.prefilled_txn = []
1000 last_index = -1
1001 for x in self.prefilled_txn:
1002 ret.prefilled_txn.append(PrefilledTransaction(x.index - last_index - 1, x.tx))
1003 last_index = x.index
1004 return ret
1005
1006 def get_siphash_keys(self):
1007 header_nonce = self.header.serialize()
1008 header_nonce += self.nonce.to_bytes(8, "little")
1009 hash_header_nonce_as_str = sha256(header_nonce)
1010 key0 = int.from_bytes(hash_header_nonce_as_str[0:8], "little")
1011 key1 = int.from_bytes(hash_header_nonce_as_str[8:16], "little")
1012 return [ key0, key1 ]
1013
1014 # Version 2 compact blocks use wtxid in shortids (rather than txid)
1015 def initialize_from_block(self, block, nonce=0, prefill_list=None, use_witness=False):
1016 if prefill_list is None:
1017 prefill_list = [0]
1018 self.header = CBlockHeader(block)
1019 self.nonce = nonce
1020 self.prefilled_txn = [ PrefilledTransaction(i, block.vtx[i]) for i in prefill_list ]
1021 self.shortids = []
1022 self.use_witness = use_witness
1023 [k0, k1] = self.get_siphash_keys()
1024 for i in range(len(block.vtx)):
1025 if i not in prefill_list:
1026 tx_hash = block.vtx[i].txid_int
1027 if use_witness:
1028 tx_hash = block.vtx[i].wtxid_int
1029 self.shortids.append(calculate_shortid(k0, k1, tx_hash))
1030
1031 def __repr__(self):
1032 return "HeaderAndShortIDs(header=%s, nonce=%d, shortids=%s, prefilledtxn=%s" % (repr(self.header), self.nonce, repr(self.shortids), repr(self.prefilled_txn))
1033
1034
1035 class BlockTransactionsRequest:
1036 __slots__ = ("blockhash", "indexes")
1037
1038 def __init__(self, blockhash=0, indexes = None):
1039 self.blockhash = blockhash
1040 self.indexes = indexes if indexes is not None else []
1041
1042 def deserialize(self, f):
1043 self.blockhash = deser_uint256(f)
1044 indexes_length = deser_compact_size(f)
1045 for _ in range(indexes_length):
1046 self.indexes.append(deser_compact_size(f))
1047
1048 def serialize(self):
1049 r = b""
1050 r += ser_uint256(self.blockhash)
1051 r += ser_compact_size(len(self.indexes))
1052 for x in self.indexes:
1053 r += ser_compact_size(x)
1054 return r
1055
1056 # helper to set the differentially encoded indexes from absolute ones
1057 def from_absolute(self, absolute_indexes):
1058 self.indexes = []
1059 last_index = -1
1060 for x in absolute_indexes:
1061 self.indexes.append(x-last_index-1)
1062 last_index = x
1063
1064 def to_absolute(self):
1065 absolute_indexes = []
1066 last_index = -1
1067 for x in self.indexes:
1068 absolute_indexes.append(x+last_index+1)
1069 last_index = absolute_indexes[-1]
1070 return absolute_indexes
1071
1072 def __repr__(self):
1073 return "BlockTransactionsRequest(hash=%064x indexes=%s)" % (self.blockhash, repr(self.indexes))
1074
1075
1076 class BlockTransactions:
1077 __slots__ = ("blockhash", "transactions")
1078
1079 def __init__(self, blockhash=0, transactions = None):
1080 self.blockhash = blockhash
1081 self.transactions = transactions if transactions is not None else []
1082
1083 def deserialize(self, f):
1084 self.blockhash = deser_uint256(f)
1085 self.transactions = deser_vector(f, CTransaction)
1086
1087 def serialize(self, with_witness=True):
1088 r = b""
1089 r += ser_uint256(self.blockhash)
1090 if with_witness:
1091 r += ser_vector(self.transactions, "serialize_with_witness")
1092 else:
1093 r += ser_vector(self.transactions, "serialize_without_witness")
1094 return r
1095
1096 def __repr__(self):
1097 return "BlockTransactions(hash=%064x transactions=%s)" % (self.blockhash, repr(self.transactions))
1098
1099
1100 class CPartialMerkleTree:
1101 __slots__ = ("nTransactions", "vBits", "vHash")
1102
1103 def __init__(self):
1104 self.nTransactions = 0
1105 self.vHash = []
1106 self.vBits = []
1107
1108 def deserialize(self, f):
1109 self.nTransactions = int.from_bytes(f.read(4), "little")
1110 self.vHash = deser_uint256_vector(f)
1111 vBytes = deser_string(f)
1112 self.vBits = []
1113 for i in range(len(vBytes) * 8):
1114 self.vBits.append(vBytes[i//8] & (1 << (i % 8)) != 0)
1115
1116 def serialize(self):
1117 r = b""
1118 r += self.nTransactions.to_bytes(4, "little")
1119 r += ser_uint256_vector(self.vHash)
1120 vBytesArray = bytearray([0x00] * ((len(self.vBits) + 7)//8))
1121 for i in range(len(self.vBits)):
1122 vBytesArray[i // 8] |= self.vBits[i] << (i % 8)
1123 r += ser_string(bytes(vBytesArray))
1124 return r
1125
1126 def __repr__(self):
1127 return "CPartialMerkleTree(nTransactions=%d, vHash=%s, vBits=%s)" % (self.nTransactions, repr(self.vHash), repr(self.vBits))
1128
1129
1130 class CMerkleBlock:
1131 __slots__ = ("header", "txn")
1132
1133 def __init__(self):
1134 self.header = CBlockHeader()
1135 self.txn = CPartialMerkleTree()
1136
1137 def deserialize(self, f):
1138 self.header.deserialize(f)
1139 self.txn.deserialize(f)
1140
1141 def serialize(self):
1142 r = b""
1143 r += self.header.serialize()
1144 r += self.txn.serialize()
1145 return r
1146
1147 def __repr__(self):
1148 return "CMerkleBlock(header=%s, txn=%s)" % (repr(self.header), repr(self.txn))
1149
1150
1151 # Objects that correspond to messages on the wire
1152 class msg_version:
1153 __slots__ = ("addrFrom", "addrTo", "nNonce", "relay", "nServices",
1154 "nStartingHeight", "nTime", "nVersion", "strSubVer")
1155 msgtype = b"version"
1156
1157 def __init__(self):
1158 self.nVersion = 0
1159 self.nServices = 0
1160 self.nTime = int(time.time())
1161 self.addrTo = CAddress()
1162 self.addrFrom = CAddress()
1163 self.nNonce = random.getrandbits(64)
1164 self.strSubVer = ''
1165 self.nStartingHeight = -1
1166 self.relay = 0
1167
1168 def deserialize(self, f):
1169 self.nVersion = int.from_bytes(f.read(4), "little", signed=True)
1170 self.nServices = int.from_bytes(f.read(8), "little")
1171 self.nTime = int.from_bytes(f.read(8), "little", signed=True)
1172 self.addrTo = CAddress()
1173 self.addrTo.deserialize(f, with_time=False)
1174
1175 self.addrFrom = CAddress()
1176 self.addrFrom.deserialize(f, with_time=False)
1177 self.nNonce = int.from_bytes(f.read(8), "little")
1178 self.strSubVer = deser_string(f).decode('utf-8')
1179
1180 self.nStartingHeight = int.from_bytes(f.read(4), "little", signed=True)
1181
1182 # Relay field is optional for version 70001 onwards
1183 # But, unconditionally check it to match behaviour in bitcoind
1184 self.relay = int.from_bytes(f.read(1), "little") # f.read(1) may return an empty b''
1185
1186 def serialize(self):
1187 r = b""
1188 r += self.nVersion.to_bytes(4, "little", signed=True)
1189 r += self.nServices.to_bytes(8, "little")
1190 r += self.nTime.to_bytes(8, "little", signed=True)
1191 r += self.addrTo.serialize(with_time=False)
1192 r += self.addrFrom.serialize(with_time=False)
1193 r += self.nNonce.to_bytes(8, "little")
1194 r += ser_string(self.strSubVer.encode('utf-8'))
1195 r += self.nStartingHeight.to_bytes(4, "little", signed=True)
1196 r += self.relay.to_bytes(1, "little")
1197 return r
1198
1199 def __repr__(self):
1200 return 'msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i relay=%i)' \
1201 % (self.nVersion, self.nServices, time.ctime(self.nTime),
1202 repr(self.addrTo), repr(self.addrFrom), self.nNonce,
1203 self.strSubVer, self.nStartingHeight, self.relay)
1204
1205
1206 class msg_verack:
1207 __slots__ = ()
1208 msgtype = b"verack"
1209
1210 def __init__(self):
1211 pass
1212
1213 def deserialize(self, f):
1214 pass
1215
1216 def serialize(self):
1217 return b""
1218
1219 def __repr__(self):
1220 return "msg_verack()"
1221
1222
1223 class msg_addr:
1224 __slots__ = ("addrs",)
1225 msgtype = b"addr"
1226
1227 def __init__(self):
1228 self.addrs = []
1229
1230 def deserialize(self, f):
1231 self.addrs = deser_vector(f, CAddress)
1232
1233 def serialize(self):
1234 return ser_vector(self.addrs)
1235
1236 def __repr__(self):
1237 return "msg_addr(addrs=%s)" % (repr(self.addrs))
1238
1239
1240 class msg_addrv2:
1241 __slots__ = ("addrs",)
1242 msgtype = b"addrv2"
1243
1244 def __init__(self):
1245 self.addrs = []
1246
1247 def deserialize(self, f):
1248 self.addrs = deser_vector(f, CAddress, "deserialize_v2")
1249
1250 def serialize(self):
1251 return ser_vector(self.addrs, "serialize_v2")
1252
1253 def __repr__(self):
1254 return "msg_addrv2(addrs=%s)" % (repr(self.addrs))
1255
1256
1257 class msg_sendaddrv2:
1258 __slots__ = ()
1259 msgtype = b"sendaddrv2"
1260
1261 def __init__(self):
1262 pass
1263
1264 def deserialize(self, f):
1265 pass
1266
1267 def serialize(self):
1268 return b""
1269
1270 def __repr__(self):
1271 return "msg_sendaddrv2()"
1272
1273
1274 class msg_inv:
1275 __slots__ = ("inv",)
1276 msgtype = b"inv"
1277
1278 def __init__(self, inv=None):
1279 if inv is None:
1280 self.inv = []
1281 else:
1282 self.inv = inv
1283
1284 def deserialize(self, f):
1285 self.inv = deser_vector(f, CInv)
1286
1287 def serialize(self):
1288 return ser_vector(self.inv)
1289
1290 def __repr__(self):
1291 return "msg_inv(inv=%s)" % (repr(self.inv))
1292
1293
1294 class msg_getdata:
1295 __slots__ = ("inv",)
1296 msgtype = b"getdata"
1297
1298 def __init__(self, inv=None):
1299 self.inv = inv if inv is not None else []
1300
1301 def deserialize(self, f):
1302 self.inv = deser_vector(f, CInv)
1303
1304 def serialize(self):
1305 return ser_vector(self.inv)
1306
1307 def __repr__(self):
1308 return "msg_getdata(inv=%s)" % (repr(self.inv))
1309
1310
1311 class msg_getblocks:
1312 __slots__ = ("locator", "hashstop")
1313 msgtype = b"getblocks"
1314
1315 def __init__(self):
1316 self.locator = CBlockLocator()
1317 self.hashstop = 0
1318
1319 def deserialize(self, f):
1320 self.locator = CBlockLocator()
1321 self.locator.deserialize(f)
1322 self.hashstop = deser_uint256(f)
1323
1324 def serialize(self):
1325 r = b""
1326 r += self.locator.serialize()
1327 r += ser_uint256(self.hashstop)
1328 return r
1329
1330 def __repr__(self):
1331 return "msg_getblocks(locator=%s hashstop=%064x)" \
1332 % (repr(self.locator), self.hashstop)
1333
1334
1335 class msg_tx:
1336 __slots__ = ("tx",)
1337 msgtype = b"tx"
1338
1339 def __init__(self, tx=None):
1340 if tx is None:
1341 self.tx = CTransaction()
1342 else:
1343 self.tx = tx
1344
1345 def deserialize(self, f):
1346 self.tx.deserialize(f)
1347
1348 def serialize(self):
1349 return self.tx.serialize_with_witness()
1350
1351 def __repr__(self):
1352 return "msg_tx(tx=%s)" % (repr(self.tx))
1353
1354 class msg_wtxidrelay:
1355 __slots__ = ()
1356 msgtype = b"wtxidrelay"
1357
1358 def __init__(self):
1359 pass
1360
1361 def deserialize(self, f):
1362 pass
1363
1364 def serialize(self):
1365 return b""
1366
1367 def __repr__(self):
1368 return "msg_wtxidrelay()"
1369
1370
1371 class msg_no_witness_tx(msg_tx):
1372 __slots__ = ()
1373
1374 def serialize(self):
1375 return self.tx.serialize_without_witness()
1376
1377
1378 class msg_block:
1379 __slots__ = ("block",)
1380 msgtype = b"block"
1381
1382 def __init__(self, block=None):
1383 if block is None:
1384 self.block = CBlock()
1385 else:
1386 self.block = block
1387
1388 def deserialize(self, f):
1389 self.block.deserialize(f)
1390
1391 def serialize(self):
1392 return self.block.serialize()
1393
1394 def __repr__(self):
1395 return "msg_block(block=%s)" % (repr(self.block))
1396
1397
1398 # Generic type to control the raw bytes sent over the wire.
1399 # The msgtype and the data must be provided.
1400 class msg_generic:
1401 __slots__ = ("msgtype", "data")
1402
1403 def __init__(self, msgtype, data=None):
1404 self.msgtype = msgtype
1405 self.data = data
1406
1407 def serialize(self):
1408 return self.data
1409
1410 def __repr__(self):
1411 return "msg_generic()"
1412
1413
1414 class msg_no_witness_block(msg_block):
1415 __slots__ = ()
1416 def serialize(self):
1417 return self.block.serialize(with_witness=False)
1418
1419
1420 class msg_getaddr:
1421 __slots__ = ()
1422 msgtype = b"getaddr"
1423
1424 def __init__(self):
1425 pass
1426
1427 def deserialize(self, f):
1428 pass
1429
1430 def serialize(self):
1431 return b""
1432
1433 def __repr__(self):
1434 return "msg_getaddr()"
1435
1436
1437 class msg_ping:
1438 __slots__ = ("nonce",)
1439 msgtype = b"ping"
1440
1441 def __init__(self, nonce=0):
1442 self.nonce = nonce
1443
1444 def deserialize(self, f):
1445 self.nonce = int.from_bytes(f.read(8), "little")
1446
1447 def serialize(self):
1448 r = b""
1449 r += self.nonce.to_bytes(8, "little")
1450 return r
1451
1452 def __repr__(self):
1453 return "msg_ping(nonce=%08x)" % self.nonce
1454
1455
1456 class msg_pong:
1457 __slots__ = ("nonce",)
1458 msgtype = b"pong"
1459
1460 def __init__(self, nonce=0):
1461 self.nonce = nonce
1462
1463 def deserialize(self, f):
1464 self.nonce = int.from_bytes(f.read(8), "little")
1465
1466 def serialize(self):
1467 r = b""
1468 r += self.nonce.to_bytes(8, "little")
1469 return r
1470
1471 def __repr__(self):
1472 return "msg_pong(nonce=%08x)" % self.nonce
1473
1474
1475 class msg_mempool:
1476 __slots__ = ()
1477 msgtype = b"mempool"
1478
1479 def __init__(self):
1480 pass
1481
1482 def deserialize(self, f):
1483 pass
1484
1485 def serialize(self):
1486 return b""
1487
1488 def __repr__(self):
1489 return "msg_mempool()"
1490
1491
1492 class msg_notfound:
1493 __slots__ = ("vec", )
1494 msgtype = b"notfound"
1495
1496 def __init__(self, vec=None):
1497 self.vec = vec or []
1498
1499 def deserialize(self, f):
1500 self.vec = deser_vector(f, CInv)
1501
1502 def serialize(self):
1503 return ser_vector(self.vec)
1504
1505 def __repr__(self):
1506 return "msg_notfound(vec=%s)" % (repr(self.vec))
1507
1508
1509 class msg_sendheaders:
1510 __slots__ = ()
1511 msgtype = b"sendheaders"
1512
1513 def __init__(self):
1514 pass
1515
1516 def deserialize(self, f):
1517 pass
1518
1519 def serialize(self):
1520 return b""
1521
1522 def __repr__(self):
1523 return "msg_sendheaders()"
1524
1525
1526 # getheaders message has
1527 # number of entries
1528 # vector of hashes
1529 # hash_stop (hash of last desired block header, 0 to get as many as possible)
1530 class msg_getheaders:
1531 __slots__ = ("hashstop", "locator",)
1532 msgtype = b"getheaders"
1533
1534 def __init__(self):
1535 self.locator = CBlockLocator()
1536 self.hashstop = 0
1537
1538 def deserialize(self, f):
1539 self.locator = CBlockLocator()
1540 self.locator.deserialize(f)
1541 self.hashstop = deser_uint256(f)
1542
1543 def serialize(self):
1544 r = b""
1545 r += self.locator.serialize()
1546 r += ser_uint256(self.hashstop)
1547 return r
1548
1549 def __repr__(self):
1550 return "msg_getheaders(locator=%s, stop=%064x)" \
1551 % (repr(self.locator), self.hashstop)
1552
1553
1554 # headers message has
1555 # <count> <vector of block headers>
1556 class msg_headers:
1557 __slots__ = ("headers",)
1558 msgtype = b"headers"
1559
1560 def __init__(self, headers=None):
1561 self.headers = headers if headers is not None else []
1562
1563 def deserialize(self, f):
1564 # comment in bitcoind indicates these should be deserialized as blocks
1565 blocks = deser_vector(f, CBlock)
1566 for x in blocks:
1567 self.headers.append(CBlockHeader(x))
1568
1569 def serialize(self):
1570 blocks = [CBlock(x) for x in self.headers]
1571 return ser_vector(blocks)
1572
1573 def __repr__(self):
1574 return "msg_headers(headers=%s)" % repr(self.headers)
1575
1576
1577 class msg_merkleblock:
1578 __slots__ = ("merkleblock",)
1579 msgtype = b"merkleblock"
1580
1581 def __init__(self, merkleblock=None):
1582 if merkleblock is None:
1583 self.merkleblock = CMerkleBlock()
1584 else:
1585 self.merkleblock = merkleblock
1586
1587 def deserialize(self, f):
1588 self.merkleblock.deserialize(f)
1589
1590 def serialize(self):
1591 return self.merkleblock.serialize()
1592
1593 def __repr__(self):
1594 return "msg_merkleblock(merkleblock=%s)" % (repr(self.merkleblock))
1595
1596
1597 class msg_filterload:
1598 __slots__ = ("data", "nHashFuncs", "nTweak", "nFlags")
1599 msgtype = b"filterload"
1600
1601 def __init__(self, data=b'00', nHashFuncs=0, nTweak=0, nFlags=0):
1602 self.data = data
1603 self.nHashFuncs = nHashFuncs
1604 self.nTweak = nTweak
1605 self.nFlags = nFlags
1606
1607 def deserialize(self, f):
1608 self.data = deser_string(f)
1609 self.nHashFuncs = int.from_bytes(f.read(4), "little")
1610 self.nTweak = int.from_bytes(f.read(4), "little")
1611 self.nFlags = int.from_bytes(f.read(1), "little")
1612
1613 def serialize(self):
1614 r = b""
1615 r += ser_string(self.data)
1616 r += self.nHashFuncs.to_bytes(4, "little")
1617 r += self.nTweak.to_bytes(4, "little")
1618 r += self.nFlags.to_bytes(1, "little")
1619 return r
1620
1621 def __repr__(self):
1622 return "msg_filterload(data={}, nHashFuncs={}, nTweak={}, nFlags={})".format(
1623 self.data, self.nHashFuncs, self.nTweak, self.nFlags)
1624
1625
1626 class msg_filteradd:
1627 __slots__ = ("data")
1628 msgtype = b"filteradd"
1629
1630 def __init__(self, data):
1631 self.data = data
1632
1633 def deserialize(self, f):
1634 self.data = deser_string(f)
1635
1636 def serialize(self):
1637 r = b""
1638 r += ser_string(self.data)
1639 return r
1640
1641 def __repr__(self):
1642 return "msg_filteradd(data={})".format(self.data)
1643
1644
1645 class msg_filterclear:
1646 __slots__ = ()
1647 msgtype = b"filterclear"
1648
1649 def __init__(self):
1650 pass
1651
1652 def deserialize(self, f):
1653 pass
1654
1655 def serialize(self):
1656 return b""
1657
1658 def __repr__(self):
1659 return "msg_filterclear()"
1660
1661
1662 class msg_feefilter:
1663 __slots__ = ("feerate",)
1664 msgtype = b"feefilter"
1665
1666 def __init__(self, feerate=0):
1667 self.feerate = feerate
1668
1669 def deserialize(self, f):
1670 self.feerate = int.from_bytes(f.read(8), "little")
1671
1672 def serialize(self):
1673 r = b""
1674 r += self.feerate.to_bytes(8, "little")
1675 return r
1676
1677 def __repr__(self):
1678 return "msg_feefilter(feerate=%08x)" % self.feerate
1679
1680
1681 class msg_sendcmpct:
1682 __slots__ = ("announce", "version")
1683 msgtype = b"sendcmpct"
1684
1685 def __init__(self, announce=False, version=2):
1686 self.announce = announce
1687 self.version = version
1688
1689 def deserialize(self, f):
1690 self.announce = bool(int.from_bytes(f.read(1), "little"))
1691 self.version = int.from_bytes(f.read(8), "little")
1692
1693 def serialize(self):
1694 r = b""
1695 r += int(self.announce).to_bytes(1, "little")
1696 r += self.version.to_bytes(8, "little")
1697 return r
1698
1699 def __repr__(self):
1700 return "msg_sendcmpct(announce=%s, version=%lu)" % (self.announce, self.version)
1701
1702
1703 class msg_cmpctblock:
1704 __slots__ = ("header_and_shortids",)
1705 msgtype = b"cmpctblock"
1706
1707 def __init__(self, header_and_shortids = None):
1708 self.header_and_shortids = header_and_shortids
1709
1710 def deserialize(self, f):
1711 self.header_and_shortids = P2PHeaderAndShortIDs()
1712 self.header_and_shortids.deserialize(f)
1713
1714 def serialize(self):
1715 r = b""
1716 r += self.header_and_shortids.serialize()
1717 return r
1718
1719 def __repr__(self):
1720 return "msg_cmpctblock(HeaderAndShortIDs=%s)" % repr(self.header_and_shortids)
1721
1722
1723 class msg_getblocktxn:
1724 __slots__ = ("block_txn_request",)
1725 msgtype = b"getblocktxn"
1726
1727 def __init__(self):
1728 self.block_txn_request = None
1729
1730 def deserialize(self, f):
1731 self.block_txn_request = BlockTransactionsRequest()
1732 self.block_txn_request.deserialize(f)
1733
1734 def serialize(self):
1735 r = b""
1736 r += self.block_txn_request.serialize()
1737 return r
1738
1739 def __repr__(self):
1740 return "msg_getblocktxn(block_txn_request=%s)" % (repr(self.block_txn_request))
1741
1742
1743 class msg_blocktxn:
1744 __slots__ = ("block_transactions",)
1745 msgtype = b"blocktxn"
1746
1747 def __init__(self):
1748 self.block_transactions = BlockTransactions()
1749
1750 def deserialize(self, f):
1751 self.block_transactions.deserialize(f)
1752
1753 def serialize(self):
1754 r = b""
1755 r += self.block_transactions.serialize()
1756 return r
1757
1758 def __repr__(self):
1759 return "msg_blocktxn(block_transactions=%s)" % (repr(self.block_transactions))
1760
1761
1762 class msg_no_witness_blocktxn(msg_blocktxn):
1763 __slots__ = ()
1764
1765 def serialize(self):
1766 return self.block_transactions.serialize(with_witness=False)
1767
1768
1769 class msg_getcfilters:
1770 __slots__ = ("filter_type", "start_height", "stop_hash")
1771 msgtype = b"getcfilters"
1772
1773 def __init__(self, filter_type=None, start_height=None, stop_hash=None):
1774 self.filter_type = filter_type
1775 self.start_height = start_height
1776 self.stop_hash = stop_hash
1777
1778 def deserialize(self, f):
1779 self.filter_type = int.from_bytes(f.read(1), "little")
1780 self.start_height = int.from_bytes(f.read(4), "little")
1781 self.stop_hash = deser_uint256(f)
1782
1783 def serialize(self):
1784 r = b""
1785 r += self.filter_type.to_bytes(1, "little")
1786 r += self.start_height.to_bytes(4, "little")
1787 r += ser_uint256(self.stop_hash)
1788 return r
1789
1790 def __repr__(self):
1791 return "msg_getcfilters(filter_type={:#x}, start_height={}, stop_hash={:x})".format(
1792 self.filter_type, self.start_height, self.stop_hash)
1793
1794 class msg_cfilter:
1795 __slots__ = ("filter_type", "block_hash", "filter_data")
1796 msgtype = b"cfilter"
1797
1798 def __init__(self, filter_type=None, block_hash=None, filter_data=None):
1799 self.filter_type = filter_type
1800 self.block_hash = block_hash
1801 self.filter_data = filter_data
1802
1803 def deserialize(self, f):
1804 self.filter_type = int.from_bytes(f.read(1), "little")
1805 self.block_hash = deser_uint256(f)
1806 self.filter_data = deser_string(f)
1807
1808 def serialize(self):
1809 r = b""
1810 r += self.filter_type.to_bytes(1, "little")
1811 r += ser_uint256(self.block_hash)
1812 r += ser_string(self.filter_data)
1813 return r
1814
1815 def __repr__(self):
1816 return "msg_cfilter(filter_type={:#x}, block_hash={:x})".format(
1817 self.filter_type, self.block_hash)
1818
1819 class msg_getcfheaders:
1820 __slots__ = ("filter_type", "start_height", "stop_hash")
1821 msgtype = b"getcfheaders"
1822
1823 def __init__(self, filter_type=None, start_height=None, stop_hash=None):
1824 self.filter_type = filter_type
1825 self.start_height = start_height
1826 self.stop_hash = stop_hash
1827
1828 def deserialize(self, f):
1829 self.filter_type = int.from_bytes(f.read(1), "little")
1830 self.start_height = int.from_bytes(f.read(4), "little")
1831 self.stop_hash = deser_uint256(f)
1832
1833 def serialize(self):
1834 r = b""
1835 r += self.filter_type.to_bytes(1, "little")
1836 r += self.start_height.to_bytes(4, "little")
1837 r += ser_uint256(self.stop_hash)
1838 return r
1839
1840 def __repr__(self):
1841 return "msg_getcfheaders(filter_type={:#x}, start_height={}, stop_hash={:x})".format(
1842 self.filter_type, self.start_height, self.stop_hash)
1843
1844 class msg_cfheaders:
1845 __slots__ = ("filter_type", "stop_hash", "prev_header", "hashes")
1846 msgtype = b"cfheaders"
1847
1848 def __init__(self, filter_type=None, stop_hash=None, prev_header=None, hashes=None):
1849 self.filter_type = filter_type
1850 self.stop_hash = stop_hash
1851 self.prev_header = prev_header
1852 self.hashes = hashes
1853
1854 def deserialize(self, f):
1855 self.filter_type = int.from_bytes(f.read(1), "little")
1856 self.stop_hash = deser_uint256(f)
1857 self.prev_header = deser_uint256(f)
1858 self.hashes = deser_uint256_vector(f)
1859
1860 def serialize(self):
1861 r = b""
1862 r += self.filter_type.to_bytes(1, "little")
1863 r += ser_uint256(self.stop_hash)
1864 r += ser_uint256(self.prev_header)
1865 r += ser_uint256_vector(self.hashes)
1866 return r
1867
1868 def __repr__(self):
1869 return "msg_cfheaders(filter_type={:#x}, stop_hash={:x})".format(
1870 self.filter_type, self.stop_hash)
1871
1872 class msg_getcfcheckpt:
1873 __slots__ = ("filter_type", "stop_hash")
1874 msgtype = b"getcfcheckpt"
1875
1876 def __init__(self, filter_type=None, stop_hash=None):
1877 self.filter_type = filter_type
1878 self.stop_hash = stop_hash
1879
1880 def deserialize(self, f):
1881 self.filter_type = int.from_bytes(f.read(1), "little")
1882 self.stop_hash = deser_uint256(f)
1883
1884 def serialize(self):
1885 r = b""
1886 r += self.filter_type.to_bytes(1, "little")
1887 r += ser_uint256(self.stop_hash)
1888 return r
1889
1890 def __repr__(self):
1891 return "msg_getcfcheckpt(filter_type={:#x}, stop_hash={:x})".format(
1892 self.filter_type, self.stop_hash)
1893
1894 class msg_cfcheckpt:
1895 __slots__ = ("filter_type", "stop_hash", "headers")
1896 msgtype = b"cfcheckpt"
1897
1898 def __init__(self, filter_type=None, stop_hash=None, headers=None):
1899 self.filter_type = filter_type
1900 self.stop_hash = stop_hash
1901 self.headers = headers
1902
1903 def deserialize(self, f):
1904 self.filter_type = int.from_bytes(f.read(1), "little")
1905 self.stop_hash = deser_uint256(f)
1906 self.headers = deser_uint256_vector(f)
1907
1908 def serialize(self):
1909 r = b""
1910 r += self.filter_type.to_bytes(1, "little")
1911 r += ser_uint256(self.stop_hash)
1912 r += ser_uint256_vector(self.headers)
1913 return r
1914
1915 def __repr__(self):
1916 return "msg_cfcheckpt(filter_type={:#x}, stop_hash={:x})".format(
1917 self.filter_type, self.stop_hash)
1918
1919 class msg_sendtxrcncl:
1920 __slots__ = ("version", "salt")
1921 msgtype = b"sendtxrcncl"
1922
1923 def __init__(self):
1924 self.version = 0
1925 self.salt = 0
1926
1927 def deserialize(self, f):
1928 self.version = int.from_bytes(f.read(4), "little")
1929 self.salt = int.from_bytes(f.read(8), "little")
1930
1931 def serialize(self):
1932 r = b""
1933 r += self.version.to_bytes(4, "little")
1934 r += self.salt.to_bytes(8, "little")
1935 return r
1936
1937 def __repr__(self):
1938 return "msg_sendtxrcncl(version=%lu, salt=%lu)" %\
1939 (self.version, self.salt)
1940
1941 class msg_feature:
1942 """FEATURE message for negotiating optional features."""
1943 __slots__ = ("feature_id", "feature_data")
1944 msgtype = b"feature"
1945
1946 def __init__(self, feature_id="", feature_data=b""):
1947 self.feature_id = feature_id
1948 self.feature_data = feature_data
1949
1950 def deserialize(self, f):
1951 self.feature_id = deser_string(f).decode()
1952 self.feature_data = deser_string(f)
1953
1954 def serialize(self):
1955 r = ser_string(self.feature_id.encode())
1956 r += ser_string(self.feature_data)
1957 return r
1958
1959 def __repr__(self):
1960 return f"msg_feature(feature_id={self.feature_id}, data={self.feature_data.hex()})"
1961
1962
1963 class TestFrameworkScript(unittest.TestCase):
1964 def test_addrv2_encode_decode(self):
1965 def check_addrv2(ip, net):
1966 addr = CAddress()
1967 addr.net, addr.ip = net, ip
1968 ser = addr.serialize_v2()
1969 actual = CAddress()
1970 actual.deserialize_v2(BytesIO(ser))
1971 self.assertEqual(actual, addr)
1972
1973 check_addrv2("1.65.195.98", CAddress.NET_IPV4)
1974 check_addrv2("2001:41f0::62:6974:636f:696e", CAddress.NET_IPV6)
1975 check_addrv2("2bqghnldu6mcug4pikzprwhtjjnsyederctvci6klcwzepnjd46ikjyd.onion", CAddress.NET_TORV3)
1976 check_addrv2("255fhcp6ajvftnyo7bwz3an3t4a4brhopm3bamyh2iu5r3gnr2rq.b32.i2p", CAddress.NET_I2P)
1977 check_addrv2("fc32:17ea:e415:c3bf:9808:149d:b5a2:c9aa", CAddress.NET_CJDNS)
1978
1979 def test_varint_encode_decode(self):
1980 def check_varint(num, expected_encoding_hex):
1981 expected_encoding = bytes.fromhex(expected_encoding_hex)
1982 self.assertEqual(ser_varint(num), expected_encoding)
1983 self.assertEqual(deser_varint(BytesIO(expected_encoding)), num)
1984
1985 # test cases from serialize_tests.cpp:varint_bitpatterns
1986 check_varint(0, "00")
1987 check_varint(0x7f, "7f")
1988 check_varint(0x80, "8000")
1989 check_varint(0x1234, "a334")
1990 check_varint(0xffff, "82fe7f")
1991 check_varint(0x123456, "c7e756")
1992 check_varint(0x80123456, "86ffc7e756")
1993 check_varint(0xffffffff, "8efefefe7f")
1994 check_varint(0xffffffffffffffff, "80fefefefefefefefe7f")
1995