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
bank_send_loop: Get feature flag from root bank #31954
Conversation
62447e5
to
db7e76f
Compare
db7e76f
to
0a7fae7
Compare
Codecov Report
@@ Coverage Diff @@
## master #31954 +/- ##
=========================================
- Coverage 81.9% 81.9% -0.1%
=========================================
Files 766 766
Lines 208683 208642 -41
=========================================
- Hits 171012 170964 -48
- Misses 37671 37678 +7 |
@@ -426,6 +431,15 @@ impl ClusterInfoVoteListener { | |||
&verified_vote_packets, | |||
)?; | |||
} | |||
// Check if we've crossed the feature boundary |
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.
Reviewer note: Better to have this here a second time (in addition to before the loop) to avoid grabbing a read lock on bank_forks
every iteration
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.
can we factor this optimization out to a separate PR to reduce the backport surface?
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.
can we factor this optimization out to a separate PR to reduce the backport surface?
if you gimme write on your branch, i have this change made locally
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.
can we factor this optimization out to a separate PR
To confirm, you're only talking about removing the if
statement that skips reading feature set if we know the feature is already activated ? My initial comment was pointing out that we were reading in two places, but that was better to both 1) start with a valid value on first couple iterations of loop and 2) avoid spamming the lock.
That being said, receive_and_process_vote_packets()
does recv_timeout(200ms)
so my concern about having feature set happen every iteration of the loop is mitigated by receive_and_process_vote_packets()
taking a nontrivial amount of time to return
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.
just gave you write access. if you're talking about the refactor to pass the flag rather than the feature set that was to avoid cloning or holding the bank forks lock for too long.
the if
statement could probably be removed taking into consideration the 200ms
sleep that steve pointed out.
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.
nope. the whole swap from Option<FeatureSet>
to bool
. master...t-nelson:solana:feature-flag-fix
we're already doing the inefficient thing and that inefficiency did not contribute to the testnet outage, so the optimization doesn't need to be backported
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.
sounds good, i'm fine with the clone.
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.
sounds good, i'm fine with the clone.
hrmf, seems like github has some new default branch protection rules or something. it won't let me push my changes 'cause i rewrote your tip. mind pulling my branch and pushing up the change?
ping me when we're readhy and i'll re-enable rebase+merge for this so we don't need a separate PR
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.
nice thanks, should now be 2 commits. hopefully github does the right thing and only backports the first one.
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.
nice thanks, should now be 2 commits. hopefully github does the right thing and only backports the first one.
it'll try to do them both. trivial to drop the last one tho
any concerns about the 32 block delay in activation? seems like ideally we'd use the most recently frozen bank. |
Don't expect it would be a huge difference. Also most normal ways of startup would start with a root bank right? starting from snapshot or catching up old ledger? |
Agreed with Ashwin here - I don't think so. It is still a binary on/off regardless of any delay. If anything, the 32 block delay imposed by it being a root in the new epoch will create some distance from the epoch boundary, so maybe cluster more stable there as opposed to the Bank(s) that initially cross epoch boundary.
Correct, we will always have a root in solana/runtime/src/bank_forks.rs Lines 80 to 83 in 40d3e8e
also noting that we return an solana/runtime/src/bank_forks.rs Lines 153 to 155 in 40d3e8e
|
This is the case for mainnet beta; it will be a gradual thing for testnet as nodes upgrade if we reuse the existing feature key. |
nice! i would prefer not to create a feature gate if we can avoid it, the original optimization this code handled wasn't consensus breaking either. |
What's the worst case here? That after block Seems like should be fine as long as turbine votes are landing 😃 Alternatively we could remove the |
i think i'm more concerned about the class of bug than this particular instance of it. consider a feature gate that affects multiple components which sample different banks... actually, even in this case, i believe the runtime and vote program instances would be observed active at different slots |
The only bank hash breaking check is in |
Pretty sure in most cases we're doing bank specific activities like processing transactions/program modifications for feature flags, so it's not an issue because then you just check if the feature is active on that specific bank |
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 agree with Ashwin & Carl in thinking that the delay caused by using root_bank()
should not be an issue for this PR. Think it would be good to ensure Trent agrees too tho
i'm not strictly concerned with overt consensus breakage. the timing stuff is less straight-forward to reason about (i think in the case of this instance, it's mostly fine). the only part that's not clear to me now is the timing considerations of this block solana/core/src/replay_stage.rs Lines 3001 to 3006 in 8fbada4
|
I see, yeah for this particular change I think it should be fine - we don't drop any As for the replay code you linked, the intention was not to change any behavior at the feature boundary but intended for improving our restart behavior regarding missing/out of date local towers. As to why we feature flagged it, I believe it was because under |
so it seems like the potential timing issues are
|
Seems the concerns left are about the general timing issues of activating this feature? Should we merge this and pick it up in a separate issue?
do you have more context on this?
Not sure i follow this exact scenario, we root the in between slots locally, or they were rooted by us pre restart? But basically any restart around the epoch boundary could be trigger this race if the saved tower was later or missing. The intention here is to try our best to not send a slashable vote by adopting on chain state. In this restart around epoch boundary case the worst that could happen is the current behavior of starting with an empty or inaccurate tower, we can only possibly start from a tower the cluster observed us having previously. |
i must've read the code wrong last week. these two cases use the same bank (+/- refreshes)
ok thanks for the details! that last paragraph assuages my concerns one last doom scenario: if all or part of the cluster were to not be making roots at all across the epoch boundary, the feature would not activate for the effected nodes. i think this is actually fine though, as the whole cluster would activate at the same time wrt ancestry? |
In this case we would start receiving Once we make a root past the boundary the worst case is that it happens right at a leader boundary, and that leader would drop some votes. This is incredibly unlikely as the cluster usually will root and activate around the same time. Even if this were to somehow happen it could only happen once per leader compared to every leader slot as it is now. |
0a7fae7
to
cacb5f3
Compare
I can see Ashwin force-pushed 34 minutes ago, but I'm guessing because the diff is identical (with items now split across commits), it didn't remove the ship-its that Carl and I already gave ... if that's what happened and not some other glitch that didn't wipe our ship-its that's pretty neat |
or exploitable 🤔 |
Problem
Previously we were using the working bank to access the feature set. This only works while we are leader, but we start sending gossip votes to banking stage slightly before we are leader.
Summary of Changes
Instead use the root bank from bank forks to access feature set.
Fixes #