From 8c38105a2a7b9944ec8b6b85ecb08b5b7771dc62 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 8 Mar 2019 08:52:05 +0300 Subject: [PATCH] do not store sapling ct root aside from the header --- db/src/block_chain_db.rs | 19 ++++++++----------- db/src/kv/memorydb.rs | 28 ++++------------------------ db/src/kv/mod.rs | 2 +- db/src/kv/transaction.rs | 27 ++++++++++----------------- 4 files changed, 23 insertions(+), 53 deletions(-) diff --git a/db/src/block_chain_db.rs b/db/src/block_chain_db.rs index f0119469..54c58c49 100644 --- a/db/src/block_chain_db.rs +++ b/db/src/block_chain_db.rs @@ -19,7 +19,7 @@ use kv::{ use kv::{ COL_COUNT, COL_BLOCK_HASHES, COL_BLOCK_HEADERS, COL_BLOCK_TRANSACTIONS, COL_TRANSACTIONS, COL_TRANSACTIONS_META, COL_BLOCK_NUMBERS, COL_SAPLING_NULLIFIERS, COL_SPROUT_NULLIFIERS, - COL_SPROUT_BLOCK_ROOTS, COL_SAPLING_BLOCK_ROOTS, COL_TREE_STATES, + COL_SPROUT_BLOCK_ROOTS, COL_TREE_STATES, }; use storage::{ BlockRef, Error, BlockHeaderProvider, BlockProvider, BlockOrigin, TransactionMeta, IndexedBlockProvider, @@ -62,8 +62,7 @@ mod cache { pub const CACHE_SPROUT_NULLIFIERS: u32 = 5; pub const CACHE_SAPLING_NULLIFIERS: u32 = 5; pub const CACHE_TREE_STATES: u32 = 10; - pub const CACHE_SPROUT_BLOCK_ROOTS: u32 = 2; - pub const CACHE_SAPLING_BLOCK_ROOTS: u32 = 3; + pub const CACHE_SPROUT_BLOCK_ROOTS: u32 = 5; pub fn set(cfg: &mut ::kv::DatabaseConfig, total: usize, col: u32, distr: u32) { cfg.set_cache(Some(col), (total as f32 * distr as f32 / 100f32).round() as usize) @@ -81,8 +80,7 @@ mod cache { CACHE_SPROUT_NULLIFIERS + CACHE_SAPLING_NULLIFIERS + CACHE_TREE_STATES + - CACHE_SPROUT_BLOCK_ROOTS + - CACHE_SAPLING_BLOCK_ROOTS + CACHE_SPROUT_BLOCK_ROOTS ); } } @@ -106,7 +104,6 @@ impl BlockChainDatabase> cache::set(&mut cfg, total_cache, COL_TREE_STATES, cache::CACHE_TREE_STATES); cache::set(&mut cfg, total_cache, COL_SPROUT_BLOCK_ROOTS, cache::CACHE_SPROUT_BLOCK_ROOTS); - cache::set(&mut cfg, total_cache, COL_SAPLING_BLOCK_ROOTS, cache::CACHE_SAPLING_BLOCK_ROOTS); cfg.bloom_filters.insert(Some(COL_TRANSACTIONS_META), 32); @@ -268,6 +265,7 @@ impl BlockChainDatabase where T: KeyValueDatabase { .expect(&format!("Corrupted database - no sapling root for block {}", parent_hash)) }; + let sapling_tree_root = block.header.raw.final_sapling_root; let mut update = DBTransaction::new(); update.insert(KeyValue::BlockHeader(*block.hash(), block.header.raw)); let tx_hashes = block.transactions.iter().map(|tx| tx.hash).collect::>(); @@ -299,12 +297,10 @@ impl BlockChainDatabase where T: KeyValueDatabase { } let sprout_tree_root = sprout_tree_state.root(); - update.insert(KeyValue::BlockRoot(EpochRef::new(EpochTag::Sprout, block.header.hash), sprout_tree_root)); + update.insert(KeyValue::SproutBlockRoot(block.header.hash, sprout_tree_root)); update.insert(KeyValue::SproutTreeState(sprout_tree_root, sprout_tree_state)); // TODO: possible optimization is not to store sapling trees until sapling is activated - let sapling_tree_root = sapling_tree_state.root(); - update.insert(KeyValue::BlockRoot(EpochRef::new(EpochTag::Sapling, block.header.hash), sapling_tree_root)); update.insert(KeyValue::SaplingTreeState(sapling_tree_root, sapling_tree_state)); self.db.write(update).map_err(Error::DatabaseError) @@ -674,11 +670,12 @@ impl TreeStateProvider for BlockChainDatabase where T: KeyValueDatabase { } fn sprout_block_root(&self, block_hash: &H256) -> Option { - self.get(Key::BlockRoot(EpochRef::new(EpochTag::Sprout, *block_hash))).and_then(Value::as_block_root) + self.get(Key::SproutBlockRoot(*block_hash)).and_then(Value::as_sprout_block_root) } fn sapling_block_root(&self, block_hash: &H256) -> Option { - self.get(Key::BlockRoot(EpochRef::new(EpochTag::Sapling, *block_hash))).and_then(Value::as_block_root) + self.block_header(BlockRef::Hash(*block_hash)) + .map(|header| header.final_sapling_root) } } diff --git a/db/src/kv/memorydb.rs b/db/src/kv/memorydb.rs index 859d08b2..05619603 100644 --- a/db/src/kv/memorydb.rs +++ b/db/src/kv/memorydb.rs @@ -14,7 +14,6 @@ struct InnerDatabase { meta: HashMap<&'static str, KeyState>, block_hash: HashMap>, sprout_block_root: HashMap>, - sapling_block_root: HashMap>, block_header: HashMap>, block_transactions: HashMap>>, transaction: HashMap>, @@ -82,10 +81,7 @@ impl MemoryDatabase { |k| Key::TreeRoot(EpochRef::new(EpochTag::Sprout, k)))); let sprout_block_root = replace(&mut db.sprout_block_root, HashMap::default()).into_iter() - .flat_map(|(key, state)| - state.into_operation(key, - |k, v| KeyValue::BlockRoot(EpochRef::new(EpochTag::Sprout, k), v), - |k| Key::BlockRoot(EpochRef::new(EpochTag::Sprout, k)))); + .flat_map(|(key, state)| state.into_operation(key, KeyValue::SproutBlockRoot, Key::SproutBlockRoot)); let sapling_tree_state = replace(&mut db.sapling_tree_state, HashMap::default()).into_iter() .flat_map(|(key, state)| @@ -93,12 +89,6 @@ impl MemoryDatabase { KeyValue::SaplingTreeState, |k| Key::TreeRoot(EpochRef::new(EpochTag::Sapling, k)))); - let sapling_block_root = replace(&mut db.sapling_block_root, HashMap::default()).into_iter() - .flat_map(|(key, state)| - state.into_operation(key, - |k, v| KeyValue::BlockRoot(EpochRef::new(EpochTag::Sapling, k), v), - |k| Key::BlockRoot(EpochRef::new(EpochTag::Sprout, k)))); - Transaction { operations: meta .chain(block_hash) @@ -111,7 +101,6 @@ impl MemoryDatabase { .chain(sprout_tree_state) .chain(sapling_tree_state) .chain(sprout_block_root) - .chain(sapling_block_root) .chain(sprout_nullifiers) .chain(sapling_nullifiers) .collect() @@ -139,10 +128,7 @@ impl KeyValueDatabase for MemoryDatabase { }, KeyValue::SproutTreeState(key, value) => { db.sprout_tree_state.insert(key, KeyState::Insert(value)); }, KeyValue::SaplingTreeState(key, value) => { db.sapling_tree_state.insert(key, KeyState::Insert(value)); }, - KeyValue::BlockRoot(key, value) => match key.epoch() { - EpochTag::Sprout => { db.sprout_block_root.insert(*key.hash(), KeyState::Insert(value)); }, - EpochTag::Sapling => { db.sapling_block_root.insert(*key.hash(), KeyState::Insert(value)); }, - }, + KeyValue::SproutBlockRoot(key, value) => { db.sprout_block_root.insert(key, KeyState::Insert(value)); }, }, Operation::Delete(delete) => match delete { Key::Meta(key) => { db.meta.insert(key, KeyState::Delete); } @@ -161,10 +147,7 @@ impl KeyValueDatabase for MemoryDatabase { EpochTag::Sprout => { db.sprout_tree_state.insert(*key.hash(), KeyState::Delete); }, EpochTag::Sapling => { db.sapling_tree_state.insert(*key.hash(), KeyState::Delete); }, }, - Key::BlockRoot(key) => match key.epoch() { - EpochTag::Sprout => { db.sprout_block_root.insert(*key.hash(), KeyState::Delete); }, - EpochTag::Sapling => { db.sapling_block_root.insert(*key.hash(), KeyState::Delete); }, - }, + Key::SproutBlockRoot(key) => { db.sprout_block_root.insert(key, KeyState::Delete); }, }, } } @@ -190,10 +173,7 @@ impl KeyValueDatabase for MemoryDatabase { EpochTag::Sprout => db.sprout_tree_state.get(key.hash()).cloned().unwrap_or_default().map(Value::SproutTreeState), EpochTag::Sapling => db.sapling_tree_state.get(key.hash()).cloned().unwrap_or_default().map(Value::SaplingTreeState), }, - Key::BlockRoot(ref key) => match key.epoch() { - EpochTag::Sprout => db.sprout_block_root.get(key.hash()).cloned().unwrap_or_default().map(Value::TreeRoot), - EpochTag::Sapling => db.sapling_block_root.get(key.hash()).cloned().unwrap_or_default().map(Value::TreeRoot), - }, + Key::SproutBlockRoot(ref key) => db.sprout_block_root.get(key).cloned().unwrap_or_default().map(Value::SproutTreeRoot), }; Ok(result) diff --git a/db/src/kv/mod.rs b/db/src/kv/mod.rs index 20d4dd09..eb9b2eee 100644 --- a/db/src/kv/mod.rs +++ b/db/src/kv/mod.rs @@ -15,5 +15,5 @@ pub use self::transaction::{ Key, Value, KeyValue, RawKeyValue, RawKey, COL_COUNT, COL_META, COL_BLOCK_HASHES, COL_BLOCK_HEADERS, COL_BLOCK_TRANSACTIONS, COL_TRANSACTIONS, COL_TRANSACTIONS_META, COL_BLOCK_NUMBERS, COL_SAPLING_NULLIFIERS, - COL_SPROUT_NULLIFIERS, COL_TREE_STATES, COL_SPROUT_BLOCK_ROOTS, COL_SAPLING_BLOCK_ROOTS, + COL_SPROUT_NULLIFIERS, COL_TREE_STATES, COL_SPROUT_BLOCK_ROOTS, }; diff --git a/db/src/kv/transaction.rs b/db/src/kv/transaction.rs index b013dcb2..dad3d66c 100644 --- a/db/src/kv/transaction.rs +++ b/db/src/kv/transaction.rs @@ -15,9 +15,8 @@ pub const COL_BLOCK_NUMBERS: u32 = 6; pub const COL_SPROUT_NULLIFIERS: u32 = 7; pub const COL_SAPLING_NULLIFIERS: u32 = 8; pub const COL_SPROUT_BLOCK_ROOTS: u32 = 9; -pub const COL_SAPLING_BLOCK_ROOTS: u32 = 10; -pub const COL_TREE_STATES: u32 = 11; -pub const COL_CONFIGURATION: u32 = 12; +pub const COL_TREE_STATES: u32 = 10; +pub const COL_CONFIGURATION: u32 = 11; #[derive(Debug)] pub enum Operation { @@ -38,7 +37,7 @@ pub enum KeyValue { Nullifier(EpochRef), SproutTreeState(H256, SproutTreeState), SaplingTreeState(H256, SaplingTreeState), - BlockRoot(EpochRef, H256), + SproutBlockRoot(H256, H256), } #[derive(Debug)] @@ -53,7 +52,7 @@ pub enum Key { Configuration(&'static str), Nullifier(EpochRef), TreeRoot(EpochRef), - BlockRoot(EpochRef), + SproutBlockRoot(H256), } #[derive(Debug, Clone)] @@ -69,7 +68,7 @@ pub enum Value { Empty, SproutTreeState(SproutTreeState), SaplingTreeState(SaplingTreeState), - TreeRoot(H256), + SproutTreeRoot(H256), } impl Value { @@ -88,7 +87,7 @@ impl Value { EpochTag::Sprout => deserialize(bytes).map(Value::SproutTreeState), EpochTag::Sapling => deserialize(bytes).map(Value::SaplingTreeState), }, - Key::BlockRoot(_) => deserialize(bytes).map(Value::TreeRoot), + Key::SproutBlockRoot(_) => deserialize(bytes).map(Value::SproutTreeRoot), }.map_err(|e| format!("{:?}", e)) } @@ -162,9 +161,9 @@ impl Value { } } - pub fn as_block_root(self) -> Option { + pub fn as_sprout_block_root(self) -> Option { match self { - Value::TreeRoot(v) => Some(v), + Value::SproutTreeRoot(v) => Some(v), _ => None, } } @@ -276,10 +275,7 @@ impl<'a> From<&'a KeyValue> for RawKeyValue { KeyValue::BlockNumber(ref key, ref value) => (COL_BLOCK_NUMBERS, serialize(key), serialize(value)), KeyValue::SproutTreeState(ref key, ref value) => (COL_TREE_STATES, serialize(key), serialize(value)), KeyValue::SaplingTreeState(ref key, ref value) => (COL_TREE_STATES, serialize(key), serialize(value)), - KeyValue::BlockRoot(ref key, ref value) => match key.epoch() { - EpochTag::Sprout => (COL_SPROUT_BLOCK_ROOTS, serialize(key.hash()), serialize(value)), - EpochTag::Sapling => (COL_SAPLING_BLOCK_ROOTS, serialize(key.hash()), serialize(value)), - }, + KeyValue::SproutBlockRoot(ref key, ref value) => (COL_SPROUT_BLOCK_ROOTS, serialize(key), serialize(value)), KeyValue::Configuration(ref key, ref value) => (COL_CONFIGURATION, serialize(key), serialize(value)), }; @@ -320,10 +316,7 @@ impl<'a> From<&'a Key> for RawKey { }, Key::TreeRoot(ref key) => (COL_TREE_STATES, serialize(key.hash())), Key::BlockNumber(ref key) => (COL_BLOCK_NUMBERS, serialize(key)), - Key::BlockRoot(ref key) => match key.epoch() { - EpochTag::Sprout => (COL_SPROUT_BLOCK_ROOTS, serialize(key.hash())), - EpochTag::Sapling => (COL_SAPLING_BLOCK_ROOTS, serialize(key.hash())), - }, + Key::SproutBlockRoot(ref key) => (COL_SPROUT_BLOCK_ROOTS, serialize(key)), Key::Configuration(ref key) => (COL_CONFIGURATION, serialize(key)), };