def run_block_test(params, config_overrides=None): if config_overrides is None: config_overrides = {} env = Env(db.EphemDB()) genesis_decl = {} for param in ("bloom", "timestamp", "nonce", "extraData", "gasLimit", "coinbase", "difficulty", "parentHash", "mixHash", "gasUsed"): genesis_decl[param] = params["genesisBlockHeader"][param] genesis_decl["alloc"] = params["pre"] old_config = copy.deepcopy(env.config) for k, v in config_overrides.items(): env.config[k] = v # print('overrides', config_overrides) s = state_from_genesis_declaration(genesis_decl, env, allow_empties=True) initialize_genesis_keys(s, Block(s.prev_headers[0], [], [])) c = chain.Chain(genesis=s, localtime=2**99) # print('h', encode_hex(c.state.prev_headers[0].state_root)) # print(c.state.to_dict()) # print(params["pre"]) assert c.state.env == env assert c.state.prev_headers[0].state_root == safe_decode( params["genesisBlockHeader"]["stateRoot"]), ( encode_hex(c.state.prev_headers[0].state_root), params["genesisBlockHeader"]["stateRoot"]) assert c.state.trie.root_hash == safe_decode( params["genesisBlockHeader"]["stateRoot"]) assert c.state.prev_headers[0].hash == safe_decode( params["genesisBlockHeader"]["hash"]) #print('std', c.state.to_dict()) for blk in params["blocks"]: if 'blockHeader' not in blk: success = True try: rlpdata = safe_decode(blk["rlp"][2:]) success = c.add_block(rlp.decode(rlpdata, Block)) except (ValueError, TypeError, AttributeError, VerificationFailed, DecodingError, DeserializationError, InvalidTransaction, InvalidNonce, KeyError) as e: success = False assert not success else: rlpdata = safe_decode(blk["rlp"][2:]) assert c.add_block(rlp.decode(rlpdata, Block)) env.config = old_config
def init_state(env, pre): # Setup env state = State( env=Env(config=konfig), block_prevhash=decode_hex(remove_0x_head(env['previousHash'])), prev_headers=[ mk_fake_header(i) for i in range( parse_int_or_hex(env['currentNumber']) - 1, max(-1, parse_int_or_hex(env['currentNumber']) - 257), -1) ], block_number=parse_int_or_hex(env['currentNumber']), block_coinbase=decode_hex(remove_0x_head(env['currentCoinbase'])), block_difficulty=parse_int_or_hex(env['currentDifficulty']), gas_limit=parse_int_or_hex(env['currentGasLimit']), timestamp=parse_int_or_hex(env['currentTimestamp'])) # Fill up pre for address, h in list(pre.items()): assert len(address) in (40, 42) address = decode_hex(remove_0x_head(address)) assert set(h.keys()) == set(['code', 'nonce', 'balance', 'storage']) state.set_nonce(address, parse_int_or_hex(h['nonce'])) state.set_balance(address, parse_int_or_hex(h['balance'])) state.set_code(address, decode_hex(remove_0x_head(h['code']))) for k, v in h['storage'].items(): state.set_storage_data(address, big_endian_to_int(decode_hex(k[2:])), big_endian_to_int(decode_hex(v[2:]))) state.commit(allow_empties=True) # state.commit() return state
def make_casper_genesis(validators, alloc, timestamp=0, epoch_length=100): state = mk_basic_state(alloc, None, env=Env(config=casper_config)) state.gas_limit = 10**8 * (len(validators) + 1) state.timestamp = timestamp state.block_difficulty = 1 header = state.prev_headers[0] header.timestamp = timestamp header.difficulty = 1 ct = get_casper_ct() initialize(state) casper_contract_bootstrap(state, timestamp=header.timestamp, gas_limit=header.gas_limit) # Add validators for i, (vcode, deposit_size, randao_commitment, address) in enumerate(validators): validator_inject(state, vcode, deposit_size, randao_commitment, address, i, ct) # Start the first epoch casper_start_epoch(state) assert call_casper(state, 'getEpoch', []) == 0 assert call_casper(state, 'getTotalDeposits', []) == sum([d for a, d, r, a in validators]) state.set_storage_data( utils.normalize_address(state.config['METROPOLIS_BLOCKHASH_STORE']), state.block_number % state.config['METROPOLIS_WRAPAROUND'], header.hash) state.commit() return state
def get_contract_code(init_code): s = State(env=Env(config=casper_config)) s.gas_limit = 10**9 apply_transaction(s, Transaction(0, 0, 10**8, '', 0, init_code)) addr = utils.mk_metropolis_contract_address( casper_config['METROPOLIS_ENTRY_POINT'], init_code) o = s.get_code(addr) assert o return o
def get_env(env): d = { None: config_metropolis, 'mainnet': default_config, 'homestead': config_homestead, 'tangerine': config_tangerine, 'spurious': config_spurious, 'metropolis': config_metropolis, } return env if isinstance(env, Env) else Env(config=d[env])
def check_snapshot_consistency(snapshot, env=None): if env: c = chain.Chain(env=env) else: c = chain.Chain(snapshot, Env()) snapshot2 = c.state.to_snapshot() if snapshot != snapshot2: # FIXME for i, ss in enumerate([snapshot, snapshot2]): fn = '/tmp/{}_{}'.format(STATE_STORE_FN, i) open(fn, 'w').write(json.dumps(snapshot)) raise Exception("snapshot difference, see {}*".format(fn[:-1]))
def __init__(self, root=b'', env=Env(), executing_on_head=False, **kwargs): self.env = env self.trie = SecureTrie(Trie(RefcountDB(self.db), root)) for k, v in STATE_DEFAULTS.items(): setattr(self, k, kwargs.get(k, copy.copy(v))) self.journal = [] self.cache = {} self.log_listeners = [] self.deletes = [] self.changed = {} self.executing_on_head = executing_on_head
def ephemeral_clone(self): snapshot = self.to_snapshot(root_only=True, no_prevblocks=True) env2 = Env(OverlayDB(self.env.db), self.env.config) s = State.from_snapshot(snapshot, env2) for param in STATE_DEFAULTS: setattr(s, param, getattr(self, param)) s.recent_uncles = self.recent_uncles s.prev_headers = self.prev_headers for acct in self.cache.values(): assert not acct.touched or not acct.deleted s.journal = copy.copy(self.journal) s.cache = {} return s
def __init__(self, genesis): env = Env(EphemDB(), konfig) if not genesis: genesis = mk_genesis_data(env) if 'config' in genesis: if 'homesteadBlock' in genesis['config']: env.config['HOMESTEAD_FORK_BLKNUM'] = int(genesis['config']['homesteadBlock']) env.config['DAO_FORK_BLKNUM'] = int(genesis['config']['homesteadBlock']) env.config['ANTI_DOS_FORK_BLKNUM'] = int(genesis['config']['homesteadBlock']) env.config['SPURIOUS_DRAGON_FORK_BLKNUM'] = int(genesis['config']['homesteadBlock']) self.state = state_from_genesis_declaration(genesis, env) initialize_genesis_keys(self.state, Block(self.state.prev_headers[0], [], []))
def mk_basic_state(alloc, header=None, env=None, executing_on_head=False): env = env or Env() state = State(env=env, executing_on_head=executing_on_head) if not header: header = { "number": 0, "gas_limit": env.config['BLOCK_GAS_LIMIT'], "gas_used": 0, "timestamp": 1467446877, "difficulty": 1, "uncles_hash": '0x' + encode_hex(BLANK_UNCLES_HASH) } h = BlockHeader(number=parse_as_int(header['number']), timestamp=parse_as_int(header['timestamp']), difficulty=parse_as_int(header['difficulty']), gas_limit=parse_as_int(header['gas_limit']), uncles_hash=parse_as_bin(header['uncles_hash'])) state.prev_headers = [h] for addr, data in alloc.items(): addr = normalize_address(addr) assert len(addr) == 20 if 'wei' in data: state.set_balance(addr, parse_as_int(data['wei'])) if 'balance' in data: state.set_balance(addr, parse_as_int(data['balance'])) if 'code' in data: state.set_code(addr, parse_as_bin(data['code'])) if 'nonce' in data: state.set_nonce(addr, parse_as_int(data['nonce'])) if 'storage' in data: for k, v in data['storage'].items(): state.set_storage_data(addr, parse_as_bin(k), parse_as_bin(v)) state.block_number = header["number"] state.gas_limit = header["gas_limit"] state.timestamp = header["timestamp"] state.block_difficulty = header["difficulty"] state.commit() return state
def __init__(self, genesis=None, env=None, coinbase=b'\x00' * 20, new_head_cb=None, reset_genesis=False, localtime=None, **kwargs): self.env = env or Env() # Initialize the state if b'head_hash' in self.db: # new head tag self.state = self.mk_poststate_of_blockhash( self.db.get(b'head_hash')) print('Initializing chain from saved head, #%d (%s)' % (self.state.prev_headers[0].number, encode_hex(self.state.prev_headers[0].hash))) elif genesis is None: raise Exception("Need genesis decl!") elif isinstance(genesis, State): assert env is None self.state = genesis self.env = self.state.env print('Initializing chain from provided state') elif "extraData" in genesis: self.state = state_from_genesis_declaration(genesis, self.env) reset_genesis = True print('Initializing chain from provided genesis declaration') elif "prev_headers" in genesis: self.state = State.from_snapshot(genesis, self.env) reset_genesis = True print('Initializing chain from provided state snapshot, %d (%s)' % (self.state.block_number, encode_hex(self.state.prev_headers[0].hash[:8]))) else: print('Initializing chain from new state based on alloc') self.state = mk_basic_state( genesis, { "number": kwargs.get('number', 0), "gas_limit": kwargs.get('gas_limit', 4712388), "gas_used": kwargs.get('gas_used', 0), "timestamp": kwargs.get('timestamp', 1467446877), "difficulty": kwargs.get('difficulty', 2**25), "hash": kwargs.get('prevhash', '00' * 32), "uncles_hash": kwargs.get('uncles_hash', '0x' + encode_hex(BLANK_UNCLES_HASH)) }, self.env) reset_genesis = True assert self.env.db == self.state.db initialize(self.state) self.new_head_cb = new_head_cb self.head_hash = self.state.prev_headers[0].hash self.checkpoint_head_hash = b'\x00' * 32 self.db.put(b'cp_subtree_score' + b'\x00' * 32, 2 / 3.) self.commit_logs = [] self.casper_address = self.config['CASPER_ADDRESS'] self.db.put(b'GENESIS_NUMBER', to_string(self.state.block_number)) assert self.state.block_number == self.state.prev_headers[0].number if reset_genesis: self.genesis = Block(self.state.prev_headers[0], [], []) initialize_genesis_keys(self.state, self.genesis) else: self.genesis = self.get_block_by_number(0) self.db.put(b'cp_subtree_score' + self.genesis.hash, 2 / 3.) self.min_gasprice = kwargs.get('min_gasprice', 5 * 10**9) self.coinbase = coinbase self.extra_data = 'moo ha ha says the laughing cow.' self.time_queue = [] self.parent_queue = {} self.localtime = time.time() if localtime is None else localtime
if '--rlp_blocks' in sys.argv: RLP_BLOCKS_FILE = sys.argv[sys.argv.index('--rlp_blocks') + 1] BENCHMARK = 0 if '--benchmark' in sys.argv: BENCHMARK = int(sys.argv[sys.argv.index('--benchmark') + 1]) DB_DIR = '/tmp/%d' % random.randrange(int(time.time() * 1000000)) if '--db' in sys.argv: DB_DIR = int(sys.argv[sys.argv.index('--db') + 1]) _path, _file = os.path.split(STATE_LOAD_FN) if _file in os.listdir(os.path.join(os.getcwd(), _path)): print('loading state from %s ...' % STATE_LOAD_FN) c = chain.Chain(json.load(open(STATE_LOAD_FN)), Env()) print('loaded.') elif 'genesis_frontier.json' not in os.listdir(os.getcwd()): print('Please download genesis_frontier.json from ' + 'http://vitalik.ca/files/genesis_frontier.json') sys.exit() else: c = chain.Chain(json.load(open('genesis_frontier.json')), Env(LevelDB(DB_DIR))) assert c.state.trie.root_hash.encode('hex') == \ 'd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544' assert c.state.prev_headers[0].hash.encode('hex') == \ 'd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' print('state generated from genesis') print('Attempting to open %s' % RLP_BLOCKS_FILE) _path, _file = os.path.split(RLP_BLOCKS_FILE)
def __init__(self, genesis=None, env=None, new_head_cb=None, reset_genesis=False, localtime=None, max_history=1000, **kwargs): self.env = env or Env() # Initialize the state if b'head_hash' in self.db: # new head tag self.state = self.mk_poststate_of_blockhash( self.db.get('head_hash')) self.state.executing_on_head = True print('Initializing chain from saved head, #%d (%s)' % (self.state.prev_headers[0].number, encode_hex(self.state.prev_headers[0].hash))) elif genesis is None: raise Exception("Need genesis decl!") elif isinstance(genesis, State): assert env is None self.state = genesis self.env = self.state.env print('Initializing chain from provided state') reset_genesis = True elif "extraData" in genesis: self.state = state_from_genesis_declaration(genesis, self.env, executing_on_head=True) reset_genesis = True print('Initializing chain from provided genesis declaration') elif "prev_headers" in genesis: self.state = State.from_snapshot(genesis, self.env, executing_on_head=True) reset_genesis = True print('Initializing chain from provided state snapshot, %d (%s)' % (self.state.block_number, encode_hex(self.state.prev_headers[0].hash[:8]))) elif isinstance(genesis, dict): print('Initializing chain from new state based on alloc') self.state = mk_basic_state( genesis, { "number": kwargs.get('number', 0), "gas_limit": kwargs.get('gas_limit', self.env.config['BLOCK_GAS_LIMIT']), "gas_used": kwargs.get('gas_used', 0), "timestamp": kwargs.get('timestamp', 1467446877), "difficulty": kwargs.get('difficulty', 2**25), "hash": kwargs.get('prevhash', '00' * 32), "uncles_hash": kwargs.get('uncles_hash', '0x' + encode_hex(BLANK_UNCLES_HASH)) }, self.env) reset_genesis = True assert self.env.db == self.state.db initialize(self.state) self.new_head_cb = new_head_cb if self.state.block_number == 0: assert self.state.block_number == self.state.prev_headers[0].number else: assert self.state.block_number - 1 == self.state.prev_headers[ 0].number if reset_genesis: if isinstance(self.state.prev_headers[0], FakeHeader): header = self.state.prev_headers[0].to_block_header() else: header = self.state.prev_headers[0] self.genesis = Block(header) self.state.prev_headers[0] = header initialize_genesis_keys(self.state, self.genesis) else: self.genesis = self.get_block_by_number(0) self.head_hash = self.state.prev_headers[0].hash self.time_queue = [] self.parent_queue = {} self.localtime = time.time() if localtime is None else localtime self.max_history = max_history