|
| 1 | +from ethereum import parse_genesis_declaration, db |
| 2 | +from ethereum.block import Block, BlockHeader |
| 3 | +from ethereum.config import Env |
| 4 | +import ethereum.state_transition as state_transition |
| 5 | +from ethereum import chain |
| 6 | +import rlp |
| 7 | +import json |
| 8 | +import os |
| 9 | +import sys |
| 10 | +import time |
| 11 | + |
| 12 | +# from ethereum.slogging import LogRecorder, configure_logging, set_level |
| 13 | +# config_string = ':info,eth.vm.log:trace,eth.vm.op:trace,eth.vm.stack:trace,eth.vm.exit:trace,eth.pb.msg:trace,eth.pb.tx:debug' |
| 14 | +# configure_logging(config_string=config_string) |
| 15 | + |
| 16 | +state_transition.SKIP_MEDSTATES = True |
| 17 | +state_transition.SKIP_RECEIPT_ROOT_VALIDATION = True |
| 18 | +# assert not state_transition.SKIP_MEDSTATES or state_transition.SKIP_RECEIPT_ROOT_VALIDATION |
| 19 | + |
| 20 | +STATE_LOAD_FN = 'saved_state.json' |
| 21 | +STATE_STORE_FN = 'saved_state.json' |
| 22 | +STATE_SNAPSHOT_FN = 'saved_snapshot_{}k.json' |
| 23 | + |
| 24 | +if '--saved_state' in sys.argv: |
| 25 | + STATE_LOAD_FN = sys.argv[sys.argv.index('--saved_state') + 1] |
| 26 | + |
| 27 | +RLP_BLOCKS_FILE = '1700kblocks.rlp' |
| 28 | + |
| 29 | +if '--rlp_blocks' in sys.argv: |
| 30 | + RLP_BLOCKS_FILE = sys.argv[sys.argv.index('--rlp_blocks') + 1] |
| 31 | + |
| 32 | +BENCHMARK = 0 |
| 33 | +if '--benchmark' in sys.argv: |
| 34 | + BENCHMARK = int(sys.argv[sys.argv.index('--benchmark') + 1]) |
| 35 | + |
| 36 | +_path, _file = os.path.split(STATE_LOAD_FN) |
| 37 | +if _file in os.listdir(os.path.join(os.getcwd(), _path)): |
| 38 | + print 'loading state from %s ...' % STATE_LOAD_FN |
| 39 | + c = chain.Chain(json.load(open(STATE_LOAD_FN)), Env()) |
| 40 | + print 'loaded.' |
| 41 | +elif 'genesis_frontier.json' not in os.listdir(os.getcwd()): |
| 42 | + print 'Please download genesis_frontier.json from ' + \ |
| 43 | + 'http://vitalik.ca/files/genesis_frontier.json' |
| 44 | + sys.exit() |
| 45 | +else: |
| 46 | + c = chain.Chain(json.load(open('genesis_frontier.json')), Env()) |
| 47 | + assert c.state.trie.root_hash.encode('hex') == \ |
| 48 | + 'd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544' |
| 49 | + assert c.state.prev_headers[0].hash.encode('hex') == \ |
| 50 | + 'd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' |
| 51 | + print 'state generated from genesis' |
| 52 | +print 'Attempting to open %s' % RLP_BLOCKS_FILE |
| 53 | +_path, _file = os.path.split(RLP_BLOCKS_FILE) |
| 54 | +if not _path or _file not in os.listdir(_path): |
| 55 | + print 'Please download 200kblocks.rlp from http://vitalik.ca/files/200kblocks.rlp' + \ |
| 56 | + 'and put it in this directory to continue the test' |
| 57 | + sys.exit() |
| 58 | + |
| 59 | +batch_size = 1024 * 10240 # approximately 10000 blocks |
| 60 | +f = open(RLP_BLOCKS_FILE) |
| 61 | + |
| 62 | +# skip already processed blocks |
| 63 | +skip = c.state.block_number + 1 |
| 64 | +print 'Skipping %d' % skip |
| 65 | +count = 0 |
| 66 | +block_rlps = f.readlines(batch_size) |
| 67 | +while len(block_rlps) > 0: |
| 68 | + if len(block_rlps) + count <= skip: |
| 69 | + count += len(block_rlps) |
| 70 | + block_rlps = f.readlines(batch_size) |
| 71 | + else: |
| 72 | + block_rlps = block_rlps[skip - count:] |
| 73 | + count = skip |
| 74 | + break |
| 75 | +print "skipped %d processed blocks" % skip |
| 76 | + |
| 77 | + |
| 78 | +def report(st, num_blks, num_txs, gas_used): |
| 79 | + now = time.time() |
| 80 | + elapsed = now - st |
| 81 | + tps = num_txs / elapsed |
| 82 | + bps = num_blks / elapsed |
| 83 | + gps = gas_used / elapsed |
| 84 | + print '%.2f >>> elapsed:%d blocks:%d txs:%d gas:%d bps:%d tps:%d gps:%d' % (now, elapsed, num_blks, num_txs, gas_used, bps, tps, gps) |
| 85 | + |
| 86 | + |
| 87 | +def check_snapshot_consistency(snapshot, env=None): |
| 88 | + if env: |
| 89 | + c = chain.Chain(env=env) |
| 90 | + else: |
| 91 | + c = chain.Chain(snapshot, Env()) |
| 92 | + snapshot2 = c.state.to_snapshot() |
| 93 | + if snapshot != snapshot2: # FIXME |
| 94 | + for i, ss in enumerate([snapshot, snapshot2]): |
| 95 | + fn = '/tmp/{}_{}'.format(STATE_STORE_FN, i) |
| 96 | + open(fn, 'w').write(json.dumps(snapshot)) |
| 97 | + raise Exception("snapshot difference, see {}*".format(fn[:-1])) |
| 98 | + |
| 99 | + |
| 100 | +def snapshot(c, num_blocks): |
| 101 | + print 'creating snapshot' |
| 102 | + snapshot = c.state.to_snapshot() |
| 103 | + if (num_blocks / SAVE_INTERVAL) % 2 == 1: |
| 104 | + check_snapshot_consistency(snapshot, env=None) |
| 105 | + else: |
| 106 | + check_snapshot_consistency(snapshot, env=c.env) |
| 107 | + # store checkpoint |
| 108 | + if num_blocks % SNAPSHOT_INTERVAL == 0: |
| 109 | + fn = STATE_SNAPSHOT_FN.format(num_blocks / 1000) |
| 110 | + elif num_blocks in MANUAL_SNAPSHOTS: |
| 111 | + fn = STATE_SNAPSHOT_FN.format(num_blocks) |
| 112 | + else: |
| 113 | + fn = STATE_STORE_FN |
| 114 | + open(fn, 'w').write(json.dumps(snapshot, indent=4)) |
| 115 | + |
| 116 | +REPORT_INTERVAL = 1000 |
| 117 | +SAVE_INTERVAL = 10 * 1000 |
| 118 | +SNAPSHOT_INTERVAL = 100 * 1000 |
| 119 | + |
| 120 | +MANUAL_SNAPSHOTS = [68000, 68382, 68666, 69000, 909330] |
| 121 | + |
| 122 | +# don't check pow |
| 123 | +BlockHeader.check_pow = lambda *args: True |
| 124 | + |
| 125 | +# process blocks |
| 126 | +st = time.time() |
| 127 | +num_blks = 0 |
| 128 | +num_txs = 0 |
| 129 | +gas_used = 0 |
| 130 | +while len(block_rlps) > 0: |
| 131 | + for block in block_rlps: |
| 132 | + # print 'prevh:', s.prev_headers |
| 133 | + block = rlp.decode(block.strip().decode('hex'), Block) |
| 134 | + assert c.add_block(block) |
| 135 | + num_blks += 1 |
| 136 | + num_txs += len(block.transactions) |
| 137 | + gas_used += block.gas_used |
| 138 | + if BENCHMARK > 0: |
| 139 | + report(st, num_blks, num_txs, gas_used) |
| 140 | + if num_blks == BENCHMARK: |
| 141 | + print "Benchmark completed (%d blocks)." % num_blks |
| 142 | + sys.exit() |
| 143 | + else: |
| 144 | + num_blocks = block.header.number + 1 |
| 145 | + if num_blocks % REPORT_INTERVAL == 0 or num_blocks in MANUAL_SNAPSHOTS: |
| 146 | + report(st, REPORT_INTERVAL, num_txs, gas_used) |
| 147 | + st = time.time() |
| 148 | + num_blks = 0 |
| 149 | + num_txs = 0 |
| 150 | + gas_used = 0 |
| 151 | + if num_blocks % SAVE_INTERVAL == 0 or num_blocks in MANUAL_SNAPSHOTS: |
| 152 | + snapshot(c, num_blocks) |
| 153 | + st = time.time() |
| 154 | + num_blks = 0 |
| 155 | + num_txs = 0 |
| 156 | + gas_used = 0 |
| 157 | + block_rlps = f.readlines(batch_size) |
| 158 | + |
| 159 | +print 'Test successful' |
0 commit comments