Skip to content

Commit 5782437

Browse files
committed
simulators/eth2/withdrawals: add builder tests
1 parent ee7407b commit 5782437

File tree

5 files changed

+565
-4
lines changed

5 files changed

+565
-4
lines changed

simulators/eth2/withdrawals/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,66 @@ document.
160160
- Withdrawal addresses specified on node `A` and `B` are fully withdrawing
161161

162162
</details>
163+
164+
165+
### Builder API Fallback for Withdrawals
166+
167+
* [x] Builder API Constructs Payloads with Invalid Withdrawals List
168+
<details>
169+
<summary>Click for details</summary>
170+
171+
- Start two validating nodes on Bellatrix/Paris genesis
172+
- Total of 128 Validators, 64 for each validating node
173+
- All genesis validators have Execution address withdrawal credentials
174+
- Both validating nodes are connected to a builder API mock server
175+
- Builder API server is configured to return payloads with an invalid withdrawals list, starting from capella
176+
- Wait for finalization, and verify at least one block was built by the builder API on each node
177+
- Wait for capella and verify that the invalid payloads are correctly rejected from the canonical chain
178+
- Verify that the chain is able to finalize even after the builder API returns payloads with invalid withdrawals on every request
179+
180+
</details>
181+
182+
* [x] Builder API Returns Error on Header Request Starting from Capella
183+
<details>
184+
<summary>Click for details</summary>
185+
186+
- Start two validating nodes on Bellatrix/Paris genesis
187+
- Total of 128 Validators, 64 for each validating node
188+
- All genesis validators have Execution address withdrawal credentials
189+
- Both validating nodes are connected to a builder API mock server
190+
- Builder API server is configured to return error on header request, starting from capella
191+
- Wait for capella
192+
- Wait for finalization, and verify at least one block was built by the builder API on each node
193+
- Verify that the chain is able to finalize even after the builder API returns error on every header request
194+
195+
</details>
196+
197+
* [x] Builder API Returns Error on Unblinded Block Request Starting from Capella
198+
<details>
199+
<summary>Click for details</summary>
200+
201+
- Start two validating nodes on Bellatrix/Paris genesis
202+
- Total of 128 Validators, 64 for each validating node
203+
- All genesis validators have Execution address withdrawal credentials
204+
- Both validating nodes are connected to a builder API mock server
205+
- Builder API server is configured to return error on unblinded block request, starting from capella
206+
- Wait for capella
207+
- Wait for finalization, and verify at least one block was built by the builder API on each node
208+
- Verify that the chain is able to finalize even after the builder API returns error on every unblinded block request
209+
210+
</details>
211+
212+
* [x] Builder API Returns Constructs Valid Withdrawals/Invalid StateRoot Payload Starting from Capella
213+
<details>
214+
<summary>Click for details</summary>
215+
216+
- Start two validating nodes on Bellatrix/Paris genesis
217+
- Total of 128 Validators, 64 for each validating node
218+
- All genesis validators have Execution address withdrawal credentials
219+
- Both validating nodes are connected to a builder API mock server
220+
- Builder API server is configured to produce payloads with valid withdrawals list, but invalid state root, starting from capella
221+
- Wait for capella
222+
- Verify that the consensus clients correctly circuit break the builder when the empty slots are detected
223+
- Verify that the chain is able to finalize
224+
225+
</details>

simulators/eth2/withdrawals/helper.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,3 +555,44 @@ func ComputeBLSToExecutionDomain(
555555
t.GenesisValidatorsRoot(),
556556
)
557557
}
558+
559+
type BaseTransactionCreator struct {
560+
Recipient *common.Address
561+
GasLimit uint64
562+
Amount *big.Int
563+
Payload []byte
564+
PrivateKey *ecdsa.PrivateKey
565+
}
566+
567+
func (tc *BaseTransactionCreator) MakeTransaction(
568+
nonce uint64,
569+
) (*types.Transaction, error) {
570+
var newTxData types.TxData
571+
572+
gasFeeCap := new(big.Int).Set(GasPrice)
573+
gasTipCap := new(big.Int).Set(GasTipPrice)
574+
newTxData = &types.DynamicFeeTx{
575+
Nonce: nonce,
576+
Gas: tc.GasLimit,
577+
GasTipCap: gasTipCap,
578+
GasFeeCap: gasFeeCap,
579+
To: tc.Recipient,
580+
Value: tc.Amount,
581+
Data: tc.Payload,
582+
}
583+
584+
tx := types.NewTx(newTxData)
585+
key := tc.PrivateKey
586+
if key == nil {
587+
key = VaultKey
588+
}
589+
signedTx, err := types.SignTx(
590+
tx,
591+
types.NewLondonSigner(ChainID),
592+
key,
593+
)
594+
if err != nil {
595+
return nil, err
596+
}
597+
return signedTx, nil
598+
}

simulators/eth2/withdrawals/main.go

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,72 @@ var tests = []TestSpec{
9090
},
9191
}
9292

93+
var builderTests = []TestSpec{
94+
BuilderWithdrawalsTestSpec{
95+
BaseWithdrawalsTestSpec: BaseWithdrawalsTestSpec{
96+
Name: "test-builders-capella-invalid-withdrawals",
97+
Description: `
98+
Test canonical chain can still finalize if the builders start
99+
building payloads with invalid withdrawals list.
100+
`,
101+
// All validators can withdraw from the start
102+
GenesisExecutionWithdrawalCredentialsShares: 1,
103+
},
104+
BuilderTestError: INVALID_WITHDRAWALS,
105+
},
106+
BuilderWithdrawalsTestSpec{
107+
BaseWithdrawalsTestSpec: BaseWithdrawalsTestSpec{
108+
Name: "test-builders-capella-error-on-capella-header-request",
109+
Description: `
110+
Test canonical chain can still finalize if the builders start
111+
returning error on header request after capella transition.
112+
`,
113+
// All validators can withdraw from the start
114+
GenesisExecutionWithdrawalCredentialsShares: 1,
115+
},
116+
BuilderTestError: ERROR_ON_HEADER_REQUEST,
117+
},
118+
BuilderWithdrawalsTestSpec{
119+
BaseWithdrawalsTestSpec: BaseWithdrawalsTestSpec{
120+
Name: "test-builders-capella-error-on-capella-unblind-payload-requestr",
121+
Description: `
122+
Test canonical chain can still finalize if the builders start
123+
returning error on unblinded payload request after capella transition.
124+
`,
125+
// All validators can withdraw from the start
126+
GenesisExecutionWithdrawalCredentialsShares: 1,
127+
},
128+
BuilderTestError: ERROR_ON_UNBLINDED_PAYLOAD_REQUEST,
129+
},
130+
BuilderWithdrawalsTestSpec{
131+
BaseWithdrawalsTestSpec: BaseWithdrawalsTestSpec{
132+
Name: "test-builders-capella-invalid-payload",
133+
Description: `
134+
Test consensus clients correctly circuit break builder after a
135+
period of empty blocks due to invalid unblinded blocks.
136+
The payloads are built using an invalid state root, which can only
137+
be caught after unblinding the entire payload and running it in the
138+
local execution client, at which point another payload cannot be
139+
produced locally and results in an empty slot.
140+
`,
141+
// All validators can withdraw from the start
142+
GenesisExecutionWithdrawalCredentialsShares: 1,
143+
},
144+
BuilderTestError: VALID_WITHDRAWALS_INVALID_STATE_ROOT,
145+
},
146+
BuilderWithdrawalsTestSpec{
147+
BaseWithdrawalsTestSpec: BaseWithdrawalsTestSpec{
148+
Name: "test-builders-capella-correct-withdrawals",
149+
Description: `
150+
Test canonical chain includes capella payloads built by the builder api.
151+
`,
152+
// All validators can withdraw from the start
153+
GenesisExecutionWithdrawalCredentialsShares: 1,
154+
},
155+
BuilderTestError: NO_ERROR,
156+
},
157+
}
158+
93159
func main() {
94160
// Create simulator that runs all tests
95161
sim := hivesim.New()
@@ -101,16 +167,22 @@ func main() {
101167
c := clients.ClientsByRole(clientTypes)
102168

103169
// Create the test suites
104-
engineSuite := hivesim.Suite{
170+
withdrawalsSuite := hivesim.Suite{
105171
Name: "eth2-withdrawals",
106-
Description: `Collection of test vectors that use a ExecutionClient+BeaconNode+ValidatorClient testnet.`,
172+
Description: `Collection of test vectors that use a ExecutionClient+BeaconNode+ValidatorClient testnet for Shanghai+Capella.`,
173+
}
174+
builderSuite := hivesim.Suite{
175+
Name: "eth2-withdrawals-builder",
176+
Description: `Collection of test vectors that use a ExecutionClient+BeaconNode+ValidatorClient testnet and builder API for Shanghai+Capella.`,
107177
}
108178

109179
// Add all tests to the suites
110-
addAllTests(&engineSuite, c, tests)
180+
addAllTests(&withdrawalsSuite, c, tests)
181+
addAllTests(&builderSuite, c, builderTests)
111182

112183
// Mark suites for execution
113-
hivesim.MustRunSuite(sim, engineSuite)
184+
hivesim.MustRunSuite(sim, withdrawalsSuite)
185+
hivesim.MustRunSuite(sim, builderSuite)
114186
}
115187

116188
func addAllTests(

0 commit comments

Comments
 (0)