|
| 1 | +import pytest |
| 2 | + |
| 3 | +from eth import constants |
| 4 | +from eth.consensus.noproof import NoProofConsensus |
| 5 | +from eth.chains.base import MiningChain |
| 6 | +from eth.chains.mainnet import ( |
| 7 | + MAINNET_VMS, |
| 8 | +) |
| 9 | +from eth.vm.forks import BerlinVM |
| 10 | +from eth.tools.factories.transaction import ( |
| 11 | + new_transaction |
| 12 | +) |
| 13 | + |
| 14 | + |
| 15 | +# VMs starting at London |
| 16 | +@pytest.fixture(params=MAINNET_VMS[9:]) |
| 17 | +def london_plus_miner(request, base_db, genesis_state): |
| 18 | + klass = MiningChain.configure( |
| 19 | + __name__='CrossoverTestChain', |
| 20 | + vm_configuration=( |
| 21 | + ( |
| 22 | + constants.GENESIS_BLOCK_NUMBER, |
| 23 | + BerlinVM.configure(consensus_class=NoProofConsensus), |
| 24 | + ), |
| 25 | + ( |
| 26 | + constants.GENESIS_BLOCK_NUMBER + 1, |
| 27 | + request.param.configure(consensus_class=NoProofConsensus), |
| 28 | + ), |
| 29 | + ), |
| 30 | + chain_id=1337, |
| 31 | + ) |
| 32 | + header_fields = dict( |
| 33 | + difficulty=1, |
| 34 | + gas_limit=21000 * 2, # block limit is hit with two transactions |
| 35 | + ) |
| 36 | + # On the first London+ block, it will double the block limit so that the |
| 37 | + # block *target* is hit with 2 transactions |
| 38 | + return klass.from_genesis(base_db, header_fields, genesis_state) |
| 39 | + |
| 40 | + |
| 41 | +@pytest.mark.parametrize( |
| 42 | + 'num_txns, expected_base_fee', |
| 43 | + ( |
| 44 | + (0, 875000000), |
| 45 | + (1, 937500000), |
| 46 | + # base fee should stay stable at 1 gwei when block is exactly half full |
| 47 | + (2, 1000000000), |
| 48 | + (3, 1062500000), |
| 49 | + (4, 1125000000), |
| 50 | + ), |
| 51 | +) |
| 52 | +def test_base_fee_evolution( |
| 53 | + london_plus_miner, funded_address, funded_address_private_key, num_txns, expected_base_fee): |
| 54 | + chain = london_plus_miner |
| 55 | + assert chain.header.gas_limit == 21000 * 4 |
| 56 | + |
| 57 | + vm = chain.get_vm() |
| 58 | + txns = [ |
| 59 | + new_transaction( |
| 60 | + vm, |
| 61 | + funded_address, |
| 62 | + b'\x00' * 20, |
| 63 | + private_key=funded_address_private_key, |
| 64 | + gas=21000, |
| 65 | + nonce=nonce, |
| 66 | + ) |
| 67 | + for nonce in range(num_txns) |
| 68 | + ] |
| 69 | + block_import, _, _ = chain.mine_all(txns, gas_limit=21000 * 4) |
| 70 | + mined_header = block_import.imported_block.header |
| 71 | + assert mined_header.gas_limit == 21000 * 4 |
| 72 | + assert mined_header.gas_used == 21000 * num_txns |
| 73 | + assert mined_header.base_fee_per_gas == 10 ** 9 # Initialize at 1 gwei |
| 74 | + |
| 75 | + # Next block should have an unchanged gas fee because usage was equal to target (half of limit) |
| 76 | + block_import, _, _ = chain.mine_all([], gas_limit=21000 * 4) |
| 77 | + mined_header = block_import.imported_block.header |
| 78 | + assert mined_header.gas_limit == 21000 * 4 |
| 79 | + assert mined_header.gas_used == 0 |
| 80 | + assert mined_header.base_fee_per_gas == expected_base_fee |
0 commit comments