Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,12 @@ func TestReorgInitExecMsg(gt *testing.T) {

// wait and confirm reorgs on chain A and B
dsl.CheckAll(t,
sys.L2ELA.ReorgTriggeredFn(eth.L2BlockRef{
sys.L2ELA.ReorgExactFn(eth.L2BlockRef{
Number: divergenceBlockNumber_A,
Hash: originalRef_A.Hash,
ParentHash: originalRef_A.ParentID().Hash,
}, 30),
sys.L2ELB.ReorgTriggeredFn(eth.L2BlockRef{
sys.L2ELB.ReorgExactFn(eth.L2BlockRef{
Number: divergenceBlockNumber_B,
Hash: originalRef_B.Hash,
ParentHash: originalRef_B.ParentID().Hash,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func testReorgInvalidExecMsg(gt *testing.T, txModifierFn func(msg *suptypes.Mess
sys.L2BatcherA.Start()

// wait for reorg on chain A
sys.L2ELA.ReorgTriggered(eth.L2BlockRef{
sys.L2ELA.ReorgExact(eth.L2BlockRef{
Number: divergenceBlockNumber_A,
Hash: originalHash_A,
ParentHash: originalParentHash_A,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestSequencingWindowExpiry(gt *testing.T) {
t.Logger().Info("Waiting for sequencing window expiry induced reorg now", "windowDuration", windowDuration)

// Monitor that the old unsafe chain is reorged out as expected
sys.L2ELA.ReorgTriggered(old, 50)
sys.L2ELA.ReorgExact(old, 50)

// Wait for the tx to no longer be included.
// The tx-indexer may still return the old block or be stale.
Expand Down
55 changes: 42 additions & 13 deletions op-devstack/dsl/l2_el.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,39 +125,64 @@ func (el *L2ELNode) BlockRefByNumber(num uint64) eth.L2BlockRef {
return block
}

// ReorgTriggeredFn returns a lambda that checks that a L2 reorg occurred on the expected block
// ReorgTriggeredFn returns a lambda that checks that a L2 reorg occurred on or before the expected block
// Composable with other lambdas to wait in parallel
func (el *L2ELNode) ReorgTriggeredFn(target eth.L2BlockRef, attempts int) CheckFunc {
return func() error {
el.log.Info("expecting chain to reorg on block ref", "name", el.inner.Name(), "chain", el.inner.ChainID(), "target", target)
return retry.Do0(el.ctx, attempts, &retry.FixedStrategy{Dur: 2 * time.Second},
func() error {
reorged, err := el.inner.EthClient().BlockRefByNumber(el.ctx, target.Number)
if err != nil {
if strings.Contains(err.Error(), "not found") { // reorg is happening wait a bit longer
el.log.Info("chain still hasn't been reorged", "chain", el.inner.ChainID(), "error", err)
return err
}
return err
reorged, err := el.reorgTriggered(target)
if err == nil {
el.log.Info("reorg on divergence block", "chain", el.inner.ChainID(), "pre_blockref", target, "post_blockref", reorged)
}
return err
})
}
}

if target.Hash == reorged.Hash { // want not equal
el.log.Info("chain still hasn't been reorged", "chain", el.inner.ChainID(), "ref", reorged)
return fmt.Errorf("expected head to reorg %s, but got %s", target, reorged)
// ReorgExactFn returns a lambda that checks that a L2 reorg occurred on the exact target L2 block.
// If an L2 block prior to target was reorged, this function will block forever.
// Composable with other lambdas to wait in parallel.
func (el *L2ELNode) ReorgExactFn(target eth.L2BlockRef, attempts int) CheckFunc {
return func() error {
el.log.Info("expecting chain to reorg on block ref", "name", el.inner.Name(), "chain", el.inner.ChainID(), "target", target)
return retry.Do0(el.ctx, attempts, &retry.FixedStrategy{Dur: 2 * time.Second},
func() error {
reorged, err := el.reorgTriggered(target)
if err != nil {
return err
}

if target.ParentHash != reorged.ParentHash && target.ParentHash != emptyHash {
return fmt.Errorf("expected parent of target to be the same as the parent of the reorged head, but they are different")
}

el.log.Info("reorg on divergence block", "chain", el.inner.ChainID(), "pre_blockref", target)
el.log.Info("reorg on divergence block", "chain", el.inner.ChainID(), "post_blockref", reorged)
el.log.Info("reorg on divergence block", "chain", el.inner.ChainID(), "pre_blockref", target, "post_blockref", reorged)

return nil
})
}
}

func (el *L2ELNode) reorgTriggered(target eth.L2BlockRef) (eth.BlockRef, error) {
reorged, err := el.inner.EthClient().BlockRefByNumber(el.ctx, target.Number)
if err != nil {
if strings.Contains(err.Error(), "not found") { // reorg is happening wait a bit longer
el.log.Info("chain still hasn't been reorged", "chain", el.inner.ChainID(), "error", err)
return eth.BlockRef{}, err
}
return eth.BlockRef{}, err
}

if target.Hash == reorged.Hash { // want not equal
el.log.Info("chain still hasn't been reorged", "chain", el.inner.ChainID(), "ref", reorged)
return eth.BlockRef{}, fmt.Errorf("expected head to reorg %s, but got %s", target, reorged)
}

return reorged, nil
}

func (el *L2ELNode) Advanced(label eth.BlockLabel, block uint64) {
el.require.NoError(el.AdvancedFn(label, block)())
}
Expand All @@ -178,6 +203,10 @@ func (el *L2ELNode) ReorgTriggered(target eth.L2BlockRef, attempts int) {
el.require.NoError(el.ReorgTriggeredFn(target, attempts)())
}

func (el *L2ELNode) ReorgExact(target eth.L2BlockRef, attempts int) {
el.require.NoError(el.ReorgExactFn(target, attempts)())
}

func (el *L2ELNode) TransactionTimeout() time.Duration {
return el.inner.TransactionTimeout()
}
Expand Down
2 changes: 1 addition & 1 deletion rust/kona/tests/node/reorgs/l2_reorg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestL2Reorg(gt *testing.T) {
for _, node := range out.L2ELSequencerNodes() {
reorgedHead := node.BlockRefByLabel(eth.Unsafe)
require.Greater(t, reorgedHead.Number, unsafeHead.Number)
checksPostReorg = append(checksPostReorg, node.ReorgTriggeredFn(unsafeHead, 40))
checksPostReorg = append(checksPostReorg, node.ReorgExactFn(unsafeHead, 40))
}

// Ensure that all the nodes still advance even after the reorg
Expand Down
4 changes: 2 additions & 2 deletions rust/kona/tests/supervisor/l2reorg/init_exec_msg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,12 @@ func TestReorgInitExecMsg(gt *testing.T) {

// wait and confirm reorgs on chain A and B
dsl.CheckAll(t,
sys.L2ELA.ReorgTriggeredFn(eth.L2BlockRef{
sys.L2ELA.ReorgExactFn(eth.L2BlockRef{
Number: divergenceBlockNumber_A,
Hash: originalRef_A.Hash,
ParentHash: originalRef_A.ParentID().Hash,
}, 30),
sys.L2ELB.ReorgTriggeredFn(eth.L2BlockRef{
sys.L2ELB.ReorgExactFn(eth.L2BlockRef{
Number: divergenceBlockNumber_B,
Hash: originalRef_B.Hash,
ParentHash: originalRef_B.ParentID().Hash,
Expand Down
Loading