-
Notifications
You must be signed in to change notification settings - Fork 20.4k
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
core/state, eth, trie: stabilize memory use, fix memory leak #21491
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.
LGTM!
prio := int64(len(req.path)) << 56 // depth >= 128 will never happen, storage leaves will be included in their parents | ||
for i := 0; i < 14 && i < len(req.path); i++ { | ||
prio |= int64(15-req.path[i]) << (52 - i*4) // 15-nibble => lexicographic order | ||
} | ||
s.queue.Push(req.hash, prio) |
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 wrote a little playground gist to check how this worked: https://play.golang.org/p/QKezpVe3ZX7 . Might be worth taking the gist and making a test out of it, to verify that paths are indeed prioritized correctly?
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'm going to postpone adding this into a followup PR. I want to expose the path and code/trie node separation into the Missing
and that will make this test a lot simpler. Otherwise we'd need to mess around with hard coding hashes into the tester, which we could definitely do, but it will be kind of like a black magic test with random values nobody knows where they originate from.
We've seen for a while that the bootnodes go OOM while fast syncing. Lately this became more and more pronounced, so it was clear that we have some memory issues in state sync. This PR addresses 3 independent issues:
defer sync.Close()
on the new object. This resulted in all these partially completed and discarded sync objects to be kept referenced in memory until sync fully completed or failed. This was leaking out memory and leading to crashes,defer
from within the loop and doing just 1 lazy defer at the top where the originalsync
object is created. If the object is recreated, the loop will close the old one before replacing it, so there's no leak there.A quirk in the PR is that I needed to modify the
LeafCallback
to pass thepath
too, but that was shared by both the syncer as well as the committer. I hacked anil
into the committer, but maybe it would be nice to split the callback to have a different version for SyncLeafCallback and CommitLeafCallback (I don't want to track the path for commit since it's useless burden).