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

Refactor nonce rollback to remove overly complex code #1428

Merged
merged 3 commits into from
Jun 6, 2024

Conversation

jstarry
Copy link

@jstarry jstarry commented May 18, 2024

Problem

Nonce rollback code is overly complex and hard to read. This mess is making it hard to implement handling for transactions that skip execution but are still committed as part of SIMD-0082

Summary of Changes

Refactor with more descriptive types / scenarios

Fixes #

@codecov-commenter
Copy link

codecov-commenter commented May 18, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 82.7%. Comparing base (ef8d362) to head (54a7104).
Report is 3 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1428   +/-   ##
=======================================
  Coverage    82.7%    82.7%           
=======================================
  Files         871      871           
  Lines      370249   370150   -99     
=======================================
- Hits       306391   306311   -80     
+ Misses      63858    63839   -19     

Comment on lines -722 to -726
let maybe_nonce = match (execution_status, &loaded_transaction.nonce) {
(Ok(_), _) => None, // Success, don't do any additional nonce processing
(Err(_), Some(nonce)) => {
Some((nonce, true /* rollback */))
}
Copy link
Author

Choose a reason for hiding this comment

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

Before, maybe_nonce would only be Some(..) if the tx execution status was failed and the transaction used a nonce. Also, rollback is always true in this case, it's never false. This means that prepare_if_nonce_account doesn't need to check rollback and doesn't need to check execution status if maybe_nonce is Some(..)

TransactionStatus::Successful => true,
TransactionStatus::FailedWithNonce { nonce } => {
let is_fee_payer = i == 0;
let is_nonce_account = prepare_if_nonce_account(
Copy link
Author

Choose a reason for hiding this comment

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

Since prepare_if_nonce_account always exited early if maybe_nonce was None, we can refactor to only call it for failed nonce transactions where the nonce is available.

@ryoqun ryoqun self-requested a review June 1, 2024 03:34
let should_store_account = match tx_status {
TransactionStatus::Successful => true,
TransactionStatus::FailedWithNonce { nonce } => {
let is_fee_payer = i == 0;
Copy link
Member

@ryoqun ryoqun Jun 3, 2024

Choose a reason for hiding this comment

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

nit: since you're touching very sensible piece of code, i'd take the chance to further simplify the code by factoring out the address == nonce.address() into caller by defining let is_nonce_account = ... just below let is_fee_payer = ... here.

Then, make prepare_if_nonce_account return (), which in turn make the nested if is_fee_payer { ... } go way. Also, stop passing address.

Finally, after that, prepare_if_nonce_account()'s job clearer: it does its jobs only if is_nonce_account || is_fee_payer.

Copy link
Member

Choose a reason for hiding this comment

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

also, rename to post_process_failed_nonce?

//
// Since we know we are dealing with a valid nonce account,
// unwrap is safe here
let nonce_versions = StateMut::<NonceVersions>::state(nonce.account()).unwrap();
Copy link
Member

Choose a reason for hiding this comment

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

nit: nonce.account() => account for slight increase of readability?

Comment on lines 722 to 725
enum TransactionStatus<'a> {
Successful,
FailedWithNonce { nonce: &'a NonceFull },
}
Copy link
Member

@ryoqun ryoqun Jun 3, 2024

Choose a reason for hiding this comment

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

TransactionStatus is a bit too general.

how about these?

enum StoredAccountProcessingStatus {
    Normal,
    FailedWithNonce(...)
}

// or

enum AccountCollectionMode {
    Normal,
    FailedWithNonce(...)
}

// or 

enum NonceProcessing {
    Skip,
    UpdateAfterFailure(...)
}

Copy link
Member

@ryoqun ryoqun left a comment

Choose a reason for hiding this comment

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

did initial pass.

thanks for all the simplifications. I like them.

@jstarry
Copy link
Author

jstarry commented Jun 3, 2024

Thanks for the review @ryoqun, I've applied your feedback

Copy link
Member

@ryoqun ryoqun left a comment

Choose a reason for hiding this comment

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

lgtm with no nits.

thanks for cleaning up!

@jstarry jstarry merged commit dbf070b into anza-xyz:master Jun 6, 2024
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants