-
Notifications
You must be signed in to change notification settings - Fork 261
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
account_saver: Remove nested options #2724
Conversation
let (account_infos, cached_accounts) = txn_iter | ||
.enumerate() | ||
.map(|(i, txn)| { | ||
let (account_infos, cached_accounts) = (0..accounts_and_meta_to_store.len()) |
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.
if the txn_iterator is empty, we still want to iterate over the accounts to store.
Might make sense to just have some sort of iteration over accounts_and_meta_to_store
?
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.
That sounds nice to me
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.
Hm sounded good in theory, but when I just took a stab it I ran into a problem immediately.
We implement StorableAccounts
on various tuple types. Rust does not allow us to implement Iterator
for arbitrary types that we didn't define.
So afaict we'd need to wrap these in some type or have an iter fn - which doesn't seem much better imo.
accounts-db/src/accounts_db.rs
Outdated
} else { | ||
Box::new(std::iter::empty()) | ||
}; | ||
let mut write_version_producer = if self.accounts_update_notifier.is_some() { |
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.
we either iterate over a range or have an empty. 0..0 should be equivalent, but match the Range type so we can avoid doing a Box allocation
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.
How about just using a u64
to track the latest write version and increment it whenever we notify?
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.
accounts-db/src/accounts_db.rs
Outdated
assert_eq!(transactions.len(), accounts.len()); | ||
transactions.iter().copied() | ||
} | ||
None => [].iter().copied(), |
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.
behavior change here - instead of creating a box for different types of iterators, we either have an iterator over the txns vs an empty iterator.
At the next level down we just use None
if the iterator has no next element.
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.
How about we pass Option<&[&SanitizedTransaction]>
directly?
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 suggestion from jstarry makes sense to me.
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.
@jstarry & @LucasSte as a follow-up to this I plan to move this module out of The reason I'd like to move it is to make the transition to the new transaction type not depend on the geyser interface changing, since I am seeing push-back on that front. Instead of this collecting whatever transaction-type we pass in, it will (until geyser transitions) return |
Wherever you move |
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.
Implementation looks fine as is but had some suggestions
accounts-db/src/accounts_db.rs
Outdated
} else { | ||
Box::new(std::iter::empty()) | ||
}; | ||
let mut write_version_producer = if self.accounts_update_notifier.is_some() { |
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.
How about just using a u64
to track the latest write version and increment it whenever we notify?
let (account_infos, cached_accounts) = txn_iter | ||
.enumerate() | ||
.map(|(i, txn)| { | ||
let (account_infos, cached_accounts) = (0..accounts_and_meta_to_store.len()) |
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.
That sounds nice to me
accounts-db/src/accounts_db.rs
Outdated
assert_eq!(transactions.len(), accounts.len()); | ||
transactions.iter().copied() | ||
} | ||
None => [].iter().copied(), |
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.
How about we pass Option<&[&SanitizedTransaction]>
directly?
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.
Looks fine to me. The changes are mainly localized to if there's an account_update_notifier (aka geyser) plugin. The rest of the changes are refactors.
accounts-db/src/accounts_db.rs
Outdated
assert_eq!(transactions.len(), accounts.len()); | ||
transactions.iter().copied() | ||
} | ||
None => [].iter().copied(), |
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 suggestion from jstarry makes sense to me.
I don't really think it'd be that strange - this is not actually where we "save" accounts anyways. We're just unrolling the That said, I think I could probably work around the conversion issue I mentioned previously and just put the conversion trait in Think @buffalojoec has some opinions on what should/should not be in SVM, so he may want to weigh in here. |
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
accounts-db/src/accounts_db.rs
Outdated
} else { | ||
Box::new(std::iter::empty()) | ||
}; | ||
let mut current_write_version = self |
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.
We used to only update the write_version
atomic counter for if self.accounts_update_notifier.is_some()
. I don't see anything wrong with updating it always. @brooksprumo any thoughts here?
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.
That's just a mistake on my part - reverted: ae2284a
You read my mind. I was going to look into this as well, but I didn't want to block anyone pushing bugfixes for now.
I'm fully on board with this approach. I just did something similar with rent evaluation/collection in #2753 and may also do something similar with other pieces like fees. Are you going to take it on for account saver @apfitzge ? If not I can do it! |
Problem
Summary of Changes
Fixes #