def make_frontier_receipt(base_header: BlockHeader, transaction: BaseTransaction, computation: BaseComputation) -> Receipt: # Reusable for other forks # This skips setting the state root (set to 0 instead). The logic for making a state root # lives in the FrontierVM, so that state merkelization at each receipt is skipped at Byzantium+. logs = [ Log(address, topics, data) for address, topics, data in computation.get_log_entries() ] gas_remaining = computation.get_gas_remaining() gas_refund = computation.get_gas_refund() tx_gas_used = ( transaction.gas - gas_remaining ) - min( gas_refund, (transaction.gas - gas_remaining) // 2, ) gas_used = base_header.gas_used + tx_gas_used receipt = Receipt( state_root=ZERO_HASH32, gas_used=gas_used, logs=logs, ) return receipt
def make_frontier_receipt(base_header, transaction, computation, state): # Reusable for other forks logs = [ Log(address, topics, data) for address, topics, data in computation.get_log_entries() ] gas_remaining = computation.get_gas_remaining() gas_refund = computation.get_gas_refund() tx_gas_used = ( transaction.gas - gas_remaining ) - min( gas_refund, (transaction.gas - gas_remaining) // 2, ) gas_used = base_header.gas_used + tx_gas_used receipt = Receipt( state_root=state.state_root, gas_used=gas_used, logs=logs, ) return receipt
def hash_log_entries(log_entries: Iterable[Tuple[bytes, bytes, bytes]]) -> Hash32: """ Helper function for computing the RLP hash of the logs from transaction execution. """ logs = [Log(*entry) for entry in log_entries] encoded_logs = rlp.encode(logs) logs_hash = keccak(encoded_logs) return logs_hash
def hash_log_entries(log_entries): """ Helper function for computing the RLP hash of the logs from transaction execution. """ logs = [Log(*entry) for entry in log_entries] encoded_logs = rlp.encode(logs) logs_hash = keccak(encoded_logs) return logs_hash
def make_receipt( self, status: bytes, gas_used: int, log_entries: Tuple[Tuple[bytes, Tuple[int, ...], bytes], ...] ) -> ReceiptAPI: logs = [ Log(address, topics, data) for address, topics, data in log_entries ] # TypedTransaction is responsible for wrapping this into a TypedReceipt return Receipt( state_root=status, gas_used=gas_used, logs=logs, )
def make_receipt( self, status: bytes, gas_used: int, log_entries: Tuple[Tuple[bytes, Tuple[int, ...], bytes], ...] ) -> ReceiptAPI: # 'status' is a misnomer in Frontier. Until Byzantium, it is the # intermediate state root. logs = [ Log(address, topics, data) for address, topics, data in log_entries ] return Receipt( state_root=status, gas_used=gas_used, logs=logs, )
def make_frontier_receipt(computation: ComputationAPI, new_cumulative_gas_used: int) -> ReceiptAPI: # Reusable for other forks # This skips setting the state root (set to 0 instead). The logic for making a state root # lives in the FrontierVM, so that state merkelization at each receipt is skipped at Byzantium+. logs = [ Log(address, topics, data) for address, topics, data in computation.get_log_entries() ] receipt = Receipt( state_root=ZERO_HASH32, gas_used=new_cumulative_gas_used, logs=logs, ) return receipt
def apply_to_state(pre_state, txs, received_log, genesis_blocks): alice_nonce = pre_state.account_db.get_nonce(decode_hex(alice_address)) txs = make_byzantium_txs(txs, alice_nonce) nonce = pre_state.account_db.get_nonce(decode_hex(pusher_address)) flattened_payloads = [message.payload for l in received_log.values() for message in l] for payload in flattened_payloads: unsigned_tx = { "gas": 3000000, "gas_price": int("0x2", 16), "nonce": nonce, "to": payload.toAddress, "value": payload.value, "data": payload.data, } unsigned_tx = ByzantiumTransaction.create_unsigned_transaction(**unsigned_tx) tx = unsigned_tx.as_signed_transaction(keys.PrivateKey(decode_hex(pusher_key))) nonce += 1 txs.append(tx) state_roots = [] computations = [] all_logs = [] receipts = [] for tx in txs: if encode_hex(tx.sender)==alice_address: assert tx.nonce not in alice_nonces, "Nonce {} has occured before".format(tx.nonce) alice_nonces.append(tx.nonce) state_root, computation = pre_state.apply_transaction(tx) state_roots.append(state_root) computations.append(computation) logs = [ Log(address, topics, data) for address, topics, data in computation.get_log_entries() ] all_logs.append(logs) receipt = Receipt( state_root=state_root, gas_used=50, # This is a fake filled-in gas_used value logs=logs, ) receipts.append(receipt) sent_log = {} for ID in SHARD_IDS: sent_log[ID] = [] for receipt in receipts: for event in contract.events.SentMessage().processReceipt(receipt): sent_log[event.args.shard_ID].append( # This is not a message that will be stored in the sent log, it will be # postprocessed in make_block. Namely, the next hop shard will be computed, # the base block will be computed and TTL will be assigned. Message( Block(event.args.shard_ID, sources={ID : genesis_blocks[ID] for ID in SHARD_IDS}), 10, event.args.shard_ID, MessagePayload( event.args.sendFromAddress.lower()[2:], event.args.sendToAddress.lower()[2:], event.args.value, event.args.data, ) ) ) return pre_state, sent_log