ZcashFoundation / zebra

Zcash - Financial Privacy in Rust 🦓
https://zfnd.org/zebra/
Apache License 2.0
413 stars 106 forks source link

add(mempool): Verify transactions with unmined inputs in the mempool #8857

Open arya2 opened 2 months ago

arya2 commented 2 months ago

Motivation

We want to verify transactions in the mempool that spend the transparent outputs of other transactions in the mempool.

Closes #8777.

Solution

Tests

Added tests to check that:

If needed, this PR could also add tests for:

Follow Up Work

The mempool's Downloads sends a result to the response channel too early, it should wait until the transaction is being inserted into the mempool's verified set.

PR Author's Checklist

PR Reviewer's Checklist

arya2 commented 2 weeks ago

This is a complex PR (not your fault, it's a complex issue). I've been reviewing it for a while but it feels I could spend ages reviewing this to be 100% sure. I'm OK with approving it but do you think we should ask for someone else to take a look?

In hindsight, it probably should've been split into multiple PRs. A second review would be ideal since it involves concurrency and consensus changes, though it has also gone through a few rounds of self-review.

I think a second review of just the changes to ZIP 317 block production would be okay.

Also, did you manage to test it for the use case we wish to address (i.e. sending to tex addresses?)

I haven't, and there's no acceptance test that tries to submit an orphaned transaction, I'll try doing that now.

upbqdn commented 2 weeks ago

I'm also still reviewing. A bunch of other things took precedence in the meantime, unfortunately.

arya2 commented 1 week ago

What do you mean by "orphaned" transactions in the title?

Transactions that spend outputs that are missing in the chain state, though I'm not sure if "orphan transactions" is the right term if those outputs can still be found in the mempool.

This PR is still missing an acceptance test for the use case we're trying to address (testing it manually with zcashd seems difficult, and a test that creates transactions could provide a valuable reference for other tests in the future), but I think it's fine to merge it without an acceptance test since each component has unit tests (though I'm happy to prioritize writing that test if anyone disagrees).

upbqdn commented 1 week ago

What do you mean by "orphaned" transactions in the title?

Transactions that spend outputs that are missing in the chain state, though I'm not sure if "orphan transactions" is the right term if those outputs can still be found in the mempool.

This RFC, https://github.com/zcashfoundation/zebra/blob/257567b559dba0359519d61684e80daac52cc434/book/src/dev/rfcs/0005-state-updates.md#L62, defines orphaned blocks as those that are no longer included in the best chain, which implies they were mined at some point. I'd assume orphaned txs are those in such blocks, but this PR doesn't apply to them. Maybe something like "Verify transactions spending mempool UTXOs"?

arya2 commented 1 week ago

I'm trying to figure out what happens if someone submits txs containing a circular dependency. We should make sure we can handle such cases well.

The transaction verifier would return an TransparentInputNotFound error for both because (unlike pending_utxos in the state service) the mempool only responds to AwaitOutput requests once the transaction creating that output has been added to the mempool's verified set.

A similar question around ordering the transactions in block templates caused me some strife (the code should work as expected there too, and it's been excluded from release compilations, but it was difficult to reason about). That exact question may have also caused me some strife a little earlier, as well as what happens to long chains of dependent transactions.

gustavovalverde commented 3 days ago

@mergify refresh

mergify[bot] commented 3 days ago

refresh

✅ Pull request refreshed