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

En 8240 optimize get all leaves process #2490

Merged
merged 10 commits into from Nov 25, 2020

Conversation

BeniaminDrasovean
Copy link
Contributor

Replaced GetAllLeaves() with GetAllLeavesOnChannel() throughout the whole project. The new implementation creates a new trie instance and runs getAllLeavesOnChannel(), meaning that once a node has been fully visited, it's children can be = nil. This way, no matter how big the state is, it will not fill the memory. By running getAllLeaves() on a new trie instance, it also means that the operation is not blocking, it just buffers the pruning operations. The pruning operations will be executed once there is no pruning blocking operation in progress (snapshot, getAllLeaves).

@BeniaminDrasovean BeniaminDrasovean self-assigned this Nov 20, 2020
@sasurobert sasurobert self-requested a review November 20, 2020 11:07
account := state.NewEmptyUserAccount()
err = u.marshalizer.Unmarshal(account, leaf)
err := u.marshalizer.Unmarshal(account, leaf.Value())
Copy link
Contributor

Choose a reason for hiding this comment

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

err =

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

tr.mutOperation.RUnlock()

go func() {
tr.mutOperation.RLock()
err := tr.root.getAllLeavesOnChannel(leavesChannel, []byte{}, tr.Database(), tr.marshalizer)
err = newTrie.root.getAllLeavesOnChannel(leavesChannel, []byte{}, tr.Database(), tr.marshalizer)
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't you return this error as well ? like errFound and mutex ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will live like this at the moment, like discussed.

Copy link
Contributor

@sasurobert sasurobert left a comment

Choose a reason for hiding this comment

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

small changes

Copy link
Contributor

@iulianpascalau iulianpascalau left a comment

Choose a reason for hiding this comment

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

Good implementation! 👍

@@ -767,22 +768,22 @@ func (adb *AccountsDB) recreateTrie(rootHash []byte) error {

// RecreateAllTries recreates all the tries from the accounts DB
func (adb *AccountsDB) RecreateAllTries(rootHash []byte) (map[string]data.Trie, error) {
recreatedTrie, err := adb.mainTrie.Recreate(rootHash)
leavesChannel, err := adb.mainTrie.GetAllLeavesOnChannel(rootHash)
Copy link
Contributor

Choose a reason for hiding this comment

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

why did we switched the operations here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If GetAllLeavesOnChannel() returns an error, there will be no need for the recreatedTrie.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok

data/trie/branchNode.go Outdated Show resolved Hide resolved
data/trie/patriciaMerkleTrie.go Outdated Show resolved Hide resolved
if tr.root == nil {

newTrie, err := tr.recreate(rootHash)
if err != nil || check.IfNil(newTrie) || tr.root == nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need the last condition? It is creating a new trie anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, but it can create a new empty trie, which has a nil root node.

Copy link
Contributor

Choose a reason for hiding this comment

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

then, should have been: newTrie.root == nil ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed

data/trie/patriciaMerkleTrie.go Outdated Show resolved Hide resolved
data/trie/trieStorageManager.go Show resolved Hide resolved

for _, pa := range sliceLeaves {
peerAccount, err := vs.unmarshalPeer(pa)
for pa := range leavesChannel {
Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting. This channel should cause deterministic outputs on each elrond-go node since the trie nodes traversal is deterministic. The sort you remove should no longer be necessary. However, we might get into backwards incompatibility issues. We have to check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will check for backwards compatibility issues.

identifier string,
) error {
for leaf := range leavesChannel {
keyToExport := CreateAccountKey(accType, shId, leaf.Key())

Copy link
Contributor

Choose a reason for hiding this comment

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

delete empty line

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

identifier string,
) error {
for leaf := range leavesChannel {
keyToExport := CreateAccountKey(accType, shId, leaf.Key())

Copy link
Contributor

Choose a reason for hiding this comment

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

delete empty line

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

sasurobert
sasurobert previously approved these changes Nov 24, 2020
iulianpascalau
iulianpascalau previously approved these changes Nov 24, 2020
Copy link
Contributor

@LucianMincu LucianMincu left a comment

Choose a reason for hiding this comment

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

Initial system tests passed.

@LucianMincu LucianMincu merged commit e89c578 into development Nov 25, 2020
@LucianMincu LucianMincu deleted the EN-8240-optimize-getAllLeaves-process branch November 25, 2020 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants