diff --git a/src/state/active_state.rs b/src/state/active_state.rs index 1cba78114..4aba069fc 100644 --- a/src/state/active_state.rs +++ b/src/state/active_state.rs @@ -1,6 +1,8 @@ use super::partial_crosslink_record::PartialCrosslinkRecord; use super::recent_proposer_record::RecentPropserRecord; use super::rlp::{ RlpStream, Encodable }; +use super::rlp::encode as rlp_encode; +use super::blake2::{ Blake2s, Digest }; use super::utils::types::*; pub struct ActiveState { @@ -33,6 +35,14 @@ impl ActiveState { pub fn num_recent_attesters(&self) -> usize { self.recent_attesters.len() } + + pub fn blake2s_hash(&self) -> Blake2sDigest { + let mut hasher = Blake2s::new(); + hasher.input(&rlp_encode(self).into_vec()); + let mut digest = Blake2sDigest::new(); + digest.clone_from_slice(hasher.result().as_slice()); + digest + } } /* diff --git a/src/state/block.rs b/src/state/block.rs index 542056acb..17fd6bbea 100644 --- a/src/state/block.rs +++ b/src/state/block.rs @@ -49,7 +49,9 @@ impl Block { // s.append(&self.attestation_aggregate_sig); // TODO: RLP this s.append_list(&self.shard_aggregate_votes); s.append(&self.main_chain_ref); - s.append_list(&self.state_hash); + // TODO: state hash serialization is probably incorrect. + s.append(&self.state_hash.crystallized_state); + s.append(&self.state_hash.active_state); let rlp_vec = s.out(); // Parse the RLP vector into an array compatible with the BLS signer @@ -89,7 +91,9 @@ impl Encodable for Block { // s.append(&self.attestation_aggregate_sig); // TODO: RLP this s.append_list(&self.shard_aggregate_votes); s.append(&self.main_chain_ref); - s.append_list(&self.state_hash); + // TODO: state hash serialization is probably incorrect. + s.append(&self.state_hash.crystallized_state); + s.append(&self.state_hash.active_state); // s.append(&self.sig); // TODO: RLP this } } @@ -108,7 +112,7 @@ mod tests { let parent_hash = Sha256Digest::from([0; 32]); let randao_reveal = Sha256Digest::from([1; 32]); let main_chain_ref = Sha256Digest::from([2; 32]); - let state_hash = [0; 64]; + let state_hash = StateHash::zero(); let mut b = Block::new(parent_hash, randao_reveal, main_chain_ref, @@ -128,7 +132,7 @@ mod tests { let mut b = Block::new(Sha256Digest::random(), Sha256Digest::random(), Sha256Digest::random(), - [0; 64]); + StateHash::zero()); // Both signatures fail before signing assert_eq!(b.sig_verify(&alice_keypair.public), false); @@ -152,11 +156,10 @@ mod tests { attestation_aggregate_sig: AggregateSignature::new(), shard_aggregate_votes: Vec::new(), main_chain_ref: Sha256Digest::zero(), - state_hash: [0; 64], + state_hash: StateHash::zero(), sig: None }; let e = rlp::encode(&b); - println!("{:?}", e); assert_eq!(e.len(), 168); assert_eq!(e[0], 160); assert_eq!(e[1..33], [0; 32]); diff --git a/src/state/crystallized_state.rs b/src/state/crystallized_state.rs index d0dcc9eb6..9f232fd8d 100644 --- a/src/state/crystallized_state.rs +++ b/src/state/crystallized_state.rs @@ -1,8 +1,10 @@ -use super::utils::types::Sha256Digest; +use super::utils::types::{ Sha256Digest, Blake2sDigest }; use super::validator_record::ValidatorRecord; use super::crosslink_record::CrosslinkRecord; use super::rlp::{ RlpStream, Encodable }; +use super::rlp::encode as rlp_encode; use super::ethereum_types::U256; +use super::blake2::{ Blake2s, Digest }; pub struct CrystallizedState { pub active_validators: Vec, @@ -36,6 +38,14 @@ impl CrystallizedState { self.crosslink_records.len() } + + pub fn blake2s_hash(&self) -> Blake2sDigest { + let mut hasher = Blake2s::new(); + hasher.input(&rlp_encode(self).into_vec()); + let mut digest = Blake2sDigest::new(); + digest.clone_from_slice(hasher.result().as_slice()); + digest + } } /* diff --git a/src/state/mod.rs b/src/state/mod.rs index 697730afc..b4162b7f2 100644 --- a/src/state/mod.rs +++ b/src/state/mod.rs @@ -1,5 +1,6 @@ extern crate rlp; extern crate ethereum_types; +extern crate blake2; use super::utils; diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 51c03db67..59a7d823e 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -2,5 +2,8 @@ extern crate ethereum_types; extern crate blake2; extern crate crypto_mac; +use super::state::active_state; +use super::state::crystallized_state; + pub mod types; pub mod bls; diff --git a/src/utils/types.rs b/src/utils/types.rs index 7940fe1de..f7fed2a90 100644 --- a/src/utils/types.rs +++ b/src/utils/types.rs @@ -1,4 +1,6 @@ use super::ethereum_types::{ H256, H160 }; +use super::active_state::ActiveState; +use super::crystallized_state::CrystallizedState; pub use super::blake2::Blake2s; @@ -10,6 +12,25 @@ pub type Blake2sDigest = H256; pub type Address = H160; -pub type StateHash = [u8; 64]; +pub struct StateHash { + pub active_state: Blake2sDigest, + pub crystallized_state: Blake2sDigest +} + +impl StateHash { + pub fn zero() -> Self { + Self { + active_state: Blake2sDigest::zero(), + crystallized_state: Blake2sDigest::zero() + } + } + + pub fn from_states(active: &ActiveState, crystal: &CrystallizedState) -> Self { + Self { + active_state: active.blake2s_hash(), + crystallized_state: crystal.blake2s_hash() + } + } +} pub type Bitfield = Vec;