-
Notifications
You must be signed in to change notification settings - Fork 204
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
remove mutex from trie operations #6526
remove mutex from trie operations #6526
Conversation
…refactor-trie-mutex-usage # Conflicts: # trie/branchNode.go # trie/branchNode_test.go # trie/extensionNode.go # trie/extensionNode_test.go # trie/interface.go # trie/leafNode.go # trie/leafNode_test.go # trie/patriciaMerkleTrie.go
…refactor-trie-mutex-usage # Conflicts: # trie/branchNode_test.go # trie/extensionNode_test.go # trie/leafNode_test.go # trie/patriciaMerkleTrie.go
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feat/trie-mutex-refactor #6526 +/- ##
==========================================================
Coverage 79.93% 79.94%
==========================================================
Files 733 737 +4
Lines 96458 96604 +146
==========================================================
+ Hits 77106 77227 +121
- Misses 13944 13981 +37
+ Partials 5408 5396 -12 ☔ View full report in Codecov by Sentry. |
@@ -110,3 +107,12 @@ type IdleNodeProvider interface { | |||
IsIdle() bool | |||
IsInterfaceNil() bool | |||
} | |||
|
|||
type RootManager interface { |
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 missing.
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.
trie/extensionNode.go
Outdated
defer en.childMutex.Unlock() | ||
|
||
isChildCollapsed := en.child == nil && len(en.EncodedChild) != 0 | ||
if !isChildCollapsed { |
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.
why not use en.isCollaped? exactly the same functions is wrote on top of this function.
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.
Changed.
trie/patriciaMerkleTrie.go
Outdated
@@ -249,12 +255,14 @@ func (tr *patriciaMerkleTrie) deleteBatch(data []core.TrieData) error { | |||
return nil | |||
} | |||
|
|||
if tr.root == nil { | |||
rootNode := tr.GetRootNode() | |||
if rootNode == nil { |
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.
check.IfNil ?
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.
Done.
trie/patriciaMerkleTrie.go
Outdated
|
||
if tr.root == nil { | ||
rootNode := tr.GetRootNode() | ||
if rootNode == nil { |
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.
check.ifnil?
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.
Done.
mutOperation sync.RWMutex | ||
} | ||
|
||
func NewRootManager() *rootManager { |
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.
a lot of comments are missing here. on all the file.
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
state/accountsDB.go
Outdated
return nil | ||
} | ||
|
||
err := adb.removeCode(baseAcc) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = adb.removeDataTrie(baseAcc) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (adb *AccountsDB) removeDataTrie(baseAcc baseAccountHandler) error { | ||
rootHash := baseAcc.GetRootHash() | ||
if len(rootHash) == 0 { | ||
return nil | ||
} | ||
|
||
dataTrie, err := adb.mainTrie.Recreate(rootHash) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
hashes, err := dataTrie.GetAllHashes() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
adb.obsoleteDataTrieHashes[string(rootHash)] = hashes | ||
|
||
entry, err := NewJournalEntryDataTrieRemove(rootHash, adb.obsoleteDataTrieHashes) | ||
if err != nil { | ||
return err | ||
} | ||
adb.journalize(entry) | ||
|
||
return nil | ||
return adb.removeCode(baseAcc) |
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.
rename removeCodeAndDataTrie
func? or remove it and use removeCode
directly?
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.
We need to keep track of this. When RemoveAccount()
will be used, we need to implement an efficient way of marking the removed hashes for pruning. Added a TODO
trie/patriciaMerkleTrie.go
Outdated
@@ -201,22 +205,25 @@ func (tr *patriciaMerkleTrie) insertBatch(sortedDataForInsertion []core.TrieData | |||
return nil | |||
} | |||
|
|||
if tr.root == nil { | |||
rootNode := tr.GetRootNode() | |||
if rootNode == nil { |
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.
check.IfNil ?
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.
Done.
hash []byte | ||
dirty bool |
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.
shouldn't we protect these fields by mutex in setters and getters?
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.
Indded. Added TODO and will add mutex protection in a future PR (to minimize conflicts with already opened PRs)
bn.mutex.Lock() | ||
defer bn.mutex.Unlock() |
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.
if setters in baseNode are protected by mutex, i think this protection here is not needed
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.
It is needed in order to keep all changes atomic. If I remove this there might be edgecases where different baseNode fields change from different goroutines.
setDirty(bool) | ||
isDirty() bool | ||
getMarshalizer() marshal.Marshalizer | ||
setMarshalizer(marshal.Marshalizer) | ||
getHasher() hashing.Hasher | ||
setHasher(hashing.Hasher) |
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.
maybe we can have a baseNode interface
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.
Done.
bn.hash = nil | ||
bn.dirty = true |
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.
if mutex protection is added in baseNode, cand we use setters here and avoid mutex in this file entirely?
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.
Not really, all these operations need to happen atomically.
ln.mutex.RLock() | ||
defer ln.mutex.RUnlock() |
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.
do we need mutex here?
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 mutex is protecting hash
and dirty
fields, right?
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.
It protects everything that can change on the node, so ln.Key
& ln.Value
also
trie/modifiedChildren.go
Outdated
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.
add unit tests for this file (or TODO for future PRs)
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.
Removed the file as it is no longer used.
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.
add unit tests for this file (or TODO for future PRs)
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 TODO
func (bn *baseNode) isDirty() bool { | ||
return bn.dirty |
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.
i think rootManager is accessing this so it needs protection here
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.
Indeed, will refactor mutex usage in a future PR
Reasoning behind the pull request
Proposed changes
GetAllHashes
func from the trie. This was not used, and it could lead to oom if used for a large trie.get
,update
anddelete
from the trie so that they can be called in parallelTesting procedure
Pre-requisites
Based on the Contributing Guidelines the PR author and the reviewers must check the following requirements are met:
feat
branch created?feat
branch merging, do all satellite projects have a proper tag insidego.mod
?