diff --git a/Cargo.toml b/Cargo.toml index 1450f78e35..41473f4a26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ rlp = { git = "https://github.com/paritytech/parity-common" } slog = "^2.2.3" slog-term = "^2.4.0" slog-async = "^2.3.0" +ssz = { path = "ssz" } tokio = "0.1" [dependencies.pairing] diff --git a/src/state/active_state.rs b/src/state/active_state.rs index 5f14e05cca..d107bc2992 100644 --- a/src/state/active_state.rs +++ b/src/state/active_state.rs @@ -1,7 +1,6 @@ use super::utils::types::Hash256; use super::attestation_record::AttestationRecord; -#[derive(Clone)] pub struct ActiveState { pub pending_attestations: Vec, pub recent_block_hashes: Vec, diff --git a/src/state/aggregate_vote.rs b/src/state/aggregate_vote.rs deleted file mode 100644 index 119e5f4f77..0000000000 --- a/src/state/aggregate_vote.rs +++ /dev/null @@ -1,71 +0,0 @@ -use super::utils::types::*; -use super::utils::bls::AggregateSignature; -use super::rlp::{ RlpStream, Encodable }; -use super::bytes::{ BytesMut, BufMut }; - -pub struct AggregateVote { - pub shard_id: u16, - pub shard_block_hash: Sha256Digest, - pub notary_bitfield: Bitfield, - pub aggregate_sig: AggregateSignature, -} - -impl AggregateVote { - pub fn zero() -> Self { - Self { - shard_id: 0, - shard_block_hash: Sha256Digest::zero(), - notary_bitfield: Bitfield::new(), - aggregate_sig: AggregateSignature::new() - } - } - - pub fn vote_key(&self) -> Vec { - let mut buf = BytesMut::with_capacity(34); - buf.extend_from_slice(&self.shard_block_hash.to_vec()); - buf.put_u16_be(self.shard_id); - buf.to_vec() - } -} - -/* - * RLP Encoding - */ -impl Encodable for AggregateVote { - fn rlp_append(&self, s: &mut RlpStream) { - s.append(&self.shard_id); - s.append(&self.shard_block_hash); - s.append(&self.notary_bitfield); - // s.append(&self.aggregate_sig); // TODO: represent this in RLP - } -} - - -#[cfg(test)] -mod tests { - use super::super::rlp; - use super::*; - - #[test] - fn test_zero_fn() { - let v = AggregateVote::zero(); - // TODO: test this better - assert_eq!(v.shard_id, 0); - } - - #[test] - fn test_rlp_serialization() { - let a = AggregateVote { - shard_id: 100, - shard_block_hash: Sha256Digest::zero(), - notary_bitfield: Bitfield::new(), - aggregate_sig: AggregateSignature::new() - }; - let e = rlp::encode(&a); - assert_eq!(e.len(), 35); - assert_eq!(e[0], 100); - assert_eq!(e[1], 160); - assert_eq!(e[2..34], [0; 32]); - assert_eq!(e[34], 128); - } -} diff --git a/src/state/attestation_record.rs b/src/state/attestation_record.rs index bb41694f9d..e8725cfd7f 100644 --- a/src/state/attestation_record.rs +++ b/src/state/attestation_record.rs @@ -2,14 +2,13 @@ use super::utils::types::{ Hash256, Bitfield }; use super::utils::bls::{ AggregateSignature }; -#[derive(Clone)] pub struct AttestationRecord { - slot: u64, - shard_id: u16, - oblique_parent_hashes: Vec, - shard_block_hash: Hash256, - attester_bitfield: Bitfield, - aggregate_sig: Option, + pub slot: u64, + pub shard_id: u16, + pub oblique_parent_hashes: Vec, + pub shard_block_hash: Hash256, + pub attester_bitfield: Bitfield, + pub aggregate_sig: Option, } impl AttestationRecord { diff --git a/src/state/block.rs b/src/state/block.rs index 201bc73aee..11f9192bb3 100644 --- a/src/state/block.rs +++ b/src/state/block.rs @@ -1,10 +1,7 @@ use super::utils::types::Hash256; -use super::utils::bls::{ Signature, AggregateSignature, Keypair, PublicKey }; use super::attestation_record::AttestationRecord; use super::ssz; -use std::hash::{ Hash, Hasher }; - const SSZ_BLOCK_LENGTH: usize = 192; pub struct Block { @@ -30,7 +27,8 @@ impl Block { } } - /// Returns a Vec + // Not sure if this will be useful, leaving it here for the + // time being. pub fn ssz_encode_without_attestations(&self) -> [u8; SSZ_BLOCK_LENGTH] { @@ -47,89 +45,20 @@ impl Block { } } -impl Hash for Block { - fn hash(&self, state: &mut H) { - let bytes = self.ssz_encode_without_attestations(); - bytes.hash(state); - } -} - #[cfg(test)] mod tests { - use super::super::rlp; - extern crate rand; - use super::*; - use self::rand::{ SeedableRng, XorShiftRng }; - - #[test] - fn test_signable_message_encoding() { - 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 = StateHash::zero(); - let mut b = Block::new(parent_hash, - randao_reveal, - main_chain_ref, - state_hash); - b.skip_count = 2; - let output = b.encode_to_signable_message(); - // TODO: test this better - assert_eq!(output[0], 160); - assert_eq!(output[1..21], [0; 20]); - } #[test] - fn test_sign_and_verify() { - let mut rng = XorShiftRng::from_seed([0xbc4f6d44, 0xd62f276c, 0xb963afd0, 0x5455863d]); - let alice_keypair = Keypair::generate(&mut rng); - let bob_keypair = Keypair::generate(&mut rng); - let mut b = Block::new(Sha256Digest::random(), - Sha256Digest::random(), - Sha256Digest::random(), - StateHash::zero()); - - // Both signatures fail before signing - assert_eq!(b.sig_verify(&alice_keypair.public), false); - assert_eq!(b.sig_verify(&bob_keypair.public), false); - - // Sign as Alice - b.sig_sign(&alice_keypair); - - // Alice signature passes, bobs fails - assert_eq!(b.sig_verify(&alice_keypair.public), true); - assert_eq!(b.sig_verify(&bob_keypair.public), false); - } - - #[test] - fn test_ssz_serialization() { - let b = Block { - parent_hash: Sha256Digest::zero(), - skip_count: 100, - randao_reveal: Sha256Digest::zero(), - attestation_bitfield: Bitfield::new(), - attestation_aggregate_sig: AggregateSignature::new(), - shard_aggregate_votes: Vec::new(), - main_chain_ref: Sha256Digest::zero(), - state_hash: StateHash::zero(), - sig: None - }; - let e = rlp::encode(&b); - assert_eq!(e.len(), 168); - assert_eq!(e[0], 160); - assert_eq!(e[1..33], [0; 32]); - assert_eq!(e[33], 100); - assert_eq!(e[34], 160); - assert_eq!(e[35..67], [0; 32]); - assert_eq!(e[67], 128); - assert_eq!(e[69], 160); - assert_eq!(e[70..102], [0; 32]); - /* - assert_eq!(e[102], 248); - assert_eq!(e[103], 64); - assert_eq!(e[104..136], [128; 32]); - assert_eq!(e[136..168], [128; 32]); - */ + fn test_block_zero() { + let b = Block::zero(); + assert!(b.parent_hash.is_zero()); + assert_eq!(b.slot_number, 0); + assert!(b.randao_reveal.is_zero()); + assert_eq!(b.attestations.len(), 0); + assert!(b.pow_chain_ref.is_zero()); + assert!(b.active_state_root.is_zero()); + assert!(b.crystallized_state_root.is_zero()); } } diff --git a/src/state/crosslink_record.rs b/src/state/crosslink_record.rs index fbeb4f43b8..37dfe75004 100644 --- a/src/state/crosslink_record.rs +++ b/src/state/crosslink_record.rs @@ -18,7 +18,6 @@ impl CrosslinkRecord { #[cfg(test)] mod tests { - use super::super::rlp; use super::*; #[test] diff --git a/src/state/crystallized_state.rs b/src/state/crystallized_state.rs index c799ad6bc0..8769bdcaae 100644 --- a/src/state/crystallized_state.rs +++ b/src/state/crystallized_state.rs @@ -5,7 +5,6 @@ use super::ethereum_types::U256; use super::utils::types::{ Hash256 }; -#[derive(Clone)] pub struct CrystallizedState { pub validators: Vec, pub epoch_number: u64, diff --git a/src/state/mod.rs b/src/state/mod.rs index 4f19dc66a8..45e845feff 100644 --- a/src/state/mod.rs +++ b/src/state/mod.rs @@ -5,17 +5,12 @@ extern crate bytes; extern crate ssz; use super::utils; -// use super::pubkeystore; pub mod active_state; pub mod attestation_record; pub mod crystallized_state; pub mod config; -// pub mod aggregate_vote; pub mod block; pub mod crosslink_record; -// pub mod partial_crosslink_record; -// pub mod recent_proposer_record; -// pub mod transition; pub mod shard_and_committee; pub mod validator_record; diff --git a/src/state/partial_crosslink_record.rs b/src/state/partial_crosslink_record.rs deleted file mode 100644 index 0dc2ef50f9..0000000000 --- a/src/state/partial_crosslink_record.rs +++ /dev/null @@ -1,122 +0,0 @@ -use std::io::Cursor; -use super::utils::types::{ Sha256Digest, Bitfield }; -use super::rlp::{ RlpStream, Encodable }; -use super::bytes::{ BytesMut, BufMut, Buf }; - -#[derive(Eq, Clone)] -pub struct PartialCrosslinkRecord { - pub shard_id: u16, - pub shard_block_hash: Sha256Digest, - pub voter_bitfield: Bitfield -} - -impl PartialCrosslinkRecord { - pub fn zero() -> Self { - Self { - shard_id: 0, - shard_block_hash: Sha256Digest::zero(), - voter_bitfield: Bitfield::new() - } - } - - pub fn new_from_vote_key(vote_key: &Vec, voter_bitfield: Bitfield) - -> Self - { - let mut buf = Cursor::new(vote_key); - let mut hash_bytes = [0_u8; 32]; - buf.copy_to_slice(&mut hash_bytes); - let shard_id: u16 = buf.get_u16_be(); - let shard_block_hash = Sha256Digest::from_slice(&hash_bytes); - Self { - shard_id, - shard_block_hash, - voter_bitfield - } - } - - pub fn vote_key(&self) -> Vec { - let mut buf = BytesMut::with_capacity(34); - buf.extend_from_slice(&self.shard_block_hash.to_vec()); - buf.put_u16_be(self.shard_id); - buf.to_vec() - } -} - -impl PartialEq for PartialCrosslinkRecord { - fn eq(&self, other: &PartialCrosslinkRecord) - -> bool - { - (self.shard_id == other.shard_id) & - (self.shard_block_hash == other.shard_block_hash) - } -} - -/* - * RLP Encoding - */ -impl Encodable for PartialCrosslinkRecord { - fn rlp_append(&self, s: &mut RlpStream) { - s.append(&self.shard_id); - s.append(&self.shard_block_hash); - s.append(&self.voter_bitfield); - } -} - - -#[cfg(test)] -mod tests { - use super::super::rlp; - use super::*; - - #[test] - fn test_zero() { - let p = PartialCrosslinkRecord::zero(); - assert_eq!(p.shard_id, 0); - assert_eq!(p.shard_block_hash.is_zero(), true); - assert_eq!(p.voter_bitfield.num_true_bits(), 0); - } - - #[test] - fn test_new_from_vote_key() { - let mut p = PartialCrosslinkRecord::zero(); - p.shard_id = 223; - p.shard_block_hash = Sha256Digest::random(); - - let mut bitfield = Bitfield::new(); - bitfield.set_bit(&42, &true); - - let vk = p.vote_key(); - let np = PartialCrosslinkRecord::new_from_vote_key( - &vk, bitfield.clone()); - - assert_eq!(np.shard_id, p.shard_id); - assert_eq!(np.shard_block_hash, p.shard_block_hash); - assert!(np.voter_bitfield == bitfield); - } - - #[test] - fn test_vote_key_formatting() { - let mut p = PartialCrosslinkRecord::zero(); - let vk = p.vote_key(); - assert_eq!(vk.len(), 34); - assert_eq!(vk, vec![0; 34]); - - p.shard_id = 1; - let vk = p.vote_key(); - assert_eq!(vk.len(), 34); - assert_eq!(vk[0..33].to_vec(), vec![0; 33]); - assert_eq!(vk[33], 1); - } - - #[test] - fn test_rlp_serialization() { - let mut p = PartialCrosslinkRecord::zero(); - p.shard_id = 1; - let e = rlp::encode(&p); - assert_eq!(e.len(), 35); - assert_eq!(e[0], 1); - assert_eq!(e[1], 160); - assert_eq!(e[2..34], [0; 32]); - assert_eq!(e[34], 128); - } -} diff --git a/src/state/recent_proposer_record.rs b/src/state/recent_proposer_record.rs deleted file mode 100644 index 670db9ebbe..0000000000 --- a/src/state/recent_proposer_record.rs +++ /dev/null @@ -1,56 +0,0 @@ -use super::rlp::{ RlpStream, Encodable }; -use super::utils::types::*; - -#[derive(Clone)] -pub struct RecentPropserRecord { - pub index: usize, // TODO: make u24 - pub randao_commitment: Sha256Digest, - pub balance_delta: i64, // TODO: make u24 -} - -impl RecentPropserRecord { - pub fn new(index: usize, - randao_commitment: Sha256Digest, - balance_delta: i64) -> RecentPropserRecord { - RecentPropserRecord { - index: index, - randao_commitment: randao_commitment, - balance_delta: balance_delta - } - } -} - -/* - * RLP Encoding - */ -impl Encodable for RecentPropserRecord { - fn rlp_append(&self, s: &mut RlpStream) { - s.append(&self.index); - s.append(&self.randao_commitment); - // TODO: serialize this if needed. - // s.append(&self.balance_delta); - } -} - - -#[cfg(test)] -mod tests { - use super::super::rlp; - use super::*; - - #[test] - fn test_rlp_serialization() { - let index = 1; - let randao_commitment = Sha256Digest::zero(); - let balance_delta = 99; - let r = RecentPropserRecord::new(index, randao_commitment, balance_delta); - let e = rlp::encode(&r); - assert_eq!(e.len(), 34); - assert_eq!(e[0], 1); - assert_eq!(e[1], 160); - assert_eq!(e[2..34], [0; 32]); - /* - assert_eq!(e[34], 99); - */ - } -} diff --git a/src/state/shard_and_committee.rs b/src/state/shard_and_committee.rs index 81e83be306..64d2d8a90a 100644 --- a/src/state/shard_and_committee.rs +++ b/src/state/shard_and_committee.rs @@ -1,4 +1,3 @@ -#[derive(Clone)] pub struct ShardAndCommittee { shard_id: u16, committee: Vec @@ -21,7 +20,7 @@ mod tests { #[test] fn test_shard_and_committee_zero() { - let s = CrystallizedState::zero(); + let s = ShardAndCommittee::zero(); assert_eq!(s.shard_id, 0); assert_eq!(s.committee.len(), 0); } diff --git a/src/state/validator_record.rs b/src/state/validator_record.rs index b943f79736..e69b169c11 100644 --- a/src/state/validator_record.rs +++ b/src/state/validator_record.rs @@ -49,16 +49,11 @@ impl Clone for ValidatorRecord { #[cfg(test)] mod tests { - use super::super::rlp; - extern crate rand; - use super::*; - use super::super:: - utils::test_helpers::get_dangerous_test_keypair; #[test] fn test_validator_record_zero_rand_keypair() { - let (v, kp) = ValidatorRecord::zero_with_thread_rand_keypair(); + let (v, _kp) = ValidatorRecord::zero_with_thread_rand_keypair(); // TODO: check keys assert_eq!(v.withdrawal_shard, 0); assert!(v.withdrawal_address.is_zero()); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index bae40ad228..833dc25075 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -2,9 +2,6 @@ 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; pub mod test_helpers; diff --git a/src/utils/types.rs b/src/utils/types.rs index bf65466983..4ff6ad2ada 100644 --- a/src/utils/types.rs +++ b/src/utils/types.rs @@ -1,39 +1,11 @@ use super::ethereum_types::{ H256, H160 }; -use super::active_state::ActiveState; -use super::crystallized_state::CrystallizedState; use super::boolean_bitfield::BooleanBitfield; pub use super::blake2::Blake2s; pub use super::ethereum_types::U256; -// TODO: presently the compiler accepts these two types -// as interchangable. This is somewhat loose typing, -// which is bad. Make the compiler think they're incompatible. -pub type Sha256Digest = H256; -pub type Blake2sDigest = H256; pub type Hash256 = H256; pub type Address = H160; -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 = BooleanBitfield;