Skip to content

Commit d8a1a0f

Browse files
author
Bob McElrath
committed
Closely match Core's (de-)serialization; remove old test case
1 parent 0c09892 commit d8a1a0f

File tree

3 files changed

+13
-26
lines changed

3 files changed

+13
-26
lines changed

bitcoin/core/__init__.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -399,13 +399,19 @@ def __init__(self, vin=(), vout=(), nLockTime=0, nVersion=1, witness=CTxWitness(
399399

400400
@classmethod
401401
def stream_deserialize(cls, f):
402+
"""Deserialize a transaction. This implementation corresponds to
403+
Bitcoin's SerializeTransaction() and consensus behavior. Note that
404+
Bitcoin's DecodeHexTx() also has the option to attempt deserializing
405+
as a non-witness transaction first, falling back to the consensus
406+
behavior if it fails. The difference lies in transactions which
407+
have zero inputs: they are invalid but may be (de-)serialized anyway
408+
for the purpose of signing them and adding inputs. If the behavior
409+
of DecodeHexTx() is needed it could be added, but not here. """
402410
nVersion = struct.unpack(b"<i", ser_read(f,4))[0]
403411
pos = f.tell()
404412
markerbyte = struct.unpack(b'B', ser_read(f, 1))[0]
405-
if markerbyte == 0:
406-
flagbyte = struct.unpack(b'B', ser_read(f, 1))[0]
407-
if flagbyte != 1:
408-
raise DeserializationFormatError
413+
flagbyte = struct.unpack(b'B', ser_read(f, 1))[0]
414+
if markerbyte == 0 and flagbyte == 1:
409415
vin = VectorSerializer.stream_deserialize(CTxIn, f)
410416
vout = VectorSerializer.stream_deserialize(CTxOut, f)
411417
wit = CTxWitness(tuple(0 for dummy in range(len(vin))))
@@ -421,21 +427,18 @@ def stream_deserialize(cls, f):
421427

422428

423429
def stream_serialize(self, f):
430+
f.write(struct.pack(b"<i", self.nVersion))
424431
if not self.wit.is_null():
425-
if len(self.wit.vtxinwit) != len(self.vin):
426-
raise SerializationMissingWitnessError
427-
f.write(struct.pack(b"<i", self.nVersion))
432+
assert(len(self.wit.vtxinwit) <= len(self.vin))
428433
f.write(b'\x00') # Marker
429434
f.write(b'\x01') # Flag
430435
VectorSerializer.stream_serialize(CTxIn, self.vin, f)
431436
VectorSerializer.stream_serialize(CTxOut, self.vout, f)
432437
self.wit.stream_serialize(f)
433-
f.write(struct.pack(b"<I", self.nLockTime))
434438
else:
435-
f.write(struct.pack(b"<i", self.nVersion))
436439
VectorSerializer.stream_serialize(CTxIn, self.vin, f)
437440
VectorSerializer.stream_serialize(CTxOut, self.vout, f)
438-
f.write(struct.pack(b"<I", self.nLockTime))
441+
f.write(struct.pack(b"<I", self.nLockTime))
439442

440443
def is_coinbase(self):
441444
return len(self.vin) == 1 and self.vin[0].prevout.is_null()

bitcoin/core/serialize.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,6 @@ class SerializationTruncationError(SerializationError):
5555
Thrown by deserialize() and stream_deserialize()
5656
"""
5757

58-
class SerializationMissingWitnessError(SerializationError):
59-
"""Missing witness data when serializing a segregated witness transaction
60-
"""
61-
6258
class DeserializationExtraDataError(SerializationError):
6359
"""Deserialized data had extra data at the end
6460
@@ -71,11 +67,6 @@ def __init__(self, msg, obj, padding):
7167
self.obj = obj
7268
self.padding = padding
7369

74-
class DeserializationFormatError(SerializationError):
75-
"""Deserialized data does not have the correct marker or flag bytes for a
76-
segwit serialization
77-
"""
78-
7970
def ser_read(f, n):
8071
"""Read from a stream safely
8172
@@ -371,9 +362,7 @@ def uint256_to_shortstr(u):
371362
'Hash160',
372363
'SerializationError',
373364
'SerializationTruncationError',
374-
'SerializationMissingWitnessError',
375365
'DeserializationExtraDataError',
376-
'DeserializationFormatError',
377366
'ser_read',
378367
'Serializable',
379368
'ImmutableSerializable',

bitcoin/tests/data/tx_invalid.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@
2323
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]],
2424
"010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", true],
2525

26-
["Tests for CheckTransaction()"],
27-
["No inputs"],
28-
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]],
29-
"0100000000010000000000000000015100000000", true],
30-
3126
["No outputs"],
3227
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x05ab9e14d983742513f0f451e105ffb4198d1dd4 EQUAL"]],
3328
"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022100f16703104aab4e4088317c862daec83440242411b039d14280e03dd33b487ab802201318a7be236672c5c56083eb7a5a195bc57a40af7923ff8545016cd3b571e2a601232103c40e5d339df3f30bf753e7e04450ae4ef76c9e45587d1d993bdc4cd06f0651c7acffffffff0000000000", true],

0 commit comments

Comments
 (0)