Implement TX serialization
This will be used in other tests
This commit is contained in:
parent
471f50787f
commit
0bbfb0b2e7
@ -27,14 +27,14 @@
|
||||
|
||||
'''Transaction-related classes and functions.'''
|
||||
|
||||
|
||||
from collections import namedtuple
|
||||
from struct import pack
|
||||
|
||||
from electrumx.lib.hash import sha256, double_sha256, hash_to_hex_str
|
||||
from electrumx.lib.util import (
|
||||
cachedproperty, unpack_int32_from, unpack_int64_from,
|
||||
unpack_uint16_from, unpack_uint32_from, unpack_uint64_from
|
||||
unpack_uint16_from, unpack_uint32_from, unpack_uint64_from,
|
||||
pack_le_int32, pack_varint, pack_le_uint32, pack_le_uint32, pack_le_int64,
|
||||
pack_varbytes,
|
||||
)
|
||||
|
||||
|
||||
@ -45,7 +45,15 @@ class Tx(namedtuple("Tx", "version inputs outputs locktime")):
|
||||
def is_coinbase(self):
|
||||
return self.inputs[0].is_coinbase
|
||||
|
||||
# FIXME: add hash as a cached property?
|
||||
def serialize(self):
|
||||
return b''.join((
|
||||
pack_le_int32(self.version),
|
||||
pack_varint(len(self.inputs)),
|
||||
b''.join(tx_in.serialize() for tx_in in self.inputs),
|
||||
pack_varint(len(self.outputs)),
|
||||
b''.join(tx_out.serialize() for tx_out in self.outputs),
|
||||
pack_le_uint32(self.locktime)
|
||||
))
|
||||
|
||||
|
||||
class TxInput(namedtuple("TxInput", "prev_hash prev_idx script sequence")):
|
||||
@ -65,9 +73,22 @@ class TxInput(namedtuple("TxInput", "prev_hash prev_idx script sequence")):
|
||||
return ("Input({}, {:d}, script={}, sequence={:d})"
|
||||
.format(prev_hash, self.prev_idx, script, self.sequence))
|
||||
|
||||
def serialize(self):
|
||||
return b''.join((
|
||||
self.prev_hash,
|
||||
pack_le_uint32(self.prev_idx),
|
||||
pack_varbytes(self.script),
|
||||
pack_le_uint32(self.sequence),
|
||||
))
|
||||
|
||||
|
||||
class TxOutput(namedtuple("TxOutput", "value pk_script")):
|
||||
pass
|
||||
|
||||
def serialize(self):
|
||||
return b''.join((
|
||||
pack_le_int64(self.value),
|
||||
pack_varbytes(self.pk_script),
|
||||
))
|
||||
|
||||
|
||||
class Deserializer(object):
|
||||
@ -530,7 +551,7 @@ class DeserializerDecred(Deserializer):
|
||||
|
||||
if produce_hash:
|
||||
# TxSerializeNoWitness << 16 == 0x10000
|
||||
no_witness_header = pack('<I', 0x10000 | (version & 0xffff))
|
||||
no_witness_header = pack_le_uint32(0x10000 | (version & 0xffff))
|
||||
prefix_tx = no_witness_header + self.binary[start+4:end_prefix]
|
||||
tx_hash = self.blake256(prefix_tx)
|
||||
else:
|
||||
|
||||
37
tests/lib/test_tx.py
Normal file
37
tests/lib/test_tx.py
Normal file
@ -0,0 +1,37 @@
|
||||
import electrumx.lib.tx as tx_lib
|
||||
|
||||
tests = [
|
||||
"020000000192809f0b234cb850d71d020e678e93f074648ed0df5affd0c46d3bcb177f"
|
||||
"9ccf020000008b483045022100c5403bcf86c3ae7b8fd4ca0d1e4df6729cc1af05ff95"
|
||||
"d9726b43a64b41dd5d9902207fab615f41871885aa3062fc7d8f8d9d3dcbc2e4867c5d"
|
||||
"96dd7a176b99e927924141040baa4271a82c5f1a09a5ea63d763697ca0545b6049c4dd"
|
||||
"8e8d099dd91f2da10eb11e829000a82047ac56969fb582433067a21c3171e569d1832c"
|
||||
"34fdd793cfc8ffffffff030000000000000000226a20195ce612d20e5284eb78bb28c9"
|
||||
"c50d6139b10b77b2d5b2f94711b13162700472bfc53000000000001976a9144a519c63"
|
||||
"f985ba5ab8b71bb42f1ecb82a0a0d80788acf6984315000000001976a9148b80536aa3"
|
||||
"c460258cda834b86a46787c9a2b0bf88ac00000000",
|
||||
"0200000003ee933f16c93d433bfd45426e94ddb4c0406aecac66f1c23a9e55151430c2"
|
||||
"b4c4a70000006b483045022100c940624ddbefcf86f3a3d820347de9c695204583a3ce"
|
||||
"9977c45cb1d6f69d577202205e0d9e9c0bfc2993160edad71cd1474b6308d990a89a54"
|
||||
"c80d7c62295edd2a394121039999e7c52a1447916b2af30478669c4e6e3ce52b895da7"
|
||||
"78f0b46b73f8ea6f00feffffff30be91ac83fee19e06304732027a39f9ec9018c5aae1"
|
||||
"159bf1c5de53dea61785fc0200006a473044022057cee17c3e123864336bdd6373e4bc"
|
||||
"0bf030ca70dd078520705930a4168610d0022061fdeedfbeb0b89c3b20db220799978b"
|
||||
"c94e11e4155b810b8b59df019b3f1859412103e2074e4387eeb3b1dec2fc8b953b0c13"
|
||||
"c53d0d3b7b676e1b3ca75ee606ecf750feffffffdd462d60e51be69451f06c36ba4490"
|
||||
"aaad8ebf40501dd27341e9c64a5f633324000000006a473044022043511ab874f0037c"
|
||||
"5726b1efc69fcdb638fac74ab3f6766eb80947cff8c1175a02200606ccf8db60f56e77"
|
||||
"03f6d5b81f5f5141f5b029a7b5a35700907f368b7e0f024121038daab4c77b9a428efb"
|
||||
"23aa2ccadc5c5332f299f5e51d1f1600524c0313ab9ec2feffffff04fe66c200000000"
|
||||
"001976a914a8c27c62fafec0a07d28b3b905912e9f385a7f1a88ac2a3b560800000000"
|
||||
"1976a914c20992e92764ef7e33e2cf6ed538d34b18a1fff888ac00a3e1110000000019"
|
||||
"76a9147137cd9dc7aad0d1cbc8e0ec12aae753d1acfaf488ac5d2b0f00000000001976"
|
||||
"a914c10084f449e968b0d71ee23a308954c68d8c97e488ac28620700"
|
||||
]
|
||||
|
||||
def test_tx_serialiazation():
|
||||
for test in tests:
|
||||
test = bytes.fromhex(test)
|
||||
deser = tx_lib.Deserializer(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.serialize() == test
|
||||
Loading…
Reference in New Issue
Block a user