Skip to content

Commit 42da4c9

Browse files
committed
Make eth_call free again
- when running a call, set the header's base gas fee to 0 - API update: state_in_temp_block -> in_costless_state to reference ^
1 parent f77982c commit 42da4c9

File tree

6 files changed

+34
-21
lines changed

6 files changed

+34
-21
lines changed

eth/abc.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,9 +1693,9 @@ def chain_id(self) -> int:
16931693

16941694
@property
16951695
@abstractmethod
1696-
def base_gas_fee(self) -> Optional[int]:
1696+
def base_fee_per_gas(self) -> Optional[int]:
16971697
"""
1698-
Return the base gas fee of the block
1698+
Return the base fee per gas of the block
16991699
"""
17001700
...
17011701

@@ -3501,10 +3501,10 @@ def get_state_class(cls) -> Type[StateAPI]:
35013501
...
35023502

35033503
@abstractmethod
3504-
def state_in_temp_block(self) -> ContextManager[StateAPI]:
3504+
def in_costless_state(self) -> ContextManager[StateAPI]:
35053505
"""
35063506
Return a :class:`~typing.ContextManager` with the current state wrapped in a temporary
3507-
block.
3507+
block. In this state, the ability to pay gas costs is ignored.
35083508
"""
35093509
...
35103510

eth/chains/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ def get_transaction_result(
443443
transaction: SignedTransactionAPI,
444444
at_header: BlockHeaderAPI) -> bytes:
445445

446-
with self.get_vm(at_header).state_in_temp_block() as state:
446+
with self.get_vm(at_header).in_costless_state() as state:
447447
computation = state.costless_execute_transaction(transaction)
448448

449449
computation.raise_if_error()
@@ -455,7 +455,7 @@ def estimate_gas(
455455
at_header: BlockHeaderAPI = None) -> int:
456456
if at_header is None:
457457
at_header = self.get_canonical_head()
458-
with self.get_vm(at_header).state_in_temp_block() as state:
458+
with self.get_vm(at_header).in_costless_state() as state:
459459
return self.gas_estimator(state, transaction)
460460

461461
def import_block(self,

eth/vm/base.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ def create_execution_context(cls,
183183
gas_limit=header.gas_limit,
184184
prev_hashes=prev_hashes,
185185
chain_id=chain_context.chain_id,
186-
base_gas_fee=header.base_fee_per_gas,
186+
base_fee_per_gas=header.base_fee_per_gas,
187187
)
188188

189189
def execute_bytecode(self,
@@ -676,13 +676,19 @@ def get_state_class(cls) -> Type[StateAPI]:
676676
return cls._state_class
677677

678678
@contextlib.contextmanager
679-
def state_in_temp_block(self) -> Iterator[StateAPI]:
679+
def in_costless_state(self) -> Iterator[StateAPI]:
680680
header = self.get_header()
681+
681682
temp_block = self.generate_block_from_parent_header_and_coinbase(header, header.coinbase)
682683
prev_hashes = itertools.chain((header.hash,), self.previous_hashes)
683684

685+
if temp_block.header.base_fee_per_gas is None:
686+
free_header = temp_block.header
687+
else:
688+
free_header = temp_block.header.copy(base_fee_per_gas=0)
689+
684690
state = self.build_state(self.chaindb.db,
685-
temp_block.header,
691+
free_header,
686692
self.chain_context,
687693
prev_hashes)
688694

eth/vm/execution_context.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class ExecutionContext(ExecutionContextAPI):
2222
_gas_limit = None
2323
_prev_hashes = None
2424
_chain_id = None
25-
_base_gas_fee = None
25+
_base_fee_per_gas = None
2626

2727
def __init__(
2828
self,
@@ -33,15 +33,15 @@ def __init__(
3333
gas_limit: int,
3434
prev_hashes: Iterable[Hash32],
3535
chain_id: int,
36-
base_gas_fee: Optional[int]) -> None:
36+
base_fee_per_gas: Optional[int]) -> None:
3737
self._coinbase = coinbase
3838
self._timestamp = timestamp
3939
self._block_number = block_number
4040
self._difficulty = difficulty
4141
self._gas_limit = gas_limit
4242
self._prev_hashes = CachedIterable(prev_hashes)
4343
self._chain_id = chain_id
44-
self._base_gas_fee = base_gas_fee
44+
self._base_fee_per_gas = base_fee_per_gas
4545

4646
@property
4747
def coinbase(self) -> Address:
@@ -72,8 +72,8 @@ def chain_id(self) -> int:
7272
return self._chain_id
7373

7474
@property
75-
def base_gas_fee(self) -> int:
76-
if self._base_gas_fee is None:
75+
def base_fee_per_gas(self) -> int:
76+
if self._base_fee_per_gas is None:
7777
raise AttributeError(f"This header at Block #{self.block_number} does not have a base gas fee")
7878
else:
79-
return self._base_gas_fee
79+
return self._base_fee_per_gas

eth/vm/forks/london/state.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ def build_evm_message(
4545
self,
4646
transaction: SignedTransactionAPI,
4747
) -> MessageAPI:
48-
transaction_context = self.vm_state.get_transaction_context(transaction)
49-
gas_fee = transaction.gas * transaction_context.gas_price
48+
gas_fee = transaction.gas * self.vm_state.get_gas_price(transaction)
5049

5150
# Buy Gas
5251
self.vm_state.delta_balance(transaction.sender, -1 * gas_fee)
@@ -172,7 +171,7 @@ def validate_transaction(
172171
validate_london_normalized_transaction(
173172
state=self,
174173
transaction=transaction,
175-
base_fee_per_gas=self.execution_context.base_gas_fee
174+
base_fee_per_gas=self.execution_context.base_fee_per_gas
176175
)
177176

178177
def get_transaction_context(self: StateAPI,
@@ -184,15 +183,15 @@ def get_transaction_context(self: StateAPI,
184183
if isinstance(transaction, LondonTypedTransaction): # TODO probably do this somewhere else
185184
priority_fee_per_gas = min(
186185
transaction.max_priority_fee_per_gas,
187-
transaction.max_fee_per_gas - self.execution_context.base_gas_fee
186+
transaction.max_fee_per_gas - self.execution_context.base_fee_per_gas
188187
)
189188
else:
190189
priority_fee_per_gas = min(
191190
transaction.gas_price,
192-
transaction.gas_price - self.execution_context.base_gas_fee
191+
transaction.gas_price - self.execution_context.base_fee_per_gas
193192
)
194193

195-
effective_gas_price = self.execution_context.base_gas_fee + priority_fee_per_gas
194+
effective_gas_price = self.execution_context.base_fee_per_gas + priority_fee_per_gas
196195
return self.get_transaction_context_class()(
197196
gas_price=effective_gas_price,
198197
origin=transaction.sender

eth/vm/state.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ def difficulty(self) -> int:
8888
def gas_limit(self) -> int:
8989
return self.execution_context.gas_limit
9090

91+
def get_gas_price(self, transaction: SignedTransactionAPI) -> int:
92+
base_gas_price = self.execution_context.base_fee_per_gas
93+
priority_fee_per_gas = min(
94+
transaction.max_priority_fee_per_gas,
95+
transaction.max_fee_per_gas - base_gas_price,
96+
)
97+
return priority_fee_per_gas + base_gas_price
98+
9199
#
92100
# Access to account db
93101
#

0 commit comments

Comments
 (0)