Skip to content

Commit

Permalink
#3514 Fix l1 info root after reorg (#3515) (#3524)
Browse files Browse the repository at this point in the history
* Fix ResetL1InfoRoot + typos

* mocks

* linter

* refactor

* more robust

* Fix comments

* Add extra check reorg after calling get information

* Fix non e2e test
  • Loading branch information
ARR552 authored Apr 4, 2024
1 parent e1eefe5 commit 74827e8
Show file tree
Hide file tree
Showing 18 changed files with 172 additions and 71 deletions.
2 changes: 1 addition & 1 deletion aggregator/aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ func (a *Aggregator) buildInputProver(ctx context.Context, batchToVerify *state.
if err != nil {
return nil, err
}
leaves, err := a.State.GetLeafsByL1InfoRoot(ctx, *l1InfoRoot, nil)
leaves, err := a.State.GetLeavesByL1InfoRoot(ctx, *l1InfoRoot, nil)
if err != nil {
return nil, err
}
Expand Down
10 changes: 5 additions & 5 deletions aggregator/aggregator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ func TestTryGenerateBatchProof(t *testing.T) {
}
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
require.NoError(err)
m.proverMock.On("BatchProof", expectedInputProver).Return(nil, errBanana).Once()
Expand Down Expand Up @@ -844,7 +844,7 @@ func TestTryGenerateBatchProof(t *testing.T) {
}
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
require.NoError(err)
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
Expand Down Expand Up @@ -888,7 +888,7 @@ func TestTryGenerateBatchProof(t *testing.T) {
}
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
require.NoError(err)
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
Expand Down Expand Up @@ -932,7 +932,7 @@ func TestTryGenerateBatchProof(t *testing.T) {
}
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
require.NoError(err)
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
Expand Down Expand Up @@ -989,7 +989,7 @@ func TestTryGenerateBatchProof(t *testing.T) {
TimestampBatchEtrog: &t,
}
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
require.NoError(err)
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
Expand Down
2 changes: 1 addition & 1 deletion aggregator/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type stateInterface interface {
CleanupBatchProofs(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
CleanupLockedBatchProofs(ctx context.Context, duration string, dbTx pgx.Tx) (int64, error)
GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error)
GetLeafsByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error)
GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error)
GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
GetForcedBatchParentHash(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
GetVirtualBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VirtualBatch, error)
Expand Down
6 changes: 3 additions & 3 deletions aggregator/mocks/mock_state.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion l1infotree/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,33 @@ func NewL1InfoTree(height uint8, initialLeaves [][32]byte) (*L1InfoTree, error)
var err error
mt.siblings, mt.currentRoot, err = mt.initSiblings(initialLeaves)
if err != nil {
log.Error("error initializing si siblings. Error: ", err)
log.Error("error initializing siblings. Error: ", err)
return nil, err
}
log.Debug("Initial count: ", mt.count)
log.Debug("Initial root: ", mt.currentRoot)
return mt, nil
}

// ResetL1InfoTree resets the L1InfoTree.
func (mt *L1InfoTree) ResetL1InfoTree(initialLeaves [][32]byte) (*L1InfoTree, error) {
log.Info("Resetting L1InfoTree...")
newMT := &L1InfoTree{
zeroHashes: generateZeroHashes(32), // nolint:gomnd
height: 32, // nolint:gomnd
count: uint32(len(initialLeaves)),
}
var err error
newMT.siblings, newMT.currentRoot, err = newMT.initSiblings(initialLeaves)
if err != nil {
log.Error("error initializing siblings. Error: ", err)
return nil, err
}
log.Debug("Reset initial count: ", newMT.count)
log.Debug("Reset initial root: ", newMT.currentRoot)
return newMT, nil
}

func buildIntermediate(leaves [][32]byte) ([][][]byte, [][32]byte) {
var (
nodes [][][]byte
Expand Down
2 changes: 1 addition & 1 deletion state/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ type storage interface {
GetRawBatchTimestamps(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*time.Time, *time.Time, error)
GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
GetLeafsByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]L1InfoTreeExitRootStorageEntry, error)
GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]L1InfoTreeExitRootStorageEntry, error)
GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*Block, error)
GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
GetForcedBatchParentHash(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
Expand Down
15 changes: 7 additions & 8 deletions state/l1infotree.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package state
import (
"context"
"errors"
"fmt"

"github.com/0xPolygonHermez/zkevm-node/l1infotree"
"github.com/0xPolygonHermez/zkevm-node/log"
Expand Down Expand Up @@ -34,20 +33,20 @@ func (s *State) buildL1InfoTreeCacheIfNeed(ctx context.Context, dbTx pgx.Tx) err
if s.l1InfoTree != nil {
return nil
}
log.Debugf("Building L1InfoTree cache")
allLeaves, err := s.storage.GetAllL1InfoRootEntries(ctx, dbTx)
// Reset L1InfoTree siblings and leaves
allLeaves, err := s.GetAllL1InfoRootEntries(ctx, dbTx)
if err != nil {
log.Error("error getting all leaves. Error: ", err)
return fmt.Errorf("error getting all leaves. Error: %w", err)
log.Error("error getting all leaves to reset l1InfoTree. Error: ", err)
return err
}
var leaves [][32]byte
for _, leaf := range allLeaves {
leaves = append(leaves, leaf.Hash())
}
mt, err := l1infotree.NewL1InfoTree(uint8(32), leaves) //nolint:gomnd
mt, err := s.l1InfoTree.ResetL1InfoTree(leaves)
if err != nil {
log.Error("error creating L1InfoTree. Error: ", err)
return fmt.Errorf("error creating L1InfoTree. Error: %w", err)
log.Error("error resetting l1InfoTree. Error: ", err)
return err
}
s.l1InfoTree = mt
return nil
Expand Down
22 changes: 11 additions & 11 deletions state/mocks/mock_storage.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion state/pgstatestorage/l1infotree.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (p *PostgresStorage) GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTr
return entry, nil
}

func (p *PostgresStorage) GetLeafsByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) {
func (p *PostgresStorage) GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) {
// TODO: Optimize this query
const getLeafsByL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index
FROM state.exit_root
Expand Down
17 changes: 10 additions & 7 deletions state/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package state
import (
"context"

"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/jackc/pgx/v4"
)

Expand All @@ -13,12 +14,14 @@ func (s *State) Reset(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) erro
// - VerifiedBatches
// - Entries in exit_root table
err := s.ResetToL1BlockNumber(ctx, blockNumber, dbTx)
if err == nil {
// Discard L1InfoTree cache
// We can't rebuild cache, because we are inside a transaction, so we dont known
// is going to be a commit or a rollback. So is going to be rebuild on the next
// request that needs it.
s.l1InfoTree = nil
if err != nil {
log.Error("error resetting L1BlockNumber. Error: ", err)
return err
}
return err
// Discard L1InfoTree cache
// We can't rebuild cache, because we are inside a transaction, so we dont known
// is going to be a commit or a rollback. So is going to be rebuild on the next
// request that needs it.
s.l1InfoTree = nil
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ func (p *ProcessorL1SequenceBatchesEtrog) checkTrustedState(ctx context.Context,
reason := reorgReasons.String()

if p.sync.IsTrustedSequencer() {
log.Errorf("TRUSTED REORG DETECTED! Batch: %d reson:%s", batch.BatchNumber, reason)
log.Errorf("TRUSTED REORG DETECTED! Batch: %d reason:%s", batch.BatchNumber, reason)
// Halt function never have to return! it must blocks the process
p.halt(ctx, fmt.Errorf("TRUSTED REORG DETECTED! Batch: %d", batch.BatchNumber))
log.Errorf("CRITICAL!!!: Never have to execute this code. Halt function never have to return! it must blocks the process")
Expand Down
47 changes: 47 additions & 0 deletions synchronizer/common/syncinterfaces/mocks/state_full_interface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,13 @@ func (b *SyncTrustedBatchExecutorForEtrog) FullProcess(ctx context.Context, data
return nil, err
}

leafs, l1InfoRoot, _, err := b.state.GetL1InfoTreeDataFromBatchL2Data(ctx, data.TrustedBatch.BatchL2Data, dbTx)
leaves, l1InfoRoot, _, err := b.state.GetL1InfoTreeDataFromBatchL2Data(ctx, data.TrustedBatch.BatchL2Data, dbTx)
if err != nil {
log.Errorf("%s error getting GetL1InfoTreeDataFromBatchL2Data: %v. Error:%w", data.DebugPrefix, l1InfoRoot, err)
return nil, err
}
debugStr := data.DebugPrefix
processBatchResp, err := b.processAndStoreTxs(ctx, b.getProcessRequest(data, leafs, l1InfoRoot), dbTx, debugStr)
processBatchResp, err := b.processAndStoreTxs(ctx, b.getProcessRequest(data, leaves, l1InfoRoot), dbTx, debugStr)
if err != nil {
log.Error("%s error procesingAndStoringTxs. Error: ", debugStr, err)
return nil, err
Expand Down Expand Up @@ -197,15 +197,15 @@ func (b *SyncTrustedBatchExecutorForEtrog) IncrementalProcess(ctx context.Contex
return nil, err
}

leafs, l1InfoRoot, _, err := b.state.GetL1InfoTreeDataFromBatchL2Data(ctx, PartialBatchL2Data, dbTx)
leaves, l1InfoRoot, _, err := b.state.GetL1InfoTreeDataFromBatchL2Data(ctx, PartialBatchL2Data, dbTx)
if err != nil {
log.Errorf("%s error getting GetL1InfoTreeDataFromBatchL2Data: %v. Error:%w", data.DebugPrefix, l1InfoRoot, err)
// TODO: Need to refine, depending of the response of GetL1InfoTreeDataFromBatchL2Data
// if some leaf is missing, we need to resync from L1 to get the missing events and then process again
return nil, syncinterfaces.ErrMissingSyncFromL1
}
debugStr := fmt.Sprintf("%s: Batch %d:", data.Mode, uint64(data.TrustedBatch.Number))
processReq := b.getProcessRequest(data, leafs, l1InfoRoot)
processReq := b.getProcessRequest(data, leaves, l1InfoRoot)
processReq.Transactions = PartialBatchL2Data
processBatchResp, err := b.processAndStoreTxs(ctx, processReq, dbTx, debugStr)
if err != nil {
Expand Down
Loading

0 comments on commit 74827e8

Please sign in to comment.