nimbus-eth1/nimbus/p2p/executor.nim
Jordan Hrycaj fbff3aea68
Feature/goerli replay clique poa (#743)
* extract unused clique/mining support into separate file

why:
  mining is currently unsupported by nimbus

* Replay first 51840 transactions from Goerli block chain

why:
  Currently Goerli is loaded but the block headers are not verified.
  Replaying allows real data PoA development.

details:
  Simple stupid gzipped dump/undump layer for debugging based on
  the zlib module (no nim-faststream support.)

  This is a replay running against p2p/chain.persistBlocks() where
  the data were captured from.

* prepare stubs for PoA engine

* split executor source into sup-modules

why:
  make room for updates, clique integration should go into
  executor/update_poastate.nim

* Simplify p2p/executor.processBlock() function prototype

why:
  vmState argument always wraps basicChainDB

* split processBlock() into sub-functions

why:
  isolate the part where it will support clique/poa

* provided additional processTransaction() function prototype without _fork_ argument

why:
  with the exception of some tests, the _fork_ argument is always derived
  from the other prototype argument _vmState_

details:
  similar situation with makeReceipt()

* provide new processBlock() version explicitly supporting PoA

details:
  The new processBlock() version supporting PoA is the general one also
  supporting non-PoA networks, it needs an additional _Clique_ descriptor
  function argument for PoA state (if any.)
  The old processBlock() function without the _Clique_ descriptor argument
  retorns an error on PoA networgs (e.g. Goerli.)

* re-implemented Clique descriptor as _ref object_

why:
  gives more flexibility when moving around the descriptor object

details:
  also cleaned up a bit the clique sources

* comments for clarifying handling of Clique/PoA state descriptor
2021-07-06 14:14:45 +01:00

88 lines
3.3 KiB
Nim

# Nimbus
# Copyright (c) 2018 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.
import
./executor/[
calculate_reward,
executor_helpers,
process_block,
process_transaction]
export
calculate_reward.blockRewards,
executor_helpers.createBloom,
process_block,
process_transaction
#[
method executeTransaction(vmState: BaseVMState, transaction: Transaction): (Computation, BlockHeader) {.base.}=
# Execute the transaction in the vm
# TODO: introduced here: https://github.com/ethereum/py-evm/commit/21c57f2d56ab91bb62723c3f9ebe291d0b132dde
# Refactored/Removed here: https://github.com/ethereum/py-evm/commit/cc991bf
# Deleted here: https://github.com/ethereum/py-evm/commit/746defb6f8e83cee2c352a0ab8690e1281c4227c
raise newException(ValueError, "Must be implemented by subclasses")
method addTransaction*(vmState: BaseVMState, transaction: Transaction, c: Computation, b: Block): (Block, Table[string, string]) =
# Add a transaction to the given block and
# return `trieData` to store the transaction data in chaindb in VM layer
# Update the bloomFilter, transaction trie and receipt trie roots, bloom_filter,
# bloom, and usedGas of the block
# transaction: the executed transaction
# computation: the Computation object with executed result
# block: the Block which the transaction is added in
# var receipt = vmState.makeReceipt(transaction, computation)
# vmState.add_receipt(receipt)
# block.transactions.append(transaction)
# # Get trie roots and changed key-values.
# tx_root_hash, tx_kv_nodes = make_trie_root_and_nodes(block.transactions)
# receipt_root_hash, receipt_kv_nodes = make_trie_root_and_nodes(self.receipts)
# trie_data = merge(tx_kv_nodes, receipt_kv_nodes)
# block.bloom_filter |= receipt.bloom
# block.header.transaction_root = tx_root_hash
# block.header.receipt_root = receipt_root_hash
# block.header.bloom = int(block.bloom_filter)
# block.header.gas_used = receipt.gas_used
# return block, trie_data
result = (b, initTable[string, string]())
method applyTransaction*(
vmState: BaseVMState,
transaction: Transaction,
b: Block,
isStateless: bool): (Computation, Block, Table[string, string]) =
# Apply transaction to the given block
# transaction: the transaction need to be applied
# b: the block which the transaction applies on
# isStateless: if isStateless, call vmState.addTransaction to set block
if isStateless:
var ourBlock = b # deepcopy
vmState.blockHeader = b.header
var (computation, blockHeader) = vmState.executeTransaction(transaction)
ourBlock.header = blockHeader
var trieData: Table[string, string]
(ourBlock, trieData) = vmState.addTransaction(transaction, computation, ourBlock)
result = (computation, ourBlock, trieData)
else:
var (computation, blockHeader) = vmState.executeTransaction(transaction)
return (computation, nil, initTable[string, string]())
]#