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

Make a loop instead of using filter #2071

Closed
wants to merge 3 commits into from
Closed

Conversation

ksolana
Copy link

@ksolana ksolana commented Jul 10, 2024

Simplifies the code by avoiding redundant iteration, and collection.

@ksolana
Copy link
Author

ksolana commented Jul 10, 2024

Thanks to @ilya-bobyr for suggesting this refactoring.

Comment on lines 269 to 280
.collect_vec();
pubkeys_by_stake
.into_iter()
.filter(|&pubkey| {
if !continue_forwarding {
return false;
}
if let Some(lock) = self.get_entry(pubkey) {
let mut vote = lock.write().unwrap();
if !vote.is_vote_taken() && !vote.is_forwarded() {
let deserialized_vote_packet = vote.vote.as_ref().unwrap().clone();
if let Some(sanitized_vote_transaction) = deserialized_vote_packet
.build_sanitized_transaction(
&bank.feature_set,
bank.vote_only_bank(),
bank.as_ref(),
)
{
if forward_packet_batches_by_accounts.try_add_packet(
&sanitized_vote_transaction,
deserialized_vote_packet,
&bank.feature_set,
) {
vote.forwarded = true;
} else {
// To match behavior of regular transactions we stop
// forwarding votes as soon as one fails
continue_forwarding = false;
}
return true;
let mut count: usize = 0;
for pubkey in pubkeys_by_stake {

Choose a reason for hiding this comment

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

for statement should handle an iterator just fine.
Removing a need for a vector to be constructed.

-         .collect_vec();
          let mut count: usize = 0;
          for pubkey in pubkeys_by_stake {

Copy link
Author

@ksolana ksolana Jul 10, 2024

Choose a reason for hiding this comment

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

There was a lifetime issue with the pubkeys_by_stake. Hoisting self.latest_votes_per_pubkey.read().unwrap(); out of the call in 93c3e75 fixed it.

Copy link

@ilya-bobyr ilya-bobyr Jul 10, 2024

Choose a reason for hiding this comment

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

Yeah, I figured there might be an issue with lifetimes there.
But, I think, it is because the function type is not correctly inferred.
The returned iterator does not hold any references to the input data, so there should be no lifetimes it is capturing.

Try specifying explicitly that the returned object does not capture any lifetimes:

pub(crate) fn weighted_random_order_by_stake<'a>(
    bank: &Bank,
    pubkeys: impl Iterator<Item = &'a Pubkey>,
) -> impl Iterator<Item = Pubkey> + 'static {

I think 'a gets added to the returned type for some reason, as if you said

... -> impl Iterator<Item = Pubkey> + 'a {

Choose a reason for hiding this comment

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

At the same time, I think, it might be possible to reduce the number of copies, if it would actually return Item = &'a Pubkey.
In which case you would need to put binding on the stack and keep is there for the whole duration of the algorithm.
As the returned iterator would reference binding.
Depending on the lock contention, one or the other might be faster.

Comment on lines 290 to 291
// To match behavior of regular transactions we stop
// forwarding votes as soon as one fails. We are assuming that failure (try_add_packet) means no more space available.

Choose a reason for hiding this comment

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

Convention is to wrap on 100 characters for comments.

Suggested change
// To match behavior of regular transactions we stop
// forwarding votes as soon as one fails. We are assuming that failure (try_add_packet) means no more space available.
// To match behavior of regular transactions we stop forwarding votes as
// soon as one fails. We are assuming that failure (try_add_packet)
// means no more space available.

core/src/banking_stage/latest_unprocessed_votes.rs Outdated Show resolved Hide resolved
Comment on lines +277 to +278
let binding = self.latest_votes_per_pubkey.read().unwrap();
let pubkeys_by_stake = weighted_random_order_by_stake(&bank, binding.keys());

Choose a reason for hiding this comment

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

I think this is locking the latest_votes_per_pubkey for longer than necessary.
If the following compiles, it is a slightly better way to do it, as it releases the lock earlier:

Suggested change
let binding = self.latest_votes_per_pubkey.read().unwrap();
let pubkeys_by_stake = weighted_random_order_by_stake(&bank, binding.keys());
let pubkeys_by_stake = {
let binding = self.latest_votes_per_pubkey.read().unwrap();
weighted_random_order_by_stake(&bank, binding.keys())
};

Copy link
Author

Choose a reason for hiding this comment

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

doesn't compile because error: binding does not live long enough

Choose a reason for hiding this comment

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

This is because weighted_random_order_by_stake return type incorrectly captures the lifetime of the second argument.
I've suggested how you can fix it above.

Here is a working code with the lock lifetime reduced and some other fixes I've suggested: #2091

Copy link
Author

Choose a reason for hiding this comment

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

Thanks! I'll abandon this patch then.

core/src/banking_stage/latest_unprocessed_votes.rs Outdated Show resolved Hide resolved
@ksolana
Copy link
Author

ksolana commented Jul 11, 2024

Abandoning it in favor of #2091

@ksolana ksolana closed this Jul 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants