neptune-consensus 0.14.0

Consensus logic and proof abstractions for Neptune Cash.
use neptune_mutator_set::addition_record::AdditionRecord;
use neptune_mutator_set::commit;
use neptune_mutator_set::removal_record::absolute_index_set::AbsoluteIndexSet;
use rand::distr::Distribution;
use rand::distr::StandardUniform;
use rand::Rng;
use tasm_lib::prelude::Digest;
use tasm_lib::prelude::Tip5;
use tasm_lib::triton_vm::prelude::BFieldCodec;

use crate::transaction::utxo::Utxo;

/// The key data from a transaction input that enables a transparent audit.
///
/// Specifically, this struct contains enough data to re-derive the
/// `AbsoluteIndexSet` without the target chunks. This information uniquely
/// identifies the UTXO. Furthermore, it contains the UTXO in plaintext, which
/// in particular lays bare the amounts if native currency coins are involved.
///
/// See also:
///  - `InputCandidate`
///    -- representation of spendable UTXOs used for applying
///    input selection policy;
///  - `ExpectedUtxo` -- contains data for receiving and monitoring received
///    UTXOs;
///  - `UnlockedUtxo` -- also contains lock script and witness and mutator set
///    membership proof;
///  - `SyncedUtxo` --
///  - `IncomingUtxo` -- contains extra data and does not store the AOCL leaf
///    index;
///  - [`UtxoTriple`](crate::transaction::utxo_triple::UtxoTriple)
///    -- output counterpart to this struct, does not contain info needed to
///    re-derive the absolute index set because that information is not known by
///    the transaction initiator.
#[derive(Debug, Clone, BFieldCodec)]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct TransparentInput {
    pub utxo: Utxo,
    pub aocl_leaf_index: u64,
    pub sender_randomness: Digest,
    pub receiver_preimage: Digest,
}

impl TransparentInput {
    pub fn absolute_index_set(&self) -> AbsoluteIndexSet {
        let item = Tip5::hash(&self.utxo);
        AbsoluteIndexSet::compute(
            item,
            self.sender_randomness,
            self.receiver_preimage,
            self.aocl_leaf_index,
        )
    }

    pub fn addition_record(&self) -> AdditionRecord {
        commit(
            Tip5::hash(&self.utxo),
            self.sender_randomness,
            self.receiver_preimage.hash(),
        )
    }
}

impl Distribution<TransparentInput> for StandardUniform {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> TransparentInput {
        let utxo = rng.random::<Utxo>();
        let aocl_leaf_index = rng.random_range(0..(u64::MAX >> 1));
        let sender_randomness = rng.random();
        let receiver_preimage = rng.random();
        TransparentInput {
            utxo,
            aocl_leaf_index,
            sender_randomness,
            receiver_preimage,
        }
    }
}