-
Notifications
You must be signed in to change notification settings - Fork 21.6k
core, eth, trie: write nodebuffer asynchronously to disk #28471
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
Closed
Closed
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 |
|---|---|---|
|
|
@@ -25,25 +25,70 @@ import ( | |
| "github.com/ethereum/go-ethereum/common" | ||
| "github.com/ethereum/go-ethereum/core/rawdb" | ||
| "github.com/ethereum/go-ethereum/crypto" | ||
| "github.com/ethereum/go-ethereum/ethdb" | ||
| "github.com/ethereum/go-ethereum/log" | ||
| "github.com/ethereum/go-ethereum/trie/trienode" | ||
| "github.com/ethereum/go-ethereum/trie/triestate" | ||
| "golang.org/x/crypto/sha3" | ||
| ) | ||
|
|
||
| // trienodebuffer is a collection of modified trie nodes to aggregate the disk | ||
| // write. The content of the trienodebuffer must be checked before diving into | ||
| // disk (since it basically is not-yet-written data). | ||
| type trienodebuffer interface { | ||
| // node retrieves the trie node with given node info. | ||
| node(owner common.Hash, path []byte, hash common.Hash) (*trienode.Node, error) | ||
|
|
||
| // commit merges the dirty nodes into the trienodebuffer. This operation won't take | ||
| // the ownership of the nodes map which belongs to the bottom-most diff layer. | ||
| // It will just hold the node references from the given map which are safe to | ||
| // copy. | ||
| commit(nodes map[common.Hash]map[string]*trienode.Node) trienodebuffer | ||
|
|
||
| // revert is the reverse operation of commit. It also merges the provided nodes | ||
| // into the trienodebuffer, the difference is that the provided node set should | ||
| // revert the changes made by the last state transition. | ||
| revert(db ethdb.KeyValueReader, nodes map[common.Hash]map[string]*trienode.Node) error | ||
|
|
||
| // flush persists the in-memory dirty trie node into the disk if the configured | ||
| // memory threshold is reached. Note, all data must be written atomically. | ||
| flush(db ethdb.KeyValueStore, clean *fastcache.Cache, id uint64, force bool) error | ||
|
|
||
| // setSize sets the buffer size to the provided number, and invokes a flush | ||
| // operation if the current memory usage exceeds the new limit. | ||
| setSize(size int, db ethdb.KeyValueStore, clean *fastcache.Cache, id uint64) error | ||
|
|
||
| // reset cleans up the disk cache. | ||
| reset() | ||
|
|
||
| // empty returns an indicator if trienodebuffer contains any state transition inside. | ||
| empty() bool | ||
|
|
||
| // getSize return the trienodebuffer used size, includes: | ||
| // - the mutable dirty nodes buffered within the disk layer, | ||
| // - the immutable nodes in the disk layer. | ||
| getSize() (uint64, uint64) | ||
|
|
||
| // getAllNodes return all the trie nodes are cached in trienodebuffer. | ||
| getAllNodes() map[common.Hash]map[string]*trienode.Node | ||
|
|
||
| // getLayers return the size of cached difflayers. | ||
| getLayers() uint64 | ||
| } | ||
|
|
||
| // diskLayer is a low level persistent layer built on top of a key-value store. | ||
| type diskLayer struct { | ||
| root common.Hash // Immutable, root hash to which this layer was made for | ||
| id uint64 // Immutable, corresponding state id | ||
| db *Database // Path-based trie database | ||
| cleans *fastcache.Cache // GC friendly memory cache of clean node RLPs | ||
| buffer *nodebuffer // Node buffer to aggregate writes | ||
| buffer trienodebuffer // Node buffer to aggregate writes | ||
| stale bool // Signals that the layer became stale (state progressed) | ||
| lock sync.RWMutex // Lock used to protect stale flag | ||
| } | ||
|
|
||
| // newDiskLayer creates a new disk layer based on the passing arguments. | ||
| func newDiskLayer(root common.Hash, id uint64, db *Database, cleans *fastcache.Cache, buffer *nodebuffer) *diskLayer { | ||
| func newDiskLayer(root common.Hash, id uint64, db *Database, cleans *fastcache.Cache, buffer trienodebuffer) *diskLayer { | ||
| // Initialize a clean cache if the memory allowance is not zero | ||
| // or reuse the provided cache if it is not nil (inherited from | ||
| // the original disk layer). | ||
|
|
@@ -293,15 +338,18 @@ func (dl *diskLayer) setBufferSize(size int) error { | |
| return dl.buffer.setSize(size, dl.db.diskdb, dl.cleans, dl.id) | ||
| } | ||
|
|
||
| // size returns the approximate size of cached nodes in the disk layer. | ||
| func (dl *diskLayer) size() common.StorageSize { | ||
| // size returns the approximate size of: | ||
| // - the mutable dirty nodes buffered within the disk layer, | ||
| // - the immutable nodes in the disk layer. | ||
| func (dl *diskLayer) size() (common.StorageSize, common.StorageSize) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. update method doc
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added the docs. |
||
| dl.lock.RLock() | ||
| defer dl.lock.RUnlock() | ||
|
|
||
| if dl.stale { | ||
| return 0 | ||
| return 0, 0 | ||
| } | ||
| return common.StorageSize(dl.buffer.size) | ||
| nodeBuf, nodeImmutableBuf := dl.buffer.getSize() | ||
| return common.StorageSize(nodeBuf), common.StorageSize(nodeImmutableBuf) | ||
| } | ||
|
|
||
| // resetCache releases the memory held by clean cache to prevent memory leak. | ||
|
|
||
This file contains hidden or 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 hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Please update the method docs. With four return values, might be time to split it into a bullet-list, e.g. something like
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.
added the docs.