Skip to content
This repository was archived by the owner on May 23, 2023. It is now read-only.

Commit 36536e3

Browse files
author
Jan Xie
committed
fix chain index keys; smooth convert from old data
1 parent 5379914 commit 36536e3

File tree

1 file changed

+40
-29
lines changed

1 file changed

+40
-29
lines changed

ethereum/chain.py

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
1+
import json
2+
import random
13
import time
2-
from ethereum import utils
3-
from ethereum.utils import parse_as_bin, big_endian_to_int
4-
from ethereum import parse_genesis_declaration
5-
from ethereum.state_transition import apply_block, initialize, \
6-
pre_seal_finalize, post_seal_finalize, apply_transaction, mk_receipt_sha, \
7-
mk_transaction_sha, calc_difficulty, Receipt, mk_receipt, \
8-
update_block_env_variables, validate_uncles, validate_block_header
4+
95
import rlp
106
from rlp.utils import encode_hex
11-
from ethereum.exceptions import InvalidNonce, InsufficientStartGas, UnsignedTransaction, \
12-
BlockGasLimitReached, InsufficientBalance
13-
from ethereum.slogging import get_logger
7+
8+
from ethereum import parse_genesis_declaration
9+
from ethereum.block import Block, BlockHeader, FakeHeader, BLANK_UNCLES_HASH
1410
from ethereum.config import Env
11+
from ethereum.slogging import get_logger
1512
from ethereum.state import State, dict_to_prev_header
16-
from ethereum.block import Block, BlockHeader, FakeHeader, BLANK_UNCLES_HASH
17-
import random
18-
import json
13+
from ethereum.state_transition import apply_block, initialize, \
14+
update_block_env_variables
15+
from ethereum.utils import parse_as_bin, big_endian_to_int
16+
1917
log = get_logger('eth.chain')
2018

2119

2220
class Chain(object):
2321

2422
def __init__(self, genesis=None, env=None, coinbase=b'\x00' * 20, \
25-
new_head_cb=None, **kwargs):
23+
new_head_cb=None, reset_genesis=False, **kwargs):
2624
self.env = env or Env()
2725
# Initialize the state
28-
if 'head_hash' in self.db:
26+
if 'head_hash' in self.db: # new head tag
2927
self.state = self.mk_poststate_of_blockhash(self.db.get('head_hash'))
3028
print('Initializing chain from saved head, #%d (%s)' % \
3129
(self.state.prev_headers[0].number, encode_hex(self.state.prev_headers[0].hash)))
30+
elif 'HEAD' in self.db: # deprecated head tag
31+
self.state = self.mk_poststate_of_blockhash(self.db.get('HEAD'), convert=True)
32+
print('Converting chain from saved head in deprecated format, #%d (%s)' % \
33+
(self.state.prev_headers[0].number, encode_hex(self.state.prev_headers[0].hash)))
3234
elif genesis is None:
3335
raise Exception("Need genesis decl!")
3436
elif isinstance(genesis, State):
@@ -37,9 +39,11 @@ def __init__(self, genesis=None, env=None, coinbase=b'\x00' * 20, \
3739
elif "extraData" in genesis:
3840
self.state = parse_genesis_declaration.state_from_genesis_declaration(
3941
genesis, self.env)
42+
reset_genesis = True
4043
print('Initializing chain from provided genesis declaration')
4144
elif "prev_headers" in genesis:
4245
self.state = State.from_snapshot(genesis, self.env)
46+
reset_genesis = True
4347
print('Initializing chain from provided state snapshot, %d (%s)' % \
4448
(self.state.block_number, encode_hex(self.state.prev_headers[0].hash[:8])))
4549
else:
@@ -53,19 +57,23 @@ def __init__(self, genesis=None, env=None, coinbase=b'\x00' * 20, \
5357
"hash": kwargs.get('prevhash', '00' * 32),
5458
"uncles_hash": kwargs.get('uncles_hash', '0x' + encode_hex(BLANK_UNCLES_HASH))
5559
}, self.env)
60+
reset_genesis = True
5661

5762
initialize(self.state)
5863
self.new_head_cb = new_head_cb
5964

6065
self.head_hash = self.state.prev_headers[0].hash
61-
self.genesis = Block(self.state.prev_headers[0], [], [])
62-
self.db.put('state:'+self.head_hash, self.state.trie.root_hash)
63-
self.db.put('GENESIS_NUMBER', str(self.state.block_number))
64-
self.db.put('GENESIS_HASH', str(self.state.prev_headers[0].hash))
6566
assert self.state.block_number == self.state.prev_headers[0].number
66-
self.db.put('score:' + self.state.prev_headers[0].hash, "0")
67-
self.db.put('GENESIS_STATE', json.dumps(self.state.to_snapshot()))
68-
self.db.put(self.head_hash, 'GENESIS')
67+
self.db.put('state:'+self.head_hash, self.state.trie.root_hash)
68+
if reset_genesis:
69+
self.genesis = Block(self.state.prev_headers[0], [], [])
70+
self.db.put('GENESIS_NUMBER', str(self.state.block_number))
71+
self.db.put('GENESIS_HASH', str(self.state.prev_headers[0].hash))
72+
self.db.put('score:' + self.state.prev_headers[0].hash, "0")
73+
self.db.put('GENESIS_STATE', json.dumps(self.state.to_snapshot()))
74+
self.db.put(self.head_hash, 'GENESIS')
75+
else:
76+
self.genesis = self.get_block_by_number(0)
6977
self.min_gasprice = kwargs.get('min_gasprice', 5 * 10**9)
7078
self.coinbase = coinbase
7179
self.extra_data = 'moo ha ha says the laughing cow.'
@@ -84,14 +92,17 @@ def head(self):
8492
log.error(e)
8593
return None
8694

87-
def mk_poststate_of_blockhash(self, blockhash):
95+
def mk_poststate_of_blockhash(self, blockhash, convert=False):
8896
if blockhash not in self.db:
8997
raise Exception("Block hash %s not found" % encode_hex(blockhash))
90-
if self.db.get(blockhash) == 'GENESIS':
98+
99+
block_rlp = self.db.get(blockhash)
100+
if block_rlp == 'GENESIS':
91101
return State.from_snapshot(json.loads(self.db.get('GENESIS_STATE')), self.env)
102+
block = rlp.decode(block_rlp, Block)
103+
92104
state = State(env=self.env)
93-
state.trie.root_hash = self.db.get('state:'+blockhash)
94-
block = rlp.decode(self.db.get(blockhash), Block)
105+
state.trie.root_hash = block.header.state_root if convert else self.db.get('state:'+blockhash)
95106
update_block_env_variables(state, block)
96107
state.gas_used = block.header.gas_used
97108
state.txindex = len(block.transactions)
@@ -141,18 +152,18 @@ def get_block(self, blockhash):
141152
# parent hash and see that it is one of its children
142153
def add_child(self, child):
143154
try:
144-
existing = self.db.get('child:' + child.header.prevhash)
155+
existing = self.db.get('ci:' + child.header.prevhash)
145156
except:
146157
existing = ''
147158
existing_hashes = []
148159
for i in range(0, len(existing), 32):
149160
existing_hashes.append(existing[i: i+32])
150161
if child.header.hash not in existing_hashes:
151-
self.db.put('child:' + child.header.prevhash, existing + child.header.hash)
162+
self.db.put('ci:' + child.header.prevhash, existing + child.header.hash)
152163

153164
def get_blockhash_by_number(self, number):
154165
try:
155-
return self.db.get('block:' + str(number))
166+
return self.db.get('blocknumber:' + str(number))
156167
except:
157168
return None
158169

0 commit comments

Comments
 (0)