-
Notifications
You must be signed in to change notification settings - Fork 222
added commitInMemory method for synching optimization #7674
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
base: feat/supernova-async-exec
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Adds an “in-memory commit” path to speed up node syncing by avoiding disk persistence on most blocks, while still computing root hashes and periodically performing full commits.
Changes:
- Extend
state.AccountsAdapterwithCommitInMemory()and implement it across adapters/stubs. - Add
AccountsDB.CommitInMemory()and integrate a sync-time commit interval optimization inbaseProcessor. - Add unit tests for
CommitInMemory()and for the sync commit interval decision logic.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| testscommon/state/accountsAdapterStub.go | Extends accounts adapter stub with CommitInMemory() for tests. |
| state/interface.go | Adds CommitInMemory() to AccountsAdapter interface. |
| state/accountsDB.go | Implements CommitInMemory() and internal commitInMemory() flow. |
| state/accountsDB_test.go | Adds tests for AccountsDB.CommitInMemory(). |
| state/accountsDBApi.go | Implements CommitInMemory() as not permitted for API adapter. |
| state/accountsDBApiWithHistory.go | Implements CommitInMemory() as not permitted for API-with-history adapter. |
| process/transactionEvaluator/simulationAccountsDB.go | Adds no-op CommitInMemory() for simulation DB. |
| epochStart/bootstrap/disabled/disabledAccountsAdapter.go | Adds no-op CommitInMemory() for disabled adapter. |
| process/block/baseProcess.go | Adds sync commit interval optimization + in-memory commit path during sync. |
| process/block/export_test.go | Exposes constants/helpers for testing the new optimization logic. |
| process/block/baseProcess_test.go | Adds tests for sync commit optimization and in-memory commit invocation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return nil, err | ||
| } | ||
| } | ||
| adb.dataTries.Reset() |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commitInMemory() calls adb.dataTries.Reset(), which clears the holder map (see state/dataTriesHolder.go:70-82). This drops references to dirty data tries without committing them, so a subsequent full Commit() may no longer flush those data tries to disk, risking missing persistence / corrupted state. Consider not resetting dataTries in CommitInMemory (or tracking/retaining dirty tries until the next full commit).
| adb.dataTries.Reset() |
| if headerHandler.IsStartOfEpochBlock() { | ||
| bp.resetSyncCommitCounter() | ||
| return bp.commitInLastEpoch(headerHandler.GetEpoch()) | ||
| } |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the start-of-epoch path, the deferred log will still print in memory=true because inMemory is initialized to true and never set to false before returning commitInLastEpoch(). This makes the log line misleading (epoch commits are persisted). Set inMemory=false before the early return, or initialize it to false and only set true on the in-memory path.
| accnt, _ := adb.LoadAccount(make([]byte, 32)) | ||
| _ = adb.SaveAccount(accnt) |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test ignores the errors from LoadAccount and SaveAccount, which can mask a broken setup (e.g., TrieStub.UpdateCalled is unset so SaveAccount will error). Prefer asserting require.NoError and stubbing the trie to allow SaveAccount to succeed, so the test validates behavior under realistic conditions.
| // Call 5 times - first 4 should return true (in-memory), 5th should return false (full commit) | ||
| for i := 0; i < 4; i++ { | ||
| result := sp.ShouldUseSyncCommitOptimization(header) | ||
| assert.True(t, result, "should return true for block %d", i+1) |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert.True(t, result, "should return true for block %d", i+1) will not format the message (testify doesn't treat this as printf-style). Use assert.Truef/require.Truef, or pre-format the string, to keep failure output correct.
| assert.True(t, result, "should return true for block %d", i+1) | |
| assert.Truef(t, result, "should return true for block %d", i+1) |
| // CommitInMemory is a not permitted operation in this implementation and thus, will return an error | ||
| func (accountsDB *accountsDBApi) CommitInMemory() ([]byte, error) { |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment grammar: "CommitInMemory is a not permitted operation" should be "CommitInMemory is not a permitted operation" (or "CommitInMemory is not permitted").
| // Disabled if syncCommitInterval is 0 | ||
| if bp.syncCommitInterval == 0 { | ||
| return false | ||
| } |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldUseSyncCommitOptimization() reads bp.syncCommitInterval without holding mutSyncCommit, but SetSyncCommitInterval() writes it under the mutex. This is an actual data race if the interval is ever updated at runtime (and also leaves blocksSinceLastCommit stale when interval is set to 0). Read syncCommitInterval under the same lock (or use atomics), and consider resetting the counter when disabling/changing the interval.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or if the SetSyncCommitInterval is meant to be used only in tests, move it to the export_test file.
| accnt, _ := adb.LoadAccount(make([]byte, 32)) | ||
| _ = adb.SaveAccount(accnt) |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test ignores the errors from LoadAccount and SaveAccount, which can mask a broken setup (e.g., TrieStub.UpdateCalled is unset so SaveAccount will error). Prefer asserting require.NoError and stubbing the trie to allow SaveAccount to succeed, so the test validates behavior under realistic conditions.
| accnt, _ := adb.LoadAccount(make([]byte, 32)) | ||
| _ = adb.SaveAccount(accnt) |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test ignores the errors from LoadAccount and SaveAccount, which can mask a broken setup (e.g., TrieStub.UpdateCalled is unset so SaveAccount will error). Prefer asserting require.NoError and stubbing the trie to allow SaveAccount to succeed, so the test validates behavior under realistic conditions.
| // CommitInMemory is a not permitted operation in this implementation and thus, will return an error | ||
| func (accountsDB *accountsDBApiWithHistory) CommitInMemory() ([]byte, error) { |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment grammar: "CommitInMemory is a not permitted operation" should be "CommitInMemory is not a permitted operation" (or "CommitInMemory is not permitted").
| // Disabled if syncCommitInterval is 0 | ||
| if bp.syncCommitInterval == 0 { | ||
| return false | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or if the SetSyncCommitInterval is meant to be used only in tests, move it to the export_test file.
| return adb.commitInMemory() | ||
| } | ||
|
|
||
| func (adb *AccountsDB) commitInMemory() ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There a couple issues with this approach:
- The dataTries holder reset drops the reference to all of the changed data tries. When an account is loaded, it will have the new root hash, so it will try to load the data trie with that root hash from the db, but since the dataTrie was not commited, the recreate from db will fail. To fix this, you can remove the reset, but
- If a revert occurs, a recreateFromDb will happen - and will fail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another solution would be to commit the data tries, but into a cache.
Reasoning behind the pull request
Proposed changes
Testing procedure
Pre-requisites
Based on the Contributing Guidelines the PR author and the reviewers must check the following requirements are met:
featbranch created?featbranch merging, do all satellite projects have a proper tag insidego.mod?