-
Notifications
You must be signed in to change notification settings - Fork 697
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add selector for trusted sync to prevent from executing from an old t…
…rusted node (#3336) * add selector for trusted sync to check that batches correspond to the supported forkids
- Loading branch information
1 parent
aaad8d7
commit d837dac
Showing
8 changed files
with
217 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
synchronizer/l2_sync/l2_shared/processor_trusted_batch_selector.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package l2_shared | ||
|
||
/* | ||
This class is a implementation of SyncTrustedStateExecutor that selects the executor to use. | ||
It have a map with the forkID and the executor class to use, if none is available skip trusted sync returning a nil | ||
*/ | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/0xPolygonHermez/zkevm-node/log" | ||
"github.com/0xPolygonHermez/zkevm-node/state" | ||
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces" | ||
) | ||
|
||
type stateSyncTrustedStateExecutorSelector interface { | ||
GetForkIDInMemory(forkId uint64) *state.ForkIDInterval | ||
GetForkIDByBatchNumber(batchNumber uint64) uint64 | ||
} | ||
|
||
// SyncTrustedStateExecutorSelector Implements SyncTrustedStateExecutor | ||
type SyncTrustedStateExecutorSelector struct { | ||
state stateSyncTrustedStateExecutorSelector | ||
supportedForks map[uint64]syncinterfaces.SyncTrustedStateExecutor | ||
} | ||
|
||
// NewSyncTrustedStateExecutorSelector creates a new SyncTrustedStateExecutorSelector that implements SyncTrustedStateExecutor | ||
func NewSyncTrustedStateExecutorSelector( | ||
supportedForks map[uint64]syncinterfaces.SyncTrustedStateExecutor, | ||
state stateSyncTrustedStateExecutorSelector) *SyncTrustedStateExecutorSelector { | ||
return &SyncTrustedStateExecutorSelector{ | ||
supportedForks: supportedForks, | ||
state: state, | ||
} | ||
} | ||
|
||
// GetExecutor returns the executor that should be used for the given batch, could be nil | ||
// it returns the executor and the maximum batch number that the executor can process | ||
func (s *SyncTrustedStateExecutorSelector) GetExecutor(latestSyncedBatch uint64, maximumBatchNumberToProcess uint64) (syncinterfaces.SyncTrustedStateExecutor, uint64) { | ||
forkIDForNextBatch := s.state.GetForkIDByBatchNumber(latestSyncedBatch + 1) | ||
executor, ok := s.supportedForks[forkIDForNextBatch] | ||
if !ok { | ||
log.Warnf("No supported sync from Trusted Node for forkID %d", forkIDForNextBatch) | ||
return nil, 0 | ||
} | ||
fork := s.state.GetForkIDInMemory(forkIDForNextBatch) | ||
if fork == nil { | ||
log.Errorf("ForkID %d range not available! that is UB", forkIDForNextBatch) | ||
return nil, 0 | ||
} | ||
|
||
maxCapped := min(maximumBatchNumberToProcess, fork.ToBatchNumber) | ||
log.Debugf("using ForkID %d, lastBatch:%d (maxBatch original:%d capped:%d)", forkIDForNextBatch, | ||
latestSyncedBatch, maximumBatchNumberToProcess, maxCapped) | ||
return executor, maxCapped | ||
} | ||
|
||
// SyncTrustedState syncs the trusted state with the permissionless state. In this case | ||
// choose which executor must use | ||
func (s *SyncTrustedStateExecutorSelector) SyncTrustedState(ctx context.Context, latestSyncedBatch uint64, maximumBatchNumberToProcess uint64) error { | ||
executor, maxBatchNumber := s.GetExecutor(latestSyncedBatch, maximumBatchNumberToProcess) | ||
if executor == nil { | ||
log.Warnf("No executor available, skipping SyncTrustedState: latestSyncedBatch:%d, maximumBatchNumberToProcess:%d", | ||
latestSyncedBatch, maximumBatchNumberToProcess) | ||
return syncinterfaces.ErrCantSyncFromL2 | ||
} | ||
return executor.SyncTrustedState(ctx, latestSyncedBatch, maxBatchNumber) | ||
} | ||
|
||
// CleanTrustedState clean cache of Batches and StateRoot | ||
func (s *SyncTrustedStateExecutorSelector) CleanTrustedState() { | ||
for _, executor := range s.supportedForks { | ||
executor.CleanTrustedState() | ||
} | ||
} | ||
|
||
// GetCachedBatch implements syncinterfaces.SyncTrustedStateExecutor. Returns a cached batch | ||
func (s *SyncTrustedStateExecutorSelector) GetCachedBatch(batchNumber uint64) *state.Batch { | ||
executor, _ := s.GetExecutor(batchNumber, 0) | ||
if executor == nil { | ||
return nil | ||
} | ||
return executor.GetCachedBatch(min(batchNumber)) | ||
} |
99 changes: 99 additions & 0 deletions
99
synchronizer/l2_sync/l2_shared/tests/processor_trusted_batch_selector_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package test_l2_shared | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/0xPolygonHermez/zkevm-node/state" | ||
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces" | ||
mock_syncinterfaces "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces/mocks" | ||
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// Use case 1: | ||
// - Running incaberry mode no forkid7 yet | ||
// expected: | ||
// - | ||
|
||
func TestExecutorSelectorFirstConfiguredExecutor(t *testing.T) { | ||
mockIncaberry := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) | ||
mock1Etrog := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) | ||
mockState := mock_syncinterfaces.NewStateFullInterface(t) | ||
mockState.EXPECT().GetForkIDByBatchNumber(uint64(1 + 1)).Return(uint64(6)) | ||
forkIdInterval := state.ForkIDInterval{ | ||
FromBatchNumber: 0, | ||
ToBatchNumber: ^uint64(0), | ||
} | ||
mockState.EXPECT().GetForkIDInMemory(uint64(6)).Return(&forkIdInterval) | ||
sut := l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ | ||
uint64(6): mockIncaberry, | ||
uint64(7): mock1Etrog, | ||
}, mockState) | ||
|
||
executor, maxBatch := sut.GetExecutor(1, 200) | ||
require.Equal(t, mockIncaberry, executor) | ||
require.Equal(t, uint64(200), maxBatch) | ||
} | ||
|
||
func TestExecutorSelectorFirstExecutorCapped(t *testing.T) { | ||
mockIncaberry := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) | ||
mock1Etrog := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) | ||
mockState := mock_syncinterfaces.NewStateFullInterface(t) | ||
interval := state.ForkIDInterval{ | ||
FromBatchNumber: 1, | ||
ToBatchNumber: 99, | ||
ForkId: 6, | ||
} | ||
mockState.EXPECT().GetForkIDByBatchNumber(uint64(1 + 1)).Return(uint64(6)) | ||
mockState.EXPECT().GetForkIDInMemory(uint64(6)).Return(&interval) | ||
sut := l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ | ||
uint64(6): mockIncaberry, | ||
uint64(7): mock1Etrog, | ||
}, mockState) | ||
|
||
executor, maxBatch := sut.GetExecutor(1, 200) | ||
require.Equal(t, mockIncaberry, executor) | ||
require.Equal(t, uint64(99), maxBatch) | ||
} | ||
|
||
func TestExecutorSelectorEtrogBatchForkId7(t *testing.T) { | ||
mockIncaberry := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) | ||
mock1Etrog := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) | ||
mockState := mock_syncinterfaces.NewStateFullInterface(t) | ||
interval := state.ForkIDInterval{ | ||
FromBatchNumber: 100, | ||
ToBatchNumber: 300, | ||
ForkId: 7, | ||
} | ||
mockState.EXPECT().GetForkIDByBatchNumber(uint64(100 + 1)).Return(uint64(7)) | ||
mockState.EXPECT().GetForkIDInMemory(uint64(7)).Return(&interval) | ||
sut := l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ | ||
uint64(6): mockIncaberry, | ||
uint64(7): mock1Etrog, | ||
}, mockState) | ||
|
||
executor, maxBatch := sut.GetExecutor(100, 200) | ||
require.Equal(t, mockIncaberry, executor) | ||
require.Equal(t, uint64(200), maxBatch) | ||
} | ||
|
||
func TestUnsupportedForkId(t *testing.T) { | ||
mockIncaberry := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) | ||
mock1Etrog := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) | ||
mockState := mock_syncinterfaces.NewStateFullInterface(t) | ||
|
||
mockState.EXPECT().GetForkIDByBatchNumber(uint64(100 + 1)).Return(uint64(8)) | ||
|
||
sut := l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ | ||
uint64(6): mockIncaberry, | ||
uint64(7): mock1Etrog, | ||
}, mockState) | ||
|
||
executor, _ := sut.GetExecutor(100, 200) | ||
require.Equal(t, nil, executor) | ||
|
||
err := sut.SyncTrustedState(context.Background(), 100, 200) | ||
require.ErrorIs(t, err, syncinterfaces.ErrCantSyncFromL2) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters