-
Notifications
You must be signed in to change notification settings - Fork 113
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
fix(rpc): Omit transactions with transparent coinbase spends that are immature at the next block height from block templates #6510
Conversation
Filters out transactions that are invalid at next_block_height in getblocktemplate method
26aca06
to
9b340a2
Compare
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.
The getblocktemplate method can currently construct invalid block templates if there are mempool transactions with transparent coinbase spends that are immature at the next block height.
So this is kind of a big question, but should these invalid transactions be in the mempool at all?
If we make the changes in this PR, we'll store invalid transactions in the mempool, and relay them to other nodes. And those invalid transactions could cause valid transactions to be rejected from the mempool due to conflicts, or due to mempool capacity limits. (They also waste CPU and bandwidth across the Zcash network.)
Looking at our design principles, we'd be breaking one of the core properties of Zebra's implementation: we don't store invalid data. It would be particularly confusing to store an invalid transaction in a type called VerifiedUnminedTx
:
zebra/zebra-chain/src/transaction/unmined.rs
Lines 294 to 299 in 166526a
/// A verified unmined transaction, and the corresponding transaction fee. | |
/// | |
/// This transaction has been fully verified, in the context of the mempool. | |
#[derive(Clone, Debug, PartialEq)] | |
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))] | |
pub struct VerifiedUnminedTx { |
As an alternative, if the mempool transaction verifier checks transactions against the best tip height, and returns a StorageEffectsTip
error if they can't be spent yet, they won't be stored in our mempool. This means:
- they can't be mined into blocks
- they won't be relayed to other nodes
And when the tip updates, Zebra will re-download them and try to verify them again. Which is what we want.
(If we want to store unmined transactions that could potentially become valid, like zcashd
, then that's a bigger decision. I think it should probably go back to the whole team.)
I'm sorry I have to give feedback like this, because I think this is a neat idea. (And it's quite a clever workaround!) But I'm concerned it could cause maintenance issues like subtle bugs and developer confusion.
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #6510 +/- ##
==========================================
+ Coverage 77.72% 77.79% +0.07%
==========================================
Files 304 305 +1
Lines 39665 40225 +560
==========================================
+ Hits 30830 31295 +465
- Misses 8835 8930 +95 |
I don't think so, they're not in the zcashd mempool.
Great point, it looks like zcashd always immediately rejects transactions with immature transparent coinbase spends at the next block height from the mempool (at the end of
I thought zcashd stashes these (it stashes other invalid transactions that may become valid but not these, whoops).
Hey, that's what it takes to make good code, and I took the risk by not looking closely enough at what zcashd is doing. Thank you for helping catch the mistake. |
Updated in d8c8160 so it rejects transactions with spends that aren't valid at the next block height. Unified I left the TODO for moving the check out of the state, I still think it would work, parallelize the check, and possibly avoid duplicate lookups. |
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 seems like something that we could merge as-is, but I'd like to improve the test coverage and method documentation.
zebra-rpc/src/methods/get_block_template_rpcs/get_block_template.rs
Outdated
Show resolved
Hide resolved
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.
Thanks, let's get this merged to fix CI!
Motivation
The getblocktemplate method can currently construct invalid block templates if there are mempool transactions with transparent coinbase spends that are immature at the next block height.
This PR adds a
maturity_height
field to the transaction verifier's mempool response and uses it inget_block_template()
to filter out transactions that would be invalid at the next block height.Closes #6482.
Solution
maturity_height: Option<Height>
toVerifiedUnminedTx
in the transaction verifierfetch_mempool_transactions()
Review
Anyone can review.
Reviewer Checklist
Follow Up Work
Once authorizing data is bound to the block data during semantic validation, return errors for block requests to replace this check in the state service: