Skip to content

Commit 5b205e6

Browse files
ftruzzicarver
authored andcommitted
First steps for EIP-1559 support
- add initial EIP-1559 transaction validation - add initial EIP-1559 transaction execution - rename gas_target to gas_limit - add london VM in existing tests - update block according to latest EIP updates
1 parent 1af151a commit 5b205e6

33 files changed

+1091
-20
lines changed

eth/abc.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class MiningHeaderAPI(ABC):
7474
gas_used: int
7575
timestamp: int
7676
extra_data: bytes
77+
base_fee_per_gas: int # EIP-1559
7778

7879
@property
7980
@abstractmethod
@@ -326,14 +327,17 @@ class TransactionFieldsAPI(ABC):
326327
"""
327328
A class to define all common transaction fields.
328329
"""
330+
max_fee_per_gas: int
331+
max_priority_fee_per_gas: int
332+
329333
@property
330334
@abstractmethod
331335
def nonce(self) -> int:
332336
...
333337

334338
@property
335339
@abstractmethod
336-
def gas_price(self) -> int:
340+
def gas_price(self) -> Optional[int]:
337341
...
338342

339343
@property
@@ -1684,6 +1688,14 @@ def chain_id(self) -> int:
16841688
"""
16851689
...
16861690

1691+
@property
1692+
@abstractmethod
1693+
def base_gas_fee(self) -> Optional[int]:
1694+
"""
1695+
Return the base gas fee of the block
1696+
"""
1697+
...
1698+
16871699

16881700
class ComputationAPI(ContextManager['ComputationAPI'], StackManipulationAPI):
16891701
"""
@@ -2865,9 +2877,8 @@ def get_computation(self,
28652877
#
28662878
# Transaction context
28672879
#
2868-
@classmethod
28692880
@abstractmethod
2870-
def get_transaction_context_class(cls) -> Type[TransactionContextAPI]:
2881+
def get_transaction_context_class(self) -> Type[TransactionContextAPI]:
28712882
"""
28722883
Return the :class:`~eth.vm.transaction_context.BaseTransactionContext` class that the
28732884
state class uses.
@@ -2917,9 +2928,8 @@ def validate_transaction(self, transaction: SignedTransactionAPI) -> None:
29172928
"""
29182929
...
29192930

2920-
@classmethod
29212931
@abstractmethod
2922-
def get_transaction_context(cls,
2932+
def get_transaction_context(self,
29232933
transaction: SignedTransactionAPI) -> TransactionContextAPI:
29242934
"""
29252935
Return the :class:`~eth.abc.TransactionContextAPI` for the given ``transaction``

eth/chains/mainnet/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from .constants import (
1414
MAINNET_CHAIN_ID,
15+
LONDON_MAINNET_BLOCK,
1516
BERLIN_MAINNET_BLOCK,
1617
BYZANTIUM_MAINNET_BLOCK,
1718
PETERSBURG_MAINNET_BLOCK,
@@ -39,6 +40,7 @@
3940
FrontierVM,
4041
HomesteadVM,
4142
IstanbulVM,
43+
LondonVM,
4244
MuirGlacierVM,
4345
PetersburgVM,
4446
SpuriousDragonVM,
@@ -97,6 +99,7 @@ class MainnetHomesteadVM(MainnetDAOValidatorVM):
9799
ISTANBUL_MAINNET_BLOCK,
98100
MUIR_GLACIER_MAINNET_BLOCK,
99101
BERLIN_MAINNET_BLOCK,
102+
LONDON_MAINNET_BLOCK,
100103
)
101104
MAINNET_VMS = (
102105
FrontierVM,
@@ -108,6 +111,7 @@ class MainnetHomesteadVM(MainnetDAOValidatorVM):
108111
IstanbulVM,
109112
MuirGlacierVM,
110113
BerlinVM,
114+
LondonVM,
111115
)
112116

113117
MAINNET_VM_CONFIGURATION = tuple(zip(MAINNET_FORK_BLOCKS, MAINNET_VMS))

eth/chains/mainnet/constants.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,9 @@
5757
# Berlin Block
5858
#
5959
BERLIN_MAINNET_BLOCK = BlockNumber(12244000)
60+
61+
62+
#
63+
# London Block
64+
#
65+
LONDON_MAINNET_BLOCK = BlockNumber(12244001) # TODO change to actual when known

eth/db/header.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@
5656
validate_block_number,
5757
validate_word,
5858
)
59+
from eth.vm.forks.london.blocks import (
60+
LondonBlockHeader
61+
)
5962

63+
from rlp.exceptions import (
64+
ObjectDeserializationError
65+
)
6066

6167
class HeaderDB(HeaderDatabaseAPI):
6268
def __init__(self, db: AtomicDatabaseAPI) -> None:
@@ -619,4 +625,8 @@ def _add_block_number_to_hash_lookup(db: DatabaseAPI, header: BlockHeaderAPI) ->
619625
# be looking up recent blocks.
620626
@functools.lru_cache(128)
621627
def _decode_block_header(header_rlp: bytes) -> BlockHeaderAPI:
622-
return rlp.decode(header_rlp, sedes=BlockHeader)
628+
try:
629+
return rlp.decode(header_rlp, sedes=BlockHeader)
630+
except ObjectDeserializationError:
631+
# could be a new >=London block header
632+
return rlp.decode(header_rlp, sedes=LondonBlockHeader)

eth/rlp/headers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import time
22
from typing import (
33
Dict,
4+
Optional,
45
overload,
56
)
67

@@ -202,3 +203,7 @@ def is_genesis(self) -> bool:
202203
# validate_header stops trying to check the current header against a parent header.
203204
# Can someone trick us into following a high difficulty header with genesis parent hash?
204205
return self.parent_hash == GENESIS_PARENT_HASH and self.block_number == 0
206+
207+
@property
208+
def base_fee_per_gas(self) -> Optional[int]:
209+
return 0

eth/tools/builder/chain/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
istanbul_at,
2828
muir_glacier_at,
2929
berlin_at,
30+
london_at,
3031
latest_mainnet_at,
3132
)
3233

eth/tools/builder/chain/builders.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
IstanbulVM,
7474
MuirGlacierVM,
7575
BerlinVM,
76+
LondonVM,
7677
)
7778

7879

@@ -237,6 +238,7 @@ def dao_fork_at(dao_fork_block_number: BlockNumber,
237238
istanbul_at = fork_at(IstanbulVM)
238239
muir_glacier_at = fork_at(MuirGlacierVM)
239240
berlin_at = fork_at(BerlinVM)
241+
london_at = fork_at(LondonVM)
240242

241243
latest_mainnet_at = muir_glacier_at
242244

eth/validation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def validate_uint256(value: int, title: str = "Value") -> None:
166166
)
167167
if value > UINT_256_MAX:
168168
raise ValidationError(
169-
f"{title} exeeds maximum UINT256 size. Got: {value}"
169+
f"{title} exceeds maximum UINT256 size. Got: {value}"
170170
)
171171

172172

eth/vm/base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ def create_execution_context(cls,
184184
gas_limit=header.gas_limit,
185185
prev_hashes=prev_hashes,
186186
chain_id=chain_context.chain_id,
187+
base_gas_fee=header.base_fee_per_gas,
187188
)
188189

189190
def execute_bytecode(self,
@@ -590,6 +591,7 @@ def validate_header(cls,
590591
validate_length_lte(
591592
header.extra_data, cls.extra_data_max_bytes, title="BlockHeader.extra_data")
592593

594+
# TODO skip for EIP-1559, or override this whole function?
593595
validate_gas_limit(header.gas_limit, parent_header.gas_limit)
594596

595597
if header.block_number != parent_header.block_number + 1:

eth/vm/execution_context.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import (
22
Iterable,
3+
Optional,
34
)
45

56
from eth_typing import (
@@ -21,6 +22,7 @@ class ExecutionContext(ExecutionContextAPI):
2122
_gas_limit = None
2223
_prev_hashes = None
2324
_chain_id = None
25+
_base_gas_fee = 0 # TODO check if valid
2426

2527
def __init__(
2628
self,
@@ -30,14 +32,17 @@ def __init__(
3032
difficulty: int,
3133
gas_limit: int,
3234
prev_hashes: Iterable[Hash32],
33-
chain_id: int) -> None:
35+
chain_id: int,
36+
base_gas_fee: Optional[int]) -> None:
3437
self._coinbase = coinbase
3538
self._timestamp = timestamp
3639
self._block_number = block_number
3740
self._difficulty = difficulty
3841
self._gas_limit = gas_limit
3942
self._prev_hashes = CachedIterable(prev_hashes)
4043
self._chain_id = chain_id
44+
if base_gas_fee is not None:
45+
self._base_gas_fee = base_gas_fee
4146

4247
@property
4348
def coinbase(self) -> Address:
@@ -66,3 +71,7 @@ def prev_hashes(self) -> Iterable[Hash32]:
6671
@property
6772
def chain_id(self) -> int:
6873
return self._chain_id
74+
75+
@property
76+
def base_gas_fee(self) -> Optional[int]:
77+
return self._base_gas_fee

0 commit comments

Comments
 (0)