2
util to benchmark known usecase
6
from rlp.sedes import big_endian_int, BigEndianInt, Binary, binary, CountableList
9
address = Binary.fixed_length(20, allow_empty=True)
10
int20 = BigEndianInt(20)
11
int32 = BigEndianInt(32)
12
int256 = BigEndianInt(256)
13
hash32 = Binary.fixed_length(32)
14
trie_root = Binary.fixed_length(32, allow_empty=True)
18
return b'\x00' * max(0, l - len(x)) + x
21
class Transaction(rlp.Serializable):
23
('nonce', big_endian_int),
24
('gasprice', big_endian_int),
25
('startgas', big_endian_int),
27
('value', big_endian_int),
29
('v', big_endian_int),
30
('r', big_endian_int),
31
('s', big_endian_int),
34
def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0, s=0):
35
super(Transaction, self).__init__(nonce, gasprice, startgas, to, value, data, v, r, s)
38
class BlockHeader(rlp.Serializable):
41
('uncles_hash', hash32),
42
('coinbase', address),
43
('state_root', trie_root),
44
('tx_list_root', trie_root),
45
('receipts_root', trie_root),
47
('difficulty', big_endian_int),
48
('number', big_endian_int),
49
('gas_limit', big_endian_int),
50
('gas_used', big_endian_int),
51
('timestamp', big_endian_int),
52
('extra_data', binary),
57
def __init__(self, *args, **kargs):
58
super(BlockHeader, self).__init__(*args, **kargs)
61
class Block(rlp.Serializable):
63
('header', BlockHeader),
64
('transaction_list', CountableList(Transaction)),
65
('uncles', CountableList(BlockHeader))
68
def __init__(self, header, transaction_list=[], uncles=[]):
69
super(Block, self).__init__(header, transaction_list, uncles)
72
def rand_bytes(num=32):
73
return zpad(big_endian_int.serialize(random.getrandbits(num * 8)), num)
75
rand_bytes32 = rand_bytes
87
return random.getrandbits(256)
91
return random.getrandbits(32)
94
rand_map = {hash32: rand_bytes32, trie_root: rand_bytes32, binary: rand_bytes32,
95
address: rand_address, Binary: rand_bytes8, big_endian_int: rand_int,
98
assert Binary in rand_map
101
def mk_transaction():
102
return Transaction(rand_int(), rand_int(), rand_int(), rand_address(), rand_int(),
103
rand_bytes32(), 27, rand_bigint(), rand_bigint())
104
rlp.decode(rlp.encode(mk_transaction()), Transaction)
107
def mk_block_header():
108
return BlockHeader(*[rand_map[t]() for _, t in BlockHeader.fields])
109
rlp.decode(rlp.encode(mk_block_header()), BlockHeader)
112
def mk_block(num_transactions=10, num_uncles=1):
113
return Block(mk_block_header(),
114
[mk_transaction() for i in range(num_transactions)],
115
[mk_block_header() for i in range(num_uncles)])
116
rlp.decode(rlp.encode(mk_block()), Block)
119
def do_test_serialize(block, rounds=100):
120
for i in range(rounds):
121
x = rlp.encode(block)
125
def do_test_deserialize(data, rounds=100, sedes=Block):
126
for i in range(rounds):
127
x = rlp.decode(data, sedes)
131
def main(rounds=10000):
133
d = do_test_serialize(mk_block(), rounds)
134
elapsed = time.time() - st
135
print 'Block serializations / sec: %.2f' % (rounds / elapsed)
138
d = do_test_deserialize(d, rounds)
139
elapsed = time.time() - st
140
print 'Block deserializations / sec: %.2f' % (rounds / elapsed)
143
d = do_test_serialize(mk_transaction(), rounds)
144
elapsed = time.time() - st
145
print 'TX serializations / sec: %.2f' % (rounds / elapsed)
148
d = do_test_deserialize(d, rounds, sedes=Transaction)
149
elapsed = time.time() - st
150
print 'TX deserializations / sec: %.2f' % (rounds / elapsed)
153
if __name__ == '__main__':
157
serializations / sec: 658.64
158
deserializations / sec: 1331.62
161
serializations / sec: 4628.81 : x7 speedup
162
deserializations / sec: 4753.84 : x3.5 speedup