state: insert into nullifier trees
This commit is contained in:
parent
6758fdbd1c
commit
2095b4f0d3
|
|
@ -31,7 +31,7 @@ fn prf_nf(nk: [u8; 32], rho: [u8; 32]) -> [u8; 32] {
|
|||
any(test, feature = "proptest-impl"),
|
||||
derive(proptest_derive::Arbitrary)
|
||||
)]
|
||||
pub struct Nullifier([u8; 32]);
|
||||
pub struct Nullifier(pub [u8; 32]);
|
||||
|
||||
impl From<[u8; 32]> for Nullifier {
|
||||
fn from(buf: [u8; 32]) -> Self {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ impl From<NullifierSeed> for [u8; 32] {
|
|||
any(test, feature = "proptest-impl"),
|
||||
derive(proptest_derive::Arbitrary)
|
||||
)]
|
||||
pub struct Nullifier(pub(crate) [u8; 32]);
|
||||
pub struct Nullifier(pub [u8; 32]);
|
||||
|
||||
impl From<[u8; 32]> for Nullifier {
|
||||
fn from(bytes: [u8; 32]) -> Self {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use crate::{
|
|||
block,
|
||||
parameters::NetworkUpgrade,
|
||||
primitives::{Bctv14Proof, Groth16Proof},
|
||||
transparent,
|
||||
sapling, sprout, transparent,
|
||||
};
|
||||
|
||||
/// A Zcash transaction.
|
||||
|
|
@ -147,6 +147,53 @@ impl Transaction {
|
|||
}
|
||||
}
|
||||
|
||||
/// Access the sprout::Nullifiers in this transaction, regardless of version.
|
||||
pub fn sprout_nullifiers(&self) -> Box<dyn Iterator<Item = &sprout::Nullifier> + '_> {
|
||||
// This function returns a boxed iterator because the different
|
||||
// transaction variants end up having different iterator types
|
||||
match self {
|
||||
// JoinSplits with Bctv14 Proofs
|
||||
Transaction::V2 {
|
||||
joinsplit_data: Some(joinsplit_data),
|
||||
..
|
||||
}
|
||||
| Transaction::V3 {
|
||||
joinsplit_data: Some(joinsplit_data),
|
||||
..
|
||||
} => Box::new(
|
||||
joinsplit_data
|
||||
.joinsplits()
|
||||
.flat_map(|joinsplit| joinsplit.nullifiers.iter()),
|
||||
),
|
||||
// JoinSplits with Groth Proofs
|
||||
Transaction::V4 {
|
||||
joinsplit_data: Some(joinsplit_data),
|
||||
..
|
||||
} => Box::new(
|
||||
joinsplit_data
|
||||
.joinsplits()
|
||||
.flat_map(|joinsplit| joinsplit.nullifiers.iter()),
|
||||
),
|
||||
// No JoinSplits
|
||||
_ => Box::new(std::iter::empty()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the sapling::Nullifiers in this transaction, regardless of version.
|
||||
pub fn sapling_nullifiers(&self) -> Box<dyn Iterator<Item = &sapling::Nullifier> + '_> {
|
||||
// This function returns a boxed iterator because the different
|
||||
// transaction variants end up having different iterator types
|
||||
match self {
|
||||
// JoinSplits with Groth Proofs
|
||||
Transaction::V4 {
|
||||
shielded_data: Some(shielded_data),
|
||||
..
|
||||
} => Box::new(shielded_data.nullifiers()),
|
||||
// No JoinSplits
|
||||
_ => Box::new(std::iter::empty()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if transaction contains any coinbase inputs.
|
||||
pub fn contains_coinbase_input(&self) -> bool {
|
||||
self.inputs()
|
||||
|
|
|
|||
|
|
@ -65,13 +65,13 @@ impl ShieldedData {
|
|||
|
||||
/// Collect the [`Nullifier`]s for this transaction, if it contains
|
||||
/// [`Spend`]s.
|
||||
pub fn nullifiers(&self) -> Vec<Nullifier> {
|
||||
self.spends().map(|spend| spend.nullifier).collect()
|
||||
pub fn nullifiers(&self) -> impl Iterator<Item = &Nullifier> {
|
||||
self.spends().map(|spend| &spend.nullifier)
|
||||
}
|
||||
|
||||
/// Collect the cm_u's for this transaction, if it contains [`Output`]s.
|
||||
pub fn note_commitments(&self) -> Vec<jubjub::Fq> {
|
||||
self.outputs().map(|output| output.cm_u).collect()
|
||||
pub fn note_commitments(&self) -> impl Iterator<Item = &jubjub::Fq> {
|
||||
self.outputs().map(|output| &output.cm_u)
|
||||
}
|
||||
|
||||
/// Calculate the Spend/Output binding verification key.
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ pub struct FinalizedState {
|
|||
block_by_height: sled::Tree,
|
||||
tx_by_hash: sled::Tree,
|
||||
utxo_by_outpoint: sled::Tree,
|
||||
// sprout_nullifiers: sled::Tree,
|
||||
// sapling_nullifiers: sled::Tree,
|
||||
sprout_nullifiers: sled::Tree,
|
||||
sapling_nullifiers: sled::Tree,
|
||||
// sprout_anchors: sled::Tree,
|
||||
// sapling_anchors: sled::Tree,
|
||||
/// Commit blocks to the finalized state up to this height, then exit Zebra.
|
||||
|
|
@ -69,8 +69,8 @@ impl FinalizedState {
|
|||
block_by_height: db.open_tree(b"block_by_height").unwrap(),
|
||||
tx_by_hash: db.open_tree(b"tx_by_hash").unwrap(),
|
||||
utxo_by_outpoint: db.open_tree(b"utxo_by_outpoint").unwrap(),
|
||||
// sprout_nullifiers: db.open_tree(b"sprout_nullifiers").unwrap(),
|
||||
// sapling_nullifiers: db.open_tree(b"sapling_nullifiers").unwrap(),
|
||||
sprout_nullifiers: db.open_tree(b"sprout_nullifiers").unwrap(),
|
||||
sapling_nullifiers: db.open_tree(b"sapling_nullifiers").unwrap(),
|
||||
debug_stop_at_height: config.debug_stop_at_height.map(block::Height),
|
||||
};
|
||||
|
||||
|
|
@ -97,8 +97,8 @@ impl FinalizedState {
|
|||
total_flushed += self.block_by_height.flush()?;
|
||||
total_flushed += self.tx_by_hash.flush()?;
|
||||
total_flushed += self.utxo_by_outpoint.flush()?;
|
||||
// total_flushed += self.sprout_nullifiers.flush()?;
|
||||
// total_flushed += self.sapling_nullifiers.flush()?;
|
||||
total_flushed += self.sprout_nullifiers.flush()?;
|
||||
total_flushed += self.sapling_nullifiers.flush()?;
|
||||
|
||||
Ok(total_flushed)
|
||||
}
|
||||
|
|
@ -221,6 +221,8 @@ impl FinalizedState {
|
|||
&self.block_by_height,
|
||||
&self.utxo_by_outpoint,
|
||||
&self.tx_by_hash,
|
||||
&self.sprout_nullifiers,
|
||||
&self.sapling_nullifiers,
|
||||
)
|
||||
.transaction(
|
||||
move |(
|
||||
|
|
@ -229,6 +231,8 @@ impl FinalizedState {
|
|||
block_by_height,
|
||||
utxo_by_outpoint,
|
||||
tx_by_hash,
|
||||
sprout_nullifiers,
|
||||
sapling_nullifiers,
|
||||
)| {
|
||||
// TODO: check highest entry of hash_by_height as in RFC
|
||||
|
||||
|
|
@ -248,9 +252,14 @@ impl FinalizedState {
|
|||
|
||||
utxo_by_outpoint.zs_insert(outpoint, output)?;
|
||||
}
|
||||
|
||||
for sprout_nullifier in transaction.sprout_nullifiers() {
|
||||
sprout_nullifiers.zs_insert(sprout_nullifier, ())?;
|
||||
}
|
||||
for sapling_nullifier in transaction.sapling_nullifiers() {
|
||||
sapling_nullifiers.zs_insert(sapling_nullifier, ())?;
|
||||
}
|
||||
}
|
||||
// sprout_nullifiers
|
||||
// sapling_nullifiers
|
||||
|
||||
// for some reason type inference fails here
|
||||
Ok::<_, sled::transaction::ConflictableTransactionError>(hash)
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ use std::{convert::TryInto, sync::Arc};
|
|||
use zebra_chain::{
|
||||
block,
|
||||
block::Block,
|
||||
sapling,
|
||||
serialization::{ZcashDeserialize, ZcashSerialize},
|
||||
transaction,
|
||||
sprout, transaction,
|
||||
transaction::Transaction,
|
||||
transparent,
|
||||
};
|
||||
|
|
@ -89,6 +90,42 @@ impl IntoSled for block::Hash {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoSled for &sprout::Nullifier {
|
||||
type Bytes = [u8; 32];
|
||||
|
||||
fn as_bytes(&self) -> Self::Bytes {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn into_ivec(self) -> sled::IVec {
|
||||
self.as_bytes().as_ref().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoSled for &sapling::Nullifier {
|
||||
type Bytes = [u8; 32];
|
||||
|
||||
fn as_bytes(&self) -> Self::Bytes {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn into_ivec(self) -> sled::IVec {
|
||||
self.as_bytes().as_ref().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoSled for () {
|
||||
type Bytes = [u8; 0];
|
||||
|
||||
fn as_bytes(&self) -> Self::Bytes {
|
||||
[]
|
||||
}
|
||||
|
||||
fn into_ivec(self) -> sled::IVec {
|
||||
sled::IVec::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSled for block::Hash {
|
||||
fn from_ivec(bytes: sled::IVec) -> Result<Self, BoxError> {
|
||||
let array = bytes.as_ref().try_into().unwrap();
|
||||
|
|
|
|||
Loading…
Reference in New Issue