librustzcash
librustzcash copied to clipboard
Introduce ZIP 315 `TrustPolicy` struct or similar
We should implement the distinction of trusted and untrusted transactions outlined in ZIP 315, as a way of replacing the single "min confirmations" security level. This would then enable wallets to implement a "trust policy", whereby signals are used to determine whether an incoming payment can be trusted or not, and therefore what min-conf level to apply to the transaction to ensure security of funds.
Original OP:
We recently changed min_confirmations to be a NonZeroU32, but this exposed an issue where we still want to set it to zero for transparent coins. What we really need is a confirmation depth per pool (and for shielded pools, potentially different between own-wallet notes and externally-received notes).
We should also take into account the fact that when checking balances, we often do want to use min_confirmations = 0 for shielded pools (so that balance doesn't temporarily drop), while when creating transactions we want to enforce that it is non-zero.
@daira recently had a realization about the meaning of having different confirmation depths for change notes relative to confirmation depths for non-change notes related to the proposed scheme in ZIP 315 that I can't recall now, but that should be recorded here. IIRC ze was working on a commit to make a change related to this to ZIP 315, but I don't see that commit on https://github.com/zcash/zips/pull/607/commits yet.
We should also take into account the fact that when checking balances, we often do want to use
min_confirmations = 0for shielded pools (so that balance doesn't temporarily drop), while when creating transactions we want to enforce that it is non-zero.
Right. We do have the pending change notes in the wallet database, so we should be able to treat those as part of the balance so long as they have not expired.
(and for shielded pools, potentially different between own-wallet notes and externally-received notes).
To expand on / clarify what I meant here: we realised a while back that we don't need to have the same confirmation depth for all notes, as the decision about when to select a note for spending is entirely wallet-local. So we can e.g. use 10 confirmations for notes received from external transactions (as there is a risk of the inputs being double-spent), while using 3 confirmations for our own change notes (as we can assume we won't double-spend ourselves). Then the anchor height for a transaction can be set to the minimum of these (i.e. 3, vs. the 10 we currently set it to).
(and for shielded pools, potentially different between own-wallet notes and externally-received notes).
To expand on / clarify what I meant here: we realised a while back that we don't need to have the same confirmation depth for all notes, as the decision about when to select a note for spending is entirely wallet-local. So we can e.g. use 10 confirmations for notes received from external transactions (as there is a risk of the inputs being double-spent), while using 3 confirmations for our own change notes (as we can assume we won't double-spend ourselves). Then the anchor height for a transaction can be set to the minimum of these (i.e. 3, vs. the 10 we currently set it to).
Right, that's the idea that @daira realized was incorrect and I can't remember exactly the argument.
The comment that the above discussion was referring to was invalidated. So we're back in the position where we want to separate "confirmation depth" from "anchor depth" matching what we described in the current draft of ZIP 315, enabling both a much smaller anchor depth to be used, as well as to have confirmation depth set to that smaller anchor depth for trusted notes.
I'm currently attempting to work out the implementation for this.
There are several things that a wallet needs to select in order to produce a transaction proposal:
- The anchor height to use for Sapling and Orchard notes in the transaction.
- These could in theory be different; there is no consensus rule that requires them to come from the same block. But setting them to different heights becomes a distinguisher.
- The anchor height must be no earlier than the maximum height for the minimum confirmations from the trust policy, which is the trusted confirmations number.
- There is minimal (zero?) benefit to distinguishing these two, because they are primarily about resilience against reorgs of the note-spending transaction, whereas the untrusted confirmations are about resilience against reorgs of the note-creating transaction.
- The anchor height must be no later than the chain tip height.
- This technically conflicts with the previous requirement when the trusted confirmations number is zero (i.e. a zero-conf transaction), but in practice this requirement logically takes precedence as zero-conf shielded spends are impossible, while we do want to allow zero-conf transparent spends.
- It must be possible to build witnesses from the selected notes to the selected anchor height, which means the wallet must have a checkpoint for the anchor height.
- If we have different sets of checkpoints for Sapling and Orchard, we run into a problem of deciding whether to have more optimal anchor heights for one pool but a distinguisher, or a less optimal but singular anchor height (that depending on how far back it gets picked might also become a distinguisher depending on why the wallet has different checkpoint information).
- The set of trusted notes to use as inputs.
- Their mined height must satisfy the trusted confirmations policy.
- For shielded notes, they must be mined by at latest the anchor height.
- Notice that this permits
- The set of untrusted notes to use as inputs.
- These must be mined by at latest the anchor height, and their mined height must satisfy the untrusted confirmations policy.
Anchor height selection has the following inputs:
- The wallet's view of the chain tip height.
- The trust policy (for the trusted confirmations value).
- The available checkpoints for Sapling and/or Orchard.
Note selection has the following inputs:
- The account.
- The target value.
- The anchor height.
- The trust policy (for trusted / untrusted filtering).
Related to #1413
👍 .
@str4d, I just want to confirm that this is simply linking the issue to the confirmations policy work, and not necessarily introducing any new requests for changes :)
Correct, this is the issue that your PR closes, and AFAICT your PR covers everything we've previously discussed here.