Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow changing L1 synced height via admin RPC/CLI #1044

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from

Conversation

colinlyguo
Copy link
Member

@colinlyguo colinlyguo commented Sep 17, 2024

1. Purpose or design rationale of this PR

For two typical errors in the logs:

  • "failed to get batch chunk ranges, empty chunk block ranges": revert to a "safe" height, the updates are idempotent.
  • "Unexpected queue index in SyncService expected=805,224 got=805,329": revert to a height that contains the last synced L1 message.

2. PR title

Your PR title must follow conventional commits (as we are doing squash merge for each PR), so it must start with one of the following types:

  • feat: A new feature

3. Deployment tag versioning

Has the version in params/version.go been updated?

  • Yes

4. Breaking change label

Does this PR have the breaking-change label?

  • This PR is not a breaking change

@HAOYUatHZ
Copy link
Member

HAOYUatHZ commented Sep 18, 2024

How about we check if the new height is lower than the previously stored height?
If the new height is higher, we won't allow it to overwrite the previous value.

@colinlyguo
Copy link
Member Author

colinlyguo commented Sep 18, 2024

41ab50d

yeah. it's a reasonable defense. added in 41ab50d.

omerfirmak
omerfirmak previously approved these changes Sep 18, 2024
internal/web3ext/web3ext.go Outdated Show resolved Hide resolved
eth/api.go Outdated Show resolved Hide resolved
@colinlyguo
Copy link
Member Author

colinlyguo commented Sep 18, 2024

How about we check if the new height is lower than the previously stored height? If the new height is higher, we won't allow it to overwrite the previous value.

I found this brings up another issue, if someone updates the height to a very small height (e.g. block 1, which is << the deployment height), the height cannot be increased through this rpc.

eth/api.go Outdated

// SetRollupEventSyncedL1Height sets the synced L1 height for rollup event synchronization
func (api *ScrollAPI) SetRollupEventSyncedL1Height(height uint64) error {
rollupSyncService := api.eth.GetRollupSyncService()
Copy link
Member

@georgehao georgehao Sep 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think don't expose it to api, it's too dangerous, just cmd. Because any internal staff can connect to API and reset the height by API.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch. currently moved to "admin" namespace in e39cdb1.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RPC providers do not expose the scroll_ namespace: https://bit.ly/scroll-l2geth-rpc. But I agree it is better to have this in the admin_ namespace.

@colinlyguo
Copy link
Member Author

colinlyguo commented Sep 19, 2024

local test:
setL1MessageSyncedL1Height: success case.

> admin.setL1MessageSyncedL1Height(20785078);
null

INFO [09-19|14:12:25.368|eth/api.go:278]                                        Setting L1 message synced L1 height      height=20,785,078
INFO [09-19|14:12:25.369|rollup/sync_service/sync_service.go:155]               Reset sync service                       height=20,785,078
INFO [09-19|14:12:25.369|rollup/sync_service/sync_service.go:101]               Starting L1 message sync service         latestProcessedBlock=20,785,078
TRACE[09-19|14:12:26.332|rollup/sync_service/sync_service.go:173]               Sync service fetchMessages               latestProcessedBlock=20,785,078 latestConfirmed=20,785,074
TRACE[09-19|14:12:36.332|rollup/sync_service/sync_service.go:173]               Sync service fetchMessages               latestProcessedBlock=20,785,078 latestConfirmed=20,785,074

> scroll.syncStatus
{
  l1MessageSyncHeight: 20785106, -> a new height which > 20785078
  l1RollupSyncHeight: 18393700,
  l2BlockSyncHeight: 517679,
  l2FinalizedBlockHeight: 165610
}

setL1MessageSyncedL1Height: a wrong height.

DEBUG[09-19|14:09:35.352|rollup/sync_service/sync_service.go:241]               Received new L1 events                   fromBlock=20,670,001 toBlock=20,670,100 count=7
ERROR[09-19|14:09:35.353|rollup/sync_service/sync_service.go:252]               Unexpected queue index in SyncService    expected=937,164 got=932,518 msg="{QueueIndex:932518 Gas:168000 To:0x781e90f1c8Fc4611c9b7497C3B47F99Ef6969CbC Value:+0 Data:[142 241 51 46 0 0 0 0 0 0 0 0 0 0 0 0 83 163 156 144 242 176 244 166 135 92 196 20 104 205 235 5 64 68 146 215 0 0 0 0 0 0 0 0 0 0 0 0 83 163 156 144 242 176 244 166 135 92 196 20 104 205 235 5 64 68 146 215 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 212 158 11 26 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 58 166 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 160 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] Sender:0x7885BcBd5CeCEf1336b5300fb5186A12DDD8c478}"

setRollupEventSyncedL1Height: success case.

> admin.setRollupEventSyncedL1Height(18306000);
null

INFO [09-19|13:50:15.749|eth/api.go:278]                                        Setting L1 message synced L1 height      height=18,306,000
INFO [09-19|13:50:15.750|rollup/sync_service/sync_service.go:155]               Reset sync service                       height=18,306,000
INFO [09-19|13:50:15.750|rollup/sync_service/sync_service.go:101]               Starting L1 message sync service         latestProcessedBlock=18,306,000
TRACE[09-19|13:50:16.693|rollup/sync_service/sync_service.go:173]               Sync service fetchMessages               latestProcessedBlock=18,306,000 latestConfirmed=20,784,978

> scroll.syncStatus
{
  l1MessageSyncHeight: 20784946,
  l1RollupSyncHeight: 18309600, -> a new height which > 18306000
  l2BlockSyncHeight: 508165,
  l2FinalizedBlockHeight: 443195
}

setRollupEventSyncedL1Height: a wrong height.

ERROR[09-19|13:41:21.751|rollup/rollup_sync_service/rollup_sync_service.go:206] failed to parse and update rollup event logs err="failed to get local node info, batch index: 8518, err: failed to get batch chunk ranges, empty chunk block ranges"

@colinlyguo colinlyguo changed the title feat: allow changing L1 synced height via RPC/CLI feat: allow changing L1 synced height via admin RPC/CLI Sep 19, 2024
s.resetMu.Lock()
defer s.resetMu.Unlock()

s.Stop()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to stop and restart?

Instead, we should just project latestProcessedBlock with a lock (i.e. lock in fetchMessages and ResetToHeight.

Then we also don't need to reinitialize the context here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha, it makes sense. changed in c588232, currently, there are some read/write ops related latestProcessedBlock and db, thus added a function level write lock.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactored to use atomic.Uint64 for latestProcessedBlock in 75413e6.

s.stateMu.Lock()
defer s.stateMu.Unlock()

rawdb.WriteSyncedL1BlockNumber(s.db, height)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to do this, no? flush() in fetchMessageswill do that anyways.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably same applies to (s *RollupSyncService) ResetToHeight as well

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed in 75413e6.

@@ -50,6 +51,8 @@ type SyncService struct {
pollInterval time.Duration
latestProcessedBlock uint64
scope event.SubscriptionScope

stateMu sync.Mutex // protects the service state, e.g. db and latestProcessedBlock updates

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect simply making latestProcessedBlock an atomic.Uint64 would work just fine instead of adding a mutex here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed in 75413e6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants