Implement `State` object
See original GitHub issueWhat is wrong?
Currently, the VM
class is part of the constructor for the Computation
object. Here are the places where it is currently used.
evm/logic/block.py:7: block_hash = computation.vm.get_ancestor_hash(block_number)
evm/logic/block.py:13: computation.stack.push(computation.vm.block.header.coinbase)
evm/logic/block.py:17: computation.stack.push(computation.vm.block.header.timestamp)
evm/logic/block.py:21: computation.stack.push(computation.vm.block.header.block_number)
evm/logic/block.py:25: computation.stack.push(computation.vm.block.header.difficulty)
evm/logic/block.py:29: computation.stack.push(computation.vm.block.header.gas_limit)
evm/logic/system.py:87: computation.vm.logger.debug(
evm/logic/system.py:141: computation.vm.logger.debug(
evm/vm/forks/spurious_dragon/utils.py:22: yield computation.vm.block.header.coinbase
evm/vm/computation.py:76: self.vm = vm
evm/vm/computation.py:197: child_computation = self.vm.apply_create_message(child_msg)
evm/vm/computation.py:199: child_computation = self.vm.apply_message(child_msg)
evm/vm/computation.py:280: with self.vm.state_db(read_only, self.msg.access_list) as state_db:
Giving computation direct access to the VM
is problematic for a number of reasons.
- poor isolation for what data and APIs are available during EVM execution.
- makes implementation of stateless clients difficult.
- makes VM execution inherently non-pure.
How can it be fixed
To fix this, lets create a new State
object. Similar to how the Transaction
class is specified for each VM
, the State
object should be similarly overrideable.
VM.get_state_class()
VM.get_state()
VM.state
(this could be a convenienceproperty
that just delegates toVM.get_state()
.
The State
object will need the following things.
- Access to the current block header information (
coinbase/timestamp/block_number/difficulty/gas_limit
. - The ancestry hashes for the current block number.
- Access to the
StateDB
The State
object will also need the following APIs available to it.
VM.apply_message
VM.apply_create_message
I think the best way to accomplish this is to relocate the following APIs to live directly on the State
object itself, removing them from the VM
object.
VM.apply_message
VM.apply_create_message
VM.apply_computation
Note that VM.apply_computation
needs access to VM.get_opcode_fn()
and VM.precompiles
. This indicates we’ll need to supply the State
object with a way to get at this data. The simplest solution that comes to mind is to add them as extra arguments:
class State:
def apply_computation(self, message, opcodes, precompiles):
...
Issue Analytics
- State:
- Created 6 years ago
- Comments:6 (6 by maintainers)
@pipermerriam Your solution works well and clean! I apply it by replacing
_state_class
:Thank you so much.
close via #247