def apply_fixture_block_to_chain( block_fixture: Dict[str, Any], chain: BaseChain, perform_validation: bool = True ) -> Tuple[BaseBlock, BaseBlock, BaseBlock]: """ :return: (premined_block, mined_block, rlp_encoded_mined_block) """ # The block to import may be in a different block-class-range than the # chain's current one, so we use the block number specified in the # fixture to look up the correct block class. if 'blockHeader' in block_fixture: block_number = block_fixture['blockHeader']['number'] block_class = chain.get_vm_class_for_block_number( block_number).get_block_class() else: block_class = chain.get_vm().get_block_class() block = rlp.decode(block_fixture['rlp'], sedes=block_class) mined_block, _, _ = chain.import_block( block, perform_validation=perform_validation) rlp_encoded_mined_block = rlp.encode(mined_block, sedes=block_class) return (block, mined_block, rlp_encoded_mined_block)
def dict_to_spoof_transaction( chain: BaseChain, header: BlockHeader, transaction_dict: Dict[str, Any]) -> SpoofTransaction: """ Convert dicts used in calls & gas estimates into a spoof transaction """ txn_dict = normalize_transaction_dict(transaction_dict) sender = txn_dict.get('from', ZERO_ADDRESS) if 'nonce' in txn_dict: nonce = txn_dict['nonce'] else: vm = chain.get_vm(header) nonce = vm.state.account_db.get_nonce(sender) gas_price = txn_dict.get('gasPrice', 0) gas = txn_dict.get('gas', header.gas_limit) unsigned = chain.get_vm_class(header).create_unsigned_transaction( nonce=nonce, gas_price=gas_price, gas=gas, to=txn_dict['to'], value=txn_dict['value'], data=txn_dict['data'], ) return SpoofTransaction(unsigned, from_=sender)
def get_block_at_number(chain: BaseChain, at_block: Union[str, int]) -> BaseBlock: # mypy doesn't have user defined type guards yet # https://github.com/python/mypy/issues/5206 if is_integer(at_block) and at_block >= 0: # type: ignore # optimization to avoid requesting block, then header, then block again return chain.get_canonical_block_by_number(at_block) else: at_header = get_header(chain, at_block) return chain.get_block_by_header(at_header)
def genesis(chain_class: BaseChain, db: BaseAtomicDB = None, params: Dict[str, HeaderParams] = None, state: GeneralState = None) -> BaseChain: """ Initialize the given chain class with the given genesis header parameters and chain state. """ if state is None: genesis_state = {} # type: AccountState else: genesis_state = _fill_and_normalize_state(state) genesis_params_defaults = _get_default_genesis_params(genesis_state) if params is None: genesis_params = genesis_params_defaults else: genesis_params = merge(genesis_params_defaults, params) if db is None: base_db = AtomicDB() # type: BaseAtomicDB else: base_db = db return chain_class.from_genesis(base_db, genesis_params, genesis_state)
def get_header(chain: BaseChain, at_block: Union[str, int]) -> BlockHeader: if at_block == 'pending': raise NotImplementedError("RPC interface does not support the 'pending' block at this time") elif at_block == 'latest': at_header = chain.get_canonical_head() elif at_block == 'earliest': # TODO find if genesis block can be non-zero. Why does 'earliest' option even exist? at_header = chain.get_canonical_block_by_number(0).header # mypy doesn't have user defined type guards yet # https://github.com/python/mypy/issues/5206 elif is_integer(at_block) and at_block >= 0: # type: ignore at_header = chain.get_canonical_block_by_number(at_block).header else: raise TypeError("Unrecognized block reference: %r" % at_block) return at_header
def __init__(self, chain: BaseChain, initial_tx_validation_block_number: int) -> None: self.chain = chain self._initial_tx_class = self._get_tx_class_for_block_number( initial_tx_validation_block_number ) self._ordered_tx_classes = [ vm_class.get_transaction_class() for _, vm_class in chain.get_vm_configuration() ] self._initial_tx_class_index = self._ordered_tx_classes.index(self._initial_tx_class)
def block_to_dict( block: BaseBlock, chain: BaseChain, include_transactions: bool) -> Dict[str, Union[str, List[str]]]: header_dict = header_to_dict(block.header) block_dict: Dict[str, Union[str, List[str]]] = dict( header_dict, totalDifficulty=hex(chain.get_score(block.hash)), uncles=[encode_hex(uncle.hash) for uncle in block.uncles], size=hex(len(rlp.encode(block))), ) if include_transactions: # block_dict['transactions'] = map(transaction_to_dict, block.transactions) raise NotImplementedError( "Cannot return transaction object with block, yet") else: block_dict['transactions'] = [ encode_hex(tx.hash) for tx in block.transactions ] return block_dict
def _import_blocks(chain: BaseChain) -> BaseChain: for block in blocks: chain.import_block(block) return chain
def import_block(block: BaseBlock, chain: BaseChain) -> BaseChain: """ Import the provided ``block`` into the chain. """ chain.import_block(block) return chain
def account_db_at_block(chain: BaseChain, at_block: Union[str, int], read_only: bool=True) ->BaseAccountDB: at_header = get_header(chain, at_block) vm = chain.get_vm(at_header) return vm.state.account_db