Extract frame_system SignedExtensions into separate files. (#6474)

* Split the code.

* Restructure.

* Split tests.

* Self-review.

* Break lines.

* Move tests out.

* Rename CheckEra -> CheckMortality but keep backwards compatibility

* Update frame/system/src/extensions/check_mortality.rs

* Don't rename the IDENTIFIER for now.

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Tomasz Drwięga
2020-06-24 17:01:42 +02:00
committed by GitHub
parent e016a49322
commit fb56eacd8d
12 changed files with 1757 additions and 1464 deletions
+424
View File
@@ -0,0 +1,424 @@
// This file is part of Substrate.
// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::*;
use mock::{*, Origin};
use sp_core::H256;
use sp_runtime::DispatchError;
use frame_support::weights::WithPostDispatchInfo;
#[test]
fn origin_works() {
let o = Origin::from(RawOrigin::<u64>::Signed(1u64));
let x: Result<RawOrigin<u64>, Origin> = o.into();
assert_eq!(x.unwrap(), RawOrigin::<u64>::Signed(1u64));
}
#[test]
fn stored_map_works() {
new_test_ext().execute_with(|| {
System::insert(&0, 42);
assert!(System::allow_death(&0));
System::inc_ref(&0);
assert!(!System::allow_death(&0));
System::insert(&0, 69);
assert!(!System::allow_death(&0));
System::dec_ref(&0);
assert!(System::allow_death(&0));
assert!(KILLED.with(|r| r.borrow().is_empty()));
System::kill_account(&0);
assert_eq!(KILLED.with(|r| r.borrow().clone()), vec![0u64]);
});
}
#[test]
fn deposit_event_should_work() {
new_test_ext().execute_with(|| {
System::initialize(
&1,
&[0u8; 32].into(),
&[0u8; 32].into(),
&Default::default(),
InitKind::Full,
);
System::note_finished_extrinsics();
System::deposit_event(SysEvent::CodeUpdated);
System::finalize();
assert_eq!(
System::events(),
vec![
EventRecord {
phase: Phase::Finalization,
event: SysEvent::CodeUpdated,
topics: vec![],
}
]
);
System::initialize(
&2,
&[0u8; 32].into(),
&[0u8; 32].into(),
&Default::default(),
InitKind::Full,
);
System::deposit_event(SysEvent::NewAccount(32));
System::note_finished_initialize();
System::deposit_event(SysEvent::KilledAccount(42));
System::note_applied_extrinsic(&Ok(().into()), Default::default());
System::note_applied_extrinsic(
&Err(DispatchError::BadOrigin.into()),
Default::default()
);
System::note_finished_extrinsics();
System::deposit_event(SysEvent::NewAccount(3));
System::finalize();
assert_eq!(
System::events(),
vec![
EventRecord {
phase: Phase::Initialization,
event: SysEvent::NewAccount(32),
topics: vec![],
},
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: SysEvent::KilledAccount(42),
topics: vec![]
},
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: SysEvent::ExtrinsicSuccess(Default::default()),
topics: vec![]
},
EventRecord {
phase: Phase::ApplyExtrinsic(1),
event: SysEvent::ExtrinsicFailed(
DispatchError::BadOrigin.into(),
Default::default()
),
topics: vec![]
},
EventRecord {
phase: Phase::Finalization,
event: SysEvent::NewAccount(3),
topics: vec![]
},
]
);
});
}
#[test]
fn deposit_event_uses_actual_weight() {
new_test_ext().execute_with(|| {
System::initialize(
&1,
&[0u8; 32].into(),
&[0u8; 32].into(),
&Default::default(),
InitKind::Full,
);
System::note_finished_initialize();
let pre_info = DispatchInfo {
weight: 1000,
.. Default::default()
};
System::note_applied_extrinsic(
&Ok(Some(300).into()),
pre_info,
);
System::note_applied_extrinsic(
&Ok(Some(1000).into()),
pre_info,
);
System::note_applied_extrinsic(
// values over the pre info should be capped at pre dispatch value
&Ok(Some(1200).into()),
pre_info,
);
System::note_applied_extrinsic(
&Err(DispatchError::BadOrigin.with_weight(999)),
pre_info,
);
assert_eq!(
System::events(),
vec![
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: SysEvent::ExtrinsicSuccess(
DispatchInfo {
weight: 300,
.. Default::default()
},
),
topics: vec![]
},
EventRecord {
phase: Phase::ApplyExtrinsic(1),
event: SysEvent::ExtrinsicSuccess(
DispatchInfo {
weight: 1000,
.. Default::default()
},
),
topics: vec![]
},
EventRecord {
phase: Phase::ApplyExtrinsic(2),
event: SysEvent::ExtrinsicSuccess(
DispatchInfo {
weight: 1000,
.. Default::default()
},
),
topics: vec![]
},
EventRecord {
phase: Phase::ApplyExtrinsic(3),
event: SysEvent::ExtrinsicFailed(
DispatchError::BadOrigin.into(),
DispatchInfo {
weight: 999,
.. Default::default()
},
),
topics: vec![]
},
]
);
});
}
#[test]
fn deposit_event_topics() {
new_test_ext().execute_with(|| {
const BLOCK_NUMBER: u64 = 1;
System::initialize(
&BLOCK_NUMBER,
&[0u8; 32].into(),
&[0u8; 32].into(),
&Default::default(),
InitKind::Full,
);
System::note_finished_extrinsics();
let topics = vec![
H256::repeat_byte(1),
H256::repeat_byte(2),
H256::repeat_byte(3),
];
// We deposit a few events with different sets of topics.
System::deposit_event_indexed(&topics[0..3], SysEvent::NewAccount(1));
System::deposit_event_indexed(&topics[0..1], SysEvent::NewAccount(2));
System::deposit_event_indexed(&topics[1..2], SysEvent::NewAccount(3));
System::finalize();
// Check that topics are reflected in the event record.
assert_eq!(
System::events(),
vec![
EventRecord {
phase: Phase::Finalization,
event: SysEvent::NewAccount(1),
topics: topics[0..3].to_vec(),
},
EventRecord {
phase: Phase::Finalization,
event: SysEvent::NewAccount(2),
topics: topics[0..1].to_vec(),
},
EventRecord {
phase: Phase::Finalization,
event: SysEvent::NewAccount(3),
topics: topics[1..2].to_vec(),
}
]
);
// Check that the topic-events mapping reflects the deposited topics.
// Note that these are indexes of the events.
assert_eq!(
System::event_topics(&topics[0]),
vec![(BLOCK_NUMBER, 0), (BLOCK_NUMBER, 1)],
);
assert_eq!(
System::event_topics(&topics[1]),
vec![(BLOCK_NUMBER, 0), (BLOCK_NUMBER, 2)],
);
assert_eq!(
System::event_topics(&topics[2]),
vec![(BLOCK_NUMBER, 0)],
);
});
}
#[test]
fn prunes_block_hash_mappings() {
new_test_ext().execute_with(|| {
// simulate import of 15 blocks
for n in 1..=15 {
System::initialize(
&n,
&[n as u8 - 1; 32].into(),
&[0u8; 32].into(),
&Default::default(),
InitKind::Full,
);
System::finalize();
}
// first 5 block hashes are pruned
for n in 0..5 {
assert_eq!(
System::block_hash(n),
H256::zero(),
);
}
// the remaining 10 are kept
for n in 5..15 {
assert_eq!(
System::block_hash(n),
[n as u8; 32].into(),
);
}
})
}
#[test]
fn set_code_checks_works() {
struct CallInWasm(Vec<u8>);
impl sp_core::traits::CallInWasm for CallInWasm {
fn call_in_wasm(
&self,
_: &[u8],
_: Option<Vec<u8>>,
_: &str,
_: &[u8],
_: &mut dyn sp_externalities::Externalities,
_: sp_core::traits::MissingHostFunctions,
) -> Result<Vec<u8>, String> {
Ok(self.0.clone())
}
}
let test_data = vec![
("test", 1, 2, Err(Error::<Test>::SpecVersionNeedsToIncrease)),
("test", 1, 1, Err(Error::<Test>::SpecVersionNeedsToIncrease)),
("test2", 1, 1, Err(Error::<Test>::InvalidSpecName)),
("test", 2, 1, Ok(())),
("test", 0, 1, Err(Error::<Test>::SpecVersionNeedsToIncrease)),
("test", 1, 0, Err(Error::<Test>::SpecVersionNeedsToIncrease)),
];
for (spec_name, spec_version, impl_version, expected) in test_data.into_iter() {
let version = RuntimeVersion {
spec_name: spec_name.into(),
spec_version,
impl_version,
..Default::default()
};
let call_in_wasm = CallInWasm(version.encode());
let mut ext = new_test_ext();
ext.register_extension(sp_core::traits::CallInWasmExt::new(call_in_wasm));
ext.execute_with(|| {
let res = System::set_code(
RawOrigin::Root.into(),
vec![1, 2, 3, 4],
);
assert_eq!(expected.map_err(DispatchError::from), res);
});
}
}
#[test]
fn set_code_with_real_wasm_blob() {
let executor = substrate_test_runtime_client::new_native_executor();
let mut ext = new_test_ext();
ext.register_extension(sp_core::traits::CallInWasmExt::new(executor));
ext.execute_with(|| {
System::set_block_number(1);
System::set_code(
RawOrigin::Root.into(),
substrate_test_runtime_client::runtime::WASM_BINARY.to_vec(),
).unwrap();
assert_eq!(
System::events(),
vec![EventRecord {
phase: Phase::Initialization,
event: SysEvent::CodeUpdated,
topics: vec![],
}],
);
});
}
#[test]
fn runtime_upgraded_with_set_storage() {
let executor = substrate_test_runtime_client::new_native_executor();
let mut ext = new_test_ext();
ext.register_extension(sp_core::traits::CallInWasmExt::new(executor));
ext.execute_with(|| {
System::set_storage(
RawOrigin::Root.into(),
vec![(
well_known_keys::CODE.to_vec(),
substrate_test_runtime_client::runtime::WASM_BINARY.to_vec()
)],
).unwrap();
});
}
#[test]
fn events_not_emitted_during_genesis() {
new_test_ext().execute_with(|| {
// Block Number is zero at genesis
assert!(System::block_number().is_zero());
System::on_created_account(Default::default());
assert!(System::events().is_empty());
// Events will be emitted starting on block 1
System::set_block_number(1);
System::on_created_account(Default::default());
assert!(System::events().len() == 1);
});
}
#[test]
fn ensure_one_of_works() {
fn ensure_root_or_signed(o: RawOrigin<u64>) -> Result<Either<(), u64>, Origin> {
EnsureOneOf::<u64, EnsureRoot<u64>, EnsureSigned<u64>>::try_origin(o.into())
}
assert_eq!(ensure_root_or_signed(RawOrigin::Root).unwrap(), Either::Left(()));
assert_eq!(ensure_root_or_signed(RawOrigin::Signed(0)).unwrap(), Either::Right(0));
assert!(ensure_root_or_signed(RawOrigin::None).is_err())
}