Light friendly storage tracking: changes trie + extending over ranges (#628)

* changes_trie

* changs_trie: continue

* changes_trie: adding tests

* fixed TODO

* removed obsolete ExtrinsicChanges

* encodable ChangesTrieConfiguration

* removed polkadot fle

* fixed grumbles

* ext_storage_changes_root returns u32

* moved changes trie root to digest

* removed commented code

* read storage values from native code

* fixed grumbles

* fixed grumbles

* missing comma
This commit is contained in:
Svyatoslav Nikolsky
2018-09-18 10:14:41 +03:00
committed by Gav Wood
parent 24479cd7f5
commit 7fa337afbc
64 changed files with 3130 additions and 788 deletions
@@ -18,13 +18,11 @@
#![cfg(feature = "std")]
use std::collections::HashMap;
use rstd::prelude::*;
use codec::Encode;
use runtime_support::{StorageValue, StorageMap};
use primitives::traits::{Zero, As};
use substrate_primitives::Blake2Hasher;
use {runtime_io, primitives};
use primitives;
use super::{Trait, ENUM_SET_SIZE, EnumSet, NextEnumSet, CreationFee, TransferFee,
ReclaimRebate, ExistentialDeposit, TransactionByteFee, TransactionBaseFee, TotalIssuance,
FreeBalance};
@@ -57,10 +55,10 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
fn build_storage(self) -> ::std::result::Result<HashMap<Vec<u8>, Vec<u8>>, String> {
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
let total_issuance: T::Balance = self.balances.iter().fold(Zero::zero(), |acc, &(_, n)| acc + n);
let mut r: runtime_io::TestExternalities<Blake2Hasher> = map![
let mut r: primitives::StorageMap = map![
Self::hash(<NextEnumSet<T>>::key()).to_vec() => T::AccountIndex::sa(self.balances.len() / ENUM_SET_SIZE).encode(),
Self::hash(<TransactionBaseFee<T>>::key()).to_vec() => self.transaction_base_fee.encode(),
Self::hash(<TransactionByteFee<T>>::key()).to_vec() => self.transaction_byte_fee.encode(),
@@ -79,6 +77,6 @@ impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
for (who, value) in self.balances.into_iter() {
r.insert(Self::hash(&<FreeBalance<T>>::key_for(who)).to_vec(), value.encode());
}
Ok(r.into())
Ok(r)
}
}
+5 -4
View File
@@ -19,8 +19,8 @@
#![cfg(test)]
use primitives::BuildStorage;
use primitives::testing::{Digest, Header};
use substrate_primitives::{H256, Blake2Hasher};
use primitives::testing::{Digest, DigestItem, Header};
use substrate_primitives::{H256, Blake2Hasher, RlpCodec};
use runtime_io;
use {GenesisConfig, Module, Trait, system};
@@ -41,6 +41,7 @@ impl system::Trait for Runtime {
type AccountId = u64;
type Header = Header;
type Event = ();
type Log = DigestItem;
}
impl Trait for Runtime {
type Balance = u64;
@@ -50,7 +51,7 @@ impl Trait for Runtime {
type Event = ();
}
pub fn new_test_ext(ext_deposit: u64, monied: bool) -> runtime_io::TestExternalities<Blake2Hasher> {
pub fn new_test_ext(ext_deposit: u64, monied: bool) -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = system::GenesisConfig::<Runtime>::default().build_storage().unwrap();
let balance_factor = if ext_deposit > 0 {
256
@@ -73,7 +74,7 @@ pub fn new_test_ext(ext_deposit: u64, monied: bool) -> runtime_io::TestExternali
t.into()
}
pub fn new_test_ext2(ext_deposit: u64, monied: bool) -> runtime_io::TestExternalities<Blake2Hasher> {
pub fn new_test_ext2(ext_deposit: u64, monied: bool) -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = system::GenesisConfig::<Runtime>::default().build_storage().unwrap();
let balance_factor = if ext_deposit > 0 {
256
+13 -16
View File
@@ -46,15 +46,10 @@ use runtime_support::{storage, Parameter};
use runtime_support::dispatch::Result;
use runtime_support::storage::StorageValue;
use runtime_support::storage::unhashed::StorageVec;
use primitives::traits::{MaybeSerializeDebug, OnFinalise, Member, DigestItem};
use primitives::traits::{MaybeSerializeDebug, OnFinalise, Member};
use primitives::bft::MisbehaviorReport;
use system::{ensure_signed, ensure_inherent};
#[cfg(any(feature = "std", test))]
use substrate_primitives::Blake2Hasher;
#[cfg(any(feature = "std", test))]
use std::collections::HashMap;
pub const AUTHORITY_AT: &'static [u8] = b":auth:";
pub const AUTHORITY_COUNT: &'static [u8] = b":auth:len";
@@ -88,22 +83,24 @@ pub enum RawLog<SessionKey> {
AuthoritiesChange(Vec<SessionKey>),
}
impl<SessionKey: Member> DigestItem for RawLog<SessionKey> {
type AuthorityId = SessionKey;
impl<SessionKey: Member> RawLog<SessionKey> {
/// Try to cast the log entry as AuthoritiesChange log entry.
fn as_authorities_change(&self) -> Option<&[SessionKey]> {
pub fn as_authorities_change(&self) -> Option<&[SessionKey]> {
match *self {
RawLog::AuthoritiesChange(ref item) => Some(&item),
RawLog::AuthoritiesChange(ref item) => Some(item),
}
}
}
// Implementation for tests outside of this crate.
impl<N> From<RawLog<N>> for u64 {
fn from(log: RawLog<N>) -> u64 {
#[cfg(any(feature = "std", test))]
impl<N> From<RawLog<N>> for primitives::testing::DigestItem {
fn from(log: RawLog<N>) -> primitives::testing::DigestItem {
match log {
RawLog::AuthoritiesChange(_) => 1,
RawLog::AuthoritiesChange(authorities) =>
primitives::generic::DigestItem::AuthoritiesChange
::<substrate_primitives::H256, u64>(authorities.into_iter()
.enumerate().map(|(i, _)| i as u64).collect()),
}
}
}
@@ -252,10 +249,10 @@ impl<T: Trait> Default for GenesisConfig<T> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_storage(self) -> ::std::result::Result<HashMap<Vec<u8>, Vec<u8>>, String> {
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
use codec::{Encode, KeyedVec};
let auth_count = self.authorities.len() as u32;
let mut r: runtime_io::TestExternalities<Blake2Hasher> = self.authorities.into_iter().enumerate().map(|(i, v)|
let mut r: primitives::StorageMap = self.authorities.into_iter().enumerate().map(|(i, v)|
((i as u32).to_keyed_vec(AUTHORITY_AT), v.encode())
).collect();
r.insert(AUTHORITY_COUNT.to_vec(), auth_count.encode());
@@ -22,11 +22,9 @@ use {Trait, ContractFee, CallBaseFee, CreateBaseFee, GasPrice, MaxDepth, BlockGa
use runtime_primitives;
use runtime_primitives::traits::As;
use runtime_io::{self, twox_128};
use runtime_io::twox_128;
use runtime_support::StorageValue;
use codec::Encode;
use std::collections::HashMap;
use substrate_primitives::Blake2Hasher;
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
@@ -54,15 +52,14 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
impl<T: Trait> runtime_primitives::BuildStorage for GenesisConfig<T> {
fn build_storage(self) -> ::std::result::Result<HashMap<Vec<u8>, Vec<u8>>, String> {
let r: runtime_io::TestExternalities<Blake2Hasher> = map![
fn build_storage(self) -> ::std::result::Result<runtime_primitives::StorageMap, String> {
Ok(map![
twox_128(<ContractFee<T>>::key()).to_vec() => self.contract_fee.encode(),
twox_128(<CallBaseFee<T>>::key()).to_vec() => self.call_base_fee.encode(),
twox_128(<CreateBaseFee<T>>::key()).to_vec() => self.create_base_fee.encode(),
twox_128(<GasPrice<T>>::key()).to_vec() => self.gas_price.encode(),
twox_128(<MaxDepth<T>>::key()).to_vec() => self.max_depth.encode(),
twox_128(<BlockGasLimit<T>>::key()).to_vec() => self.block_gas_limit.encode()
];
Ok(r.into())
])
}
}
+5 -4
View File
@@ -16,11 +16,11 @@
use double_map::StorageDoubleMap;
use runtime_io::with_externalities;
use runtime_primitives::testing::{Digest, H256, Header};
use runtime_primitives::testing::{Digest, DigestItem, H256, Header};
use runtime_primitives::traits::{BlakeTwo256};
use runtime_primitives::BuildStorage;
use runtime_support::StorageMap;
use substrate_primitives::Blake2Hasher;
use substrate_primitives::{Blake2Hasher, RlpCodec};
use wabt;
use {
runtime_io, balances, system, CodeOf, ContractAddressFor,
@@ -43,6 +43,7 @@ impl system::Trait for Test {
type AccountId = u64;
type Header = Header;
type Event = ();
type Log = DigestItem;
}
impl balances::Trait for Test {
type Balance = u64;
@@ -105,7 +106,7 @@ impl ExtBuilder {
self.creation_fee = creation_fee;
self
}
fn build(self) -> runtime_io::TestExternalities<Blake2Hasher> {
fn build(self) -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = system::GenesisConfig::<Test>::default()
.build_storage()
.unwrap();
@@ -132,7 +133,7 @@ impl ExtBuilder {
}.build_storage()
.unwrap(),
);
t.into()
runtime_io::TestExternalities::new(t)
}
}
+6 -7
View File
@@ -45,8 +45,6 @@ extern crate srml_system as system;
#[cfg(feature = "std")]
use rstd::prelude::*;
#[cfg(feature = "std")]
use std::collections::HashMap;
#[cfg(feature = "std")]
use primitives::traits::As;
#[cfg(feature = "std")]
use srml_support::StorageValue;
@@ -102,7 +100,7 @@ impl<T: seats::Trait + voting::Trait + motions::Trait> Default for GenesisConfig
#[cfg(feature = "std")]
impl<T: seats::Trait + voting::Trait + motions::Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_storage(self) -> ::std::result::Result<HashMap<Vec<u8>, Vec<u8>>, String> {
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
use codec::Encode;
Ok(map![
@@ -132,8 +130,8 @@ mod tests {
pub use substrate_primitives::H256;
pub use primitives::BuildStorage;
pub use primitives::traits::{BlakeTwo256};
pub use primitives::testing::{Digest, Header};
pub use substrate_primitives::Blake2Hasher;
pub use primitives::testing::{Digest, DigestItem, Header};
pub use substrate_primitives::{Blake2Hasher, RlpCodec};
pub use {seats, motions, voting};
impl_outer_origin! {
@@ -168,6 +166,7 @@ mod tests {
type AccountId = u64;
type Header = Header;
type Event = Event;
type Log = DigestItem;
}
impl balances::Trait for Test {
type Balance = u64;
@@ -192,7 +191,7 @@ mod tests {
type Event = Event;
}
pub fn new_test_ext(with_council: bool) -> runtime_io::TestExternalities<Blake2Hasher> {
pub fn new_test_ext(with_council: bool) -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(balances::GenesisConfig::<Test>{
balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)],
@@ -226,7 +225,7 @@ mod tests {
cooloff_period: 2,
voting_period: 1,
}.build_storage().unwrap());
t.into()
runtime_io::TestExternalities::new(t)
}
pub type System = system::Module<Test>;
+1 -1
View File
@@ -622,7 +622,7 @@ mod tests {
});
}
fn new_test_ext_with_candidate_holes() -> runtime_io::TestExternalities<Blake2Hasher> {
fn new_test_ext_with_candidate_holes() -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = new_test_ext(false);
with_externalities(&mut t, || {
<Candidates<Test>>::put(vec![0, 0, 1]);
+6 -8
View File
@@ -48,9 +48,6 @@ use srml_support::{StorageValue, StorageMap, Parameter, Dispatchable, IsSubType}
use srml_support::dispatch::Result;
use system::ensure_signed;
#[cfg(any(feature = "std", test))]
use std::collections::HashMap;
mod vote_threshold;
pub use vote_threshold::{Approved, VoteThreshold};
@@ -352,7 +349,7 @@ impl<T: Trait> Default for GenesisConfig<T> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_storage(self) -> ::std::result::Result<HashMap<Vec<u8>, Vec<u8>>, String> {
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
use codec::Encode;
Ok(map![
@@ -370,10 +367,10 @@ impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
mod tests {
use super::*;
use runtime_io::with_externalities;
use substrate_primitives::{H256, Blake2Hasher};
use substrate_primitives::{H256, Blake2Hasher, RlpCodec};
use primitives::BuildStorage;
use primitives::traits::{BlakeTwo256};
use primitives::testing::{Digest, Header};
use primitives::testing::{Digest, DigestItem, Header};
impl_outer_origin! {
pub enum Origin for Test {}
@@ -399,6 +396,7 @@ mod tests {
type AccountId = u64;
type Header = Header;
type Event = ();
type Log = DigestItem;
}
impl balances::Trait for Test {
type Balance = u64;
@@ -412,7 +410,7 @@ mod tests {
type Event = ();
}
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(balances::GenesisConfig::<Test>{
balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)],
@@ -428,7 +426,7 @@ mod tests {
voting_period: 1,
minimum_deposit: 1,
}.build_storage().unwrap());
t.into()
runtime_io::TestExternalities::new(t)
}
type System = system::Module<Test>;
+4 -2
View File
@@ -326,9 +326,10 @@ mod tests {
use super::*;
use runtime_io::with_externalities;
use substrate_primitives::{H256, Blake2Hasher};
use substrate_primitives::{H256, Blake2Hasher, RlpCodec};
use runtime_primitives::BuildStorage;
use runtime_primitives::traits::{BlakeTwo256};
use runtime_primitives::testing::DigestItem;
// The testing primitives are very useful for avoiding having to work with signatures
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
@@ -353,6 +354,7 @@ mod tests {
type AccountId = u64;
type Header = Header;
type Event = ();
type Log = DigestItem;
}
impl balances::Trait for Test {
type Balance = u64;
@@ -368,7 +370,7 @@ mod tests {
// This function basically just builds a genesis storage key/value store according to
// our desired mockup.
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
// We use default for brevity, but you can configure as desired if needed.
t.extend(balances::GenesisConfig::<Test>::default().build_storage().unwrap());
+11 -9
View File
@@ -204,11 +204,11 @@ impl<
}
fn final_checks(header: &System::Header) {
// check digest
assert!(header.digest() == &<system::Module<System>>::digest());
// remove temporaries.
<system::Module<System>>::finalise();
let new_header = <system::Module<System>>::finalise();
// check digest
assert!(header.digest() == new_header.digest());
// check storage root.
let storage_root = System::Hashing::storage_root();
@@ -266,10 +266,10 @@ mod tests {
use super::*;
use balances::Call;
use runtime_io::with_externalities;
use substrate_primitives::{H256, Blake2Hasher};
use substrate_primitives::{H256, Blake2Hasher, RlpCodec};
use primitives::BuildStorage;
use primitives::traits::{Header as HeaderT, BlakeTwo256, Lookup};
use primitives::testing::{Digest, Header, Block};
use primitives::testing::{Digest, DigestItem, Header, Block};
use system;
struct NullLookup;
@@ -305,6 +305,7 @@ mod tests {
type AccountId = u64;
type Header = Header;
type Event = MetaEvent;
type Log = DigestItem;
}
impl balances::Trait for Runtime {
type Balance = u64;
@@ -330,16 +331,17 @@ mod tests {
reclaim_rebate: 0,
}.build_storage().unwrap());
let xt = primitives::testing::TestXt(Some(1), 0, Call::transfer(2.into(), 69));
let mut t = runtime_io::TestExternalities::from(t);
let mut t = runtime_io::TestExternalities::<Blake2Hasher, RlpCodec>::new(t);
with_externalities(&mut t, || {
Executive::initialise_block(&Header::new(1, H256::default(), H256::default(), [69u8; 32].into(), Digest::default()));
Executive::initialise_block(&Header::new(1, H256::default(), H256::default(),
[69u8; 32].into(), Digest::default()));
Executive::apply_extrinsic(xt).unwrap();
assert_eq!(<balances::Module<Runtime>>::total_balance(&1), 32);
assert_eq!(<balances::Module<Runtime>>::total_balance(&2), 69);
});
}
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = system::GenesisConfig::<Runtime>::default().build_storage().unwrap();
t.extend(balances::GenesisConfig::<Runtime>::default().build_storage().unwrap());
t.into()
+7 -10
View File
@@ -54,9 +54,6 @@ use runtime_support::{StorageValue, StorageMap};
use runtime_support::dispatch::Result;
use system::ensure_signed;
#[cfg(any(feature = "std", test))]
use std::collections::HashMap;
/// A session has changed.
pub trait OnSessionChange<T> {
/// Session has changed.
@@ -265,8 +262,7 @@ impl<T: Trait> Default for GenesisConfig<T> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
{
fn build_storage(self) -> ::std::result::Result<HashMap<Vec<u8>, Vec<u8>>, String> {
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
use codec::Encode;
use primitives::traits::As;
Ok(map![
@@ -282,10 +278,10 @@ impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
mod tests {
use super::*;
use runtime_io::with_externalities;
use substrate_primitives::{H256, Blake2Hasher};
use substrate_primitives::{H256, Blake2Hasher, RlpCodec};
use primitives::BuildStorage;
use primitives::traits::{Identity, BlakeTwo256};
use primitives::testing::{Digest, Header};
use primitives::testing::{Digest, DigestItem, Header};
impl_outer_origin!{
pub enum Origin for Test {}
@@ -295,7 +291,7 @@ mod tests {
pub struct Test;
impl consensus::Trait for Test {
const NOTE_OFFLINE_POSITION: u32 = 1;
type Log = u64;
type Log = DigestItem;
type SessionKey = u64;
type OnOfflineValidator = ();
}
@@ -309,6 +305,7 @@ mod tests {
type AccountId = u64;
type Header = Header;
type Event = ();
type Log = DigestItem;
}
impl timestamp::Trait for Test {
const TIMESTAMP_SET_POSITION: u32 = 0;
@@ -324,7 +321,7 @@ mod tests {
type Consensus = consensus::Module<Test>;
type Session = Module<Test>;
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(consensus::GenesisConfig::<Test>{
code: vec![],
@@ -337,7 +334,7 @@ mod tests {
session_length: 2,
validators: vec![1, 2, 3],
}.build_storage().unwrap());
t.into()
runtime_io::TestExternalities::new(t)
}
#[test]
+4 -7
View File
@@ -18,13 +18,11 @@
#![cfg(feature = "std")]
use std::collections::HashMap;
use rstd::prelude::*;
use codec::Encode;
use runtime_support::StorageValue;
use primitives::traits::As;
use substrate_primitives::Blake2Hasher;
use {runtime_io, primitives};
use primitives;
use super::{Trait, Intentions, CurrentEra, OfflineSlashGrace, MinimumValidatorCount,
BondingDuration, SessionsPerEra, ValidatorCount, SessionReward, OfflineSlash};
@@ -60,8 +58,8 @@ impl<T: Trait> Default for GenesisConfig<T> {
}
impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
fn build_storage(self) -> ::std::result::Result<HashMap<Vec<u8>, Vec<u8>>, String> {
let r: runtime_io::TestExternalities<Blake2Hasher> = map![
fn build_storage(self) -> ::std::result::Result<primitives::StorageMap, String> {
Ok(map![
Self::hash(<Intentions<T>>::key()).to_vec() => self.intentions.encode(),
Self::hash(<SessionsPerEra<T>>::key()).to_vec() => self.sessions_per_era.encode(),
Self::hash(<ValidatorCount<T>>::key()).to_vec() => self.validator_count.encode(),
@@ -71,7 +69,6 @@ impl<T: Trait> primitives::BuildStorage for GenesisConfig<T> {
Self::hash(<SessionReward<T>>::key()).to_vec() => self.session_reward.encode(),
Self::hash(<OfflineSlash<T>>::key()).to_vec() => self.offline_slash.encode(),
Self::hash(<OfflineSlashGrace<T>>::key()).to_vec() => self.offline_slash_grace.encode()
];
Ok(r.into())
])
}
}
+13 -5
View File
@@ -20,8 +20,8 @@
use primitives::BuildStorage;
use primitives::traits::{Identity};
use primitives::testing::{Digest, Header};
use substrate_primitives::{H256, Blake2Hasher};
use primitives::testing::{Digest, DigestItem, Header};
use substrate_primitives::{H256, Blake2Hasher, RlpCodec};
use runtime_io;
use {GenesisConfig, Module, Trait, consensus, session, system, timestamp, balances};
@@ -34,7 +34,7 @@ impl_outer_origin!{
pub struct Test;
impl consensus::Trait for Test {
const NOTE_OFFLINE_POSITION: u32 = 1;
type Log = u64;
type Log = DigestItem;
type SessionKey = u64;
type OnOfflineValidator = ();
}
@@ -48,6 +48,7 @@ impl system::Trait for Test {
type AccountId = u64;
type Header = Header;
type Event = ();
type Log = DigestItem;
}
impl balances::Trait for Test {
type Balance = u64;
@@ -70,7 +71,14 @@ impl Trait for Test {
type Event = ();
}
pub fn new_test_ext(ext_deposit: u64, session_length: u64, sessions_per_era: u64, current_era: u64, monied: bool, reward: u64) -> runtime_io::TestExternalities<Blake2Hasher> {
pub fn new_test_ext(
ext_deposit: u64,
session_length: u64,
sessions_per_era: u64,
current_era: u64,
monied: bool,
reward: u64
) -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
let balance_factor = if ext_deposit > 0 {
256
@@ -116,7 +124,7 @@ pub fn new_test_ext(ext_deposit: u64, session_length: u64, sessions_per_era: u64
t.extend(timestamp::GenesisConfig::<Test>{
period: 5
}.build_storage().unwrap());
t.into()
runtime_io::TestExternalities::new(t)
}
pub type System = system::Module<Test>;
+14 -14
View File
@@ -29,7 +29,7 @@ fn note_null_offline_should_work() {
assert_eq!(Staking::offline_slash_grace(), 0);
assert_eq!(Staking::slash_count(&10), 0);
assert_eq!(Balances::free_balance(&10), 1);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
assert_eq!(Staking::slash_count(&10), 0);
assert_eq!(Balances::free_balance(&10), 1);
assert!(Staking::forcing_new_era().is_none());
@@ -43,7 +43,7 @@ fn note_offline_should_work() {
assert_eq!(Staking::offline_slash_grace(), 0);
assert_eq!(Staking::slash_count(&10), 0);
assert_eq!(Balances::free_balance(&10), 70);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
assert_eq!(Staking::slash_count(&10), 1);
assert_eq!(Balances::free_balance(&10), 50);
@@ -58,11 +58,11 @@ fn note_offline_exponent_should_work() {
assert_eq!(Staking::offline_slash_grace(), 0);
assert_eq!(Staking::slash_count(&10), 0);
assert_eq!(Balances::free_balance(&10), 150);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
assert_eq!(Staking::slash_count(&10), 1);
assert_eq!(Balances::free_balance(&10), 130);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
assert_eq!(Staking::slash_count(&10), 2);
assert_eq!(Balances::free_balance(&10), 90);
@@ -81,14 +81,14 @@ fn note_offline_grace_should_work() {
assert_eq!(Staking::slash_count(&10), 0);
assert_eq!(Balances::free_balance(&10), 70);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
assert_eq!(Staking::slash_count(&10), 1);
assert_eq!(Balances::free_balance(&10), 70);
assert_eq!(Staking::slash_count(&20), 0);
assert_eq!(Balances::free_balance(&20), 70);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
Staking::on_offline_validator(1);
assert_eq!(Staking::slash_count(&10), 2);
@@ -111,13 +111,13 @@ fn note_offline_force_unstake_session_change_should_work() {
assert_eq!(Staking::intentions(), vec![10, 20, 1]);
assert_eq!(Session::validators(), vec![10, 20]);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
assert_eq!(Balances::free_balance(&10), 50);
assert_eq!(Staking::slash_count(&10), 1);
assert_eq!(Staking::intentions(), vec![10, 20, 1]);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
assert_eq!(Staking::intentions(), vec![1, 20]);
assert_eq!(Balances::free_balance(&10), 10);
@@ -134,7 +134,7 @@ fn note_offline_auto_unstake_session_change_should_work() {
assert_eq!(Staking::intentions(), vec![10, 20]);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
Staking::on_offline_validator(1);
assert_eq!(Balances::free_balance(&10), 6980);
@@ -142,7 +142,7 @@ fn note_offline_auto_unstake_session_change_should_work() {
assert_eq!(Staking::intentions(), vec![10, 20]);
assert!(Staking::forcing_new_era().is_none());
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
Staking::on_offline_validator(1);
assert_eq!(Balances::free_balance(&10), 6940);
@@ -150,13 +150,13 @@ fn note_offline_auto_unstake_session_change_should_work() {
assert_eq!(Staking::intentions(), vec![20]);
assert!(Staking::forcing_new_era().is_some());
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(1);
assert_eq!(Balances::free_balance(&10), 6940);
assert_eq!(Balances::free_balance(&20), 6860);
assert_eq!(Staking::intentions(), vec![20]);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(1);
assert_eq!(Balances::free_balance(&10), 6940);
assert_eq!(Balances::free_balance(&20), 6700);
@@ -219,7 +219,7 @@ fn slashing_should_work() {
assert_eq!(Balances::total_balance(&10), 21);
System::set_block_number(7);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
Staking::on_offline_validator(1);
assert_eq!(Balances::total_balance(&10), 1);
@@ -390,7 +390,7 @@ fn nominating_slashes_should_work() {
assert_eq!(Balances::total_balance(&4), 40);
System::set_block_number(5);
::system::ExtrinsicIndex::<Test>::put(1);
System::set_extrinsic_index(1);
Staking::on_offline_validator(0);
Staking::on_offline_validator(1);
assert_eq!(Balances::total_balance(&1), 0);
+1 -1
View File
@@ -906,7 +906,7 @@ macro_rules! __decl_outer_log {
;
) => {
impl_outer_log!(
pub enum Log($log_internal: DigestItem<$( $log_genarg)* >) for $runtime {
pub enum Log($log_internal: DigestItem<$( $log_genarg ),*>) for $runtime {
$( $parsed_modules ( $( $parsed_args ),* ) ),*
}
);
+5 -5
View File
@@ -543,11 +543,11 @@ pub mod unhashed {
#[cfg(test)]
mod tests {
use super::*;
use runtime_io::{twox_128, TestExternalities, with_externalities};
use runtime_io::{twox_128, TestExternalities, RlpCodec, with_externalities};
#[test]
fn integers_can_be_stored() {
let mut t = TestExternalities::new();
let mut t = TestExternalities::<_, RlpCodec>::default();
with_externalities(&mut t, || {
let x = 69u32;
put(b":test", &x);
@@ -564,7 +564,7 @@ mod tests {
#[test]
fn bools_can_be_stored() {
let mut t = TestExternalities::new();
let mut t = TestExternalities::<_, RlpCodec>::default();
with_externalities(&mut t, || {
let x = true;
put(b":test", &x);
@@ -582,7 +582,7 @@ mod tests {
#[test]
fn vecs_can_be_retrieved() {
let mut t = TestExternalities::new();
let mut t = TestExternalities::<_, RlpCodec>::default();
with_externalities(&mut t, || {
runtime_io::set_storage(&twox_128(b":test"), b"\x0b\0\0\0Hello world");
let x = b"Hello world".to_vec();
@@ -594,7 +594,7 @@ mod tests {
#[test]
fn vecs_can_be_stored() {
let mut t = TestExternalities::new();
let mut t = TestExternalities::<_, RlpCodec>::default();
let x = b"Hello world".to_vec();
with_externalities(&mut t, || {
+107 -29
View File
@@ -19,7 +19,6 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(any(feature = "std", test))]
extern crate substrate_primitives;
#[cfg_attr(any(feature = "std", test), macro_use)]
@@ -45,17 +44,23 @@ extern crate safe_mix;
use rstd::prelude::*;
use primitives::traits::{self, CheckEqual, SimpleArithmetic, SimpleBitOps, Zero, One, Bounded,
Hash, Member, MaybeDisplay, EnsureOrigin};
use runtime_support::{StorageValue, StorageMap, Parameter};
Hash, Member, MaybeDisplay, EnsureOrigin, Digest as DigestT, As};
use runtime_support::{storage, StorageValue, StorageMap, Parameter};
use safe_mix::TripletMix;
#[cfg(any(feature = "std", test))]
use rstd::marker::PhantomData;
#[cfg(any(feature = "std", test))]
use codec::Encode;
#[cfg(any(feature = "std", test))]
use runtime_io::{twox_128, TestExternalities, Blake2Hasher};
use runtime_io::{twox_128, TestExternalities, Blake2Hasher, RlpCodec};
#[cfg(any(feature = "std", test))]
use substrate_primitives::ChangesTrieConfiguration;
/// Current extrinsic index (u32) is stored under this key.
pub const EXTRINSIC_INDEX: &'static [u8] = b":extrinsic_index";
/// Changes trie configuration is stored under this key.
pub const CHANGES_TRIE_CONFIG: &'static [u8] = b":changes_trie";
/// Compute the extrinsics root of a list of extrinsics.
pub fn extrinsics_root<H: Hash, E: codec::Encode>(extrinsics: &[E]) -> H::Output {
@@ -74,7 +79,7 @@ pub trait Trait: Eq + Clone {
type BlockNumber: Parameter + Member + MaybeDisplay + SimpleArithmetic + Default + Bounded + Copy + rstd::hash::Hash;
type Hash: Parameter + Member + MaybeDisplay + SimpleBitOps + Default + Copy + CheckEqual + rstd::hash::Hash + AsRef<[u8]>;
type Hashing: Hash<Output = Self::Hash>;
type Digest: Parameter + Member + Default + traits::Digest;
type Digest: Parameter + Member + Default + traits::Digest<Hash = Self::Hash>;
type AccountId: Parameter + Member + MaybeDisplay + Ord + Default;
type Header: Parameter + traits::Header<
Number = Self::BlockNumber,
@@ -82,6 +87,7 @@ pub trait Trait: Eq + Clone {
Digest = Self::Digest
>;
type Event: Parameter + Member + From<Event>;
type Log: From<Log<Self>> + Into<DigestItemOf<Self>>;
}
pub type DigestItemOf<T> = <<T as Trait>::Digest as traits::Digest>::Item;
@@ -144,6 +150,39 @@ impl<AccountId> From<Option<AccountId>> for RawOrigin<AccountId> {
/// Exposed trait-generic origin type.
pub type Origin<T> = RawOrigin<<T as Trait>::AccountId>;
pub type Log<T> = RawLog<
<T as Trait>::Hash,
>;
/// A logs in this module.
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[derive(Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog<Hash> {
/// Changes trie has been computed for this block. Contains the root of
/// changes trie.
ChangesTrieRoot(Hash),
}
impl<Hash: Member> RawLog<Hash> {
/// Try to cast the log entry as ChangesTrieRoot log entry.
pub fn as_changes_trie_root(&self) -> Option<&Hash> {
match *self {
RawLog::ChangesTrieRoot(ref item) => Some(item),
}
}
}
// Implementation for tests outside of this crate.
#[cfg(any(feature = "std", test))]
impl From<RawLog<substrate_primitives::H256>> for primitives::testing::DigestItem {
fn from(log: RawLog<substrate_primitives::H256>) -> primitives::testing::DigestItem {
match log {
RawLog::ChangesTrieRoot(root) => primitives::generic::DigestItem::ChangesTrieRoot
::<substrate_primitives::H256, u64>(root),
}
}
}
decl_storage! {
trait Store for Module<T: Trait> as System {
@@ -151,7 +190,6 @@ decl_storage! {
ExtrinsicCount: u32;
pub BlockHash get(block_hash): required map [ T::BlockNumber => T::Hash ];
pub ExtrinsicIndex get(extrinsic_index): u32;
ExtrinsicData get(extrinsic_data): required map [ u32 => Vec<u8> ];
RandomSeed get(random_seed): required T::Hash;
/// The current block number being processed. Set by `execute_block`.
@@ -204,15 +242,20 @@ pub fn ensure_inherent<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), &'s
}
impl<T: Trait> Module<T> {
/// Gets the index of extrinsic that is currenty executing.
pub fn extrinsic_index() -> Option<u32> {
storage::unhashed::get(EXTRINSIC_INDEX)
}
/// Start the execution of a particular block.
pub fn initialise(number: &T::BlockNumber, parent_hash: &T::Hash, txs_root: &T::Hash) {
// populate environment.
storage::unhashed::put(EXTRINSIC_INDEX, &0u32);
<Number<T>>::put(number);
<ParentHash<T>>::put(parent_hash);
<BlockHash<T>>::insert(*number - One::one(), parent_hash);
<ExtrinsicsRoot<T>>::put(txs_root);
<RandomSeed<T>>::put(Self::calculate_random());
<ExtrinsicIndex<T>>::put(0u32);
<Events<T>>::kill();
}
@@ -223,13 +266,23 @@ impl<T: Trait> Module<T> {
let number = <Number<T>>::take();
let parent_hash = <ParentHash<T>>::take();
let digest = <Digest<T>>::take();
let mut digest = <Digest<T>>::take();
let extrinsics_root = <ExtrinsicsRoot<T>>::take();
let storage_root = T::Hashing::storage_root();
let storage_changes_root = T::Hashing::storage_changes_root(number.as_());
// we can't compute changes trie root earlier && put it to the Digest
// because it will include all currently existing temporaries
if let Some(storage_changes_root) = storage_changes_root {
let item = RawLog::ChangesTrieRoot(storage_changes_root);
let item = <T as Trait>::Log::from(item).into();
digest.push(item);
}
// <Events<T>> stays to be inspected by the client.
<T::Header as traits::Header>::new(number, extrinsics_root, storage_root, parent_hash, digest)
<T::Header as traits::Header>::new(number, extrinsics_root, storage_root,
parent_hash, digest)
}
/// Deposits a log and ensures it matches the blocks log data.
@@ -241,7 +294,8 @@ impl<T: Trait> Module<T> {
/// Deposits an event onto this block's event record.
pub fn deposit_event(event: T::Event) {
let phase = <ExtrinsicIndex<T>>::get().map_or(Phase::Finalization, |c| Phase::ApplyExtrinsic(c));
let extrinsic_index = Self::extrinsic_index();
let phase = extrinsic_index.map_or(Phase::Finalization, |c| Phase::ApplyExtrinsic(c));
let mut events = Self::events();
events.push(EventRecord { phase, event });
<Events<T>>::put(events);
@@ -261,13 +315,13 @@ impl<T: Trait> Module<T> {
/// Get the basic externalities for this module, useful for tests.
#[cfg(any(feature = "std", test))]
pub fn externalities() -> TestExternalities<Blake2Hasher> {
map![
pub fn externalities() -> TestExternalities<Blake2Hasher, RlpCodec> {
TestExternalities::new(map![
twox_128(&<BlockHash<T>>::key_for(T::BlockNumber::zero())).to_vec() => [69u8; 32].encode(), // TODO: replace with Hash::default().encode
twox_128(<Number<T>>::key()).to_vec() => T::BlockNumber::one().encode(),
twox_128(<ParentHash<T>>::key()).to_vec() => [69u8; 32].encode(), // TODO: replace with Hash::default().encode
twox_128(<RandomSeed<T>>::key()).to_vec() => T::Hash::default().encode()
]
])
}
/// Set the block number to something in particular. Can be used as an alternative to
@@ -277,6 +331,12 @@ impl<T: Trait> Module<T> {
<Number<T>>::put(n);
}
/// Sets the index of extrinsic that is currenty executing.
#[cfg(any(feature = "std", test))]
pub fn set_extrinsic_index(extrinsic_index: u32) {
storage::unhashed::put(EXTRINSIC_INDEX, &extrinsic_index)
}
/// Set the parent hash number to something in particular. Can be used as an alternative to
/// `initialise` for tests that don't need to bother with the other environment entries.
#[cfg(any(feature = "std", test))]
@@ -299,7 +359,7 @@ impl<T: Trait> Module<T> {
/// Note what the extrinsic data of the current extrinsic index is. If this is called, then
/// ensure `derive_extrinsics` is also called before block-building is completed.
pub fn note_extrinsic(encoded_xt: Vec<u8>) {
<ExtrinsicData<T>>::insert(<ExtrinsicIndex<T>>::get().unwrap_or_default(), encoded_xt);
<ExtrinsicData<T>>::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt);
}
/// To be called immediately after an extrinsic has been applied.
@@ -308,14 +368,16 @@ impl<T: Trait> Module<T> {
Ok(_) => Event::ExtrinsicSuccess,
Err(_) => Event::ExtrinsicFailed,
}.into());
<ExtrinsicIndex<T>>::put(<ExtrinsicIndex<T>>::get().unwrap_or_default() + 1u32);
let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32;
storage::unhashed::put(EXTRINSIC_INDEX, &next_extrinsic_index);
}
/// To be called immediately after `note_applied_extrinsic` of the last extrinsic of the block
/// has been called.
pub fn note_finished_extrinsics() {
<ExtrinsicCount<T>>::put(<ExtrinsicIndex<T>>::get().unwrap_or_default());
<ExtrinsicIndex<T>>::kill();
let extrinsic_index: u32 = storage::unhashed::take(EXTRINSIC_INDEX).unwrap_or_default();
<ExtrinsicCount<T>>::put(extrinsic_index);
}
/// Remove all extrinsics data and save the extrinsics trie root.
@@ -330,12 +392,20 @@ impl<T: Trait> Module<T> {
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct GenesisConfig<T: Trait>(PhantomData<T>);
pub struct GenesisConfig<T: Trait> {
/// Changes trie configuration.
pub changes_trie_config: Option<ChangesTrieConfiguration>,
/// Marker for 'storing' T.
pub _phantom: ::std::marker::PhantomData<T>,
}
#[cfg(any(feature = "std", test))]
impl<T: Trait> Default for GenesisConfig<T> {
fn default() -> Self {
GenesisConfig(PhantomData)
GenesisConfig {
changes_trie_config: Default::default(),
_phantom: Default::default(),
}
}
}
@@ -345,13 +415,22 @@ impl<T: Trait> primitives::BuildStorage for GenesisConfig<T>
fn build_storage(self) -> Result<primitives::StorageMap, String> {
use codec::Encode;
Ok(map![
let mut storage: primitives::StorageMap = map![
Self::hash(&<BlockHash<T>>::key_for(T::BlockNumber::zero())).to_vec() => [69u8; 32].encode(),
Self::hash(<Number<T>>::key()).to_vec() => 1u64.encode(),
Self::hash(<ParentHash<T>>::key()).to_vec() => [69u8; 32].encode(),
Self::hash(<RandomSeed<T>>::key()).to_vec() => [0u8; 32].encode(),
Self::hash(<ExtrinsicIndex<T>>::key()).to_vec() => [0u8; 4].encode()
])
Self::hash(<RandomSeed<T>>::key()).to_vec() => [0u8; 32].encode()
];
storage.insert(EXTRINSIC_INDEX.to_vec(), 0u32.encode());
if let Some(changes_trie_config) = self.changes_trie_config {
storage.insert(
CHANGES_TRIE_CONFIG.to_vec(),
changes_trie_config.encode());
}
Ok(storage)
}
}
@@ -362,7 +441,7 @@ mod tests {
use substrate_primitives::H256;
use primitives::BuildStorage;
use primitives::traits::BlakeTwo256;
use primitives::testing::{Digest, Header};
use primitives::testing::{Digest, DigestItem, Header};
impl_outer_origin!{
pub enum Origin for Test where system = super {}
@@ -380,6 +459,7 @@ mod tests {
type AccountId = u64;
type Header = Header;
type Event = u16;
type Log = DigestItem;
}
impl From<Event> for u16 {
@@ -393,9 +473,7 @@ mod tests {
type System = Module<Test>;
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
GenesisConfig::<Test>::default().build_storage().unwrap().into()
}
+10 -9
View File
@@ -167,11 +167,11 @@ impl<T: Trait> runtime_primitives::BuildStorage for GenesisConfig<T>
mod tests {
use super::*;
use runtime_io::with_externalities;
use runtime_io::{with_externalities, TestExternalities, RlpCodec};
use substrate_primitives::H256;
use runtime_primitives::BuildStorage;
use runtime_primitives::traits::{BlakeTwo256};
use runtime_primitives::testing::{Digest, Header};
use runtime_primitives::testing::{Digest, DigestItem, Header};
impl_outer_origin! {
pub enum Origin for Test {}
@@ -189,10 +189,11 @@ mod tests {
type AccountId = u64;
type Header = Header;
type Event = ();
type Log = DigestItem;
}
impl consensus::Trait for Test {
const NOTE_OFFLINE_POSITION: u32 = 1;
type Log = u64;
type Log = DigestItem;
type SessionKey = u64;
type OnOfflineValidator = ();
}
@@ -206,8 +207,8 @@ mod tests {
fn timestamp_works() {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(GenesisConfig::<Test> { period: 0 }.build_storage().unwrap());
let mut t = runtime_io::TestExternalities::from(t);
with_externalities(&mut t, || {
with_externalities(&mut TestExternalities::<_, RlpCodec>::new(t), || {
Timestamp::set_timestamp(42);
assert_ok!(Timestamp::dispatch(Call::set(69), Origin::INHERENT));
assert_eq!(Timestamp::now(), 69);
@@ -219,8 +220,8 @@ mod tests {
fn double_timestamp_should_fail() {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(GenesisConfig::<Test> { period: 5 }.build_storage().unwrap());
let mut t = runtime_io::TestExternalities::from(t);
with_externalities(&mut t, || {
with_externalities(&mut TestExternalities::<_, RlpCodec>::new(t), || {
Timestamp::set_timestamp(42);
assert_ok!(Timestamp::dispatch(Call::set(69), Origin::INHERENT));
let _ = Timestamp::dispatch(Call::set(70), Origin::INHERENT);
@@ -232,8 +233,8 @@ mod tests {
fn block_period_is_enforced() {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(GenesisConfig::<Test> { period: 5 }.build_storage().unwrap());
let mut t = runtime_io::TestExternalities::from(t);
with_externalities(&mut t, || {
with_externalities(&mut TestExternalities::<_, RlpCodec>::new(t), || {
Timestamp::set_timestamp(42);
let _ = Timestamp::dispatch(Call::set(46), Origin::INHERENT);
});
+4 -3
View File
@@ -331,10 +331,10 @@ mod tests {
use super::*;
use runtime_io::with_externalities;
use substrate_primitives::{H256, Blake2Hasher};
use substrate_primitives::{H256, Blake2Hasher, RlpCodec};
use runtime_primitives::BuildStorage;
use runtime_primitives::traits::{BlakeTwo256};
use runtime_primitives::testing::{Digest, Header};
use runtime_primitives::testing::{Digest, DigestItem, Header};
impl_outer_origin! {
pub enum Origin for Test {}
@@ -352,6 +352,7 @@ mod tests {
type AccountId = u64;
type Header = Header;
type Event = ();
type Log = DigestItem;
}
impl balances::Trait for Test {
type Balance = u64;
@@ -368,7 +369,7 @@ mod tests {
type Balances = balances::Module<Test>;
type Treasury = Module<Test>;
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher, RlpCodec> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
t.extend(balances::GenesisConfig::<Test>{
balances: vec![(0, 100), (1, 99), (2, 1)],