Skip to content
This repository has been archived by the owner on Oct 14, 2022. It is now read-only.

Commit

Permalink
Added StateChain append condition
Browse files Browse the repository at this point in the history
  • Loading branch information
octavonce committed Jul 17, 2019
1 parent 81c7754 commit e797b7a
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/chain/Cargo.toml
Expand Up @@ -13,6 +13,7 @@ lru = "0.1.13"
rlp = "0.3.0"
parking_lot = "0.7.1"
hex = "0.3.2"
patricia-trie = "0.3.0"
account = { path = "../account" }
crypto = { path = "../crypto" }
events = { path = "../events" }
Expand Down
41 changes: 40 additions & 1 deletion src/chain/src/state_chain/block.rs
Expand Up @@ -38,6 +38,9 @@ use std::sync::Arc;
use std::net::SocketAddr;
use std::str;
use rlp::{Rlp, RlpStream};
use persistence::{Codec, BlakeDbHasher};
use patricia_trie::TrieDBMut;
use hashdb::HashDB;

lazy_static! {
/// Atomic reference count to state chain genesis block
Expand Down Expand Up @@ -147,7 +150,43 @@ impl Block for StateBlock {
Some(Box::new(fun))
}

fn append_condition(_block: Arc<StateBlock>, chain_state: Self::ChainState) -> Result<Self::ChainState, ChainErr> {
fn append_condition(block: Arc<StateBlock>, mut chain_state: Self::ChainState) -> Result<Self::ChainState, ChainErr> {
let pool_state = &mut chain_state.pool_state;

if block.epoch != pool_state.epoch {
return Err(ChainErr::BadAppendCondition);
}

// Validate and apply each event in the block
for event in block.events.iter().cloned() {
let node_id = event.node_id();

// TODO: Handle different errors
if pool_state.account_sent_by_validator(&node_id).is_err() {
return Err(ChainErr::BadAppendCondition);
}

let raw_root_hash = chain_state.db.retrieve(PersistentDb::ROOT_HASH_KEY).unwrap();
let mut root_hash_slice = [0; 32];

root_hash_slice.copy_from_slice(&raw_root_hash);

let mut root = Hash(root_hash_slice);

{
let mut trie = TrieDBMut::<BlakeDbHasher, Codec>::new(&mut chain_state.db, &mut root);

if event.validate_apply(&mut trie).is_err() {
return Err(ChainErr::BadAppendCondition);
}
}

let root = root.0.to_vec();

// Update root hash entry
chain_state.db.put(PersistentDb::ROOT_HASH_KEY, &root);
}

Ok(chain_state)
}

Expand Down
3 changes: 1 addition & 2 deletions src/crypto/src/hash.rs
Expand Up @@ -16,9 +16,8 @@
along with the Purple Library. If not, see <http://www.gnu.org/licenses/>.
*/

use blake2_rfc::blake2b::{blake2b, Blake2b};
use blake2_rfc::blake2b::blake2b;
use blake_hasher::BlakeHasher;
use byteorder::{LittleEndian, WriteBytesExt};
use crc32fast::Hasher as CrcHasher;
use hashdb::Hasher;
use quickcheck::Arbitrary;
Expand Down
7 changes: 7 additions & 0 deletions src/events/src/lib.rs
Expand Up @@ -50,6 +50,9 @@ use crypto::Hash;
use crypto::NodeId;
use std::hash::Hash as HashTrait;
use std::hash::Hasher;
use persistence::Codec;
use patricia_trie::TrieDBMut;
use persistence::BlakeDbHasher;

#[derive(Clone, Debug)]
pub enum Event {
Expand Down Expand Up @@ -84,6 +87,10 @@ impl HashTrait for Event {
}

impl Event {
pub fn validate_apply(&self, trie: &mut TrieDBMut<BlakeDbHasher, Codec>) -> Result<(), ()> {
unimplemented!();
}

pub fn stamp(&self) -> Stamp {
match *self {
Event::Heartbeat(ref event) => event.stamp.clone(),
Expand Down
10 changes: 9 additions & 1 deletion src/persistence/src/persistent_db.rs
Expand Up @@ -98,6 +98,8 @@ pub struct PersistentDb {
}

impl PersistentDb {
pub const ROOT_HASH_KEY: &'static [u8] = b"root_hash";

pub fn new(db_ref: Arc<DB>, cf_name: Option<&'static str>) -> PersistentDb {
if !is_initialized() {
panic!("Persistence module not initialized! Call `persistence::init()` before using anything");
Expand Down Expand Up @@ -203,7 +205,13 @@ impl PersistentDb {
Operation::Put(ref val) => Some(val.clone()),
Operation::Remove => None,
},
None => self.get_db(key),
None => match self.get_db(key) {
Some(res) => Some(res),
None => match key {
Self::ROOT_HASH_KEY => Some(Hash::NULL_RLP.0.to_vec()),
_ => None
}
},
}
} else {
let result = self.memory_db.get(key);
Expand Down

0 comments on commit e797b7a

Please sign in to comment.