A random beacon (#96)

* Completely rework dispatch mechanism into something modular.

Not yet complete but 75% there.

* Council vote tests.

* Fix tests.

* whitespace.

* Fix demo runtime tests.

* Fix up tests.

* Remove dead code.

* Initial util code for random beacon

* Timestamp uses new storage API.

* Move over system module to new API.

* Much nicer storage API, moved over staking module.

* More refactoring.

* Democracy uses new storage API.

* Council uses new RPC.

* Fix more tests.

* Use match for Id

* Generic mix.

* Integrate random beacon

* Update binaries.

* Fixes relating to with_ext removal.

* Remove dead code.

* Rework mixer into an iterator adaptor.

* Link to paper.

* Algorithm cleanups

* Merge and fix test.

* Docs.

* Fix typo.

* rename

* Fix tests.
This commit is contained in:
Gav Wood
2018-03-20 10:48:11 +08:00
committed by GitHub
parent 1ecd05dac9
commit ad552cba4b
21 changed files with 432 additions and 336 deletions
+32 -13
View File
@@ -46,7 +46,8 @@ mod tests {
use demo_primitives::{Hash, Header, BlockNumber, Digest};
use demo_runtime::transaction::{Transaction, UncheckedTransaction};
use demo_runtime::block::Block;
use demo_runtime::runtime::staking::{self, FreeBalanceOf, balance};
use demo_runtime::runtime::staking::{FreeBalanceOf, balance};
use demo_runtime::runtime::{staking, system};
use demo_runtime::dispatch;
use ed25519::{Public, Pair};
@@ -76,10 +77,13 @@ mod tests {
fn panic_execution_with_foreign_code_gives_error() {
let mut t: TestExternalities = map![
twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0],
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8],
twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32]
];
let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
let r = Executor::new().call(&mut t, BLOATY_CODE, "initialise_block", &vec![].and(&Header::from_block_number(1u64)));
assert!(r.is_ok());
let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&tx()));
assert!(r.is_err());
}
@@ -87,10 +91,13 @@ mod tests {
fn panic_execution_with_native_equivalent_code_gives_error() {
let mut t: TestExternalities = map![
twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0],
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8],
twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32]
];
let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
let r = Executor::new().call(&mut t, COMPACT_CODE, "initialise_block", &vec![].and(&Header::from_block_number(1u64)));
assert!(r.is_ok());
let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&tx()));
assert!(r.is_err());
}
@@ -98,10 +105,13 @@ mod tests {
fn successful_execution_with_native_equivalent_code_gives_ok() {
let mut t: TestExternalities = map![
twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8],
twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32]
];
let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
let r = Executor::new().call(&mut t, COMPACT_CODE, "initialise_block", &vec![].and(&Header::from_block_number(1u64)));
assert!(r.is_ok());
let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&tx()));
assert!(r.is_ok());
runtime_io::with_externalities(&mut t, || {
@@ -114,10 +124,13 @@ mod tests {
fn successful_execution_with_foreign_code_gives_ok() {
let mut t: TestExternalities = map![
twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8],
twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32]
];
let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
let r = Executor::new().call(&mut t, BLOATY_CODE, "initialise_block", &vec![].and(&Header::from_block_number(1u64)));
assert!(r.is_ok());
let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&tx()));
assert!(r.is_ok());
runtime_io::with_externalities(&mut t, || {
@@ -229,11 +242,14 @@ mod tests {
fn panic_execution_gives_error() {
let mut t: TestExternalities = map![
twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0],
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8],
twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32]
];
let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm");
let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
let r = WasmExecutor.call(&mut t, &foreign_code[..], "initialise_block", &vec![].and(&Header::from_block_number(1u64)));
assert!(r.is_ok());
let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&tx()));
assert!(r.is_err());
}
@@ -241,11 +257,14 @@ mod tests {
fn successful_execution_gives_ok() {
let mut t: TestExternalities = map![
twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8],
twox_128(&system::BlockHashAt::key_for(0)).to_vec() => vec![0u8; 32]
];
let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm");
let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
let r = WasmExecutor.call(&mut t, &foreign_code[..], "initialise_block", &vec![].and(&Header::from_block_number(1u64)));
assert!(r.is_ok());
let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&tx()));
assert!(r.is_ok());
runtime_io::with_externalities(&mut t, || {
+3 -2
View File
@@ -18,8 +18,9 @@ use runtime::{system, consensus, session};
impl_stubs!(
execute_block => |block| system::internal::execute_block(block),
execute_transaction => |(header, utx)| system::internal::execute_transaction(utx, header),
finalise_block => |header| system::internal::finalise_block(header),
initialise_block => |header| system::internal::initialise_block(&header),
execute_transaction => |utx| system::internal::execute_transaction(utx),
finalise_block => |()| system::internal::finalise_block(),
validator_count => |()| session::validator_count(),
validators => |()| session::validators(),
authorities => |()| consensus::authorities()
-82
View File
@@ -1,82 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Substrate Demo.
// Substrate Demo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate Demo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate Demo. If not, see <http://www.gnu.org/licenses/>.
//! Environment API: Allows certain information to be accessed throughout the runtime.
use rstd::boxed::Box;
use rstd::mem;
use rstd::cell::RefCell;
use rstd::rc::Rc;
use demo_primitives::{BlockNumber, Digest, Hash};
#[derive(Default)]
/// The information that can be accessed globally.
pub struct Environment {
/// The current block number.
pub block_number: BlockNumber,
/// The current block's parent hash.
pub parent_hash: Hash,
/// The current block digest.
pub digest: Digest,
}
/// Do something with the environment and return its value. Keep the function short.
pub fn with_env<T, F: FnOnce(&mut Environment) -> T>(f: F) -> T {
let e = env();
let mut eb = e.borrow_mut();
f(&mut *eb)
}
#[cfg(target_arch = "wasm32")]
fn env() -> Rc<RefCell<Environment>> {
// Initialize it to a null value
static mut SINGLETON: *const Rc<RefCell<Environment>> = 0 as *const Rc<RefCell<Environment>>;
unsafe {
if SINGLETON == 0 as *const Rc<RefCell<Environment>> {
// Make it
let singleton: Rc<RefCell<Environment>> = Rc::new(RefCell::new(Default::default()));
// Put it in the heap so it can outlive this call
SINGLETON = mem::transmute(Box::new(singleton));
}
// Now we give out a copy of the data that is safe to use concurrently.
(*SINGLETON).clone()
}
}
#[cfg(not(target_arch = "wasm32"))]
fn env() -> Rc<RefCell<Environment>> {
// Initialize it to a null value
thread_local!{
static SINGLETON: RefCell<*const Rc<RefCell<Environment>>> = RefCell::new(0 as *const Rc<RefCell<Environment>>);
}
SINGLETON.with(|s| unsafe {
if *s.borrow() == 0 as *const Rc<RefCell<Environment>> {
// Make it
let singleton: Rc<RefCell<Environment>> = Rc::new(RefCell::new(Default::default()));
// Put it in the heap so it can outlive this call
*s.borrow_mut() = mem::transmute(Box::new(singleton));
}
// Now we give out a copy of the data that is safe to use concurrently.
(**s.borrow()).clone()
})
}
+1 -1
View File
@@ -38,9 +38,9 @@ extern crate integer_sqrt;
#[macro_use] pub mod dispatch;
pub mod safe_mix;
pub mod block;
pub mod transaction;
pub mod environment;
pub mod runtime;
pub mod api;
+65 -66
View File
@@ -508,7 +508,6 @@ mod tests {
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner};
use keyring::Keyring::*;
use environment::with_env;
use demo_primitives::AccountId;
use runtime::{staking, session, democracy};
use super::public::Dispatch;
@@ -522,7 +521,7 @@ mod tests {
fn basic_environment_works() {
let mut t = new_test_ext();
with_externalities(&mut t, || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
assert_eq!(next_vote_from(1), 4);
assert_eq!(next_vote_from(4), 4);
assert_eq!(next_vote_from(5), 8);
@@ -554,7 +553,7 @@ mod tests {
#[test]
fn simple_candidate_submission_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
assert_eq!(candidates(), Vec::<AccountId>::new());
assert_eq!(candidate_reg_info(*Alice), None);
assert_eq!(candidate_reg_info(*Bob), None);
@@ -590,7 +589,7 @@ mod tests {
let mut t = new_test_ext_with_candidate_holes();
with_externalities(&mut t, || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
assert_eq!(candidates(), vec![AccountId::default(), AccountId::default(), Alice.to_raw_public()]);
PublicPass::test(&Bob).submit_candidacy(1);
@@ -606,7 +605,7 @@ mod tests {
let mut t = new_test_ext_with_candidate_holes();
with_externalities(&mut t, || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
assert_eq!(candidates(), vec![AccountId::default(), AccountId::default(), Alice.into()]);
PublicPass::test(&Bob).submit_candidacy(0);
@@ -623,7 +622,7 @@ mod tests {
let mut t = new_test_ext_with_candidate_holes();
with_externalities(&mut t, || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
PublicPass::test(&Dave).submit_candidacy(3);
});
}
@@ -632,7 +631,7 @@ mod tests {
#[should_panic(expected = "invalid candidate slot")]
fn bad_candidate_slot_submission_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
assert_eq!(candidates(), Vec::<AccountId>::new());
PublicPass::test(&Alice).submit_candidacy(1);
});
@@ -642,7 +641,7 @@ mod tests {
#[should_panic(expected = "invalid candidate slot")]
fn non_free_candidate_slot_submission_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
assert_eq!(candidates(), Vec::<AccountId>::new());
PublicPass::test(&Alice).submit_candidacy(0);
PublicPass::test(&Bob).submit_candidacy(0);
@@ -653,7 +652,7 @@ mod tests {
#[should_panic(expected = "duplicate candidate submission")]
fn dupe_candidate_submission_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
assert_eq!(candidates(), Vec::<AccountId>::new());
PublicPass::test(&Alice).submit_candidacy(0);
PublicPass::test(&Alice).submit_candidacy(1);
@@ -664,7 +663,7 @@ mod tests {
#[should_panic(expected = "candidate has not enough funds")]
fn poor_candidate_submission_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
assert_eq!(candidates(), Vec::<AccountId>::new());
PublicPass::test(&One).submit_candidacy(0);
});
@@ -673,7 +672,7 @@ mod tests {
#[test]
fn voting_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
PublicPass::test(&Eve).submit_candidacy(0);
@@ -702,7 +701,7 @@ mod tests {
#[test]
fn resubmitting_voting_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
PublicPass::test(&Eve).submit_candidacy(0);
PublicPass::test(&Dave).set_approvals(vec![true], 0);
@@ -720,7 +719,7 @@ mod tests {
#[test]
fn retracting_voter_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
PublicPass::test(&Eve).submit_candidacy(0);
PublicPass::test(&Bob).submit_candidacy(1);
@@ -767,7 +766,7 @@ mod tests {
#[should_panic(expected = "retraction index mismatch")]
fn invalid_retraction_index_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
PublicPass::test(&Charlie).submit_candidacy(0);
PublicPass::test(&Alice).set_approvals(vec![true], 0);
PublicPass::test(&Bob).set_approvals(vec![true], 0);
@@ -779,7 +778,7 @@ mod tests {
#[should_panic(expected = "retraction index invalid")]
fn overflow_retraction_index_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
PublicPass::test(&Charlie).submit_candidacy(0);
PublicPass::test(&Alice).set_approvals(vec![true], 0);
PublicPass::test(&Alice).retract_voter(1);
@@ -790,7 +789,7 @@ mod tests {
#[should_panic(expected = "cannot retract non-voter")]
fn non_voter_retraction_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
PublicPass::test(&Charlie).submit_candidacy(0);
PublicPass::test(&Alice).set_approvals(vec![true], 0);
PublicPass::test(&Bob).retract_voter(0);
@@ -800,7 +799,7 @@ mod tests {
#[test]
fn simple_tally_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
assert!(!presentation_active());
PublicPass::test(&Bob).submit_candidacy(0);
@@ -809,7 +808,7 @@ mod tests {
PublicPass::test(&Eve).set_approvals(vec![false, true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
assert!(presentation_active());
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0);
PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0);
@@ -833,14 +832,14 @@ mod tests {
with_externalities(&mut new_test_ext(), || {
assert!(staking::can_slash(&Dave, 10));
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Bob).submit_candidacy(0);
PublicPass::test(&Eve).submit_candidacy(1);
PublicPass::test(&Bob).set_approvals(vec![true, false], 0);
PublicPass::test(&Eve).set_approvals(vec![false, true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0);
PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0);
PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0);
@@ -854,21 +853,21 @@ mod tests {
#[test]
fn retracting_inactive_voter_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Bob).submit_candidacy(0);
PublicPass::test(&Bob).set_approvals(vec![true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0);
internal::end_block();
with_env(|e| e.block_number = 8);
system::testing::set_block_number(8);
PublicPass::test(&Eve).submit_candidacy(0);
PublicPass::test(&Eve).set_approvals(vec![true], 1);
internal::end_block();
with_env(|e| e.block_number = 10);
system::testing::set_block_number(10);
PublicPass::test(&Dave).present_winner(Eve.into(), 41, 1);
internal::end_block();
@@ -889,21 +888,21 @@ mod tests {
#[should_panic(expected = "candidate must not form a duplicated member if elected")]
fn presenting_for_double_election_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Bob).submit_candidacy(0);
PublicPass::test(&Bob).set_approvals(vec![true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0);
internal::end_block();
with_env(|e| e.block_number = 8);
system::testing::set_block_number(8);
PublicPass::test(&Bob).submit_candidacy(0);
PublicPass::test(&Bob).set_approvals(vec![true], 1);
internal::end_block();
with_env(|e| e.block_number = 10);
system::testing::set_block_number(10);
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 1);
});
}
@@ -911,25 +910,25 @@ mod tests {
#[test]
fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Bob).submit_candidacy(0);
PublicPass::test(&Bob).set_approvals(vec![true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0);
internal::end_block();
with_env(|e| e.block_number = 8);
system::testing::set_block_number(8);
PublicPass::test(&Eve).submit_candidacy(0);
PublicPass::test(&Eve).set_approvals(vec![true], 1);
internal::end_block();
with_env(|e| e.block_number = 10);
system::testing::set_block_number(10);
PublicPass::test(&Dave).present_winner(Eve.into(), 41, 1);
internal::end_block();
with_env(|e| e.block_number = 11);
system::testing::set_block_number(11);
PublicPass::test(&Alice).submit_candidacy(0);
PublicPass::test(&Eve).reap_inactive_voter(
@@ -949,21 +948,21 @@ mod tests {
#[should_panic(expected = "bad reporter index")]
fn retracting_inactive_voter_with_bad_reporter_index_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Bob).submit_candidacy(0);
PublicPass::test(&Bob).set_approvals(vec![true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 8, 0);
internal::end_block();
with_env(|e| e.block_number = 8);
system::testing::set_block_number(8);
PublicPass::test(&Eve).submit_candidacy(0);
PublicPass::test(&Eve).set_approvals(vec![true], 1);
internal::end_block();
with_env(|e| e.block_number = 10);
system::testing::set_block_number(10);
PublicPass::test(&Dave).present_winner(Eve.into(), 38, 1);
internal::end_block();
@@ -979,21 +978,21 @@ mod tests {
#[should_panic(expected = "bad target index")]
fn retracting_inactive_voter_with_bad_target_index_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Bob).submit_candidacy(0);
PublicPass::test(&Bob).set_approvals(vec![true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 8, 0);
internal::end_block();
with_env(|e| e.block_number = 8);
system::testing::set_block_number(8);
PublicPass::test(&Eve).submit_candidacy(0);
PublicPass::test(&Eve).set_approvals(vec![true], 1);
internal::end_block();
with_env(|e| e.block_number = 10);
system::testing::set_block_number(10);
PublicPass::test(&Dave).present_winner(Eve.into(), 38, 1);
internal::end_block();
@@ -1008,7 +1007,7 @@ mod tests {
#[test]
fn attempting_to_retract_active_voter_should_slash_reporter() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Bob).submit_candidacy(0);
PublicPass::test(&Charlie).submit_candidacy(1);
PublicPass::test(&Dave).submit_candidacy(2);
@@ -1019,18 +1018,18 @@ mod tests {
PublicPass::test(&Eve).set_approvals(vec![false, false, false, true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0);
PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0);
PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0);
PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0);
internal::end_block();
with_env(|e| e.block_number = 8);
system::testing::set_block_number(8);
PrivPass::test().set_desired_seats(3);
internal::end_block();
with_env(|e| e.block_number = 10);
system::testing::set_block_number(10);
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 1);
PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 1);
internal::end_block();
@@ -1051,21 +1050,21 @@ mod tests {
#[should_panic(expected = "reaper must be a voter")]
fn attempting_to_retract_inactive_voter_by_nonvoter_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Bob).submit_candidacy(0);
PublicPass::test(&Bob).set_approvals(vec![true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0);
internal::end_block();
with_env(|e| e.block_number = 8);
system::testing::set_block_number(8);
PublicPass::test(&Eve).submit_candidacy(0);
PublicPass::test(&Eve).set_approvals(vec![true], 1);
internal::end_block();
with_env(|e| e.block_number = 10);
system::testing::set_block_number(10);
PublicPass::test(&Dave).present_winner(Eve.into(), 41, 1);
internal::end_block();
@@ -1081,7 +1080,7 @@ mod tests {
#[should_panic(expected = "candidate not worthy of leaderboard")]
fn presenting_loser_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Alice).submit_candidacy(0);
PublicPass::test(&Ferdie).set_approvals(vec![true], 0);
PublicPass::test(&Bob).submit_candidacy(1);
@@ -1094,7 +1093,7 @@ mod tests {
PublicPass::test(&Eve).set_approvals(vec![false, false, false, false, true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0);
PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0);
PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0);
@@ -1106,7 +1105,7 @@ mod tests {
#[test]
fn presenting_loser_first_should_not_matter() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Alice).submit_candidacy(0);
PublicPass::test(&Ferdie).set_approvals(vec![true], 0);
PublicPass::test(&Bob).submit_candidacy(1);
@@ -1119,7 +1118,7 @@ mod tests {
PublicPass::test(&Eve).set_approvals(vec![false, false, false, false, true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 0);
PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0);
PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0);
@@ -1139,7 +1138,7 @@ mod tests {
#[should_panic(expected = "cannot present outside of presentation period")]
fn present_panics_outside_of_presentation_period() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
assert!(!presentation_active());
PublicPass::test(&Eve).present_winner(Eve.into(), 1, 0);
});
@@ -1149,14 +1148,14 @@ mod tests {
#[should_panic(expected = "index not current")]
fn present_panics_with_invalid_vote_index() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Bob).submit_candidacy(0);
PublicPass::test(&Eve).submit_candidacy(1);
PublicPass::test(&Bob).set_approvals(vec![true, false], 0);
PublicPass::test(&Eve).set_approvals(vec![false, true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 11, 1);
});
}
@@ -1165,7 +1164,7 @@ mod tests {
#[should_panic(expected = "presenter must have sufficient slashable funds")]
fn present_panics_when_presenter_is_poor() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
assert!(!presentation_active());
PublicPass::test(&Alice).submit_candidacy(0);
@@ -1174,7 +1173,7 @@ mod tests {
PublicPass::test(&Eve).set_approvals(vec![false, true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
assert_eq!(staking::balance(&Alice), 1);
PublicPass::test(&Alice).present_winner(Alice.into(), 30, 0);
});
@@ -1183,7 +1182,7 @@ mod tests {
#[test]
fn invalid_present_tally_should_slash() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
assert!(!presentation_active());
assert_eq!(staking::balance(&Dave), 40);
@@ -1193,7 +1192,7 @@ mod tests {
PublicPass::test(&Eve).set_approvals(vec![false, true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Bob.into(), 80, 0);
assert_eq!(staking::balance(&Dave), 38);
@@ -1203,7 +1202,7 @@ mod tests {
#[test]
fn runners_up_should_be_kept() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
assert!(!presentation_active());
PublicPass::test(&Alice).submit_candidacy(0);
@@ -1219,7 +1218,7 @@ mod tests {
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
assert!(presentation_active());
PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0);
assert_eq!(leaderboard(), Some(vec![
@@ -1262,7 +1261,7 @@ mod tests {
#[test]
fn second_tally_should_use_runners_up() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PublicPass::test(&Alice).submit_candidacy(0);
PublicPass::test(&Ferdie).set_approvals(vec![true], 0);
PublicPass::test(&Bob).submit_candidacy(1);
@@ -1275,19 +1274,19 @@ mod tests {
PublicPass::test(&Eve).set_approvals(vec![false, false, false, false, true], 0);
internal::end_block();
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
PublicPass::test(&Dave).present_winner(Alice.into(), 60, 0);
PublicPass::test(&Dave).present_winner(Charlie.into(), 21, 0);
PublicPass::test(&Dave).present_winner(Dave.into(), 31, 0);
PublicPass::test(&Dave).present_winner(Eve.into(), 41, 0);
internal::end_block();
with_env(|e| e.block_number = 8);
system::testing::set_block_number(8);
PublicPass::test(&Ferdie).set_approvals(vec![false, false, true, false], 1);
PrivPass::test().set_desired_seats(3);
internal::end_block();
with_env(|e| e.block_number = 10);
system::testing::set_block_number(10);
PublicPass::test(&Dave).present_winner(Charlie.into(), 81, 1);
PublicPass::test(&Dave).present_winner(Dave.into(), 31, 1);
internal::end_block();
@@ -228,7 +228,6 @@ mod tests {
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner};
use keyring::Keyring::{Alice, Bob, Charlie, Dave};
use environment::with_env;
use demo_primitives::AccountId;
use runtime::democracy::VoteThreshold;
use runtime::{staking, council, democracy};
@@ -242,7 +241,7 @@ mod tests {
#[test]
fn basic_environment_works() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
assert_eq!(staking::bonding_duration(), 0);
assert_eq!(cooloff_period(), 2);
assert_eq!(voting_period(), 1);
@@ -274,7 +273,7 @@ mod tests {
#[test]
fn referendum_cancellation_should_work_when_unanimous() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
democracy::internal::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove);
assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]);
@@ -287,7 +286,7 @@ mod tests {
assert_eq!(proposals(), vec![(2, hash)]);
internal::end_block(1);
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
internal::end_block(2);
assert_eq!(democracy::active_referendums(), vec![]);
assert_eq!(staking::bonding_duration(), 0);
@@ -297,7 +296,7 @@ mod tests {
#[test]
fn referendum_cancellation_should_fail_when_not_unanimous() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
democracy::internal::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove);
@@ -308,7 +307,7 @@ mod tests {
PublicPass::new(&Charlie).vote(hash, false);
internal::end_block(1);
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
internal::end_block(2);
assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]);
});
@@ -317,7 +316,7 @@ mod tests {
#[test]
fn referendum_cancellation_should_fail_when_abstentions() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
democracy::internal::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove);
@@ -327,7 +326,7 @@ mod tests {
PublicPass::new(&Bob).vote(hash, true);
internal::end_block(1);
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
internal::end_block(2);
assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]);
});
@@ -336,7 +335,7 @@ mod tests {
#[test]
fn veto_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
let hash = proposal.blake2_256();
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
@@ -350,13 +349,13 @@ mod tests {
#[should_panic]
fn double_veto_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
let hash = proposal.blake2_256();
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
PublicPass::new(&Bob).veto(hash);
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
PublicPass::new(&Bob).veto(hash);
});
@@ -366,13 +365,13 @@ mod tests {
#[should_panic]
fn retry_in_cooloff_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
let hash = proposal.blake2_256();
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
PublicPass::new(&Bob).veto(hash);
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
});
}
@@ -380,19 +379,19 @@ mod tests {
#[test]
fn retry_after_cooloff_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
let hash = proposal.blake2_256();
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
PublicPass::new(&Bob).veto(hash);
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
PublicPass::new(&Bob).vote(hash, false);
PublicPass::new(&Charlie).vote(hash, true);
internal::end_block(3);
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
internal::end_block(4);
assert_eq!(proposals().len(), 0);
assert_eq!(democracy::active_referendums(), vec![(0, 7, bonding_duration_proposal(42), VoteThreshold::SimpleMajority)]);
@@ -402,13 +401,13 @@ mod tests {
#[test]
fn alternative_double_veto_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
let hash = proposal.blake2_256();
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
PublicPass::new(&Bob).veto(hash);
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
PublicPass::new(&Charlie).veto(hash);
assert_eq!(proposals().len(), 0);
@@ -419,7 +418,7 @@ mod tests {
#[test]
fn simple_propose_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
let hash = proposal.blake2_256();
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
@@ -433,13 +432,13 @@ mod tests {
#[test]
fn unvoted_proposal_should_expire_without_action() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
assert_eq!(tally(&proposal.blake2_256()), (1, 0, 2));
internal::end_block(1);
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
internal::end_block(2);
assert_eq!(proposals().len(), 0);
assert_eq!(democracy::active_referendums().len(), 0);
@@ -449,7 +448,7 @@ mod tests {
#[test]
fn unanimous_proposal_should_expire_with_biased_referendum() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
PublicPass::new(&Bob).vote(proposal.blake2_256(), true);
@@ -457,7 +456,7 @@ mod tests {
assert_eq!(tally(&proposal.blake2_256()), (3, 0, 0));
internal::end_block(1);
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
internal::end_block(2);
assert_eq!(proposals().len(), 0);
assert_eq!(democracy::active_referendums(), vec![(0, 5, proposal, VoteThreshold::SuperMajorityAgainst)]);
@@ -467,7 +466,7 @@ mod tests {
#[test]
fn majority_proposal_should_expire_with_unbiased_referendum() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
PublicPass::new(&Bob).vote(proposal.blake2_256(), true);
@@ -475,7 +474,7 @@ mod tests {
assert_eq!(tally(&proposal.blake2_256()), (2, 1, 0));
internal::end_block(1);
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
internal::end_block(2);
assert_eq!(proposals().len(), 0);
assert_eq!(democracy::active_referendums(), vec![(0, 5, proposal, VoteThreshold::SimpleMajority)]);
@@ -486,7 +485,7 @@ mod tests {
#[should_panic]
fn propose_by_public_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let proposal = bonding_duration_proposal(42);
PublicPass::new(&Dave).propose(Box::new(proposal));
});
+19 -20
View File
@@ -348,7 +348,6 @@ mod tests {
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner};
use keyring::Keyring::*;
use environment::with_env;
use demo_primitives::AccountId;
use dispatch::PrivCall as Proposal;
use runtime::staking::PublicPass;
@@ -382,7 +381,7 @@ mod tests {
#[test]
fn locked_for_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
propose_sessions_per_era(&Alice, 2, 2u64);
propose_sessions_per_era(&Alice, 4, 4u64);
propose_sessions_per_era(&Alice, 3, 3u64);
@@ -395,11 +394,11 @@ mod tests {
#[test]
fn single_proposal_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
propose_sessions_per_era(&Alice, 2, 1u64);
democracy::internal::end_block(system::block_number());
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
let r = 0;
PublicPass::test(&Alice).vote(r, true);
@@ -418,7 +417,7 @@ mod tests {
#[test]
fn deposit_for_proposals_should_be_taken() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
propose_sessions_per_era(&Alice, 2, 5u64);
PublicPass::test(&Bob).second(0);
PublicPass::test(&Eve).second(0);
@@ -433,7 +432,7 @@ mod tests {
#[test]
fn deposit_for_proposals_should_be_returned() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
propose_sessions_per_era(&Alice, 2, 5u64);
PublicPass::test(&Bob).second(0);
PublicPass::test(&Eve).second(0);
@@ -450,7 +449,7 @@ mod tests {
#[should_panic]
fn proposal_with_deposit_below_minimum_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
propose_sessions_per_era(&Alice, 2, 0u64);
});
}
@@ -459,7 +458,7 @@ mod tests {
#[should_panic]
fn poor_proposer_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
propose_sessions_per_era(&Alice, 2, 11u64);
});
}
@@ -468,7 +467,7 @@ mod tests {
#[should_panic]
fn poor_seconder_should_panic() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
propose_sessions_per_era(&Bob, 2, 11u64);
PublicPass::test(&Alice).second(0);
});
@@ -482,25 +481,25 @@ mod tests {
#[test]
fn runners_up_should_come_after() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 0);
system::testing::set_block_number(0);
propose_bonding_duration(&Alice, 2, 2u64);
propose_bonding_duration(&Alice, 4, 4u64);
propose_bonding_duration(&Alice, 3, 3u64);
democracy::internal::end_block(system::block_number());
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
PublicPass::test(&Alice).vote(0, true);
democracy::internal::end_block(system::block_number());
staking::internal::check_new_era();
assert_eq!(staking::bonding_duration(), 4u64);
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
PublicPass::test(&Alice).vote(1, true);
democracy::internal::end_block(system::block_number());
staking::internal::check_new_era();
assert_eq!(staking::bonding_duration(), 3u64);
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
PublicPass::test(&Alice).vote(2, true);
democracy::internal::end_block(system::block_number());
staking::internal::check_new_era();
@@ -515,7 +514,7 @@ mod tests {
#[test]
fn simple_passing_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove);
PublicPass::test(&Alice).vote(r, true);
@@ -533,10 +532,10 @@ mod tests {
#[test]
fn cancel_referendum_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove);
PublicPass::test(&Alice).vote(r, true);
PrivPass::new().cancel_referendum(r);
PrivPass::test().cancel_referendum(r);
democracy::internal::end_block(system::block_number());
staking::internal::check_new_era();
@@ -548,7 +547,7 @@ mod tests {
#[test]
fn simple_failing_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove);
PublicPass::test(&Alice).vote(r, false);
@@ -566,7 +565,7 @@ mod tests {
#[test]
fn controversial_voting_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove);
PublicPass::test(&Alice).vote(r, true);
PublicPass::test(&Bob).vote(r, false);
@@ -587,7 +586,7 @@ mod tests {
#[test]
fn controversial_low_turnout_voting_should_work() {
with_externalities(&mut new_test_ext(), || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove);
PublicPass::test(&Eve).vote(r, false);
PublicPass::test(&Ferdie).vote(r, true);
@@ -607,7 +606,7 @@ mod tests {
assert_eq!(staking::era_length(), 1u64);
assert_eq!(staking::total_stake(), 210u64);
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
let r = inject_referendum(1, sessions_per_era_propsal(2), VoteThreshold::SuperMajorityApprove);
PublicPass::test(&Dave).vote(r, true);
PublicPass::test(&Eve).vote(r, false);
+11 -12
View File
@@ -151,7 +151,6 @@ mod tests {
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner};
use keyring::Keyring;
use environment::with_env;
use demo_primitives::AccountId;
use runtime::{consensus, session};
@@ -183,46 +182,46 @@ mod tests {
let mut t = simple_setup();
with_externalities(&mut t, || {
// Block 1: Change to length 3; no visible change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
PrivPass::test().set_length(3);
check_rotate_session();
assert_eq!(length(), 2);
assert_eq!(current_index(), 0);
// Block 2: Length now changed to 3. Index incremented.
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
PrivPass::test().set_length(3);
check_rotate_session();
assert_eq!(length(), 3);
assert_eq!(current_index(), 1);
// Block 3: Length now changed to 3. Index incremented.
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
check_rotate_session();
assert_eq!(length(), 3);
assert_eq!(current_index(), 1);
// Block 4: Change to length 2; no visible change.
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
PrivPass::test().set_length(2);
check_rotate_session();
assert_eq!(length(), 3);
assert_eq!(current_index(), 1);
// Block 5: Length now changed to 2. Index incremented.
with_env(|e| e.block_number = 5);
system::testing::set_block_number(5);
check_rotate_session();
assert_eq!(length(), 2);
assert_eq!(current_index(), 2);
// Block 6: No change.
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
check_rotate_session();
assert_eq!(length(), 2);
assert_eq!(current_index(), 2);
// Block 7: Next index.
with_env(|e| e.block_number = 7);
system::testing::set_block_number(7);
check_rotate_session();
assert_eq!(length(), 2);
assert_eq!(current_index(), 3);
@@ -234,17 +233,17 @@ mod tests {
let mut t = simple_setup();
with_externalities(&mut t, || {
// Block 1: No change
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
check_rotate_session();
assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]);
// Block 2: Session rollover, but no change.
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
check_rotate_session();
assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]);
// Block 3: Set new key for validator 2; no visible change.
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
PublicPass::test(&[20; 32]).set_key([22; 32]);
assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]);
@@ -252,7 +251,7 @@ mod tests {
assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]);
// Block 4: Session rollover, authority 2 changes.
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
check_rotate_session();
assert_eq!(consensus::authorities(), vec![[11u8; 32], [22u8; 32]]);
});
+29 -30
View File
@@ -569,7 +569,6 @@ mod tests {
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner};
use keyring::Keyring::*;
use environment::with_env;
use demo_primitives::AccountId;
use runtime::{staking, session};
use runtime::democracy::PrivPass;
@@ -600,7 +599,7 @@ mod tests {
assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]);
// Block 1: Add three validators. No obvious change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
public::Call::stake().dispatch(PublicPass::new(&Alice));
PublicPass::new(&Bob).stake();
PublicPass::new(&Dave).stake();
@@ -608,39 +607,39 @@ mod tests {
assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]);
// Block 2: New validator set now.
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
check_new_era();
assert_eq!(session::validators(), vec![Dave.to_raw_public(), Bob.into()]);
// Block 3: Unstake highest, introduce another staker. No change yet.
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
PublicPass::new(&Charlie).stake();
PublicPass::new(&Dave).unstake();
check_new_era();
// Block 4: New era - validators change.
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
check_new_era();
assert_eq!(session::validators(), vec![Charlie.to_raw_public(), Bob.into()]);
// Block 5: Transfer stake from highest to lowest. No change yet.
with_env(|e| e.block_number = 5);
system::testing::set_block_number(5);
PublicPass::new(&Dave).transfer(Alice.to_raw_public(), 40);
check_new_era();
// Block 6: Lowest now validator.
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
check_new_era();
assert_eq!(session::validators(), vec![Alice.to_raw_public(), Charlie.into()]);
// Block 7: Unstake three. No change yet.
with_env(|e| e.block_number = 7);
system::testing::set_block_number(7);
PublicPass::new(&Charlie).unstake();
check_new_era();
assert_eq!(session::validators(), vec![Alice.to_raw_public(), Charlie.into()]);
// Block 8: Back to one and two.
with_env(|e| e.block_number = 8);
system::testing::set_block_number(8);
check_new_era();
assert_eq!(session::validators(), vec![Alice.to_raw_public(), Bob.into()]);
});
@@ -661,21 +660,21 @@ mod tests {
assert_eq!(CurrentEra::get(), 0u64);
// Block 1: No change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
check_new_era();
assert_eq!(SessionsPerEra::get(), 2u64);
assert_eq!(LastEraLengthChange::get(), 0u64);
assert_eq!(CurrentEra::get(), 0u64);
// Block 2: Simple era change.
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
check_new_era();
assert_eq!(SessionsPerEra::get(), 2u64);
assert_eq!(LastEraLengthChange::get(), 0u64);
assert_eq!(CurrentEra::get(), 1u64);
// Block 3: Schedule an era length change; no visible changes.
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
PrivPass::test().set_sessions_per_era(3);
check_new_era();
assert_eq!(SessionsPerEra::get(), 2u64);
@@ -683,28 +682,28 @@ mod tests {
assert_eq!(CurrentEra::get(), 1u64);
// Block 4: Era change kicks in.
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
check_new_era();
assert_eq!(SessionsPerEra::get(), 3u64);
assert_eq!(LastEraLengthChange::get(), 4u64);
assert_eq!(CurrentEra::get(), 2u64);
// Block 5: No change.
with_env(|e| e.block_number = 5);
system::testing::set_block_number(5);
check_new_era();
assert_eq!(SessionsPerEra::get(), 3u64);
assert_eq!(LastEraLengthChange::get(), 4u64);
assert_eq!(CurrentEra::get(), 2u64);
// Block 6: No change.
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
check_new_era();
assert_eq!(SessionsPerEra::get(), 3u64);
assert_eq!(LastEraLengthChange::get(), 4u64);
assert_eq!(CurrentEra::get(), 2u64);
// Block 7: Era increment.
with_env(|e| e.block_number = 7);
system::testing::set_block_number(7);
check_new_era();
assert_eq!(SessionsPerEra::get(), 3u64);
assert_eq!(LastEraLengthChange::get(), 4u64);
@@ -714,7 +713,7 @@ mod tests {
#[test]
fn staking_balance_works() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 42);
assert_eq!(FreeBalanceOf::get(*Alice), 42);
assert_eq!(ReservedBalanceOf::get(*Alice), 0);
@@ -738,7 +737,7 @@ mod tests {
#[test]
#[should_panic]
fn staking_balance_transfer_when_bonded_panics() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 111);
PublicPass::new(&Alice).stake();
PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69);
@@ -747,7 +746,7 @@ mod tests {
#[test]
fn reserving_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 111);
assert_eq!(balance(&Alice), 111);
@@ -765,7 +764,7 @@ mod tests {
#[test]
#[should_panic]
fn staking_balance_transfer_when_reserved_panics() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 111);
reserve_balance(&Alice, 69);
PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69);
@@ -774,7 +773,7 @@ mod tests {
#[test]
fn deducting_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 111);
assert!(deduct_unbonded(&Alice, 69));
assert_eq!(FreeBalanceOf::get(*Alice), 42);
@@ -788,7 +787,7 @@ mod tests {
twox_128(&BondageOf::key_for(*Alice)).to_vec() => vec![].and(&2u64)
];
with_externalities(&mut t, || {
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
assert_eq!(unlock_block(&Alice), LockStatus::LockedUntil(2));
assert!(!deduct_unbonded(&Alice, 69));
});
@@ -796,7 +795,7 @@ mod tests {
#[test]
fn refunding_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 42);
refund(&Alice, 69);
assert_eq!(FreeBalanceOf::get(*Alice), 111);
@@ -805,7 +804,7 @@ mod tests {
#[test]
fn slashing_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 111);
reserve_balance(&Alice, 69);
assert!(slash(&Alice, 69));
@@ -816,7 +815,7 @@ mod tests {
#[test]
fn slashing_incomplete_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 42);
reserve_balance(&Alice, 21);
assert!(!slash(&Alice, 69));
@@ -827,7 +826,7 @@ mod tests {
#[test]
fn unreserving_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 111);
reserve_balance(&Alice, 111);
unreserve_balance(&Alice, 42);
@@ -838,7 +837,7 @@ mod tests {
#[test]
fn slashing_reserved_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 111);
reserve_balance(&Alice, 111);
assert!(slash_reserved(&Alice, 42));
@@ -849,7 +848,7 @@ mod tests {
#[test]
fn slashing_incomplete_reserved_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 111);
reserve_balance(&Alice, 42);
assert!(!slash_reserved(&Alice, 69));
@@ -860,7 +859,7 @@ mod tests {
#[test]
fn transferring_reserved_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 111);
reserve_balance(&Alice, 111);
assert!(transfer_reserved_balance(&Alice, &Bob, 42));
@@ -873,7 +872,7 @@ mod tests {
#[test]
fn transferring_incomplete_reserved_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
with_externalities(&mut testing::externalities(1, 3, 1), || {
FreeBalanceOf::insert(*Alice, 111);
reserve_balance(&Alice, 42);
assert!(!transfer_reserved_balance(&Alice, &Bob, 69));
+65 -49
View File
@@ -22,27 +22,27 @@ use rstd::mem;
use runtime_io::{print, storage_root, enumerated_trie_root};
use codec::{KeyedVec, Slicable};
use runtime_support::{Hashable, storage, StorageValue, StorageMap};
use environment::with_env;
use demo_primitives::{AccountId, Hash, TxOrder, BlockNumber, Header, Log};
use block::Block;
use block::{self, Block};
use transaction::UncheckedTransaction;
use runtime::{staking, session};
use runtime::democracy::PrivPass;
use dispatch;
use safe_mix::TripletMix;
storage_items! {
pub Nonce: b"sys:non" => default map [ AccountId => TxOrder ];
pub BlockHashAt: b"sys:old" => required map [ BlockNumber => Hash ];
pub Nonce get(nonce): b"sys:non" => default map [ AccountId => TxOrder ];
pub BlockHashAt get(block_hash): b"sys:old" => required map [ BlockNumber => Hash ];
RandomSeed get(random_seed): b"sys:rnd" => required Hash;
// The current block number being processed. Set by `execute_block`.
Number get(block_number): b"sys:num" => required BlockNumber;
ParentHash get(parent_hash): b"sys:pha" => required Hash;
TransactionsRoot get(transactions_root): b"sys:txr" => required Hash;
Digest: b"sys:dig" => default block::Digest;
}
pub const CODE: &'static[u8] = b":code";
/// The current block number being processed. Set by `execute_block`.
pub fn block_number() -> BlockNumber {
with_env(|e| e.block_number)
}
impl_dispatch! {
pub mod privileged;
fn set_code(new: Vec<u8>) = 0;
@@ -51,7 +51,7 @@ impl_dispatch! {
impl privileged::Dispatch for PrivPass {
/// Set the new code.
fn set_code(self, new: Vec<u8>) {
storage::unhashed::put_raw(b":code", &new);
storage::unhashed::put_raw(CODE, &new);
}
}
@@ -62,16 +62,14 @@ pub mod internal {
/// Deposits a log and ensures it matches the blocks log data.
pub fn deposit_log(log: Log) {
with_env(|e| e.digest.logs.push(log));
let mut l = Digest::get();
l.logs.push(log);
Digest::put(l);
}
/// Actually execute all transitioning for `block`.
pub fn execute_block(mut block: Block) {
// populate environment from header.
with_env(|e| {
e.block_number = block.header.number;
e.parent_hash = block.header.parent_hash;
});
initialise_block(&block.header);
// any initial checks
initial_checks(&block);
@@ -90,41 +88,35 @@ pub mod internal {
post_finalise(&block.header);
}
/// Start the execution of a particular block.
pub fn initialise_block(mut header: &Header) {
// populate environment from header.
Number::put(header.number);
ParentHash::put(header.parent_hash);
TransactionsRoot::put(header.transaction_root);
RandomSeed::put(calculate_random());
}
/// Execute a transaction outside of the block execution function.
/// This doesn't attempt to validate anything regarding the block.
pub fn execute_transaction(utx: UncheckedTransaction, mut header: Header) -> Header {
// populate environment from header.
with_env(|e| {
e.block_number = header.number;
e.parent_hash = header.parent_hash;
mem::swap(&mut header.digest, &mut e.digest);
});
pub fn execute_transaction(utx: UncheckedTransaction) {
super::execute_transaction(utx);
with_env(|e| {
mem::swap(&mut header.digest, &mut e.digest);
});
header
}
/// Finalise the block - it is up the caller to ensure that all header fields are valid
/// except state-root.
pub fn finalise_block(mut header: Header) -> Header {
// populate environment from header.
with_env(|e| {
e.block_number = header.number;
e.parent_hash = header.parent_hash;
mem::swap(&mut header.digest, &mut e.digest);
});
pub fn finalise_block() -> Header {
staking::internal::check_new_era();
session::internal::check_rotate_session();
header.state_root = storage_root().into();
with_env(|e| {
mem::swap(&mut header.digest, &mut e.digest);
});
RandomSeed::kill();
let header = Header {
number: Number::take(),
digest: Digest::take(),
parent_hash: ParentHash::take(),
transaction_root: TransactionsRoot::take(),
state_root: storage_root().into(),
};
post_finalise(&header);
@@ -176,9 +168,10 @@ fn final_checks(block: &Block) {
let ref header = block.header;
// check digest
with_env(|e| {
assert!(header.digest == e.digest);
});
assert!(header.digest == Digest::get());
// remove temporaries.
kill_temps();
// check storage root.
let storage_root = storage_root().into();
@@ -186,12 +179,27 @@ fn final_checks(block: &Block) {
assert!(header.state_root == storage_root, "Storage root must match that calculated.");
}
fn kill_temps() {
Number::kill();
ParentHash::kill();
RandomSeed::kill();
Digest::kill();
TransactionsRoot::kill();
}
fn post_finalise(header: &Header) {
// store the header hash in storage; we can't do it before otherwise there would be a
// cyclic dependency.
BlockHashAt::insert(&header.number, &header.blake2_256().into());
}
fn calculate_random() -> Hash {
let c = block_number() - 1;
(0..81)
.map(|i| if c >= i { block_hash(c - i) } else { Default::default() })
.triplet_mix()
}
#[cfg(feature = "std")]
fn info_expect_equal_hash(given: &Hash, expected: &Hash) {
use primitives::hexdisplay::HexDisplay;
@@ -217,9 +225,16 @@ pub mod testing {
pub fn externalities() -> TestExternalities {
map![
twox_128(&BlockHashAt::key_for(&0)).to_vec() => [69u8; 32].encode()
twox_128(&BlockHashAt::key_for(&0)).to_vec() => [69u8; 32].encode(),
twox_128(Number::key()).to_vec() => 1u64.encode(),
twox_128(ParentHash::key()).to_vec() => [69u8; 32].encode(),
twox_128(RandomSeed::key()).to_vec() => [0u8; 32].encode()
]
}
pub fn set_block_number(n: BlockNumber) {
Number::put(n);
}
}
#[cfg(test)]
@@ -231,7 +246,6 @@ mod tests {
use runtime_support::StorageValue;
use codec::{Joiner, KeyedVec, Slicable};
use keyring::Keyring::*;
use environment::with_env;
use primitives::hexdisplay::HexDisplay;
use demo_primitives::{Header, Digest};
use transaction::{UncheckedTransaction, Transaction};
@@ -243,7 +257,8 @@ mod tests {
fn staking_balance_transfer_dispatch_works() {
let mut t: TestExternalities = map![
twox_128(&staking::FreeBalanceOf::key_for(*One)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
twox_128(staking::TransactionFee::key()).to_vec() => vec![10u8, 0, 0, 0, 0, 0, 0, 0]
twox_128(staking::TransactionFee::key()).to_vec() => vec![10u8, 0, 0, 0, 0, 0, 0, 0],
twox_128(&BlockHashAt::key_for(&0)).to_vec() => [69u8; 32].encode()
];
let tx = UncheckedTransaction {
@@ -256,7 +271,8 @@ mod tests {
};
with_externalities(&mut t, || {
internal::execute_transaction(tx, Header::from_block_number(1));
internal::initialise_block(&Header::from_block_number(1));
internal::execute_transaction(tx);
assert_eq!(staking::balance(&One), 32);
assert_eq!(staking::balance(&Two), 69);
});
+138
View File
@@ -0,0 +1,138 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Substrate Demo.
// Substrate Demo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate Demo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate Demo. If not, see <http://www.gnu.org/licenses/>.
//! Means of mixing a series of hashes to create a single secure hash.
//!
//! Described in http://www.cs.huji.ac.il/~nati/PAPERS/coll_coin_fl.pdf
use rstd::ops::{BitAnd, BitOr};
pub const MAX_DEPTH: usize = 17;
fn sub_mix<T>(seeds: &[T]) -> T where
T: BitAnd<Output = T> + BitOr<Output = T> + Copy
{
(seeds[0] & seeds[1]) | (seeds[1] & seeds[2]) | (seeds[0] & seeds[2])
}
/// Mix a slice.
pub fn triplet_mix<T>(seeds: &[T]) -> Result<T, ()> where
T: BitAnd<Output = T> + BitOr<Output = T>,
T: Default + Copy
{
Ok(seeds.iter().cloned().triplet_mix())
}
/// The mixed trait for mixing a sequence.
pub trait TripletMix {
/// The items in the sequence and simultaneously the return of the mixing.
type Item;
/// The output of the mixing algorithm on the sequence. Items in the sequence beyond
/// the largest power of three that fits within the the sequence up until `3 ** MAX_DEPTH`
/// are ignored.
fn triplet_mix(self) -> Self::Item;
}
impl<I, T> TripletMix for I where
I: Iterator<Item = T>,
T: BitAnd<Output = T> + BitOr<Output = T> + Default + Copy
{
type Item = T;
fn triplet_mix(self) -> Self::Item {
let mut accum = [[T::default(); 3]; MAX_DEPTH];
let mut result = T::default();
for (i, seed) in self.enumerate() {
accum[0][i % 3] = seed;
let mut index_at_depth = i;
for depth in 0..MAX_DEPTH {
if index_at_depth % 3 != 2 {
break;
}
index_at_depth /= 3;
result = sub_mix(&accum[depth]);
// end of the threesome at depth.
if depth == MAX_DEPTH - 1 {
// end of our stack - bail with result.
break;
} else {
// save in the stack for parent computation
accum[depth + 1][index_at_depth % 3] = result;
}
}
}
result
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sub_mix_works() {
assert_eq!(sub_mix(&[0, 0, 0][..]), 0);
assert_eq!(sub_mix(&[0, 0, 1][..]), 0);
assert_eq!(sub_mix(&[0, 1, 0][..]), 0);
assert_eq!(sub_mix(&[0, 1, 1][..]), 1);
assert_eq!(sub_mix(&[1, 0, 0][..]), 0);
assert_eq!(sub_mix(&[1, 0, 1][..]), 1);
assert_eq!(sub_mix(&[1, 1, 0][..]), 1);
assert_eq!(sub_mix(&[1, 1, 1][..]), 1);
assert_eq!(sub_mix(&[0, 0, 0][..]), 0);
assert_eq!(sub_mix(&[0, 0, 2][..]), 0);
assert_eq!(sub_mix(&[0, 2, 0][..]), 0);
assert_eq!(sub_mix(&[0, 2, 2][..]), 2);
assert_eq!(sub_mix(&[2, 0, 0][..]), 0);
assert_eq!(sub_mix(&[2, 0, 2][..]), 2);
assert_eq!(sub_mix(&[2, 2, 0][..]), 2);
assert_eq!(sub_mix(&[2, 2, 2][..]), 2);
}
#[test]
fn triplet_mix_works_on_first_level() {
assert_eq!(triplet_mix(&[0, 0, 0][..]).unwrap(), 0);
assert_eq!(triplet_mix(&[0, 0, 1][..]).unwrap(), 0);
assert_eq!(triplet_mix(&[0, 1, 0][..]).unwrap(), 0);
assert_eq!(triplet_mix(&[0, 1, 1][..]).unwrap(), 1);
assert_eq!(triplet_mix(&[1, 0, 0][..]).unwrap(), 0);
assert_eq!(triplet_mix(&[1, 0, 1][..]).unwrap(), 1);
assert_eq!(triplet_mix(&[1, 1, 0][..]).unwrap(), 1);
assert_eq!(triplet_mix(&[1, 1, 1][..]).unwrap(), 1);
assert_eq!(triplet_mix(&[0, 0, 0][..]).unwrap(), 0);
assert_eq!(triplet_mix(&[0, 0, 2][..]).unwrap(), 0);
assert_eq!(triplet_mix(&[0, 2, 0][..]).unwrap(), 0);
assert_eq!(triplet_mix(&[0, 2, 2][..]).unwrap(), 2);
assert_eq!(triplet_mix(&[2, 0, 0][..]).unwrap(), 0);
assert_eq!(triplet_mix(&[2, 0, 2][..]).unwrap(), 2);
assert_eq!(triplet_mix(&[2, 2, 0][..]).unwrap(), 2);
assert_eq!(triplet_mix(&[2, 2, 2][..]).unwrap(), 2);
}
#[test]
fn triplet_mix_works_on_second_level() {
assert_eq!(triplet_mix(&[0, 0, 0, 0, 0, 1, 0, 1, 0][..]).unwrap(), 0);
assert_eq!(triplet_mix(&[0, 1, 1, 1, 0, 0, 1, 0, 1][..]).unwrap(), 1);
assert_eq!(triplet_mix(&[1, 1, 0, 1, 1, 1, 0, 0, 0][..]).unwrap(), 1);
}
#[test]
fn triplet_mix_works_on_third_level() {
assert_eq!(triplet_mix(&[0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0][..]).unwrap(), 1);
}
}
@@ -189,7 +189,7 @@ mod tests {
assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
// Block 1: Make proposal. Approve it. Era length changes.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
public::approve(&two, 1);
staking::internal::check_new_era();
@@ -212,13 +212,13 @@ mod tests {
assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
// Block 1: Make proposal. Fail it.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
staking::internal::check_new_era();
assert_eq!(staking::era_length(), 1);
// Block 2: Make proposal. Approve it. It should change era length.
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
public::approve(&two, 2);
staking::internal::check_new_era();
@@ -241,7 +241,7 @@ mod tests {
assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
// Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
staking::internal::check_new_era();
assert_eq!(staking::era_length(), 1);
@@ -264,7 +264,7 @@ mod tests {
assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
// Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
public::approve(&two, 0);
staking::internal::check_new_era();
@@ -288,7 +288,7 @@ mod tests {
assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
// Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
public::approve(&two, 1);
public::approve(&two, 1);
@@ -313,7 +313,7 @@ mod tests {
assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
// Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
public::propose(&two, &Proposal::StakingSetSessionsPerEra(2));
staking::internal::check_new_era();
@@ -337,7 +337,7 @@ mod tests {
assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
// Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
public::approve(&two, 1);
staking::internal::check_new_era();
assert_eq!(staking::era_length(), 1);
@@ -361,7 +361,7 @@ mod tests {
assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
// Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
public::approve(&four, 1);
staking::internal::check_new_era();
@@ -217,46 +217,46 @@ mod tests {
let mut t = simple_setup();
with_externalities(&mut t, || {
// Block 1: Change to length 3; no visible change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
set_length(3);
check_rotate_session();
assert_eq!(length(), 2);
assert_eq!(current_index(), 0);
// Block 2: Length now changed to 3. Index incremented.
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
set_length(3);
check_rotate_session();
assert_eq!(length(), 3);
assert_eq!(current_index(), 1);
// Block 3: Length now changed to 3. Index incremented.
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
check_rotate_session();
assert_eq!(length(), 3);
assert_eq!(current_index(), 1);
// Block 4: Change to length 2; no visible change.
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
set_length(2);
check_rotate_session();
assert_eq!(length(), 3);
assert_eq!(current_index(), 1);
// Block 5: Length now changed to 2. Index incremented.
with_env(|e| e.block_number = 5);
system::testing::set_block_number(5);
check_rotate_session();
assert_eq!(length(), 2);
assert_eq!(current_index(), 2);
// Block 6: No change.
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
check_rotate_session();
assert_eq!(length(), 2);
assert_eq!(current_index(), 2);
// Block 7: Next index.
with_env(|e| e.block_number = 7);
system::testing::set_block_number(7);
check_rotate_session();
assert_eq!(length(), 2);
assert_eq!(current_index(), 3);
@@ -268,17 +268,17 @@ mod tests {
let mut t = simple_setup();
with_externalities(&mut t, || {
// Block 1: No change
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
check_rotate_session();
assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]);
// Block 2: Session rollover, but no change.
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
check_rotate_session();
assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]);
// Block 3: Set new key for validator 2; no visible change.
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
set_key(&[20; 32], &[22; 32]);
assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]);
@@ -286,7 +286,7 @@ mod tests {
assert_eq!(consensus::authorities(), vec![[11u8; 32], [21u8; 32]]);
// Block 4: Session rollover, authority 2 changes.
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
check_rotate_session();
assert_eq!(consensus::authorities(), vec![[11u8; 32], [22u8; 32]]);
});
@@ -310,7 +310,7 @@ mod tests {
assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]);
// Block 1: Add three validators. No obvious change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
stake(&one);
stake(&two);
stake(&four);
@@ -318,39 +318,39 @@ mod tests {
assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]);
// Block 2: New validator set now.
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
check_new_era();
assert_eq!(session::validators(), vec![four.clone(), two.clone()]);
// Block 3: Unstake highest, introduce another staker. No change yet.
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
stake(&three);
unstake(&four);
check_new_era();
// Block 4: New era - validators change.
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
check_new_era();
assert_eq!(session::validators(), vec![three.clone(), two.clone()]);
// Block 5: Transfer stake from highest to lowest. No change yet.
with_env(|e| e.block_number = 5);
system::testing::set_block_number(5);
transfer(&four, &one, 40);
check_new_era();
// Block 6: Lowest now validator.
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
check_new_era();
assert_eq!(session::validators(), vec![one.clone(), three.clone()]);
// Block 7: Unstake three. No change yet.
with_env(|e| e.block_number = 7);
system::testing::set_block_number(7);
unstake(&three);
check_new_era();
assert_eq!(session::validators(), vec![one.clone(), three.clone()]);
// Block 8: Back to one and two.
with_env(|e| e.block_number = 8);
system::testing::set_block_number(8);
check_new_era();
assert_eq!(session::validators(), vec![one.clone(), two.clone()]);
});
@@ -369,21 +369,21 @@ mod tests {
assert_eq!(current_era(), 0u64);
// Block 1: No change.
with_env(|e| e.block_number = 1);
system::testing::set_block_number(1);
check_new_era();
assert_eq!(sessions_per_era(), 2u64);
assert_eq!(last_era_length_change(), 0u64);
assert_eq!(current_era(), 0u64);
// Block 2: Simple era change.
with_env(|e| e.block_number = 2);
system::testing::set_block_number(2);
check_new_era();
assert_eq!(sessions_per_era(), 2u64);
assert_eq!(last_era_length_change(), 0u64);
assert_eq!(current_era(), 1u64);
// Block 3: Schedule an era length change; no visible changes.
with_env(|e| e.block_number = 3);
system::testing::set_block_number(3);
set_sessions_per_era(3);
check_new_era();
assert_eq!(sessions_per_era(), 2u64);
@@ -391,28 +391,28 @@ mod tests {
assert_eq!(current_era(), 1u64);
// Block 4: Era change kicks in.
with_env(|e| e.block_number = 4);
system::testing::set_block_number(4);
check_new_era();
assert_eq!(sessions_per_era(), 3u64);
assert_eq!(last_era_length_change(), 4u64);
assert_eq!(current_era(), 2u64);
// Block 5: No change.
with_env(|e| e.block_number = 5);
system::testing::set_block_number(5);
check_new_era();
assert_eq!(sessions_per_era(), 3u64);
assert_eq!(last_era_length_change(), 4u64);
assert_eq!(current_era(), 2u64);
// Block 6: No change.
with_env(|e| e.block_number = 6);
system::testing::set_block_number(6);
check_new_era();
assert_eq!(sessions_per_era(), 3u64);
assert_eq!(last_era_length_change(), 4u64);
assert_eq!(current_era(), 2u64);
// Block 7: Era increment.
with_env(|e| e.block_number = 7);
system::testing::set_block_number(7);
check_new_era();
assert_eq!(sessions_per_era(), 3u64);
assert_eq!(last_era_length_change(), 4u64);
@@ -264,6 +264,15 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) {
}
}
#[cfg(any(feature = "std", test))]
pub mod testing {
use super::*;
pub fn set_block_number(n: BlockNumber) {
with_env(|e| e.block_number = n);
}
}
#[cfg(test)]
mod tests {
use super::*;