-
Notifications
You must be signed in to change notification settings - Fork 4.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
Remove activated feature for removing inactive delegations from stakes cache #21732
Remove activated feature for removing inactive delegations from stakes cache #21732
Conversation
automerge label removed due to a CI failure |
61b24c5
to
beeba33
Compare
automerge label removed due to a CI failure |
account.set_lamports(0); | ||
account.data_as_mut_slice().fill(0); |
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.
@ryoqun can you take a look at this? When the stakes_remove_delegation_if_inactive
feature was activated, we no longer remove delegations simply if the account balance is zero for stake accounts. The data must still be large enough to hold stake state AND it must not deserialize into a state that has a delegation.
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 change will only affect consensus if we create a new builtin for an active stake account.
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.
haha, you're editing scary part. thanks for pinging :)
to be sure, account with lamport=0 should always be same account hash regardless of its data contents. that's why this doesn't need feature-gated, right?
i mean, there's a risk of differing bank hash in add_builtin_account
(
Line 2814 in 1149c18
self.burn_and_purge_account(program_id, account); |
add_precompiled_account
) under mixed-version cluster condition unless the above premise holds 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.
Yes, exactly, the account hash shouldn't change. The risk in builtin/precompiled accounts is that the stakes cache state is corrupted so maybe worth adding a new feature gate in your opinion? There is a new change (#21654) that prunes corrupt state from the stakes cache but I'd rather not test it.
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 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.
The risk in builtin/precompiled accounts is that the stakes cache state is corrupted so maybe worth adding a new feature gate in your opinion?
i don't think it's worth adding a new feature gate. i always forget the following impracticality of these attacks... xD:
Lines 2807 to 2814 in 1149c18
// it's very unlikely to be squatted at program_id as non-system account because of burden to | |
// find victim's pubkey/hash. So, when account.owner is indeed native_loader's, it's | |
// safe to assume it's a genuine program. | |
if native_loader::check_id(account.owner()) { | |
Some(account) | |
} else { | |
// malicious account is pre-occupying at program_id | |
self.burn_and_purge_account(program_id, account); |
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.
// Both resetting account balance to 0 and zeroing the account data
// is needed to really purge from AccountsDb and flush the Stakes cache
account.set_lamports(0);
account.data_as_mut_slice().fill(0);
What does above comment actually mean?
I see zero lamports accounts are not stored in accounts-db even if they have non zero data and data_len.
Also, the code indicates that is the case:
https://github.com/solana-labs/solana/blob/64abd008c/runtime/src/accounts_db.rs#L4971-L4978
This causes stakes cache to be inconsistent with accounts-db. Whereas previously if lamports = 0, the delegation was removed from stakes cache as well.
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 burn_and_purge_account
method is only called when we forcefully purge an account so this checks ensures that if we purge an active stake account, it actually gets removed from the stakes cache. Simply setting the lamports to 0 is not enough because the stake account state could still be deserialized into a delegation and then update_stake_delegation
would be called with Some(0, Delegation)
and self.stake_delegations.remove(stake_pubkey)
wouldn't be called.
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 the code comment could be better expressed, because as it is right now, it may falsely imply that setting account balance to 0 may not always remove the account from AccountsDb, which to my understanding it is not true.
But that issue aside and ignoring accounts-db for the moment, regarding the stakes-cache:
- old code used to remove delegations if
lamports == 0
: https://github.com/solana-labs/solana/blob/476124de5/runtime/src/stakes.rs#L181-L185 - not removing delegations from stakes-cache when
lamports == 0
will cause stakes cache to be inconsistent with accounts-db. ie. there will be zombie delegations in stakes cache with no associated stake account in accounts-db.
Is there any scenario that we don't want to remove the delegation from the stakes-cache when account's lamports == 0
?
Codecov Report
@@ Coverage Diff @@
## master #21732 +/- ##
========================================
Coverage 81.3% 81.3%
========================================
Files 516 516
Lines 144033 144155 +122
========================================
+ Hits 117139 117241 +102
- Misses 26894 26914 +20 |
// Both resetting account balance to 0 and zeroing the account data | ||
// is needed to really purge from AccountsDb and flush the Stakes cache |
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 grooming
runtime/src/stakes.rs
Outdated
|
||
if remove_delegation { | ||
// when account is removed (lamports == 0), remove it from Stakes as well | ||
// when stake is no longer delegated, remove it from Stakes as well |
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.
nits: as well
could be removed as it was referring to the 0 lamported ness?
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 with nit (and after merge conflict cleaning)
e2bd002
to
1daca5f
Compare
automerge label removed due to a CI failure |
Problem
Feature is active on all clusters and can be cleaned up
Summary of Changes
Fixes #