Skip to content

Commit 8666e45

Browse files
spencer-tbmarioevz
andauthored
chore(tests): EIP-6110: additional edge cases (#1467)
* chore(tests): additional eip6110 edge cases. * chore(docs): update changelog. * fix(types,tests): Improve docstrings to describe the requests * fix: review changes --------- Co-authored-by: Mario Vega <[email protected]>
1 parent 2b5f461 commit 8666e45

File tree

6 files changed

+290
-13
lines changed

6 files changed

+290
-13
lines changed

docs/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Test fixtures for use by clients are available for each release on the [Github r
2626
-[EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Add invalid nonce authorizations tests for the case of multiple signers when the sender's nonce gets increased ([#1441](https://github.com/ethereum/execution-spec-tests/pull/1441)).
2727
-[EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Add a test that verifies that set code transactions are correctly rejected before Prague activation ([#1463](https://github.com/ethereum/execution-spec-tests/pull/1463)).
2828
-[EIP-7623](https://eips.ethereum.org/EIPS/eip-7623): Additionally parametrize transaction validity tests with the `to` set to an EOA account (previously only contracts) ([#1422](https://github.com/ethereum/execution-spec-tests/pull/1422)).
29+
-[EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Add extra deposit request edge cases, sending eth to the deposit contract while sending a deposit request ([#1467](https://github.com/ethereum/execution-spec-tests/pull/1467)).
30+
-[EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Remove pytest skips for consolidation request cases ([#1449](https://github.com/ethereum/execution-spec-tests/pull/1449)).
2931

3032
### 📋 Misc
3133

src/ethereum_test_types/types.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,10 +1109,26 @@ class DepositRequest(RequestBase, CamelModel):
11091109
"""Deposit Request type."""
11101110

11111111
pubkey: BLSPublicKey
1112+
"""
1113+
The public key of the beacon chain validator.
1114+
"""
11121115
withdrawal_credentials: Hash
1116+
"""
1117+
The withdrawal credentials of the beacon chain validator.
1118+
"""
11131119
amount: HexNumber
1120+
"""
1121+
The amount in gwei of the deposit.
1122+
"""
11141123
signature: BLSSignature
1124+
"""
1125+
The signature of the deposit using the validator's private key that matches the
1126+
`pubkey`.
1127+
"""
11151128
index: HexNumber
1129+
"""
1130+
The index of the deposit.
1131+
"""
11161132

11171133
type: ClassVar[int] = 0
11181134

@@ -1131,8 +1147,17 @@ class WithdrawalRequest(RequestBase, CamelModel):
11311147
"""Withdrawal Request type."""
11321148

11331149
source_address: Address = Address(0)
1150+
"""
1151+
The address of the execution layer account that made the withdrawal request.
1152+
"""
11341153
validator_pubkey: BLSPublicKey
1154+
"""
1155+
The current public key of the validator as it currently is in the beacon state.
1156+
"""
11351157
amount: HexNumber
1158+
"""
1159+
The amount in gwei to be withdrawn on the beacon chain.
1160+
"""
11361161

11371162
type: ClassVar[int] = 1
11381163

@@ -1149,8 +1174,17 @@ class ConsolidationRequest(RequestBase, CamelModel):
11491174
"""Consolidation Request type."""
11501175

11511176
source_address: Address = Address(0)
1177+
"""
1178+
The address of the execution layer account that made the consolidation request.
1179+
"""
11521180
source_pubkey: BLSPublicKey
1181+
"""
1182+
The public key of the source validator as it currently is in the beacon state.
1183+
"""
11531184
target_pubkey: BLSPublicKey
1185+
"""
1186+
The public key of the target validator as it currently is in the beacon state.
1187+
"""
11541188

11551189
type: ClassVar[int] = 2
11561190

tests/prague/eip6110_deposits/helpers.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,29 @@ class DepositRequest(DepositRequestBase):
3232
"""
3333
Calldata modifier function.
3434
"""
35+
extra_wei: int = 0
36+
"""
37+
Extra amount in wei to be sent with the deposit.
38+
If this value modulo 10**9 is not zero, the deposit will be invalid.
39+
The value can be negative but if the total value is negative, an exception will be raised.
40+
"""
3541

3642
interaction_contract_address: ClassVar[Address] = Address(Spec.DEPOSIT_CONTRACT_ADDRESS)
3743

3844
@cached_property
3945
def value(self) -> int:
40-
"""Returns the value of the deposit transaction."""
41-
return self.amount * 10**9
46+
"""
47+
Return the value of the deposit transaction, equal to the amount in gwei plus the
48+
extra amount in wei.
49+
"""
50+
value = (self.amount * 10**9) + self.extra_wei
51+
if value < 0:
52+
raise ValueError("Value cannot be negative")
53+
return value
4254

4355
@cached_property
4456
def deposit_data_root(self) -> Hash:
45-
"""Returns the deposit data root of the deposit."""
57+
"""Return the deposit data root of the deposit."""
4658
pubkey_root = sha256(self.pubkey, b"\x00" * 16)
4759
signature_root = sha256(
4860
sha256(self.signature[:64]), sha256(self.signature[64:], b"\x00" * 32)
@@ -55,7 +67,7 @@ def deposit_data_root(self) -> Hash:
5567
@cached_property
5668
def calldata(self) -> bytes:
5769
"""
58-
Returns the calldata needed to call the beacon chain deposit contract and make the deposit.
70+
Return the calldata needed to call the beacon chain deposit contract and make the deposit.
5971
6072
deposit(
6173
bytes calldata pubkey,
@@ -157,6 +169,10 @@ class DepositContract(DepositInteractionBase):
157169
"""
158170
Gas limit for the transaction.
159171
"""
172+
tx_value: int = 0
173+
"""
174+
Value to send with the transaction.
175+
"""
160176

161177
contract_balance: int = 32_000_000_000_000_000_000 * 100
162178
"""
@@ -212,15 +228,18 @@ def transactions(self) -> List[Transaction]:
212228
gas_limit=self.tx_gas_limit,
213229
gas_price=0x07,
214230
to=self.entry_address,
215-
value=0,
231+
value=self.tx_value,
216232
data=b"".join(r.calldata for r in self.requests),
217233
sender=self.sender_account,
218234
)
219235
]
220236

221237
def update_pre(self, pre: Alloc):
222238
"""Return the pre-state of the account."""
223-
self.sender_account = pre.fund_eoa(self.sender_balance)
239+
required_balance = self.sender_balance
240+
if self.tx_value > 0:
241+
required_balance = max(required_balance, self.tx_value + self.tx_gas_limit * 7)
242+
self.sender_account = pre.fund_eoa(required_balance)
224243
self.contract_address = pre.deploy_contract(
225244
code=self.contract_code, balance=self.contract_balance
226245
)

tests/prague/eip6110_deposits/test_deposits.py

Lines changed: 215 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,25 @@
245245
],
246246
id="send_eth_from_eoa",
247247
),
248+
pytest.param(
249+
[
250+
DepositContract(
251+
requests=[
252+
DepositRequest(
253+
pubkey=0x01,
254+
withdrawal_credentials=0x02,
255+
amount=32_000_000_000,
256+
signature=0x03,
257+
index=0x0,
258+
valid=False,
259+
calldata_modifier=lambda _: b"",
260+
)
261+
],
262+
),
263+
],
264+
# TODO: EIP-5920: Send using PAY opcode
265+
id="send_eth_to_contract_no_deposit_data",
266+
),
248267
pytest.param(
249268
[
250269
DepositContract(
@@ -694,7 +713,202 @@
694713
],
695714
id="single_deposit_from_contract_call_depth_high",
696715
),
697-
# TODO: Send eth with the transaction to the contract
716+
pytest.param(
717+
[
718+
DepositTransaction(
719+
requests=[
720+
DepositRequest(
721+
pubkey=0x01,
722+
withdrawal_credentials=0x02,
723+
amount=1_000_000_001,
724+
signature=0x03,
725+
index=0x0,
726+
)
727+
],
728+
),
729+
],
730+
id="single_deposit_from_eoa_minimum_plus_one",
731+
),
732+
pytest.param(
733+
[
734+
DepositTransaction(
735+
requests=[
736+
DepositRequest(
737+
pubkey=0x01,
738+
withdrawal_credentials=0x02,
739+
amount=1_000_000_000,
740+
signature=0x03,
741+
index=0x0,
742+
extra_wei=1,
743+
valid=False,
744+
)
745+
],
746+
),
747+
],
748+
id="single_deposit_from_eoa_minimum_plus_one_wei",
749+
),
750+
pytest.param(
751+
[
752+
DepositTransaction(
753+
requests=[
754+
DepositRequest(
755+
pubkey=0x01,
756+
withdrawal_credentials=0x02,
757+
amount=1_000_000_000,
758+
signature=0x03,
759+
index=0x0,
760+
extra_wei=-1,
761+
valid=False,
762+
)
763+
],
764+
),
765+
],
766+
id="single_deposit_from_eoa_minimum_minus_one_wei",
767+
),
768+
pytest.param(
769+
[
770+
DepositContract(
771+
requests=[
772+
DepositRequest(
773+
pubkey=0x01,
774+
withdrawal_credentials=0x02,
775+
amount=1_000_000_000,
776+
signature=0x03,
777+
index=0x0,
778+
extra_wei=1,
779+
valid=False,
780+
)
781+
],
782+
),
783+
],
784+
id="single_deposit_from_contract_minimum_plus_one_wei",
785+
),
786+
pytest.param(
787+
[
788+
DepositContract(
789+
requests=[
790+
DepositRequest(
791+
pubkey=0x01,
792+
withdrawal_credentials=0x02,
793+
amount=1_000_000_000,
794+
signature=0x03,
795+
index=0x0,
796+
extra_wei=-1,
797+
valid=False,
798+
)
799+
],
800+
),
801+
],
802+
id="single_deposit_from_contract_minimum_minus_one_wei",
803+
),
804+
pytest.param(
805+
[
806+
DepositTransaction(
807+
requests=[
808+
DepositRequest(
809+
pubkey=0x01,
810+
withdrawal_credentials=0x02,
811+
amount=1_000_000_001,
812+
signature=0x03,
813+
index=0x0,
814+
),
815+
DepositRequest(
816+
pubkey=0x01,
817+
withdrawal_credentials=0x02,
818+
amount=999_999_999,
819+
signature=0x03,
820+
index=0x1,
821+
valid=False,
822+
),
823+
],
824+
),
825+
],
826+
id="multiple_deposits_from_eoa_minimum_plus_one_minimum_minus_one",
827+
),
828+
pytest.param(
829+
[
830+
DepositContract(
831+
requests=[
832+
DepositRequest(
833+
pubkey=0x01,
834+
withdrawal_credentials=0x02,
835+
amount=32_000_000_000,
836+
signature=0x03,
837+
index=0x0,
838+
valid=False,
839+
)
840+
],
841+
# Send 32 ETH minus 1 wei to the contract, note `DepositRequest.amount` is in
842+
# gwei
843+
tx_value=32_000_000_000 * 10**9 - 1,
844+
contract_balance=0,
845+
),
846+
],
847+
id="send_not_enough_eth_to_contract_with_zero_balance",
848+
),
849+
pytest.param(
850+
[
851+
DepositContract(
852+
requests=[
853+
DepositRequest(
854+
pubkey=0x01,
855+
withdrawal_credentials=0x02,
856+
amount=999_999_999,
857+
signature=0x03,
858+
index=0x0,
859+
valid=False,
860+
)
861+
],
862+
tx_value=1_000_000_000 * 10**9,
863+
),
864+
],
865+
id="send_eth_to_contract_insufficient_deposit",
866+
),
867+
pytest.param(
868+
[
869+
DepositContract(
870+
requests=[
871+
DepositRequest(
872+
pubkey=0x01,
873+
withdrawal_credentials=0x02,
874+
amount=32_000_000_000,
875+
signature=0x03,
876+
index=0x0,
877+
)
878+
],
879+
# Send 32 ETH (in wei) to the contract
880+
tx_value=32_000_000_000 * 10**9,
881+
contract_balance=0,
882+
),
883+
],
884+
id="send_exact_eth_amount_for_deposit",
885+
),
886+
pytest.param(
887+
[
888+
DepositContract(
889+
requests=[
890+
DepositRequest(
891+
pubkey=0x01,
892+
withdrawal_credentials=0x02,
893+
amount=32_000_000_000,
894+
signature=0x03,
895+
index=0x0,
896+
),
897+
DepositRequest(
898+
pubkey=0x01,
899+
withdrawal_credentials=0x02,
900+
amount=32_000_000_000,
901+
signature=0x03,
902+
index=0x1,
903+
),
904+
],
905+
# Send 64 ETH (in wei) to the contract
906+
tx_value=64_000_000_000 * 10**9,
907+
contract_balance=0,
908+
),
909+
],
910+
id="send_exact_eth_amount_for_multiple_deposits",
911+
),
698912
],
699913
)
700914
def test_deposit(

0 commit comments

Comments
 (0)