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