pub(crate) fn add_to_non_finalized_chain_unique<NullifierT>(
chain_nullifiers: &mut HashMap<NullifierT, Hash>,
shielded_data_nullifiers: impl IntoIterator<Item = NullifierT>,
revealing_tx_id: Hash,
) -> Result<(), ValidateContextError>Expand description
Reject double-spends of nullifiers:
- both within the same
JoinSplit(sprout only), - from different
JoinSplits,sapling::Spends ororchard::Actions in thisTransaction’s shielded data, or - one from this shielded data, and another from:
(Duplicate finalized nullifiers are rejected during service contextual validation,
see no_duplicates_in_finalized_chain for details.)
§Consensus
A nullifier MUST NOT repeat either within a transaction, or across transactions in a valid blockchain. Sprout, Sapling, Orchard, and Ironwood nullifiers are considered disjoint, even if they have the same bit pattern.
https://zips.z.cash/protocol/protocol.pdf#nullifierset
We comply with the “disjoint” rule by storing the nullifiers for each pool in separate sets (also with different types), so that even if different pools have nullifiers with same bit pattern, they won’t be considered the same when determining uniqueness. This is enforced by the callers of this function.