From 55e0c661a11585c8afd7d59251d3ad45f194c5e4 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Mon, 24 Dec 2018 18:24:12 +0300 Subject: [PATCH] refactor nullifier tag to epoch tag --- db/src/block_chain_db.rs | 10 +++++----- db/src/kv/memorydb.rs | 14 +++++++------- db/src/kv/transaction.rs | 10 +++++----- storage/src/commitments.rs | 12 ++++++++++++ storage/src/lib.rs | 14 +++++++++++++- storage/src/nullifier.rs | 23 ++++++----------------- verification/src/accept_transaction.rs | 6 +++--- 7 files changed, 51 insertions(+), 38 deletions(-) create mode 100644 storage/src/commitments.rs diff --git a/db/src/block_chain_db.rs b/db/src/block_chain_db.rs index 3098125a..854f4262 100644 --- a/db/src/block_chain_db.rs +++ b/db/src/block_chain_db.rs @@ -25,7 +25,7 @@ use storage::{ BlockRef, Error, BlockHeaderProvider, BlockProvider, BlockOrigin, TransactionMeta, IndexedBlockProvider, TransactionMetaProvider, TransactionProvider, TransactionOutputProvider, BlockChain, Store, SideChainOrigin, ForkChain, Forkable, CanonStore, ConfigStore, BestBlock, NullifierTracker, Nullifier, - NullifierTag, + EpochTag, }; const KEY_BEST_BLOCK_NUMBER: &'static str = "best_block_number"; @@ -293,7 +293,7 @@ impl BlockChainDatabase where T: KeyValueDatabase { for js_descriptor in js.descriptions.iter() { for nullifier in &js_descriptor.nullifiers[..] { let nullifier_key = Nullifier::new( - NullifierTag::Sprout, + EpochTag::Sprout, H256::from(&nullifier[..]) ); if self.contains_nullifier(nullifier_key) { @@ -308,7 +308,7 @@ impl BlockChainDatabase where T: KeyValueDatabase { if let Some(ref sapling) = tx.raw.sapling { for spend in &sapling.spends { let nullifier_key = Nullifier::new( - NullifierTag::Sapling, + EpochTag::Sapling, H256::from(&spend.nullifier[..]) ); if self.contains_nullifier(nullifier_key) { @@ -379,7 +379,7 @@ impl BlockChainDatabase where T: KeyValueDatabase { for js_descriptor in js.descriptions.iter() { for nullifier in &js_descriptor.nullifiers[..] { let nullifier_key = Nullifier::new( - NullifierTag::Sprout, + EpochTag::Sprout, H256::from(&nullifier[..]) ); if !self.contains_nullifier(nullifier_key) { @@ -394,7 +394,7 @@ impl BlockChainDatabase where T: KeyValueDatabase { if let Some(ref sapling) = tx.raw.sapling { for spend in &sapling.spends { let nullifier_key = Nullifier::new( - NullifierTag::Sapling, + EpochTag::Sapling, H256::from(&spend.nullifier[..]) ); if !self.contains_nullifier(nullifier_key) { diff --git a/db/src/kv/memorydb.rs b/db/src/kv/memorydb.rs index 85cfb74f..29d8f19d 100644 --- a/db/src/kv/memorydb.rs +++ b/db/src/kv/memorydb.rs @@ -7,7 +7,7 @@ use bytes::Bytes; use ser::List; use chain::{Transaction as ChainTransaction, BlockHeader}; use kv::{Transaction, Key, KeyState, Operation, Value, KeyValueDatabase, KeyValue}; -use storage::{TransactionMeta, NullifierTag}; +use storage::{TransactionMeta, EpochTag}; #[derive(Default, Debug)] struct InnerDatabase { @@ -84,8 +84,8 @@ impl KeyValueDatabase for MemoryDatabase { KeyValue::BlockNumber(key, value) => { db.block_number.insert(key, KeyState::Insert(value)); }, KeyValue::Configuration(key, value) => { db.configuration.insert(key, KeyState::Insert(value)); }, KeyValue::Nullifier(key) => match key.tag() { - NullifierTag::Sprout => { db.sprout_nullifiers.insert(*key.hash(), KeyState::Insert(())); }, - NullifierTag::Sapling => { db.sapling_nullifiers.insert(*key.hash(), KeyState::Insert(())); }, + EpochTag::Sprout => { db.sprout_nullifiers.insert(*key.hash(), KeyState::Insert(())); }, + EpochTag::Sapling => { db.sapling_nullifiers.insert(*key.hash(), KeyState::Insert(())); }, }, }, Operation::Delete(delete) => match delete { @@ -98,8 +98,8 @@ impl KeyValueDatabase for MemoryDatabase { Key::BlockNumber(key) => { db.block_number.insert(key, KeyState::Delete); } Key::Configuration(key) => { db.configuration.insert(key, KeyState::Delete); } Key::Nullifier(key) => match key.tag() { - NullifierTag::Sprout => { db.sprout_nullifiers.insert(*key.hash(), KeyState::Delete); }, - NullifierTag::Sapling => { db.sapling_nullifiers.insert(*key.hash(), KeyState::Delete); }, + EpochTag::Sprout => { db.sprout_nullifiers.insert(*key.hash(), KeyState::Delete); }, + EpochTag::Sapling => { db.sapling_nullifiers.insert(*key.hash(), KeyState::Delete); }, }, }, } @@ -119,8 +119,8 @@ impl KeyValueDatabase for MemoryDatabase { Key::BlockNumber(ref key) => db.block_number.get(key).cloned().unwrap_or_default().map(Value::BlockNumber), Key::Configuration(ref key) => db.configuration.get(key).cloned().unwrap_or_default().map(Value::Configuration), Key::Nullifier(ref key) => match key.tag() { - NullifierTag::Sprout => db.sprout_nullifiers.get(key.hash()).cloned().unwrap_or_default().map(|_| Value::Empty), - NullifierTag::Sapling => db.sapling_nullifiers.get(key.hash()).cloned().unwrap_or_default().map(|_| Value::Empty), + EpochTag::Sprout => db.sprout_nullifiers.get(key.hash()).cloned().unwrap_or_default().map(|_| Value::Empty), + EpochTag::Sapling => db.sapling_nullifiers.get(key.hash()).cloned().unwrap_or_default().map(|_| Value::Empty), } }; diff --git a/db/src/kv/transaction.rs b/db/src/kv/transaction.rs index 527640fa..1aea1969 100644 --- a/db/src/kv/transaction.rs +++ b/db/src/kv/transaction.rs @@ -2,7 +2,7 @@ use bytes::Bytes; use hash::H256; use ser::{serialize, List, deserialize}; use chain::{Transaction as ChainTransaction, BlockHeader}; -use storage::{TransactionMeta, Nullifier, NullifierTag}; +use storage::{TransactionMeta, Nullifier, EpochTag}; pub const COL_COUNT: u32 = 16; pub const COL_META: u32 = 0; @@ -233,8 +233,8 @@ impl<'a> From<&'a KeyValue> for RawKeyValue { KeyValue::Transaction(ref key, ref value) => (COL_TRANSACTIONS, serialize(key), serialize(value)), KeyValue::TransactionMeta(ref key, ref value) => (COL_TRANSACTIONS_META, serialize(key), serialize(value)), KeyValue::Nullifier(ref key) => match key.tag() { - NullifierTag::Sprout => (COL_SPROUT_NULLIFIERS, serialize(key.hash()), Bytes::new()), - NullifierTag::Sapling => (COL_SAPLING_NULLIFIERS, serialize(key.hash()), Bytes::new()), + EpochTag::Sprout => (COL_SPROUT_NULLIFIERS, serialize(key.hash()), Bytes::new()), + EpochTag::Sapling => (COL_SAPLING_NULLIFIERS, serialize(key.hash()), Bytes::new()), }, KeyValue::BlockNumber(ref key, ref value) => (COL_BLOCK_NUMBERS, serialize(key), serialize(value)), KeyValue::Configuration(ref key, ref value) => (COL_CONFIGURATION, serialize(key), serialize(value)), @@ -272,8 +272,8 @@ impl<'a> From<&'a Key> for RawKey { Key::Transaction(ref key) => (COL_TRANSACTIONS, serialize(key)), Key::TransactionMeta(ref key) => (COL_TRANSACTIONS_META, serialize(key)), Key::Nullifier(ref key) => match key.tag() { - NullifierTag::Sprout => (COL_SPROUT_NULLIFIERS, serialize(key.hash())), - NullifierTag::Sapling => (COL_SAPLING_NULLIFIERS, serialize(key.hash())), + EpochTag::Sprout => (COL_SPROUT_NULLIFIERS, serialize(key.hash())), + EpochTag::Sapling => (COL_SAPLING_NULLIFIERS, serialize(key.hash())), }, Key::BlockNumber(ref key) => (COL_BLOCK_NUMBERS, serialize(key)), Key::Configuration(ref key) => (COL_CONFIGURATION, serialize(key)), diff --git a/storage/src/commitments.rs b/storage/src/commitments.rs new file mode 100644 index 00000000..1faf65a1 --- /dev/null +++ b/storage/src/commitments.rs @@ -0,0 +1,12 @@ +use EpochTag; +use hash::H256; + +/// Trait to query sequence of blockchain commitments; +pub trait CommitmentProvider : Sync { + /// Total amount of stored commitments + fn commitments_count(&self, tag: EpochTag) -> u64; + /// Commitment at given position + fn commitment_at(&self, index: u64, tag: EpochTag) -> H256; + /// Root of all stored commitments + fn commitments_merkle_root(&self, tag: EpochTag) -> H256; +} diff --git a/storage/src/lib.rs b/storage/src/lib.rs index e063ce12..ef2e0e3a 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -36,4 +36,16 @@ pub use error::Error; pub use store::{AsSubstore, Store, SharedStore, CanonStore, ConfigStore}; pub use transaction_meta::TransactionMeta; pub use transaction_provider::{TransactionProvider, TransactionOutputProvider, TransactionMetaProvider}; -pub use nullifier::{Nullifier, NullifierTracker, Tag as NullifierTag}; +pub use nullifier::{Nullifier, NullifierTracker}; + +/// Epoch tag. +/// +/// Sprout and Sapling nullifiers/commitments are considered disjoint, +/// even if they have the same bit pattern. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum EpochTag { + /// Sprout nullifier. + Sprout, + /// Sapling nullifier. + Sapling, +} diff --git a/storage/src/nullifier.rs b/storage/src/nullifier.rs index 586ff84e..7dc0123b 100644 --- a/storage/src/nullifier.rs +++ b/storage/src/nullifier.rs @@ -1,21 +1,10 @@ use hash::H256; - -/// Nullifier epoch (tag). -/// -/// Sprout and Sapling nullifiers are considered disjoint, -/// even if they have the same bit pattern. -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum Tag { - /// Sprout nullifier. - Sprout, - /// Sapling nullifier. - Sapling, -} +use EpochTag; /// Nullifier. #[derive(Debug, Clone, Copy, PartialEq)] pub struct Nullifier { - tag: Tag, + tag: EpochTag, hash: H256, } @@ -26,7 +15,7 @@ pub trait NullifierTracker : Sync { impl Nullifier { /// New nullifer. - pub fn new(tag: Tag, hash: H256) -> Self { + pub fn new(tag: EpochTag, hash: H256) -> Self { Nullifier { tag: tag, hash: hash, @@ -34,7 +23,7 @@ impl Nullifier { } /// Nullifer tag - pub fn tag(&self) -> Tag { + pub fn tag(&self) -> EpochTag { self.tag } @@ -44,8 +33,8 @@ impl Nullifier { } } -impl From<(Tag, H256)> for Nullifier { - fn from(tuple: (Tag, H256)) -> Self { +impl From<(EpochTag, H256)> for Nullifier { + fn from(tuple: (EpochTag, H256)) -> Self { Nullifier { tag: tuple.0, hash: tuple.1, diff --git a/verification/src/accept_transaction.rs b/verification/src/accept_transaction.rs index 41a7973d..5d619210 100644 --- a/verification/src/accept_transaction.rs +++ b/verification/src/accept_transaction.rs @@ -1,6 +1,6 @@ use ser::Serializable; use crypto::Groth16VerifyingKey; -use storage::{TransactionMetaProvider, TransactionOutputProvider, Nullifier, NullifierTag, NullifierTracker}; +use storage::{TransactionMetaProvider, TransactionOutputProvider, Nullifier, EpochTag, NullifierTracker}; use network::{ConsensusParams}; use script::{Script, verify_script, VerificationFlags, TransactionSignatureChecker, TransactionInputSigner, SighashBase}; use duplex_store::DuplexTransactionOutputProvider; @@ -615,7 +615,7 @@ impl<'a> JoinSplitNullifiers<'a> { if let Some(ref join_split) = self.transaction.raw.join_split { for description in join_split.descriptions.iter() { for nullifier in &description.nullifiers[..] { - let check = Nullifier::new(NullifierTag::Sprout, H256::from(&nullifier[..])); + let check = Nullifier::new(EpochTag::Sprout, H256::from(&nullifier[..])); if self.tracker.contains_nullifier(check) { return Err(TransactionError::JoinSplitDeclared(*check.hash())) @@ -664,7 +664,7 @@ impl<'a> SaplingNullifiers<'a> { fn check(&self) -> Result<(), TransactionError> { if let Some(ref sapling) = self.transaction.raw.sapling { for spend in &sapling.spends { - let check = Nullifier::new(NullifierTag::Sapling, H256::from(&spend.nullifier[..])); + let check = Nullifier::new(EpochTag::Sapling, H256::from(&spend.nullifier[..])); if self.tracker.contains_nullifier(check) { return Err(TransactionError::SaplingDeclared(*check.hash()))