Commit c95264e7 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge pull request #4569 from ethereum-optimism/action-test-l1-rpc-error

op-e2e: action test derivation with flaky L1 RPC
parents f0e145d0 88a3dfc2
...@@ -42,7 +42,7 @@ type L1Replica struct { ...@@ -42,7 +42,7 @@ type L1Replica struct {
l1Cfg *core.Genesis l1Cfg *core.Genesis
l1Signer types.Signer l1Signer types.Signer
failL1RPC error // mock error failL1RPC func() error // mock error
} }
// NewL1Replica constructs a L1Replica starting at the given genesis. // NewL1Replica constructs a L1Replica starting at the given genesis.
...@@ -145,10 +145,18 @@ func (s *L1Replica) CanonL1Chain() func(num uint64) *types.Block { ...@@ -145,10 +145,18 @@ func (s *L1Replica) CanonL1Chain() func(num uint64) *types.Block {
// ActL1RPCFail makes the next L1 RPC request to this node fail // ActL1RPCFail makes the next L1 RPC request to this node fail
func (s *L1Replica) ActL1RPCFail(t Testing) { func (s *L1Replica) ActL1RPCFail(t Testing) {
if s.failL1RPC != nil { // already set to fail? failed := false
t.InvalidAction("already have a mock l1 rpc fail set") s.failL1RPC = func() error {
if failed {
return nil
}
failed = true
return errors.New("mock L1 RPC error")
} }
s.failL1RPC = errors.New("mock L1 RPC error") }
func (s *L1Replica) MockL1RPCErrors(fn func() error) {
s.failL1RPC = fn
} }
func (s *L1Replica) EthClient() *ethclient.Client { func (s *L1Replica) EthClient() *ethclient.Client {
...@@ -161,9 +169,11 @@ func (s *L1Replica) RPCClient() client.RPC { ...@@ -161,9 +169,11 @@ func (s *L1Replica) RPCClient() client.RPC {
return testutils.RPCErrFaker{ return testutils.RPCErrFaker{
RPC: client.NewBaseRPCClient(cl), RPC: client.NewBaseRPCClient(cl),
ErrFn: func() error { ErrFn: func() error {
err := s.failL1RPC if s.failL1RPC != nil {
s.failL1RPC = nil // reset back, only error once. return s.failL1RPC()
return err } else {
return nil
}
}, },
} }
} }
......
package actions
import (
"errors"
"math/rand"
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)
func TestDerivationWithFlakyL1RPC(gt *testing.T) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create
_, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log)
rng := rand.New(rand.NewSource(1234))
sequencer.ActL2PipelineFull(t)
verifier.ActL2PipelineFull(t)
// build a L1 chain with 20 blocks and matching L2 chain and batches to test some derivation work
miner.ActEmptyBlock(t)
for i := 0; i < 20; i++ {
sequencer.ActL1HeadSignal(t)
sequencer.ActL2PipelineFull(t)
sequencer.ActBuildToL1Head(t)
batcher.ActSubmitAll(t)
miner.ActL1StartBlock(12)(t)
miner.ActL1IncludeTx(batcher.batcherAddr)(t)
miner.ActL1EndBlock(t)
}
// Make verifier aware of head
verifier.ActL1HeadSignal(t)
// Now make the L1 RPC very flaky: requests will randomly fail with 50% chance
miner.MockL1RPCErrors(func() error {
if rng.Intn(2) == 0 {
return errors.New("mock rpc error")
}
return nil
})
// And sync the verifier
verifier.ActL2PipelineFull(t)
// Verifier should be synced, even though it hit lots of temporary L1 RPC errors
require.Equal(t, sequencer.L2Unsafe(), verifier.L2Safe(), "verifier is synced")
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment