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

change(mempool) reject transactions with spent outpoints or nullifiers #5434

Merged
merged 9 commits into from
Oct 24, 2022

Conversation

arya2
Copy link
Contributor

@arya2 arya2 commented Oct 20, 2022

Motivation

To reject transactions in the mempool when they're invalidated by recently committed blocks.

Closes #2631

Solution

  • Add the transactions of committed blocks to the ChainTipBlock
  • Reject and remove transactions in the mempool that are using spent outpoints or nullifiers from the latest chain tip
  • Reject mined transactions

Review

This PR is part of regular scheduled work.

Reviewer Checklist

  • Will the PR name make sense to users?
    • Does it need extra CHANGELOG info? (new features, breaking changes, large changes)
  • Are the PR labels correct?
  • Does the code do what the ticket and PR says?
  • How do you know it works? Does it have tests?

@arya2 arya2 added C-bug Category: This is a bug P-Medium ⚡ I-usability Zebra is hard to understand or use labels Oct 20, 2022
@arya2 arya2 self-assigned this Oct 20, 2022
@github-actions github-actions bot added the C-enhancement Category: This is an improvement label Oct 20, 2022
@arya2 arya2 force-pushed the recently-spent-outpoints branch 2 times, most recently from 5120809 to f158500 Compare October 20, 2022 02:16
@arya2 arya2 requested a review from teor2345 October 20, 2022 02:35
@codecov
Copy link

codecov bot commented Oct 20, 2022

Codecov Report

Merging #5434 (51b841b) into main (a2dba8c) will decrease coverage by 0.00%.
The diff coverage is 100.00%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5434      +/-   ##
==========================================
- Coverage   79.12%   79.12%   -0.01%     
==========================================
  Files         308      308              
  Lines       39324    39394      +70     
==========================================
+ Hits        31115    31170      +55     
- Misses       8209     8224      +15     

Copy link
Member

@upbqdn upbqdn left a comment

Choose a reason for hiding this comment

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

This looks good to me.

I don't know how often is poll_ready actually called, so my concern is that if there happen to be two or more blocks mined fast one after another (which can happen), Zebra would skip some blocks. This applies to other checks as well, for example, in remove_same_effects.

zebrad/src/components/mempool.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

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

Looks great!

(And it's simpler than I thought 🙂)

I have a minor suggestion about naming things.

@teor2345
Copy link
Contributor

A possible alternative may be to pass the non_finalized_state_receiver to the mempool so that it can check the spent_utxos and nullifiers of all recently committed blocks on the best chain, rather than just the ChainTipBlock.

This isn't needed, because the mempool only updates by one block at a time. If there are multiple blocks, it assumes it has fallen out of sync, and resets itself.

@teor2345 teor2345 added I-slow Problems with performance or responsiveness and removed C-enhancement Category: This is an improvement labels Oct 21, 2022
@teor2345
Copy link
Contributor

This is a bug fix. We want to do it to improve the mempool, it's just a higher priority now we're doing mining RPCs.

So don't think we need to put it behind the getblocktemplate-rpcs feature, because it's a fix that we want in production. (And it's ok for the audit as well, because it's more like zcashd.)

@teor2345
Copy link
Contributor

teor2345 commented Oct 21, 2022

I don't know how often is poll_ready actually called, so my concern is that if there happen to be two or more blocks mined fast one after another (which can happen), Zebra would skip some blocks. This applies to other checks as well, for example, in remove_same_effects.

If Zebra gets multiple blocks between mempool updates, it drops all the mempool transactions, and starts fresh with an empty mempool.

This is implemented using a Reset, rather than a Grow:

/// Resets can happen for different reasons:
/// - a newly created or cloned [`ChainTipChange`], which is behind the
/// current tip,
/// - extending the chain with a network upgrade activation block,
/// - switching to a different best [`Chain`][1], also known as a rollback, and
/// - receiving multiple blocks since the previous change.
///
/// To keep the code and tests simple, Zebra performs the same reset
/// actions, regardless of the reset reason.
///
/// `Reset`s do not have the transaction hashes from the tip block, because
/// all transactions should be cleared by a reset.
///
/// [1]: super::non_finalized_state::Chain
Reset {

We track this as part of ChainTipChange.last_tip_change():

if Some(block.previous_block_hash) != self.last_change_hash
|| NetworkUpgrade::is_activation_height(self.network, block.height)
{
TipAction::reset_with(block)
} else {
TipAction::grow_with(block)
}

arya2 added 2 commits October 21, 2022 11:45
…mempool that have been invalidated by the latest block commit
…oves nullifier retrieval to the new Storage method, rejects mined_ids, and updates tests
@arya2 arya2 force-pushed the recently-spent-outpoints branch from f158500 to b5cffbf Compare October 21, 2022 21:08
@github-actions github-actions bot added the C-enhancement Category: This is an improvement label Oct 21, 2022
@arya2
Copy link
Contributor Author

arya2 commented Oct 21, 2022

I don't know how often is poll_ready actually called, so my concern is that if there happen to be two or more blocks mined fast one after another (which can happen), Zebra would skip some blocks. This applies to other checks as well, for example, in remove_same_effects.

I was also concerned about this.

If Zebra gets multiple blocks between mempool updates, it drops all the mempool transactions, and starts fresh with an empty mempool.

Good to know that's not an issue.

@arya2 arya2 marked this pull request as ready for review October 21, 2022 21:47
@arya2 arya2 requested review from a team as code owners October 21, 2022 21:47
@arya2 arya2 changed the title change(mempool) rejects transactions with spent outpoints or nullifiers change(mempool) reject transactions with spent outpoints or nullifiers Oct 21, 2022
Copy link
Contributor

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

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

I think this looks good, just a few minor clarifications.

Do you need help with the test failures?
I know we've done some fixes on the main branch, so I'll update this PR to the latest main.

Edit: it was an unrelated test failure

zebrad/src/components/mempool/storage.rs Show resolved Hide resolved
zebrad/src/components/mempool/storage/tests/prop.rs Outdated Show resolved Hide resolved
@teor2345
Copy link
Contributor

@Mergifyio update

@mergify
Copy link
Contributor

mergify bot commented Oct 24, 2022

update

✅ Branch has been successfully updated

@teor2345
Copy link
Contributor

Ah, the test failure was a ssh issue:

Connection timed out during banner exchange

https://github.com/ZcashFoundation/zebra/actions/runs/3300645552/jobs/5445970948#step:6:112

teor2345
teor2345 previously approved these changes Oct 24, 2022
Copy link
Contributor

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

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

Looks good, happy for this to go in without any of my suggestions.
(Or anyone can re-approve once they are done.)

mergify bot added a commit that referenced this pull request Oct 24, 2022
@mergify mergify bot merged commit e9452d9 into main Oct 24, 2022
@mergify mergify bot deleted the recently-spent-outpoints branch October 24, 2022 19:48
teor2345 added a commit that referenced this pull request Feb 6, 2023
#5434)

* adds transactions to ChainTipBlock and rejects transactions from the mempool that have been invalidated by the latest block commit

* merges remove_same_effects in with reject_invalidated_transactions, moves nullifier retrieval to the new Storage method, rejects mined_ids, and updates tests

* updates DuplicateSpend's error message

* fixes tests

* Update zebrad/src/components/mempool/storage.rs

Co-authored-by: teor <[email protected]>

* adds comment

* formatting for the proptest

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: teor <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug C-enhancement Category: This is an improvement I-slow Problems with performance or responsiveness I-usability Zebra is hard to understand or use
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Send committed spent OutPoints & nullifiers to the mempool for rejection
4 participants