mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 13:28:01 -05:00
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 <90280386+james-prysm@users.noreply.github.com>
This commit is contained in:
3
changelog/nisdas_add_deposit_request_testing.md
Normal file
3
changelog/nisdas_add_deposit_request_testing.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Added
|
||||
|
||||
- Added deposit request testing for electra.
|
||||
@@ -159,6 +159,7 @@ func GethTestnetGenesis(genesisTime uint64, cfg *clparams.BeaconChainConfig) *co
|
||||
ShanghaiTime: shanghaiTime,
|
||||
CancunTime: cancunTime,
|
||||
PragueTime: pragueTime,
|
||||
DepositContractAddress: common.HexToAddress(cfg.DepositContractAddress),
|
||||
BlobScheduleConfig: ¶ms.BlobScheduleConfig{
|
||||
Cancun: ¶ms.BlobConfig{
|
||||
Target: 3,
|
||||
|
||||
@@ -28,6 +28,7 @@ type componentHandler struct {
|
||||
web3Signer e2etypes.ComponentRunner
|
||||
bootnode e2etypes.ComponentRunner
|
||||
eth1Miner e2etypes.ComponentRunner
|
||||
txGen e2etypes.ComponentRunner
|
||||
builders e2etypes.MultipleComponentRunners
|
||||
eth1Proxy e2etypes.MultipleComponentRunners
|
||||
eth1Nodes e2etypes.MultipleComponentRunners
|
||||
|
||||
@@ -176,6 +176,62 @@ func (d *Depositor) SendAndMine(ctx context.Context, offset, nvals int, batch ty
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendAndMineByBatch uses the deterministic validator generator to generate deposits for `nvals` (number of validators).
|
||||
// To control which validators should receive deposits, so that we can generate deposits at different stages of e2e,
|
||||
// the `offset` parameter skips the first N validators in the deterministic list.
|
||||
// In order to test the requirement that our deposit follower is able to handle multiple partial deposits,
|
||||
// the `partial` flag specifies that half of the deposits should be broken up into 2 transactions.
|
||||
// Once the set of deposits has been generated, it submits a transaction for each deposit
|
||||
// (using 2 transactions for partial deposits) and then uses WaitForBlocks to send these transactions by one batch per block.
|
||||
// The batch size is determined by the provided batch size provided as an argument.
|
||||
func (d *Depositor) SendAndMineByBatch(ctx context.Context, offset, nvals, batchSize int, batch types.DepositBatch, partial bool) error {
|
||||
balance, err := d.Client.BalanceAt(ctx, d.Key.Address, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// This is the "Send" part of the function. Compute deposits for `nvals` validators,
|
||||
// with half of those deposits being split over 2 transactions if the `partial` flag is true,
|
||||
// and throwing away any validators before `offset`.
|
||||
deposits, err := computeDeposits(offset, nvals, partial)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
numBatch := len(deposits) / batchSize
|
||||
log.WithField("numDeposits", len(deposits)).WithField("batchSize", batchSize).WithField("numBatches", numBatch).WithField("balance", balance.String()).WithField("account", d.Key.Address.Hex()).Info("SendAndMineByBatch check")
|
||||
for i := 0; i < numBatch; i++ {
|
||||
txo, err := d.txops(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, dd := range deposits[i*batchSize : (i+1)*batchSize] {
|
||||
if err := d.SendDeposit(dd, txo, batch); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// This is the "AndMine" part of the function. WaitForBlocks will spam transactions to/from the given key
|
||||
// to advance the EL chain and until the chain has advanced the requested amount.
|
||||
if err = WaitForBlocks(d.Client, d.Key, 1); err != nil {
|
||||
return fmt.Errorf("failed to mine blocks %w", err)
|
||||
}
|
||||
}
|
||||
txo, err := d.txops(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Send out the last partial batch
|
||||
for _, dd := range deposits[numBatch*batchSize:] {
|
||||
if err := d.SendDeposit(dd, txo, batch); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// This is the "AndMine" part of the function. WaitForBlocks will spam transactions to/from the given key
|
||||
// to advance the EL chain and until the chain has advanced the requested amount.
|
||||
if err = WaitForBlocks(d.Client, d.Key, 1); err != nil {
|
||||
return fmt.Errorf("failed to mine blocks %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendDeposit sends a single deposit. A record of this deposit will be tracked for the life of the Depositor,
|
||||
// allowing evaluators to use the deposit history to make assertions about those deposits.
|
||||
func (d *Depositor) SendDeposit(dep *eth.Deposit, txo *bind.TransactOpts, batch types.DepositBatch) error {
|
||||
|
||||
@@ -39,6 +39,13 @@ type TransactionGenerator struct {
|
||||
seed int64
|
||||
started chan struct{}
|
||||
cancel context.CancelFunc
|
||||
paused bool
|
||||
}
|
||||
|
||||
func (t *TransactionGenerator) UnderlyingProcess() *os.Process {
|
||||
// Transaction Generator runs under the same underlying process so
|
||||
// we return an empty process object.
|
||||
return &os.Process{}
|
||||
}
|
||||
|
||||
func NewTransactionGenerator(keystore string, seed int64) *TransactionGenerator {
|
||||
@@ -94,6 +101,9 @@ func (t *TransactionGenerator) Start(ctx context.Context) error {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case <-ticker.C:
|
||||
if t.paused {
|
||||
continue
|
||||
}
|
||||
backend := ethclient.NewClient(client)
|
||||
err = SendTransaction(client, mineKey.PrivateKey, f, gasPrice, mineKey.Address.String(), txCount, backend, false)
|
||||
if err != nil {
|
||||
@@ -211,11 +221,13 @@ func SendTransaction(client *rpc.Client, key *ecdsa.PrivateKey, f *filler.Filler
|
||||
|
||||
// Pause pauses the component and its underlying process.
|
||||
func (t *TransactionGenerator) Pause() error {
|
||||
t.paused = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resume resumes the component and its underlying process.
|
||||
func (t *TransactionGenerator) Resume() error {
|
||||
t.paused = false
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -225,6 +225,7 @@ func (r *testRunner) testDepositsAndTx(ctx context.Context, g *errgroup.Group,
|
||||
|
||||
func (r *testRunner) testTxGeneration(ctx context.Context, g *errgroup.Group, keystorePath string, requiredNodes []e2etypes.ComponentRunner) {
|
||||
txGenerator := eth1.NewTransactionGenerator(keystorePath, r.config.Seed)
|
||||
r.comHandler.txGen = txGenerator
|
||||
g.Go(func() error {
|
||||
if err := helpers.ComponentsStarted(ctx, requiredNodes); err != nil {
|
||||
return fmt.Errorf("transaction generator requires eth1 nodes to be run: %w", err)
|
||||
@@ -501,6 +502,19 @@ func (r *testRunner) defaultEndToEndRun() error {
|
||||
if err := r.runEvaluators(ec, conns, tickingStartTime); err != nil {
|
||||
return errors.Wrap(err, "one or more evaluators failed")
|
||||
}
|
||||
// Test execution request processing in electra.
|
||||
if r.config.TestDeposits && params.ElectraEnabled() {
|
||||
if err := r.comHandler.txGen.Pause(); err != nil {
|
||||
r.t.Error(err)
|
||||
}
|
||||
err = r.depositor.SendAndMineByBatch(ctx, int(params.BeaconConfig().MinGenesisActiveValidatorCount)+int(e2e.DepositCount), int(e2e.PostElectraDepositCount), int(params.BeaconConfig().MaxDepositRequestsPerPayload), e2etypes.PostElectraDepositBatch, false)
|
||||
if err != nil {
|
||||
r.t.Error(err)
|
||||
}
|
||||
if err := r.comHandler.txGen.Resume(); err != nil {
|
||||
r.t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
index := e2e.TestParams.BeaconNodeCount + e2e.TestParams.LighthouseBeaconNodeCount
|
||||
if config.TestSync {
|
||||
|
||||
@@ -120,6 +120,9 @@ var StandardLighthouseNodeCount = 2
|
||||
// DepositCount is the number of deposits the E2E runner should make to evaluate post-genesis deposit processing.
|
||||
var DepositCount = uint64(64)
|
||||
|
||||
// PostElectraDepositCount is the number of deposits the E2E runner should make to evaluate post-electra deposit processing.
|
||||
var PostElectraDepositCount = uint64(32)
|
||||
|
||||
// PregenesisExecCreds is the number of withdrawal credentials of genesis validators which use an execution address.
|
||||
var PregenesisExecCreds = uint64(8)
|
||||
|
||||
|
||||
@@ -116,6 +116,9 @@ const (
|
||||
// PostGenesisDepositBatch deposits are sent to test that deposits appear in blocks as expected
|
||||
// and validators become active.
|
||||
PostGenesisDepositBatch
|
||||
// PostElectraDepositBatch deposits are sent to test that deposits sent after electra has been transitioned
|
||||
// work as expected.
|
||||
PostElectraDepositBatch
|
||||
)
|
||||
|
||||
// DepositBalancer represents a type that can sum, by validator, all deposits made in E2E prior to the function call.
|
||||
|
||||
Reference in New Issue
Block a user