diff --git a/pallets/cash/src/internal/change_validators.rs b/pallets/cash/src/internal/change_validators.rs index 0237e9323..9e661c804 100644 --- a/pallets/cash/src/internal/change_validators.rs +++ b/pallets/cash/src/internal/change_validators.rs @@ -26,8 +26,101 @@ pub fn change_validators(validators: Vec) -> Result<() internal::notices::dispatch_change_authority_notice::(validators); - // rotate to the queued session, and rotate from this one when notices are fully signed + // rotate to the currently queued session, and queue a new session with the new validators in NextValidators ::SessionInterface::rotate_session(); Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + chains::*, notices::*, reason::Reason, tests::*, AccountId32, LatestNotice, NoticeStates, + Notices, ValidatorKeys, + }; + use frame_support::storage::{IterableStorageDoubleMap, StorageDoubleMap, StorageMap}; + use mock::opaque::MockSessionKeys; + + #[test] + fn test_change_val() { + new_test_ext().execute_with(|| { + let prev_substrate_id: AccountId32 = [8; 32].into(); + let prev_keys = ValidatorKeys { + substrate_id: prev_substrate_id.clone(), + eth_address: [9; 20], + }; + + NextValidators::insert(prev_substrate_id, prev_keys); + + let substrate_id: AccountId32 = [2; 32].into(); + let eth_address = [1; 20]; + let val_keys = vec![ValidatorKeys { + substrate_id: substrate_id.clone(), + eth_address: eth_address.clone(), + }]; + let session_keys = MockSessionKeys { dummy: 1u64.into() }; + assert_eq!( + Ok(()), + Session::set_keys( + frame_system::RawOrigin::Signed(substrate_id.clone()).into(), + session_keys.clone(), + vec![] + ) + ); + assert_eq!(change_validators::(val_keys.clone()), Ok(())); + let val_state_post: Vec = + NextValidators::iter().map(|x| x.1).collect::>(); + assert_eq!(val_state_post, val_keys); + + let notice_state_post: Vec<(ChainId, NoticeId, NoticeState)> = + NoticeStates::iter().collect(); + let notice_state = notice_state_post.into_iter().next().unwrap(); + let notice = Notices::get(notice_state.0, notice_state.1); + + // bumps era + let expected_notice_id = NoticeId(1, 0); + let expected_notice = Notice::ChangeAuthorityNotice(ChangeAuthorityNotice::Eth { + id: expected_notice_id, + parent: [0u8; 32], + new_authorities: vec![eth_address], + }); + + assert_eq!( + ( + ChainId::Eth, + expected_notice_id, + NoticeState::Pending { + signature_pairs: ChainSignatureList::Eth(vec![]) + } + ), + notice_state + ); + assert_eq!(notice, Some(expected_notice.clone())); + assert_eq!( + LatestNotice::get(ChainId::Eth), + Some((expected_notice_id, expected_notice.hash())) + ); + + assert_eq!( + vec![&(substrate_id, session_keys)], + Session::queued_keys().iter().collect::>() + ); + }); + } + + #[test] + fn test_keys_unset() { + new_test_ext().execute_with(|| { + let substrate_id: AccountId32 = [2; 32].into(); + let vals = vec![ValidatorKeys { + substrate_id: substrate_id.clone(), + eth_address: [1; 20], + }]; + assert_eq!( + change_validators::(vals.clone()), + Err(Reason::ChangeValidatorsError) + ); + }); + } +} diff --git a/pallets/cash/src/params.rs b/pallets/cash/src/params.rs index 93ce5e64e..1f5bdfbb7 100644 --- a/pallets/cash/src/params.rs +++ b/pallets/cash/src/params.rs @@ -20,5 +20,5 @@ pub const TRANSFER_FEE: Quantity = Quantity::from_nominal("0.01", CASH); /// Number of blocks between HTTP requests from offchain workers to open oracle price feed. pub const ORACLE_POLL_INTERVAL_BLOCKS: u32 = 10; -// #[cfg(not(debug_assertions))] -pub const SESSION_PERIOD: u32 = 14400; // @ 6s blocks, 1 period per day +// The number of blocks in between periodic sessions +pub const SESSION_PERIOD: u32 = 14400; // Assuming 6s blocks, ~1 period per day diff --git a/pallets/cash/src/tests/mock.rs b/pallets/cash/src/tests/mock.rs index 2b08a6284..00d8f0666 100644 --- a/pallets/cash/src/tests/mock.rs +++ b/pallets/cash/src/tests/mock.rs @@ -61,15 +61,6 @@ impl pallet_session::SessionHandler for TestSessionHandler { fn on_before_session_ending() {} } -pub struct TestSessionManager; -impl pallet_session::SessionManager for TestSessionManager { - fn end_session(_: SessionIndex) {} - fn start_session(_: SessionIndex) {} - fn new_session(_: SessionIndex) -> Option> { - None - } -} - pub mod opaque { use super::*; @@ -138,7 +129,7 @@ impl pallet_session::Config for Test { type ValidatorIdOf = ConvertInto; type ShouldEndSession = TestShouldEndSession; type NextSessionRotation = (); - type SessionManager = TestSessionManager; + type SessionManager = Cash; type SessionHandler = TestSessionHandler; type Keys = opaque::MockSessionKeys; type DisabledValidatorsThreshold = (); //sp_runtime::Perbill::from_percent(33);