add logic to the db

This commit is contained in:
NikVolf 2019-01-17 13:36:52 +03:00
parent c833d392c4
commit 4ac862f51c
4 changed files with 56 additions and 16 deletions

View File

@ -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,
EpochTag,
EpochTag, RegularTreeState, TreeStateProvider,
};
const KEY_BEST_BLOCK_NUMBER: &'static str = "best_block_number";
@ -206,20 +206,41 @@ impl<T> BlockChainDatabase<T> where T: KeyValueDatabase {
return Ok(())
}
let parent_hash = block.header.raw.previous_header_hash.clone();
if !self.contains_block(parent_hash.clone().into()) && !parent_hash.is_zero() {
let parent_hash = block.header.raw.previous_header_hash;
if !self.contains_block(parent_hash.into()) && !parent_hash.is_zero() {
return Err(Error::UnknownParent);
}
let mut tree_state = if parent_hash.is_zero() {
RegularTreeState::new()
} else {
self.tree_at_block(&parent_hash)
.expect(&format!("Corrupted database - no root for block {}", parent_hash))
};
let mut update = DBTransaction::new();
update.insert(KeyValue::BlockHeader(block.hash().clone(), block.header.raw));
let tx_hashes = block.transactions.iter().map(|tx| tx.hash.clone()).collect::<Vec<_>>();
update.insert(KeyValue::BlockTransactions(block.header.hash.clone(), List::from(tx_hashes)));
update.insert(KeyValue::BlockHeader(*block.hash(), block.header.raw));
let tx_hashes = block.transactions.iter().map(|tx| tx.hash).collect::<Vec<_>>();
update.insert(KeyValue::BlockTransactions(block.header.hash, List::from(tx_hashes)));
for tx in block.transactions.into_iter() {
if let Some(ref js) = tx.raw.join_split {
for js_descriptor in js.descriptions.iter() {
for commitment in &js_descriptor.commitments[..] {
tree_state.append(H256::from(&commitment[..]))
.expect("Appending to a full commitment tree in the block insertion")
}
}
}
update.insert(KeyValue::Transaction(tx.hash, tx.raw));
}
let tree_root = tree_state.root();
update.insert(KeyValue::BlockRoot(block.header.hash, tree_root));
update.insert(KeyValue::TreeState(tree_root, tree_state));
self.db.write(update).map_err(Error::DatabaseError)
}
@ -577,6 +598,16 @@ impl<T> NullifierTracker for BlockChainDatabase<T> where T: KeyValueDatabase {
}
}
impl<T> TreeStateProvider for BlockChainDatabase<T> where T: KeyValueDatabase {
fn tree_at(&self, root: &H256) -> Option<RegularTreeState> {
self.get(Key::TreeRoot(*root)).and_then(Value::as_tree_state)
}
fn block_root(&self, block_hash: &H256) -> Option<H256> {
self.get(Key::BlockRoot(*block_hash)).and_then(Value::as_block_root)
}
}
impl<T> BlockChain for BlockChainDatabase<T> where T: KeyValueDatabase {
fn insert(&self, block: IndexedBlock) -> Result<(), Error> {
BlockChainDatabase::insert(self, block)

View File

@ -141,6 +141,20 @@ impl Value {
_ => None,
}
}
pub fn as_tree_state(self) -> Option<RegularTreeState> {
match self {
Value::TreeState(tree) => Some(tree),
_ => None,
}
}
pub fn as_block_root(self) -> Option<H256> {
match self {
Value::TreeRoot(v) => Some(v),
_ => None,
}
}
}
#[derive(Debug, Clone)]

View File

@ -147,6 +147,10 @@ impl<D: Dim> TreeState<D> {
root
}
pub fn empty_root() -> H256 {
EMPTY_ROOTS[D::HEIGHT]
}
}
pub type RegularTreeState = TreeState<H32>;

View File

@ -3,16 +3,7 @@ use bytes::Bytes;
use RegularTreeState;
pub trait TreeStateProvider {
fn tree_bytes_at(&self, root: &H256) -> Option<Bytes>;
fn tree_at(&self, root: &H256) -> Option<RegularTreeState> {
self.tree_bytes_at(root)
.map(
|bytes| serialization::Reader::new(&bytes[..])
.read::<RegularTreeState>()
.expect("Corrupted database: wrong tree state format!")
)
}
fn tree_at(&self, root: &H256) -> Option<RegularTreeState>;
fn block_root(&self, block_hash: &H256) -> Option<H256>;