From adbeecbdcf1746ad69b4fc27e4606432bd01b207 Mon Sep 17 00:00:00 2001 From: Gav <gavin@parity.io> Date: Sun, 14 Jan 2018 23:41:32 +0100 Subject: [PATCH] Rejig tests and ensure authorities are addressed consistently. --- substrate/state_machine/src/lib.rs | 42 ++++++++++------------ substrate/wasm-runtime/polkadot/src/lib.rs | 38 ++++++++++++-------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/substrate/state_machine/src/lib.rs b/substrate/state_machine/src/lib.rs index 58ba558322a..38c481113f2 100644 --- a/substrate/state_machine/src/lib.rs +++ b/substrate/state_machine/src/lib.rs @@ -114,13 +114,9 @@ impl OverlayedChanges { pub trait Error: 'static + fmt::Debug + fmt::Display + Send {} impl<E> Error for E where E: 'static + fmt::Debug + fmt::Display + Send {} -fn value_vec(mut value: usize, initial: Vec<u8>) -> Vec<u8> { - let mut acc = initial; - while value > 0 { - acc.push(value as u8); - value /= 256; - } - acc +fn to_keyed_vec(value: u32, mut prepend: Vec<u8>) -> Vec<u8> { + prepend.extend((0..::std::mem::size_of::<u32>()).into_iter().map(|i| (value >> (i * 8)) as u8)); + prepend } /// Externalities: pinned to specific active address. @@ -134,12 +130,12 @@ pub trait Externalities { /// Set storage of current contract being called (effective immediately). fn set_storage(&mut self, key: Vec<u8>, value: Vec<u8>); - /// Get the current set of validators. - fn validators(&self) -> Result<Vec<&[u8]>, Self::Error> { - (0..self.storage(b"\0validator_count")?.into_iter() + /// Get the current set of authorities. + fn authorities(&self) -> Result<Vec<&[u8]>, Self::Error> { + (0..self.storage(b"con\0aut\0len")?.into_iter() .rev() - .fold(0, |acc, &i| (acc << 8) + (i as usize))) - .map(|i| self.storage(&value_vec(i, b"\0validator".to_vec()))) + .fold(0, |acc, &i| (acc << 8) + (i as u32))) + .map(|i| self.storage(&to_keyed_vec(i, b"con\0aut\0".to_vec()))) .collect() } } @@ -248,22 +244,22 @@ mod tests { } #[test] - fn validators_call_works() { + fn authorities_call_works() { let mut ext = TestExternalities::default(); - assert_eq!(ext.validators(), Ok(vec![])); + assert_eq!(ext.authorities(), Ok(vec![])); - ext.set_storage(b"\0validator_count".to_vec(), vec![]); - assert_eq!(ext.validators(), Ok(vec![])); + ext.set_storage(b"con\0aut\0len".to_vec(), vec![0u8; 4]); + assert_eq!(ext.authorities(), Ok(vec![])); - ext.set_storage(b"\0validator_count".to_vec(), vec![1]); - assert_eq!(ext.validators(), Ok(vec![&[][..]])); + ext.set_storage(b"con\0aut\0len".to_vec(), vec![1u8, 0, 0, 0]); + assert_eq!(ext.authorities(), Ok(vec![&[][..]])); - ext.set_storage(b"\0validator".to_vec(), b"first".to_vec()); - assert_eq!(ext.validators(), Ok(vec![&b"first"[..]])); + ext.set_storage(b"con\0aut\0\0\0\0\0".to_vec(), b"first".to_vec()); + assert_eq!(ext.authorities(), Ok(vec![&b"first"[..]])); - ext.set_storage(b"\0validator_count".to_vec(), vec![2]); - ext.set_storage(b"\0validator\x01".to_vec(), b"second".to_vec()); - assert_eq!(ext.validators(), Ok(vec![&b"first"[..], &b"second"[..]])); + ext.set_storage(b"con\0aut\0len".to_vec(), vec![2u8, 0, 0, 0]); + ext.set_storage(b"con\0aut\0\x01\0\0\0".to_vec(), b"second".to_vec()); + assert_eq!(ext.authorities(), Ok(vec![&b"first"[..], &b"second"[..]])); } } diff --git a/substrate/wasm-runtime/polkadot/src/lib.rs b/substrate/wasm-runtime/polkadot/src/lib.rs index 205d2e31a7d..b54eac0cdf0 100644 --- a/substrate/wasm-runtime/polkadot/src/lib.rs +++ b/substrate/wasm-runtime/polkadot/src/lib.rs @@ -117,15 +117,6 @@ fn env() -> Rc<RefCell<Environment>> { } } -fn value_vec(mut value: u32, initial: Vec<u8>) -> Vec<u8> { - let mut acc = initial; - while value > 0 { - acc.push(value as u8); - value /= 256; - } - acc -} - trait EndianSensitive: Sized { fn to_le(self) -> Self { self } fn to_be(self) -> Self { self } @@ -176,10 +167,10 @@ fn storage_into<T: Storage>(key: &[u8]) -> T { T::storage_into(key) } - trait KeyedVec { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec<u8>; } + impl KeyedVec for AccountID { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec<u8> { let mut r = prepend_key.to_vec(); @@ -188,6 +179,25 @@ impl KeyedVec for AccountID { } } +macro_rules! impl_endians { + ( $( $t:ty ),* ) => { $( + impl KeyedVec for $t { + fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec<u8> { + let size = size_of::<Self>(); + let value_bytes = self.to_le(); + let value_slice = unsafe { + std::slice::from_raw_parts(transmute::<*const Self, *const u8>(&value_bytes), size) + }; + let mut r = prepend_key.to_vec(); + r.extend_from_slice(value_slice); + r + } + } + )* } +} + +impl_endians!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize); + // TODO: include RLP implementation // TODO: add keccak256 (or some better hashing scheme) & ECDSA-recover (or some better sig scheme) @@ -266,20 +276,20 @@ pub mod consensus { use super::*; pub fn set_authority(index: u32, authority: AccountID) { - runtime_support::set_storage(&value_vec(index, b"\0authority".to_vec()), &authority[..]); + authority.store(&index.to_keyed_vec(b"con\0aut\0")); } fn authority(index: u32) -> AccountID { - runtime_support::storage_into(&value_vec(index, b"\0authority".to_vec())).unwrap() + storage_into(&index.to_keyed_vec(b"con\0aut\0")) } pub fn set_authority_count(count: u32) { (count..authority_count()).for_each(|i| set_authority(i, SessionKey::default())); - runtime_support::set_storage(b"\0authority_count", &value_vec(count, Vec::new())); + count.store(b"con\0aut\0len"); } fn authority_count() -> u32 { - runtime_support::storage(b"\0authority_count").into_iter().rev().fold(0, |acc, i| (acc << 8) + (i as u32)) + storage_into(b"con\0aut\0len") } /// Get the current set of authorities. These are the session keys. -- GitLab