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,
|
BlockRef, Error, BlockHeaderProvider, BlockProvider, BlockOrigin, TransactionMeta, IndexedBlockProvider,
|
||||||
TransactionMetaProvider, TransactionProvider, TransactionOutputProvider, BlockChain, Store,
|
TransactionMetaProvider, TransactionProvider, TransactionOutputProvider, BlockChain, Store,
|
||||||
SideChainOrigin, ForkChain, Forkable, CanonStore, ConfigStore, BestBlock, NullifierTracker, Nullifier,
|
SideChainOrigin, ForkChain, Forkable, CanonStore, ConfigStore, BestBlock, NullifierTracker, Nullifier,
|
||||||
EpochTag,
|
EpochTag, RegularTreeState, TreeStateProvider,
|
||||||
};
|
};
|
||||||
|
|
||||||
const KEY_BEST_BLOCK_NUMBER: &'static str = "best_block_number";
|
const KEY_BEST_BLOCK_NUMBER: &'static str = "best_block_number";
|
||||||
|
@ -206,20 +206,41 @@ impl<T> BlockChainDatabase<T> where T: KeyValueDatabase {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent_hash = block.header.raw.previous_header_hash.clone();
|
let parent_hash = block.header.raw.previous_header_hash;
|
||||||
if !self.contains_block(parent_hash.clone().into()) && !parent_hash.is_zero() {
|
if !self.contains_block(parent_hash.into()) && !parent_hash.is_zero() {
|
||||||
return Err(Error::UnknownParent);
|
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();
|
let mut update = DBTransaction::new();
|
||||||
update.insert(KeyValue::BlockHeader(block.hash().clone(), block.header.raw));
|
update.insert(KeyValue::BlockHeader(*block.hash(), block.header.raw));
|
||||||
let tx_hashes = block.transactions.iter().map(|tx| tx.hash.clone()).collect::<Vec<_>>();
|
let tx_hashes = block.transactions.iter().map(|tx| tx.hash).collect::<Vec<_>>();
|
||||||
update.insert(KeyValue::BlockTransactions(block.header.hash.clone(), List::from(tx_hashes)));
|
update.insert(KeyValue::BlockTransactions(block.header.hash, List::from(tx_hashes)));
|
||||||
|
|
||||||
for tx in block.transactions.into_iter() {
|
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));
|
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)
|
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 {
|
impl<T> BlockChain for BlockChainDatabase<T> where T: KeyValueDatabase {
|
||||||
fn insert(&self, block: IndexedBlock) -> Result<(), Error> {
|
fn insert(&self, block: IndexedBlock) -> Result<(), Error> {
|
||||||
BlockChainDatabase::insert(self, block)
|
BlockChainDatabase::insert(self, block)
|
||||||
|
|
|
@ -141,6 +141,20 @@ impl Value {
|
||||||
_ => None,
|
_ => 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)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -147,6 +147,10 @@ impl<D: Dim> TreeState<D> {
|
||||||
|
|
||||||
root
|
root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn empty_root() -> H256 {
|
||||||
|
EMPTY_ROOTS[D::HEIGHT]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type RegularTreeState = TreeState<H32>;
|
pub type RegularTreeState = TreeState<H32>;
|
||||||
|
|
|
@ -3,16 +3,7 @@ use bytes::Bytes;
|
||||||
use RegularTreeState;
|
use RegularTreeState;
|
||||||
|
|
||||||
pub trait TreeStateProvider {
|
pub trait TreeStateProvider {
|
||||||
fn tree_bytes_at(&self, root: &H256) -> Option<Bytes>;
|
fn tree_at(&self, root: &H256) -> Option<RegularTreeState>;
|
||||||
|
|
||||||
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 block_root(&self, block_hash: &H256) -> Option<H256>;
|
fn block_root(&self, block_hash: &H256) -> Option<H256>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue