Skip to content

Commit

Permalink
Update StateTree and implement cache (#108)
Browse files Browse the repository at this point in the history
* fix and implement cache on state tree

* constructor rename
  • Loading branch information
austinabell authored Dec 16, 2019
1 parent 4c9fbd8 commit c916eb4
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 5 deletions.
12 changes: 12 additions & 0 deletions vm/actor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ pub struct ActorState {
sequence: u64,
}

impl ActorState {
/// Constructor for actor state
pub fn new(code_id: CodeID, state: Cid, balance: BigUint, sequence: u64) -> Self {
Self {
code_id,
state,
balance,
sequence,
}
}
}

/// Actor trait which defines the common functionality of system Actors
pub trait Actor {
/// Returns Actor Cid
Expand Down
4 changes: 4 additions & 0 deletions vm/state_tree/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ edition = "2018"
actor = {path = "../actor"}
address = {path = "../address"}
vm = {path = "../../vm"}
cid = "0.3.1"

[dev-dependencies]
num-bigint = "0.2.3"
90 changes: 85 additions & 5 deletions vm/state_tree/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,89 @@
use actor::{ActorState, CodeID};
use actor::ActorState;
use address::Address;
use vm::TokenAmount;
use std::collections::HashMap;

pub trait StateTree {
fn get_actor_address(&self, n: CodeID) -> Address;
fn get_actor_state(&self, n: CodeID) -> ActorState;
fn balance(&self, a: Address) -> TokenAmount;
fn get_actor(&self, addr: Address) -> Option<ActorState>;
fn set_actor(&mut self, addr: Address, actor: ActorState) -> Result<(), String>;
}

struct HamtNode; // TODO
struct Store; // TODO
/// State tree implementation using hamt
pub struct HamtStateTree {
/// hamt root node
_root: HamtNode,
/// IPLD store
_store: Store,

actor_cache: HashMap<Address, ActorState>,
}

impl Default for HamtStateTree {
/// Constructor for a hamt state tree given an IPLD store
fn default() -> Self {
Self {
_root: HamtNode,
_store: Store,
actor_cache: HashMap::new(),
}
}
}

impl StateTree for HamtStateTree {
fn get_actor(&self, address: Address) -> Option<ActorState> {
// TODO resolve ID address

// Check cache for actor state
if let Some(addr) = self.actor_cache.get(&address) {
return Some(addr.clone());
}

// if state doesn't exist, find using hamt
// TODO
None
}
fn set_actor(&mut self, addr: Address, actor: ActorState) -> Result<(), String> {
// TODO resolve ID address

// Set actor state in cache
if let Some(act) = self.actor_cache.insert(addr, actor.clone()) {
if act == actor {
// New value is same as cached, no need to set in hamt
return Ok(());
}
}

// Set actor state in hamt
// TODO
Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;
use actor::{ActorState, CodeID};
use cid::{Cid, Codec, Version};
use num_bigint::BigUint;

#[test]
fn get_set_cache() {
let cid = Cid::new(Codec::DagProtobuf, Version::V1, &[0u8]);
let act_s = ActorState::new(CodeID::Account, cid.clone(), BigUint::default(), 1);
let act_a = ActorState::new(CodeID::Account, cid.clone(), BigUint::default(), 2);
let addr = Address::new_id(1).unwrap();
let mut tree = HamtStateTree::default();

// test address not in cache
assert_eq!(tree.get_actor(addr.clone()), None);
// test successful insert
assert_eq!(tree.set_actor(addr.clone(), act_s.clone()), Ok(()));
// test inserting with different data
assert_eq!(tree.set_actor(addr.clone(), act_a.clone()), Ok(()));
// Assert insert with same data returns ok
assert_eq!(tree.set_actor(addr.clone(), act_a.clone()), Ok(()));
// test getting set item
assert_eq!(tree.get_actor(addr.clone()).unwrap(), act_a);
}
}

0 comments on commit c916eb4

Please sign in to comment.