def apply_block(state, block): # Pre-processing and verification snapshot = state.snapshot() cs = get_consensus_strategy(state.config) try: # Start a new block context cs.initialize(state, block) # Basic validation assert validate_header(state, block.header) assert cs.check_seal(state, block.header) assert cs.validate_uncles(state, block) assert validate_transaction_tree(state, block) # Process transactions for tx in block.transactions: apply_transaction(state, tx) # Finalize (incl paying block rewards) cs.finalize(state, block) # Verify state root, tx list root, receipt root #print('std', state.to_dict()) assert verify_execution_results(state, block) # Post-finalize (ie. add the block header to the state for now) post_finalize(state, block) except (ValueError, AssertionError) as e: state.revert(snapshot) raise e return state
def test_transaction(db): k, v, k2, v2 = accounts() chain = Chain({v: {"balance": utils.denoms.ether * 1}}, difficulty=1) blk = mine_next_block(chain) tx = get_transaction() assert tx not in blk.transactions messages.apply_transaction(chain.state, tx) assert chain.state.get_balance(v) == utils.denoms.finney * 990 assert chain.state.get_balance(v2) == utils.denoms.finney * 10
def make_casper_genesis(alloc, epoch_length, withdrawal_delay, base_interest_factor, base_penalty_factor): # The Casper-specific config declaration casper_config = copy.deepcopy(config.default_config) casper_config['HOMESTEAD_FORK_BLKNUM'] = 0 casper_config['ANTI_DOS_FORK_BLKNUM'] = 0 casper_config['CLEARING_FORK_BLKNUM'] = 0 casper_config['CONSENSUS_STRATEGY'] = 'hybrid_casper' casper_config['NULL_SENDER'] = utils.sha3('NULL_SENDER') casper_config['EPOCH_LENGTH'] = epoch_length casper_config['WITHDRAWAL_DELAY'] = withdrawal_delay casper_config['OWNER'] = a0 casper_config['BASE_INTEREST_FACTOR'] = base_interest_factor casper_config['BASE_PENALTY_FACTOR'] = base_penalty_factor # Get initialization txs init_txs, casper_address = mk_initializers(casper_config, casper_config['NULL_SENDER']) casper_config['CASPER_ADDRESS'] = casper_address # Create state and apply required state_transitions for initializing Casper state = genesis_helpers.mk_basic_state( alloc, None, env=config.Env(config=casper_config)) state.gas_limit = 10**8 for tx in init_txs: state.set_balance(utils.privtoaddr(casper_config['NULL_SENDER']), 15**18) success, output = apply_transaction(state, tx) assert success state.gas_used = 0 state.set_balance(utils.privtoaddr(casper_config['NULL_SENDER']), 0) consensus.initialize(state) state.commit() return state
def compute_state_test_unit(state, txdata, indices, konfig): state.env.config = konfig s = state.snapshot() try: # Create the transaction tx = transactions.Transaction( nonce=parse_int_or_hex(txdata['nonce'] or b"0"), gasprice=parse_int_or_hex(txdata['gasPrice'] or b"0"), startgas=parse_int_or_hex(txdata['gasLimit'][indices["gas"]] or b"0"), to=decode_hex(remove_0x_head(txdata['to'])), value=parse_int_or_hex(txdata['value'][indices["value"]] or b"0"), data=decode_hex(remove_0x_head(txdata['data'][indices["data"]]))) if 'secretKey' in txdata: tx.sign(decode_hex(remove_0x_head(txdata['secretKey']))) else: tx.v = parse_int_or_hex(txdata['v']) # Run it prev = state.to_dict() success, output = apply_transaction(state, tx) print("Applied tx") except InvalidTransaction as e: print("Exception: %r" % e) success, output = False, b'' # state.set_code('0x3e180b1862f9d158abb5e519a6d8605540c23682', b'') state.commit() post = state.to_dict() # print('pozt', post) output_decl = { "hash": '0x' + encode_hex(state.trie.root_hash), "indexes": indices, "diff": mk_state_diff(prev, post) } state.revert(s) return output_decl
def initialize(state, block=None): config = state.config state.txindex = 0 state.gas_used = 0 state.bloom = 0 state.receipts = [] if block is not None: update_block_env_variables(state, block) # Initalize the next epoch in the Casper contract if state.block_number % state.config['EPOCH_LENGTH'] == 0 and state.block_number != 0: key, account = state.config['NULL_SENDER'], privtoaddr(state.config['NULL_SENDER']) data = casper_utils.casper_translator.encode('initialize_epoch', [state.block_number // state.config['EPOCH_LENGTH']]) transaction = transactions.Transaction(state.get_nonce(account), 0, 3141592, state.config['CASPER_ADDRESS'], 0, data).sign(key) success, output = apply_transaction(state, transaction) assert success if state.is_DAO(at_fork_height=True): for acct in state.config['CHILD_DAO_LIST']: state.transfer_value( acct, state.config['DAO_WITHDRAWER'], state.get_balance(acct)) if state.is_METROPOLIS(at_fork_height=True): state.set_code(utils.normalize_address( config["METROPOLIS_STATEROOT_STORE"]), config["METROPOLIS_GETTER_CODE"]) state.set_code(utils.normalize_address( config["METROPOLIS_BLOCKHASH_STORE"]), config["METROPOLIS_GETTER_CODE"])
def direct_tx(self, transaction): self.last_tx = transaction if self.last_sender is not None and privtoaddr( self.last_sender) != transaction.sender: self.last_sender = None success, output = apply_transaction(self.head_state, transaction) self.block.transactions.append(transaction) if not success: raise TransactionFailed() return output
def broadcast_deposit(self): if not self.valcode_tx or not self.deposit_tx: # Generate transactions valcode_tx = self.mk_validation_code_tx() valcode_addr = utils.mk_contract_address(self.coinbase, self.nonce-1) deposit_tx = self.mk_deposit_tx(3 * 10**18, valcode_addr) # Verify the transactions pass temp_state = self.chain.state.ephemeral_clone() valcode_success, o1 = apply_transaction(temp_state, valcode_tx) deposit_success, o2 = apply_transaction(temp_state, deposit_tx) if not (valcode_success and deposit_success): self.nonce = self.chain.state.get_nonce(self.coinbase) raise Exception('Valcode tx or deposit tx failed') self.valcode_tx = valcode_tx log.info('Valcode Tx generated: {}'.format(str(valcode_tx))) self.valcode_addr = valcode_addr self.deposit_tx = deposit_tx log.info('Deposit Tx generated: {}'.format(str(deposit_tx))) self.broadcast_transaction(self.valcode_tx) self.broadcast_transaction(self.deposit_tx)
def broadcast_logout(self, login_logout_flag): epoch = self.chain.state.block_number // self.epoch_length # Generage the message logout_msg = casper_utils.mk_logout(self.get_validator_index(self.chain.state), epoch, self.key) # Generate transactions logout_tx = self.mk_logout(logout_msg) # Verify the transactions pass temp_state = self.chain.state.ephemeral_clone() logout_success, o1 = apply_transaction(temp_state, logout_tx) if not logout_success: self.nonce = self.chain.state.get_nonce(self.coinbase) raise Exception('Valcode tx or deposit tx failed') log.info('Login/logout Tx generated: {}'.format(str(logout_tx))) self.broadcast_transaction(logout_tx)
def tx(self, sender=k0, to=b'\x00' * 20, value=0, data=b'', startgas=STARTGAS, gasprice=GASPRICE): sender_addr = privtoaddr(sender) transaction = Transaction(self.state.get_nonce(sender_addr), gasprice, startgas, to, value, data).sign(sender) success, output = apply_transaction(self.state, transaction) if not success: raise TransactionFailed() return output