class VarstrSerializer(Serializer): def __init__(self, desc=""): self.lenfield = VarintSerializer() def serialize(self, str): return (self.lenfield.serialize(len(str)) + str) def get_size_for_len(self, i): return self.lenfield.get_size(i) + i def deserialize(self, data, cursor=0): length, newpos = self.lenfield.deserialize(data, cursor) #data = data[newpos:] if (length > len(data) - newpos): raise MissingDataException("Decoding error: not enough data for varstring (expected:%d, got:%d)" % (length, len(data) - newpos)) return (data[newpos:newpos+length], newpos+length)
class VarstrSerializer(Serializer): def __init__(self, desc=""): self.lenfield = VarintSerializer() def serialize(self, str): return (self.lenfield.serialize(len(str)) + str) def get_size_for_len(self, i): return self.lenfield.get_size(i) + i def deserialize(self, data, cursor=0): length, newpos = self.lenfield.deserialize(data, cursor) #data = data[newpos:] if (length > len(data) - newpos): raise MissingDataException( "Decoding error: not enough data for varstring (expected:%d, got:%d)" % (length, len(data) - newpos)) return (data[newpos:newpos + length], newpos + length)
class InvMessageSerializer(Serializer): INV_ENCODER = VarsizelistSerializer(VarintSerializer(), InvitemSerializer()) def serialize(self, inv_msg): return (self.INV_ENCODER.serialize(inv_msg.items)) def deserialize(self, data, cursor=0): invitems, cursor = self.INV_ENCODER.deserialize(data, cursor) return (InvMessage(invitems), cursor)
class GetdataMessageSerializer(Serializer): GETDATA_ENC = VarsizelistSerializer(VarintSerializer(), InvitemSerializer()) def serialize(self, getdata_msg): return (self.GETDATA_ENC.serialize(getdata_msg.invitems)) def deserialize(self, data, cursor=0): invitems, cursor = self.GETDATA_ENC.deserialize(data, cursor) return (GetdataMessage(invitems), cursor)
class AddrMessageSerializer(Serializer): ADDR = VarsizelistSerializer(VarintSerializer("count"), TimenetaddrSerializer()) def serialize(self, addr_msg): return (self.ADDR.serialize(addr_msg.timenetaddr_list)) def deserialize(self, data, cursor=0): addr_list, cursor = self.ADDR.deserialize(data, cursor) return (AddrMessage(addr_list), cursor)
def test_varint_serialize(self): self.assertEquals(hexstr(VarintSerializer().serialize(5)), "05") self.assertEquals(hexstr(VarintSerializer().serialize(252)), "fc") self.assertEquals(hexstr(VarintSerializer().serialize(253)), "fdfd00") self.assertEquals(hexstr(VarintSerializer().serialize(65535)), "fdffff") self.assertEquals(hexstr(VarintSerializer().serialize(65536)), "fe00000100") self.assertEquals(hexstr(VarintSerializer().serialize(4294967295)), "feffffffff") self.assertEquals(hexstr(VarintSerializer().serialize(4294967296)), "ff0000000001000000")
class AlertPayloadSerializer(Serializer): PAYLOAD = Structure([Field("<I", "version"), Field("<Q", "relay_until"), Field("<Q", "expiration"), Field("<I", "id"), Field("<I", "cancel"), VarsizelistSerializer(VarintSerializer("count"), VarintSerializer("set_cancel")), Field("<I", "min_ver"), Field("<I", "max_ver"), VarsizelistSerializer(VarintSerializer("count"), VarstrSerializer("set_sub_ver")), Field("<I", "priority"), VarstrSerializer("comment"), VarstrSerializer("statusbar"), VarstrSerializer("reserved")]) def serialize(self, alert_payload): return (self.PAYLOAD.serialize([alert_payload.version, alert_payload.relay_until, alert_payload.expiration, alert_payload.id, alert_payload.cancel, alert_payload.set_cancel, alert_payload.min_ver, alert_payload.max_ver, alert_payload.set_sub_ver, alert_payload.priority, alert_payload.comment, alert_payload.statusbar, alert_payload.reserved])) def deserialize(self, data, cursor=0): payload_fields, cursor = self.PAYLOAD.deserialize(data, cursor) (version, relay_until, expiration, id, cancel, set_cancel, min_ver, max_ver, \ set_sub_ver, priority, comment, statusbar, reserved) = payload_fields return (AlertPayload(version, relay_until, expiration, id, cancel, set(set_cancel), min_ver, max_ver, set(set_sub_ver), priority, comment, statusbar, reserved), cursor)
class TxSerializer(Serializer): TX = Structure([ Field("<I", "version"), VarsizelistSerializer(VarintSerializer("txin_count"), TxinSerializer()), VarsizelistSerializer(VarintSerializer("txout_count"), TxoutSerializer()), Field("<I", "lock_time") ], "tx") def get_size(self, tx): return (self.TX.get_size( [tx.version, tx.in_list, tx.out_list, tx.locktime])) def serialize(self, tx): return (self.TX.serialize( [tx.version, tx.in_list, tx.out_list, tx.locktime])) def deserialize(self, data, cursor=0): (version, in_list, out_list, locktime), new_cursor = self.TX.deserialize(data, cursor) tx = Tx(version, in_list, out_list, locktime) tx.rawdata = data[cursor:new_cursor] return (tx, new_cursor)
class TxIndexSerializer(): TXINDEX = Structure([ Field("<I", "version"), DiskTxPosSerializer(), VarsizelistSerializer(VarintSerializer(), DiskTxPosSerializer()) ], "txindex") def __init__(self): pass def serialize(self, txindex_obj): return (self.TXINDEX.serialize( [txindex_obj.version, txindex_obj.pos, txindex_obj.spent])) def deserialize(self, data, cursor=0): (version, pos, spent), cursor = self.TXINDEX.deserialize(data, cursor) return (DbTxIndex(version, pos, spent), cursor)
def _index_transactions(self, blockhash, block=None): block_handle = self.get_block_handle(blockhash) #Add all transactions to the indexdb if not block: block = block_handle.get_block() size_blockheader = BlockheaderSerializer().get_size(block.blockheader) size_tx_size = VarintSerializer().get_size(len(block.transactions)) tx_serializer = TxSerializer() blockpos = block_handle.blockindex.blockpos txpos = block_handle.blockindex.blockpos + size_blockheader + size_tx_size for i, tx in enumerate(block.transactions): txindex = DbTxIndex(1, DiskTxPos(1, blockpos, txpos), [DiskTxPos() for _ in range(tx.output_count())]) self.indexdb.set_transactionindex(hash_tx(tx), txindex) #TODO: speed this up... if tx.rawdata: txpos += len(tx.rawdata) else: txpos += tx_serializer.get_size(tx)
def test_varint_deserialize(self): self.assertEquals( VarintSerializer().deserialize(decodehexstr("05"))[0], 5) self.assertEquals( VarintSerializer().deserialize(decodehexstr("fc"))[0], 252) self.assertEquals( VarintSerializer().deserialize(decodehexstr("fdfd00"))[0], 253) self.assertEquals( VarintSerializer().deserialize(decodehexstr("fdffff"))[0], 65535) self.assertEquals( VarintSerializer().deserialize(decodehexstr("fe00000100"))[0], 65536) self.assertEquals( VarintSerializer().deserialize(decodehexstr("feffffffff"))[0], 4294967295) self.assertEquals( VarintSerializer().deserialize( decodehexstr("ff0000000001000000"))[0], 4294967296)
class MerkleTxSerializer(Serializer): MERKLE_TX = Structure([ TxSerializer(), Uint256Serializer(), VarsizelistSerializer(VarintSerializer(), Uint256Serializer()), Field("<I", "nindex") ], "tx") def get_size(self, tx): return (self.MERKLE_TX.get_size( [tx.tx, tx.blockhash, tx.merkle_branch, tx.nindex])) def serialize(self, tx): return (self.MERKLE_TX.serialize( [tx.tx, tx.blockhash, tx.merkle_branch, tx.nindex])) def deserialize(self, data, cursor=0): (tx, blockhash, merkle_branch, nindex), cursor = self.MERKLE_TX.deserialize(data, cursor) return (MerkleTx(tx, blockhash, merkle_branch, nindex), cursor)
def __init__(self, desc=""): self.lenfield = VarintSerializer()
def __init__(self, flags=0): self.BLOCK = Structure([ BlockheaderSerializer(flags), VarsizelistSerializer(VarintSerializer("txn_count"), TxSerializer()) ], "block")
def __init__(self, flags=0): self.BLOCKLOCATOR = Structure([Field("<I", "version"), VarsizelistSerializer(VarintSerializer("count"), Uint256Serializer("locator"))])
def __init__(self, desc=""): self.lenfield = VarintSerializer()