add logic to the db
This commit is contained in:
parent
c833d392c4
commit
4ac862f51c
|
@ -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)
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -147,6 +147,10 @@ impl<D: Dim> TreeState<D> {
|
|||
|
||||
root
|
||||
}
|
||||
|
||||
pub fn empty_root() -> H256 {
|
||||
EMPTY_ROOTS[D::HEIGHT]
|
||||
}
|
||||
}
|
||||
|
||||
pub type RegularTreeState = TreeState<H32>;
|
||||
|
|
|
@ -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>;
|
||||
|
||||
|
|
Loading…
Reference in New Issue