Skip to content

Commit 56bbf3b

Browse files
committed
changes from review comments
1 parent dcd7122 commit 56bbf3b

File tree

12 files changed

+153
-143
lines changed

12 files changed

+153
-143
lines changed

README.md

+18-17
Original file line numberDiff line numberDiff line change
@@ -399,25 +399,26 @@ Returns the transaction for the given hash, raising a
399399
transaction cannot be found.
400400

401401
```python
402-
>>> t.get_transaction_by_hash('0x140c1da1370a908e4c0f7c6e33bb97182011707c6a9aff954bef1084c8a48b25')
403-
{'hash': '0x256baca0284f7b76238e56964dec01dce423cb11415e5f47b341a0af088bb85d',
404-
'nonce': 1,
405-
'block_hash': '0xc25d844e866b4f3f3126e5d5ceba949a7ee12b597a3d54115da63e8596531f58',
406-
'block_number': 2,
402+
>>> t.get_transaction_by_hash('0x21ae665f707e12a5f1bb13ef8c706b65cc5accfd03e7067ce683d831f51122e6')
403+
{'type': '0x2',
404+
'hash': '0x21ae665f707e12a5f1bb13ef8c706b65cc5accfd03e7067ce683d831f51122e6',
405+
'nonce': 0,
406+
'block_hash': '0x810731efeb7498fc0ac3bc7c72a71571b672c9fdbfbfd8b435f483e368e8ef7e',
407+
'block_number': 1,
407408
'transaction_index': 0,
408-
'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',
409-
'to': '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',
410-
'value': 1,
411-
'gas': 30000,
409+
'from': '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',
410+
'to': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',
411+
'value': 1337,
412+
'gas': 21000,
412413
'data': '0x',
413-
'r': 113110058401990022576610285176909677614233866647576678068104192469544316041227,
414-
's': 56040876284016779278390826082806410689817968450346221730224961588578254081442,
414+
'r': 1713666669454033023988006960017431058214051587080823768269189498559514600280,
415+
's': 32003859822305799628524852194521134173285969678963273753063458725692016415033,
415416
'chain_id': 131277322940537,
416-
'max_fee_per_gas': 1000000000,
417-
'max_priority_fee_per_gas': 1000000000,
417+
'max_fee_per_gas': 2000000000,
418+
'max_priority_fee_per_gas': 500000000,
418419
'access_list': (),
419-
'y_parity': 1}
420-
420+
'y_parity': 0,
421+
'gas_price': 1375000000}
421422
```
422423

423424
> Note: For unmined transaction, `transaction_index`, `block_number` and `block_hash` will all be `None`.
@@ -540,20 +541,20 @@ values.
540541
* `gas`: Sets the gas limit for transaction execution (integer).
541542
* `value`: The amount of ether in wei that should be sent with the transaction (integer).
542543
* `data`: The data for the transaction (hexadecimal string).
544+
* `chain_id`: The integer id for the chain the transaction is meant to interact with.
545+
543546

544547
In addition to the above, the following parameters are added based on the type of transaction being sent:
545548

546549
#### Legacy transactions
547550
* `gas_price`: Sets the price per unit of gas in wei that will be paid for transaction execution (integer).
548551

549552
#### Access list transactions (EIP-2930)
550-
* `chain_id`: The integer id for the chain the transaction is meant to interact with
551553
* `gas_price`: Sets the price per unit of gas in wei that will be paid for transaction execution (integer).
552554
* `access_list` (optional): Specifies accounts and storage slots expected to be accessed, based on the transaction, in order to
553555
gain a discount on the gas for those executions (see quickstart example for usage).
554556

555557
#### Dynamic fee transactions (EIP-1559)
556-
* `chain_id`: The integer id for the chain the transaction is meant to interact with
557558
* `max_fee_per_gas`: Sets the maximum fee per unit of gas in wei that will be paid for transaction execution (integer).
558559
* `max_priority_fee_per_gas`: Sets the fee per unit of gas in wei that is sent to the miner as an incentive for mining the transaction (integer).
559560
* `access_list` (optional): Specifies accounts and storage slots expected to be accessed, based on the transaction, in order to

eth_tester/backends/mock/factory.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
)
2525

2626
from eth_tester.backends.common import merge_genesis_overrides
27-
from eth_tester.constants import EIP_1559_TRANSACTION_PARAMS
27+
from eth_tester.constants import DYNAMIC_FEE_TRANSACTION_PARAMS
2828
from eth_tester.utils.address import (
2929
generate_contract_address,
3030
)
@@ -94,8 +94,8 @@ def create_transaction(transaction, block, transaction_index, is_pending, overri
9494
@to_dict
9595
def _fill_transaction(transaction, block, transaction_index, is_pending, overrides=None):
9696
is_dynamic_fee_transaction = (
97-
any(_ in transaction for _ in EIP_1559_TRANSACTION_PARAMS)
98-
or not any(_ in transaction for _ in EIP_1559_TRANSACTION_PARAMS + ('gas_price',))
97+
any(_ in transaction for _ in DYNAMIC_FEE_TRANSACTION_PARAMS)
98+
or not any(_ in transaction for _ in DYNAMIC_FEE_TRANSACTION_PARAMS + ('gas_price',))
9999
)
100100

101101
if overrides is None:

eth_tester/backends/pyevm/main.py

+12-11
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
from eth_keys import KeyAPI
2828

29-
from eth_tester.constants import EIP_1559_TRANSACTION_PARAMS
29+
from eth_tester.constants import DYNAMIC_FEE_TRANSACTION_PARAMS
3030
from eth_tester.exceptions import (
3131
BackendDistributionNotFound,
3232
BlockNotFound,
@@ -165,6 +165,7 @@ def setup_tester_chain(
165165
no_proof_vms = consensus_applier.amend_vm_configuration(vm_configuration)
166166

167167
class MainnetTesterNoProofChain(MiningChain):
168+
chain_id = 131277322940537
168169
vm_configuration = no_proof_vms
169170

170171
def create_header_from_parent(self, parent_header, **header_params):
@@ -191,7 +192,6 @@ def get_transaction_builder(self):
191192
base_db = get_db_backend()
192193

193194
chain = MainnetTesterNoProofChain.from_genesis(base_db, genesis_params, genesis_state)
194-
chain.chain_id = 131277322940537 # typed transactions need a chain_id
195195
return account_keys, chain
196196

197197

@@ -436,11 +436,9 @@ def get_base_fee(self, block_number='latest'):
436436
#
437437
@to_dict
438438
def _normalize_transaction(self, transaction, block_number='latest'):
439-
base_fee = self.get_base_fee(block_number)
440-
441439
is_dynamic_fee_transaction = (
442-
any(_ in transaction for _ in EIP_1559_TRANSACTION_PARAMS)
443-
or not any(_ in transaction for _ in EIP_1559_TRANSACTION_PARAMS + ('gas_price',))
440+
any(_ in transaction for _ in DYNAMIC_FEE_TRANSACTION_PARAMS)
441+
or not any(_ in transaction for _ in DYNAMIC_FEE_TRANSACTION_PARAMS + ('gas_price',))
444442
)
445443

446444
for key in transaction:
@@ -458,16 +456,19 @@ def _normalize_transaction(self, transaction, block_number='latest'):
458456
yield 'to', b''
459457

460458
if is_dynamic_fee_transaction:
461-
if not any(_ in transaction for _ in EIP_1559_TRANSACTION_PARAMS):
459+
if not any(_ in transaction for _ in DYNAMIC_FEE_TRANSACTION_PARAMS):
462460
yield 'max_fee_per_gas', 1 * 10**9
463461
yield 'max_priority_fee_per_gas', 1 * 10**9
464462
elif 'max_priority_fee_per_gas' in transaction and 'max_fee_per_gas' not in transaction:
465-
yield 'max_fee_per_gas', transaction['max_priority_fee_per_gas'] + 2 * base_fee
463+
yield (
464+
'max_fee_per_gas',
465+
transaction['max_priority_fee_per_gas'] + 2 * self.get_base_fee(block_number)
466+
)
466467

467468
if is_dynamic_fee_transaction or 'access_list' in transaction:
468469
# typed transaction
469470
if 'access_list' not in transaction:
470-
yield 'access_list', []
471+
yield 'access_list', ()
471472
if 'chain_id' not in transaction:
472473
yield 'chain_id', self.chain.chain_id
473474

@@ -492,7 +493,7 @@ def _create_type_aware_unsigned_transaction(self, normalized_txn):
492493
return self.chain.get_transaction_builder().new_unsigned_access_list_transaction(
493494
**normalized_txn
494495
)
495-
elif all(_ in normalized_txn for _ in ("max_fee_per_gas", "max_priority_fee_per_gas")):
496+
elif all(_ in normalized_txn for _ in DYNAMIC_FEE_TRANSACTION_PARAMS):
496497
return self.chain.get_transaction_builder().new_unsigned_dynamic_fee_transaction(
497498
**normalized_txn
498499
)
@@ -515,7 +516,7 @@ def _create_type_aware_signed_transaction(self, normalized_txn):
515516
return self.chain.get_transaction_builder().new_access_list_transaction(
516517
**normalized_txn
517518
)
518-
elif all(_ in normalized_txn for _ in ("max_fee_per_gas", "max_priority_fee_per_gas")):
519+
elif all(_ in normalized_txn for _ in DYNAMIC_FEE_TRANSACTION_PARAMS):
519520
return self.chain.get_transaction_builder().new_dynamic_fee_transaction(
520521
**normalized_txn
521522
)

eth_tester/backends/pyevm/serializers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def serialize_transaction(block, transaction, transaction_index, is_pending):
120120
'gas_price': _calculate_effective_gas_price(transaction, block, txn_type),
121121
}
122122
else:
123-
raise ValidationError('Transaction serialization error')
123+
raise ValidationError('Invariant: code path should be unreachable')
124124

125125
return merge(common_transaction_params, type_specific_params)
126126

eth_tester/constants.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@
5858
#
5959
# EIP CONSTANTS
6060
#
61-
EIP_1559_TRANSACTION_PARAMS = ('max_fee_per_gas', 'max_priority_fee_per_gas')
61+
DYNAMIC_FEE_TRANSACTION_PARAMS = ('max_fee_per_gas', 'max_priority_fee_per_gas')

eth_tester/normalization/inbound.py

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def _normalize_inbound_access_list(access_list):
9797

9898

9999
TRANSACTION_NORMALIZERS = {
100+
'type': identity, # type is not required so the type is inferred from the txn params
100101
'chain_id': identity,
101102
'from': to_canonical_address,
102103
'to': to_empty_or_canonical_address,

eth_tester/utils/backend_testing.py

+32-46
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@
5151
_make_call_throws_transaction,
5252
_decode_throws_result,
5353
)
54-
from .. import (
55-
PyEVMBackend,
56-
)
57-
5854

5955
PK_A = '0x58d23b55bc9cdce1f18c2500f40ff4ab7245df9a89505e9b1fa4851f623d241d'
6056
PK_A_ADDRESS = '0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd'
@@ -123,23 +119,24 @@ def _send_and_check_transaction(self, eth_tester, test_transaction, _from):
123119
self._check_transactions(transaction, txn)
124120

125121
@staticmethod
126-
def _check_transactions(expected_transaction, actual_transaction):
127-
assert is_same_address(actual_transaction['from'], expected_transaction['from'])
128-
if 'to' not in expected_transaction or expected_transaction['to'] == '':
122+
def _check_transactions(sent_transaction, actual_transaction):
123+
assert is_same_address(actual_transaction['from'], sent_transaction['from'])
124+
if 'to' not in sent_transaction or sent_transaction['to'] == '':
129125
assert actual_transaction['to'] == ''
130126
else:
131-
assert is_same_address(actual_transaction['to'], expected_transaction['to'])
127+
assert is_same_address(actual_transaction['to'], sent_transaction['to'])
132128

133-
if expected_transaction.get('gas_price'):
134-
assert actual_transaction['gas_price'] == expected_transaction['gas_price']
129+
assert actual_transaction['gas'] == sent_transaction['gas']
130+
assert actual_transaction['value'] == sent_transaction['value']
131+
132+
if sent_transaction.get('gas_price') is not None:
133+
assert actual_transaction['gas_price'] == sent_transaction['gas_price']
135134
else:
136-
assert actual_transaction['max_fee_per_gas'] == expected_transaction['max_fee_per_gas']
135+
assert actual_transaction['max_fee_per_gas'] == sent_transaction['max_fee_per_gas']
137136
assert (
138137
actual_transaction['max_priority_fee_per_gas'] ==
139-
expected_transaction['max_priority_fee_per_gas']
138+
sent_transaction['max_priority_fee_per_gas']
140139
)
141-
assert actual_transaction['gas'] == expected_transaction['gas']
142-
assert actual_transaction['value'] == expected_transaction['value']
143140

144141
#
145142
# Testing Flags
@@ -347,12 +344,12 @@ def test_send_transaction_raises_with_legacy_and_dynamic_fee_fields(
347344
"max_fee_per_gas": 1000000000,
348345
"max_priority_fee_per_gas": 1000000000,
349346
}
350-
with pytest.raises(ValidationError):
347+
with pytest.raises(ValidationError, match="legacy and dynamic fee transaction values"):
351348
self._send_and_check_transaction(eth_tester, test_transaction, accounts[0])
352349

353350
def test_send_transaction_no_gas_price_or_dynamic_fees(self, eth_tester):
354351
# test that we default to a dynamic fee transaction which, while pending, will include the
355-
# gas_price as equal to the max_fee_per_gas until that is removed.
352+
# gas_price as equal to the effective gas price paid.
356353
accounts = eth_tester.get_accounts()
357354
assert accounts, "No accounts available for transaction sending"
358355

@@ -362,10 +359,11 @@ def test_send_transaction_no_gas_price_or_dynamic_fees(self, eth_tester):
362359
txn_hash = eth_tester.send_transaction(test_transaction)
363360
sent_transaction = eth_tester.get_transaction_by_hash(txn_hash)
364361

365-
assert sent_transaction.get('gas_price') == 1000000000
362+
assert sent_transaction.get('type') == '0x2'
366363
assert sent_transaction.get('max_fee_per_gas') == 1000000000
367364
assert sent_transaction.get('max_priority_fee_per_gas') == 1000000000
368365
assert sent_transaction.get('access_list') == ()
366+
assert sent_transaction.get('gas_price') == 1000000000
369367

370368
def test_send_access_list_transaction(self, eth_tester):
371369
accounts = eth_tester.get_accounts()
@@ -382,7 +380,7 @@ def test_send_access_list_transaction(self, eth_tester):
382380
}
383381
txn_hash = eth_tester.send_transaction(access_list_transaction)
384382
txn = eth_tester.get_transaction_by_hash(txn_hash)
385-
assert eth_tester.get_transaction_receipt(txn_hash)['type'] == '0x1'
383+
assert txn.get('type') == '0x1'
386384
self._check_transactions(access_list_transaction, txn)
387385

388386
# with non-empty access list
@@ -401,7 +399,7 @@ def test_send_access_list_transaction(self, eth_tester):
401399
)
402400
txn_hash = eth_tester.send_transaction(access_list_transaction)
403401
txn = eth_tester.get_transaction_by_hash(txn_hash)
404-
assert eth_tester.get_transaction_receipt(txn_hash)['type'] == '0x1'
402+
assert txn.get('type') == '0x1'
405403
self._check_transactions(access_list_transaction, txn)
406404

407405
def test_send_dynamic_fee_transaction(self, eth_tester):
@@ -419,7 +417,7 @@ def test_send_dynamic_fee_transaction(self, eth_tester):
419417
}
420418
txn_hash = eth_tester.send_transaction(dynamic_fee_transaction)
421419
txn = eth_tester.get_transaction_by_hash(txn_hash)
422-
assert eth_tester.get_transaction_receipt(txn_hash)['type'] == '0x2'
420+
assert txn.get('type') == '0x2'
423421
self._check_transactions(dynamic_fee_transaction, txn)
424422

425423
# with non-empty access list
@@ -438,7 +436,7 @@ def test_send_dynamic_fee_transaction(self, eth_tester):
438436
)
439437
txn_hash = eth_tester.send_transaction(dynamic_fee_transaction)
440438
txn = eth_tester.get_transaction_by_hash(txn_hash)
441-
assert eth_tester.get_transaction_receipt(txn_hash)['type'] == '0x2'
439+
assert txn.get('type') == '0x2'
442440
self._check_transactions(dynamic_fee_transaction, txn)
443441

444442
def test_block_number_auto_mine_transactions_enabled(self, eth_tester):
@@ -648,7 +646,6 @@ def test_get_block_by_hash(self, eth_tester):
648646
block = eth_tester.get_block_by_hash(block_hash)
649647
assert block['number'] == block_number
650648
assert block['hash'] == block_hash
651-
assert block['base_fee_per_gas'] is not None
652649

653650
def test_get_block_by_hash_full_transactions(self, eth_tester):
654651
eth_tester.mine_blocks(2)
@@ -730,30 +727,17 @@ def test_get_transaction_by_hash_for_unmined_transaction(self, eth_tester):
730727
assert transaction['hash'] == transaction_hash
731728
assert transaction['block_hash'] is None
732729

733-
def test_get_transaction_receipt_for_unmined_transaction_raises(self, eth_tester):
734-
eth_tester.disable_auto_mine_transactions()
735-
transaction_hash = eth_tester.send_transaction({
736-
"from": eth_tester.get_accounts()[0],
737-
"to": BURN_ADDRESS,
738-
"gas": 21000,
739-
})
740-
with pytest.raises(TransactionNotFound):
741-
eth_tester.get_transaction_receipt(transaction_hash)
742-
743730
def test_get_transaction_receipt_for_mined_transaction(self, eth_tester):
744731
transaction_hash = eth_tester.send_transaction({
745732
"from": eth_tester.get_accounts()[0],
746733
"to": BURN_ADDRESS,
747734
"gas": 21000,
748735
})
749-
mined_transaction = eth_tester.get_transaction_by_hash(transaction_hash)
750-
max_fee = mined_transaction['max_fee_per_gas']
751-
assert max_fee == 1000000000
752736

753737
receipt = eth_tester.get_transaction_receipt(transaction_hash)
754738
assert receipt['transaction_hash'] == transaction_hash
755739
assert receipt['type'] == '0x2'
756-
assert receipt['effective_gas_price'] == max_fee
740+
assert receipt['effective_gas_price'] == 1000000000
757741

758742
@pytest.mark.parametrize(
759743
'type_specific_params,_type',
@@ -815,7 +799,7 @@ def test_receipt_effective_gas_price_for_mined_transaction_legacy(self, eth_test
815799
assert receipt['type'] == '0x0'
816800
assert receipt['effective_gas_price'] == gas_price
817801

818-
def test_receipt_effective_gas_price_for_mined_transaction_base_fee_limit(self, eth_tester):
802+
def test_receipt_effective_gas_price_for_mined_transaction_base_fee_minimum(self, eth_tester):
819803
priority_fee = 1500000000
820804

821805
transaction_hash = eth_tester.send_transaction({
@@ -838,7 +822,7 @@ def test_receipt_effective_gas_price_for_mined_transaction_base_fee_limit(self,
838822
# effective gas price
839823
assert receipt['effective_gas_price'] == base_fee + priority_fee
840824

841-
def test_receipt_effective_gas_price_for_mined_transaction_max_fee_limit(self, eth_tester):
825+
def test_receipt_effective_gas_price_for_mined_transaction_max_fee_minimum(self, eth_tester):
842826
priority_fee = 1500000000
843827
max_fee = priority_fee + 1 # arbitrary, to differentiate from the priority fee
844828

@@ -862,6 +846,16 @@ def test_receipt_effective_gas_price_for_mined_transaction_max_fee_limit(self, e
862846
# effective gas price
863847
assert receipt['effective_gas_price'] == max_fee
864848

849+
def test_get_transaction_receipt_for_unmined_transaction_raises(self, eth_tester):
850+
eth_tester.disable_auto_mine_transactions()
851+
transaction_hash = eth_tester.send_transaction({
852+
"from": eth_tester.get_accounts()[0],
853+
"to": BURN_ADDRESS,
854+
"gas": 21000,
855+
})
856+
with pytest.raises(TransactionNotFound):
857+
eth_tester.get_transaction_receipt(transaction_hash)
858+
865859
def test_call_return13(self, eth_tester):
866860
self.skip_if_no_evm_execution()
867861

@@ -1525,16 +1519,8 @@ def test_delete_filter(self, eth_tester):
15251519
def test_receipt_gas_used_computation(self, eth_tester):
15261520
eth_tester.disable_auto_mine_transactions()
15271521

1528-
if isinstance(eth_tester.backend, PyEVMBackend):
1529-
chain_id = eth_tester.backend.chain.chain_id
1530-
15311522
tx_hashes = []
15321523
for i in range(4):
1533-
# TODO: PyEvm backend was not consistent in keeping the chain_id, so reset it. This
1534-
# needs to be investigated further.
1535-
if isinstance(eth_tester.backend, PyEVMBackend):
1536-
eth_tester.backend.chain.chain_id = chain_id
1537-
15381524
tx = {
15391525
'from': eth_tester.get_accounts()[i],
15401526
'to': eth_tester.get_accounts()[i + 1],

0 commit comments

Comments
 (0)