feat(spec-tests): Add EIP-7778 tests with multiple refund types#2074
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## eips/amsterdam/eip-7778 #2074 +/- ##
===========================================================
- Coverage 86.33% 86.14% -0.20%
===========================================================
Files 538 599 +61
Lines 34557 39475 +4918
Branches 3222 3780 +558
===========================================================
+ Hits 29835 34005 +4170
- Misses 4148 4848 +700
- Partials 574 622 +48
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
LouisTsai-Csie
left a comment
There was a problem hiding this comment.
I love this refactor! It is incredible. But it seems there is some issue with the changelog changes.
btw, I noticed some dotted lines in the codebase, but linting passes without issues. Not sure whether we’re missing some configuration or if this warning should simply be disabled, probably the latter.
fdc3e8d to
1d28b79
Compare
marioevz
left a comment
There was a problem hiding this comment.
Just some small cosmetic comments, thanks!
| else: | ||
| post[contract_address] = Account( | ||
| storage=dict.fromkeys(storage_slots, 0), | ||
| for refund_type in refund_types: |
There was a problem hiding this comment.
I don't quite understand this for loop here because we only pass a single refund type each time.
There was a problem hiding this comment.
If one wants to build a refund transaction that has multiple type of refunds within a single transaction. I could pass something like refund_types = {STORAGE_CLEAR, AUTHORIZATION_EXISTING_AUTHORITY} to have both refund types in a single transaction. (or any combination of refund types once there are more than just those 2)
| authorization_list = None | ||
| if count_auth_tuples: | ||
| authorization_list = [ | ||
| AuthorizationTuple( | ||
| address=contract_address, | ||
| nonce=0, | ||
| signer=pre.fund_eoa(amount=1), | ||
| ) | ||
| assert effective_refund > 0, ( | ||
| f"effective_refund ({effective_refund}) must be greater than 0" | ||
| ) | ||
| gas_used_post_refund = gas_used_pre_refund - effective_refund | ||
|
|
||
| refund_tx_gas_used = gas_used_pre_refund | ||
| refund_tx_gas_spent = gas_used_post_refund | ||
|
|
||
| refund_tx = Transaction( | ||
| to=contract_address, | ||
| gas_limit=refund_tx_gas_used, | ||
| sender=refund_tx_sender, | ||
| authorization_list=authorization_list, | ||
| expected_receipt={ | ||
| "gas_used": refund_tx_gas_used, | ||
| "gas_spent": refund_tx_gas_spent, | ||
| }, | ||
| ) | ||
| refund_tx_gas_price = refund_tx.max_fee_per_gas | ||
| for _ in range(count_auth_tuples) | ||
| ] | ||
|
|
||
| gas_used_pre_refund = intrinsic_cost_calc( | ||
| calldata=call_data, | ||
| return_cost_deducted_prior_execution=True, | ||
| authorization_list_or_count=authorization_list, | ||
| ) + code.gas_cost(fork) | ||
|
|
||
| # Calculate refund (still applied to user's balance) | ||
| refund_counter = gsc.R_AUTHORIZATION_EXISTING_AUTHORITY * count_auth_tuples | ||
| if not refund_tx_reverts: | ||
| refund_counter += code.refund(fork) |
There was a problem hiding this comment.
Perhaps all of this logic could sandwich the match-case logic like so:
authorization_list = None
refund_counter = 0
match refund_type:
case RefundTypes.STORAGE_CLEAR:
for slot in storage_slots:
code += Op.SSTORE(
slot,
Op.PUSH0,
# Gas accounting
original_value=1,
new_value=0,
)
empty_storage_on_success = True
case RefundTypes.AUTHORIZATION_EXISTING_AUTHORITY:
code += Op.PUSH0
authorization_list = [
AuthorizationTuple(
address=contract_address,
nonce=0,
signer=pre.fund_eoa(amount=1),
)
for _ in range(refunds_count)
]
refund_counter += gsc.R_AUTHORIZATION_EXISTING_AUTHORITY * refunds_count
case _:
raise ValueError(
f"Unknown refund type: {refund_type} (Test needs update)"
)
if not refund_tx_reverts:
refund_counter += code.refund(fork)Just to not have side-effects disjointed from the code that produces them I think.
There was a problem hiding this comment.
Ah. You are right. I went with this approach because we won't have the delegated_contract for creating the auth_tuples until we have the full code and have pre_deployed the contract with that code.
However, as I think more about this, the delegated contract does not necessarily have to be the same as the contract called by the transaction. So I can just deploy a dummy delegated contract and use that for the auth tuples. I have updated with this approach
1d28b79 to
8bd5daf
Compare
|
@marioevz @LouisTsai-Csie Have rebased the PR on top of the changes introduced in #2073 |
b60e498
into
ethereum:eips/amsterdam/eip-7778
* chore(tests): refactor refund transaction build * feat(tests): eip-7778 tests for multiple refund types
* chore(tests): refactor refund transaction build * feat(tests): eip-7778 tests for multiple refund types
* chore(tests): refactor refund transaction build * feat(tests): eip-7778 tests for multiple refund types
* chore(tests): refactor refund transaction build * feat(tests): eip-7778 tests for multiple refund types
…reum#2074) * chore(tests): refactor refund transaction build * feat(tests): eip-7778 tests for multiple refund types
* chore(tests): refactor refund transaction build * feat(tests): eip-7778 tests for multiple refund types
* chore(tests): refactor refund transaction build * feat(tests): eip-7778 tests for multiple refund types
* chore(tests): refactor refund transaction build * feat(tests): eip-7778 tests for multiple refund types
🗒️ Description
This PR does 2 things
refund_txfrom scratch🔗 Related Issues or PRs
#1874
✅ Checklist
toxchecks to avoid unnecessary CI fails, see also Code Standards and Enabling Pre-commit Checks:uvx tox -e statictype(scope):.Cute Animal Picture