Skip to content

Commit

Permalink
feat(driver): optimize reorg handling && add more tests (taikoxyz#256)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidtaikocha authored Jun 3, 2023
1 parent fb7fa88 commit 20d4ae7
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 28 deletions.
2 changes: 1 addition & 1 deletion bindings/.githead
Original file line number Diff line number Diff line change
@@ -1 +1 @@
d2823ece45f3bda8cda8aec0657748196ac2a31a
6a8029519c6170a9240972f82d11271bafd0e2d3
37 changes: 23 additions & 14 deletions driver/chain_syncer/calldata/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Syncer struct {
txListValidator *txListValidator.TxListValidator // Transactions list validator
// Used by BlockInserter
lastInsertedBlockID *big.Int
reorgDetectedFlag bool
}

// NewSyncer creates a new syncer instance.
Expand Down Expand Up @@ -74,20 +75,26 @@ func NewSyncer(
// ProcessL1Blocks fetches all `TaikoL1.BlockProposed` events between given
// L1 block heights, and then tries inserting them into L2 execution engine's block chain.
func (s *Syncer) ProcessL1Blocks(ctx context.Context, l1End *types.Header) error {
iter, err := eventIterator.NewBlockProposedIterator(ctx, &eventIterator.BlockProposedIteratorConfig{
Client: s.rpc.L1,
TaikoL1: s.rpc.TaikoL1,
StartHeight: s.state.GetL1Current().Number,
EndHeight: l1End.Number,
FilterQuery: nil,
OnBlockProposedEvent: s.onBlockProposed,
})
if err != nil {
return err
}
firstTry := true
for firstTry || s.reorgDetectedFlag {
s.reorgDetectedFlag = false
firstTry = false

iter, err := eventIterator.NewBlockProposedIterator(ctx, &eventIterator.BlockProposedIteratorConfig{
Client: s.rpc.L1,
TaikoL1: s.rpc.TaikoL1,
StartHeight: s.state.GetL1Current().Number,
EndHeight: l1End.Number,
FilterQuery: nil,
OnBlockProposedEvent: s.onBlockProposed,
})
if err != nil {
return err
}

if err := iter.Iter(); err != nil {
return err
if err := iter.Iter(); err != nil {
return err
}
}

s.state.SetL1Current(l1End)
Expand Down Expand Up @@ -129,8 +136,10 @@ func (s *Syncer) onBlockProposed(
)
s.state.SetL1Current(l1CurrentToReset)
s.lastInsertedBlockID = lastInsertedBlockIDToReset
s.reorgDetectedFlag = true
endIter()

return fmt.Errorf("reorg detected, reset l1Current cursor to %d", l1CurrentToReset.Number)
return nil
}
}

Expand Down
53 changes: 53 additions & 0 deletions driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,59 @@ func (s *DriverTestSuite) TestProcessL1Blocks() {
}
}

func (s *DriverTestSuite) TestCheckL1Reorg() {
var testnetL1SnapshotID string
s.Nil(s.RpcClient.L1RawRPC.CallContext(context.Background(), &testnetL1SnapshotID, "evm_snapshot"))
s.NotEmpty(testnetL1SnapshotID)

l1Head1, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)
l2Head1, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil)
s.Nil(err)

// Propose two L2 blocks
testutils.ProposeAndInsertValidBlock(&s.ClientTestSuite, s.p, s.d.ChainSyncer().CalldataSyncer())
testutils.ProposeAndInsertValidBlock(&s.ClientTestSuite, s.p, s.d.ChainSyncer().CalldataSyncer())

l1Head2, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)
l2Head2, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil)
s.Nil(err)
s.Greater(l2Head2.Number.Uint64(), l2Head1.Number.Uint64())
s.Greater(l1Head2.Number.Uint64(), l1Head1.Number.Uint64())

reorged, _, _, err := s.RpcClient.CheckL1Reorg(context.Background(), l2Head2.Number)
s.Nil(err)
s.False(reorged)

// Reorg back to l2Head1
var revertRes bool
s.Nil(s.RpcClient.L1RawRPC.CallContext(context.Background(), &revertRes, "evm_revert", testnetL1SnapshotID))
s.True(revertRes)

l1Head3, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)
s.Equal(l1Head3.Number.Uint64(), l1Head1.Number.Uint64())
s.Equal(l1Head3.Hash(), l1Head1.Hash())

// Propose two blocks in another fork
testutils.ProposeInvalidTxListBytes(&s.ClientTestSuite, s.p)
testutils.ProposeInvalidTxListBytes(&s.ClientTestSuite, s.p)

l1Head4, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)

s.Nil(s.d.ChainSyncer().CalldataSyncer().ProcessL1Blocks(context.Background(), l1Head4))

l2Head3, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil)
s.Nil(err)

parent, err := s.d.rpc.L2.HeaderByHash(context.Background(), l2Head3.ParentHash)
s.Nil(err)
s.Equal(l2Head3.Number.Uint64(), l2Head2.Number.Uint64())
s.Equal(parent.ParentHash, l2Head1.Hash())
}

func (s *DriverTestSuite) TestDoSyncNoNewL2Blocks() {
s.Nil(s.d.doSync())
}
Expand Down
1 change: 1 addition & 0 deletions pkg/rpc/methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ func (c *Client) CheckL1Reorg(ctx context.Context, blockID *big.Int) (bool, *typ
return false, nil, nil, err
}

blockIDToReset = blockID
break
}

Expand Down
32 changes: 22 additions & 10 deletions prover/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Prover struct {
latestVerifiedL1Height uint64
lastHandledBlockID uint64
l1Current uint64
reorgDetectedFlag bool

// Proof submitters
validProofSubmitter proofSubmitter.ProofSubmitter
Expand Down Expand Up @@ -280,17 +281,27 @@ func (p *Prover) Close() {
// proveOp performs a proving operation, find current unproven blocks, then
// request generating proofs for them.
func (p *Prover) proveOp() error {
iter, err := eventIterator.NewBlockProposedIterator(p.ctx, &eventIterator.BlockProposedIteratorConfig{
Client: p.rpc.L1,
TaikoL1: p.rpc.TaikoL1,
StartHeight: new(big.Int).SetUint64(p.l1Current),
OnBlockProposedEvent: p.onBlockProposed,
})
if err != nil {
return err
firstTry := false
for firstTry || p.reorgDetectedFlag {
p.reorgDetectedFlag = false
firstTry = false

iter, err := eventIterator.NewBlockProposedIterator(p.ctx, &eventIterator.BlockProposedIteratorConfig{
Client: p.rpc.L1,
TaikoL1: p.rpc.TaikoL1,
StartHeight: new(big.Int).SetUint64(p.l1Current),
OnBlockProposedEvent: p.onBlockProposed,
})
if err != nil {
return err
}

if err := iter.Iter(); err != nil {
return err
}
}

return iter.Iter()
return nil
}

// onBlockProposed tries to prove that the newly proposed block is valid/invalid.
Expand Down Expand Up @@ -324,8 +335,9 @@ func (p *Prover) onBlockProposed(
)
p.l1Current = l1CurrentToReset.Number.Uint64()
p.lastHandledBlockID = lastHandledBlockIDToReset.Uint64()
p.reorgDetectedFlag = true

return fmt.Errorf("reorg detected, reset l1Current cursor to %d", l1CurrentToReset.Number)
return nil
}

if event.Id.Uint64() <= p.lastHandledBlockID {
Expand Down
4 changes: 1 addition & 3 deletions testutils/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,9 @@ func ProposeAndInsertValidBlock(

s.Nil(calldataSyncer.ProcessL1Blocks(ctx, newL1Head))

newL2Head, err := s.RpcClient.L2.HeaderByNumber(context.Background(), nil)
_, err = s.RpcClient.L2.HeaderByNumber(context.Background(), nil)
s.Nil(err)

s.Greater(newL2Head.Number.Uint64(), l2Head.Number.Uint64())

return event
}

Expand Down

0 comments on commit 20d4ae7

Please sign in to comment.