Skip to content

Commit

Permalink
Add test to validate uncles across chain VMs
Browse files Browse the repository at this point in the history
Plus, fixed first bug: must double the header's gas limit at the VM
boundary.
  • Loading branch information
carver committed Aug 13, 2021
1 parent 71f0552 commit d479919
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 6 deletions.
16 changes: 11 additions & 5 deletions eth/vm/forks/london/headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from .blocks import LondonBlockHeader
from .constants import (
BASE_FEE_MAX_CHANGE_DENOMINATOR,
ELASTICITY_MULTIPLIER,
INITIAL_BASE_FEE,
)

Expand Down Expand Up @@ -72,12 +73,17 @@ def create_header_from_parent(difficulty_fn: Callable[[BlockHeaderAPI, int], int
parent_header: Optional[BlockHeaderAPI],
**header_params: Any) -> BlockHeaderAPI:

# frontier
if 'gas_limit' not in header_params:
header_params['gas_limit'] = compute_gas_limit(
parent_header,
genesis_gas_limit=GENESIS_GAS_LIMIT,
)
if parent_header.base_fee_per_gas is None:
# If the previous block was not a London block,
# double the gas limit, so the new target is the old gas limit
header_params['gas_limit'] = parent_header.gas_limit * ELASTICITY_MULTIPLIER
else:
# frontier rules
header_params['gas_limit'] = compute_gas_limit(
parent_header,
genesis_gas_limit=GENESIS_GAS_LIMIT,
)

# byzantium
if 'timestamp' not in header_params:
Expand Down
66 changes: 65 additions & 1 deletion tests/core/chain-object/test_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
import rlp

from eth_utils import decode_hex
from eth_utils.toolz import sliding_window

from eth import constants
from eth.abc import MiningChainAPI
from eth.chains.mainnet import MAINNET_GENESIS_HEADER
from eth.chains.base import MiningChain
from eth.chains.mainnet import (
MAINNET_GENESIS_HEADER,
MAINNET_VMS,
)
from eth.chains.ropsten import ROPSTEN_GENESIS_HEADER
from eth.consensus.noproof import NoProofConsensus
from eth.exceptions import (
TransactionNotFound,
)
Expand All @@ -25,6 +31,30 @@ def chain(chain_without_block_validation):
return chain_without_block_validation


VM_PAIRS = sliding_window(2, MAINNET_VMS)


@pytest.fixture(params=VM_PAIRS)
def vm_crossover_chain(request, base_db, genesis_state):
start_vm, end_vm = request.param
klass = MiningChain.configure(
__name__='CrossoverTestChain',
vm_configuration=(
(
constants.GENESIS_BLOCK_NUMBER,
start_vm.configure(consensus_class=NoProofConsensus),
),
# Can mine one block of the first VM, then the next block with be the next VM
(
constants.GENESIS_BLOCK_NUMBER + 2,
end_vm.configure(consensus_class=NoProofConsensus),
),
),
chain_id=1337,
)
return klass.from_genesis(base_db, dict(difficulty=1), genesis_state)


@pytest.fixture
def valid_chain(chain_with_block_validation):
return chain_with_block_validation
Expand Down Expand Up @@ -200,3 +230,37 @@ def test_get_transaction_receipt(chain, tx):
assert chain.get_canonical_transaction_index(tx.hash) == (1, 0)
assert chain.get_transaction_receipt_by_index(1, 0) == expected_receipt
assert chain.get_transaction_receipt(tx.hash) == expected_receipt


def _mine_result_to_header(mine_all_result):
block_import_result, _, _ = mine_all_result
return block_import_result.imported_block.header


def test_uncles_across_VMs(vm_crossover_chain):
chain = vm_crossover_chain

genesis = chain.get_canonical_block_header_by_number(0)

# Mine in 1st VM
uncle_header1 = chain.mine_block(extra_data=b'uncle1').header
canon_header1 = _mine_result_to_header(
chain.mine_all([], parent_header=genesis)
)

# Mine in 2nd VM
uncle_header2 = chain.mine_block(extra_data=b'uncle2').header
canon_header2 = _mine_result_to_header(
chain.mine_all([], parent_header=canon_header1)
)

# Mine block with uncles from both VMs
canon_block3 = chain.mine_block(uncles=[uncle_header1, uncle_header2])

assert canon_header2.hash == canon_block3.header.parent_hash

assert canon_block3.uncles == (uncle_header1, uncle_header2)

deserialized_block3 = chain.get_canonical_block_by_number(3)

assert deserialized_block3.uncles == (uncle_header1, uncle_header2)

0 comments on commit d479919

Please sign in to comment.