do not store sapling ct root aside from the header

This commit is contained in:
Svyatoslav Nikolsky 2019-03-08 08:52:05 +03:00
parent 075de98f92
commit 8c38105a2a
4 changed files with 23 additions and 53 deletions

View File

@ -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<CacheDatabase<AutoFlushingOverlayDatabase<DiskDatabase>>
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<T> BlockChainDatabase<T> 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::<Vec<_>>();
@ -299,12 +297,10 @@ impl<T> BlockChainDatabase<T> 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<T> TreeStateProvider for BlockChainDatabase<T> where T: KeyValueDatabase {
}
fn sprout_block_root(&self, block_hash: &H256) -> Option<H256> {
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<H256> {
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)
}
}

View File

@ -14,7 +14,6 @@ struct InnerDatabase {
meta: HashMap<&'static str, KeyState<Bytes>>,
block_hash: HashMap<u32, KeyState<H256>>,
sprout_block_root: HashMap<H256, KeyState<H256>>,
sapling_block_root: HashMap<H256, KeyState<H256>>,
block_header: HashMap<H256, KeyState<BlockHeader>>,
block_transactions: HashMap<H256, KeyState<List<H256>>>,
transaction: HashMap<H256, KeyState<ChainTransaction>>,
@ -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)

View File

@ -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,
};

View File

@ -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<H256> {
pub fn as_sprout_block_root(self) -> Option<H256> {
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)),
};