Skip to content

Commit a77234e

Browse files
nisdasjames-prysm
andauthored
Test Execution Deposit Requests in E2E (#14964)
* Test Deposit Requests * Remove extra epochs * Clean up Panic * Fix Slashing Config * Fix Slashing Test --------- Co-authored-by: james-prysm <[email protected]>
1 parent e0e7354 commit a77234e

File tree

8 files changed

+93
-0
lines changed

8 files changed

+93
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Added
2+
3+
- Added deposit request testing for electra.

runtime/interop/genesis.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ func GethTestnetGenesis(genesisTime uint64, cfg *clparams.BeaconChainConfig) *co
159159
ShanghaiTime: shanghaiTime,
160160
CancunTime: cancunTime,
161161
PragueTime: pragueTime,
162+
DepositContractAddress: common.HexToAddress(cfg.DepositContractAddress),
162163
BlobScheduleConfig: &params.BlobScheduleConfig{
163164
Cancun: &params.BlobConfig{
164165
Target: 3,

testing/endtoend/component_handler_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type componentHandler struct {
2828
web3Signer e2etypes.ComponentRunner
2929
bootnode e2etypes.ComponentRunner
3030
eth1Miner e2etypes.ComponentRunner
31+
txGen e2etypes.ComponentRunner
3132
builders e2etypes.MultipleComponentRunners
3233
eth1Proxy e2etypes.MultipleComponentRunners
3334
eth1Nodes e2etypes.MultipleComponentRunners

testing/endtoend/components/eth1/depositor.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,62 @@ func (d *Depositor) SendAndMine(ctx context.Context, offset, nvals int, batch ty
176176
return nil
177177
}
178178

179+
// SendAndMineByBatch uses the deterministic validator generator to generate deposits for `nvals` (number of validators).
180+
// To control which validators should receive deposits, so that we can generate deposits at different stages of e2e,
181+
// the `offset` parameter skips the first N validators in the deterministic list.
182+
// In order to test the requirement that our deposit follower is able to handle multiple partial deposits,
183+
// the `partial` flag specifies that half of the deposits should be broken up into 2 transactions.
184+
// Once the set of deposits has been generated, it submits a transaction for each deposit
185+
// (using 2 transactions for partial deposits) and then uses WaitForBlocks to send these transactions by one batch per block.
186+
// The batch size is determined by the provided batch size provided as an argument.
187+
func (d *Depositor) SendAndMineByBatch(ctx context.Context, offset, nvals, batchSize int, batch types.DepositBatch, partial bool) error {
188+
balance, err := d.Client.BalanceAt(ctx, d.Key.Address, nil)
189+
if err != nil {
190+
return err
191+
}
192+
// This is the "Send" part of the function. Compute deposits for `nvals` validators,
193+
// with half of those deposits being split over 2 transactions if the `partial` flag is true,
194+
// and throwing away any validators before `offset`.
195+
deposits, err := computeDeposits(offset, nvals, partial)
196+
if err != nil {
197+
return err
198+
}
199+
numBatch := len(deposits) / batchSize
200+
log.WithField("numDeposits", len(deposits)).WithField("batchSize", batchSize).WithField("numBatches", numBatch).WithField("balance", balance.String()).WithField("account", d.Key.Address.Hex()).Info("SendAndMineByBatch check")
201+
for i := 0; i < numBatch; i++ {
202+
txo, err := d.txops(ctx)
203+
if err != nil {
204+
return err
205+
}
206+
for _, dd := range deposits[i*batchSize : (i+1)*batchSize] {
207+
if err := d.SendDeposit(dd, txo, batch); err != nil {
208+
return err
209+
}
210+
}
211+
// This is the "AndMine" part of the function. WaitForBlocks will spam transactions to/from the given key
212+
// to advance the EL chain and until the chain has advanced the requested amount.
213+
if err = WaitForBlocks(d.Client, d.Key, 1); err != nil {
214+
return fmt.Errorf("failed to mine blocks %w", err)
215+
}
216+
}
217+
txo, err := d.txops(ctx)
218+
if err != nil {
219+
return err
220+
}
221+
// Send out the last partial batch
222+
for _, dd := range deposits[numBatch*batchSize:] {
223+
if err := d.SendDeposit(dd, txo, batch); err != nil {
224+
return err
225+
}
226+
}
227+
// This is the "AndMine" part of the function. WaitForBlocks will spam transactions to/from the given key
228+
// to advance the EL chain and until the chain has advanced the requested amount.
229+
if err = WaitForBlocks(d.Client, d.Key, 1); err != nil {
230+
return fmt.Errorf("failed to mine blocks %w", err)
231+
}
232+
return nil
233+
}
234+
179235
// SendDeposit sends a single deposit. A record of this deposit will be tracked for the life of the Depositor,
180236
// allowing evaluators to use the deposit history to make assertions about those deposits.
181237
func (d *Depositor) SendDeposit(dep *eth.Deposit, txo *bind.TransactOpts, batch types.DepositBatch) error {

testing/endtoend/components/eth1/transactions.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ type TransactionGenerator struct {
3939
seed int64
4040
started chan struct{}
4141
cancel context.CancelFunc
42+
paused bool
43+
}
44+
45+
func (t *TransactionGenerator) UnderlyingProcess() *os.Process {
46+
// Transaction Generator runs under the same underlying process so
47+
// we return an empty process object.
48+
return &os.Process{}
4249
}
4350

4451
func NewTransactionGenerator(keystore string, seed int64) *TransactionGenerator {
@@ -94,6 +101,9 @@ func (t *TransactionGenerator) Start(ctx context.Context) error {
94101
case <-ctx.Done():
95102
return nil
96103
case <-ticker.C:
104+
if t.paused {
105+
continue
106+
}
97107
backend := ethclient.NewClient(client)
98108
err = SendTransaction(client, mineKey.PrivateKey, f, gasPrice, mineKey.Address.String(), txCount, backend, false)
99109
if err != nil {
@@ -211,11 +221,13 @@ func SendTransaction(client *rpc.Client, key *ecdsa.PrivateKey, f *filler.Filler
211221

212222
// Pause pauses the component and its underlying process.
213223
func (t *TransactionGenerator) Pause() error {
224+
t.paused = true
214225
return nil
215226
}
216227

217228
// Resume resumes the component and its underlying process.
218229
func (t *TransactionGenerator) Resume() error {
230+
t.paused = false
219231
return nil
220232
}
221233

testing/endtoend/endtoend_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ func (r *testRunner) testDepositsAndTx(ctx context.Context, g *errgroup.Group,
225225

226226
func (r *testRunner) testTxGeneration(ctx context.Context, g *errgroup.Group, keystorePath string, requiredNodes []e2etypes.ComponentRunner) {
227227
txGenerator := eth1.NewTransactionGenerator(keystorePath, r.config.Seed)
228+
r.comHandler.txGen = txGenerator
228229
g.Go(func() error {
229230
if err := helpers.ComponentsStarted(ctx, requiredNodes); err != nil {
230231
return fmt.Errorf("transaction generator requires eth1 nodes to be run: %w", err)
@@ -501,6 +502,19 @@ func (r *testRunner) defaultEndToEndRun() error {
501502
if err := r.runEvaluators(ec, conns, tickingStartTime); err != nil {
502503
return errors.Wrap(err, "one or more evaluators failed")
503504
}
505+
// Test execution request processing in electra.
506+
if r.config.TestDeposits && params.ElectraEnabled() {
507+
if err := r.comHandler.txGen.Pause(); err != nil {
508+
r.t.Error(err)
509+
}
510+
err = r.depositor.SendAndMineByBatch(ctx, int(params.BeaconConfig().MinGenesisActiveValidatorCount)+int(e2e.DepositCount), int(e2e.PostElectraDepositCount), int(params.BeaconConfig().MaxDepositRequestsPerPayload), e2etypes.PostElectraDepositBatch, false)
511+
if err != nil {
512+
r.t.Error(err)
513+
}
514+
if err := r.comHandler.txGen.Resume(); err != nil {
515+
r.t.Error(err)
516+
}
517+
}
504518

505519
index := e2e.TestParams.BeaconNodeCount + e2e.TestParams.LighthouseBeaconNodeCount
506520
if config.TestSync {

testing/endtoend/params/params.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ var StandardLighthouseNodeCount = 2
120120
// DepositCount is the number of deposits the E2E runner should make to evaluate post-genesis deposit processing.
121121
var DepositCount = uint64(64)
122122

123+
// PostElectraDepositCount is the number of deposits the E2E runner should make to evaluate post-electra deposit processing.
124+
var PostElectraDepositCount = uint64(32)
125+
123126
// PregenesisExecCreds is the number of withdrawal credentials of genesis validators which use an execution address.
124127
var PregenesisExecCreds = uint64(8)
125128

testing/endtoend/types/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ const (
116116
// PostGenesisDepositBatch deposits are sent to test that deposits appear in blocks as expected
117117
// and validators become active.
118118
PostGenesisDepositBatch
119+
// PostElectraDepositBatch deposits are sent to test that deposits sent after electra has been transitioned
120+
// work as expected.
121+
PostElectraDepositBatch
119122
)
120123

121124
// DepositBalancer represents a type that can sum, by validator, all deposits made in E2E prior to the function call.

0 commit comments

Comments
 (0)