Builders

Chain Builder

The chain builder utils are intended to reduce common boilerplace for both construction of chain classes as well as building up some desired chain state.

Note

These tools are best used in conjunction with cytoolz.pipe.

Constructing Chain Classes

The following utilities are provided to assist with constructing a chain class.

eth.tools.builder.chain.fork_at(vm_class: Type[VirtualMachineAPI] = '__no__default__', at_block: int | BlockNumber = '__no__default__', chain_class: Type[ChainAPI] = '__no__default__') Type[ChainAPI]

Adds the vm_class to the chain’s vm_configuration.

from eth.chains.base import MiningChain
from eth.tools.builder.chain import build, fork_at

FrontierOnlyChain = build(MiningChain, fork_at(FrontierVM, 0))

# these two classes are functionally equivalent.
class FrontierOnlyChain(MiningChain):
    vm_configuration = (
        (0, FrontierVM),
    )

Note

This function is curriable.

The following pre-curried versions of this function are available as well, one for each mainnet fork.

  • frontier_at()

  • homestead_at()

  • tangerine_whistle_at()

  • spurious_dragon_at()

  • byzantium_at()

  • constantinople_at()

  • petersburg_at()

  • istanbul_at()

  • muir_glacier_at()

  • berlin_at()

  • london_at()

  • arrow_glacier_at()

  • gray_glacier_at()

  • paris_at()

  • shanghai_at()

  • cancun_at()

  • latest_mainnet_at() - whatever latest mainnet VM is

eth.tools.builder.chain.dao_fork_at(dao_fork_block_number: BlockNumber = '__no__default__', chain_class: Type[ChainAPI] = '__no__default__') Type[ChainAPI]

Set the block number on which the DAO fork will happen. Requires that a version of the HomesteadVM is present in the chain’s vm_configuration

eth.tools.builder.chain.disable_dao_fork(chain_class: Type[ChainAPI] = '__no__default__') Type[ChainAPI]

Set the support_dao_fork flag to False on the HomesteadVM. Requires that presence of the HomesteadVM in the vm_configuration

eth.tools.builder.chain.enable_pow_mining(chain_class: Type[ChainAPI] = '__no__default__') Type[ChainAPI]

Inject on demand generation of the proof of work mining seal on newly mined blocks into each of the chain’s vms.

eth.tools.builder.chain.disable_pow_check(chain_class: Type[ChainAPI] = '__no__default__') Type[ChainAPI]

Disable the proof of work validation check for each of the chain’s vms. This allows for block mining without generation of the proof of work seal.

Note

blocks mined this way will not be importable on any chain that does not have proof of work disabled.

eth.tools.builder.chain.name(class_name: str = '__no__default__', chain_class: Type[ChainAPI] = '__no__default__') Type[ChainAPI]

Assign the given name to the chain class.

eth.tools.builder.chain.chain_id(chain_id: int = '__no__default__', chain_class: Type[ChainAPI] = '__no__default__') Type[ChainAPI]

Set the chain_id for the chain class.

Initializing Chains

The following utilities are provided to assist with initializing a chain into the genesis state.

eth.tools.builder.chain.genesis(chain_class: ChainAPI = '__no__default__', db: AtomicDatabaseAPI | None = None, params: Dict[str, int | None | BlockNumber | bytes | Address | Hash32] | None = None, state: Dict[Address, AccountDetails] | List[Tuple[Address, Dict[str, int | bytes | Dict[int, int]]]] | None = None) ChainAPI

Initialize the given chain class with the given genesis header parameters and chain state.

Building Chains

The following utilities are provided to assist with building out chains of blocks.

eth.tools.builder.chain.copy(chain: MiningChainAPI = '__no__default__') MiningChainAPI

Make a copy of the chain at the given state. Actions performed on the resulting chain will not affect the original chain.

eth.tools.builder.chain.import_block(block: BlockAPI = '__no__default__', chain: ChainAPI = '__no__default__') ChainAPI

Import the provided block into the chain.

eth.tools.builder.chain.import_blocks(*blocks: BlockAPI) Callable[[ChainAPI], ChainAPI]

Variadic argument version of import_block()

eth.tools.builder.chain.mine_block(chain: MiningChainAPI = '__no__default__', **kwargs: Any) MiningChainAPI

Mine a new block on the chain. Header parameters for the new block can be overridden using keyword arguments.

eth.tools.builder.chain.mine_blocks(num_blocks: int = '__no__default__', chain: MiningChainAPI = '__no__default__') MiningChainAPI

Variadic argument version of mine_block()

eth.tools.builder.chain.chain_split(*splits: Iterable[Callable[[...], Any]]) Callable[[ChainAPI], Iterable[ChainAPI]]

Construct and execute multiple concurrent forks of the chain.

Any number of forks may be executed. For each fork, provide an iterable of commands.

Returns the resulting chain objects for each fork.

chain_a, chain_b = build(
    mining_chain,
    chain_split(
        (mine_block(extra_data=b'chain-a'), mine_block()),
        (mine_block(extra_data=b'chain-b'), mine_block(), mine_block()),
    ),
)
eth.tools.builder.chain.at_block_number(block_number: int | BlockNumber = '__no__default__', chain: MiningChainAPI = '__no__default__') MiningChainAPI

Rewind the chain back to the given block number. Calls to things like get_canonical_head will still return the canonical head of the chain, however, you can use mine_block to mine fork chains.