Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add try_state and integrity_test to XCM simulator fuzzer #3222

Merged
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions polkadot/xcm/xcm-simulator/fuzzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ scale-info = { version = "2.10.0", features = ["derive"] }

frame-system = { path = "../../../../substrate/frame/system" }
frame-support = { path = "../../../../substrate/frame/support" }
frame-executive = { path = "../../../../substrate/frame/executive" }
frame-try-runtime = { path = "../../../../substrate/frame/try-runtime" }
pallet-balances = { path = "../../../../substrate/frame/balances" }
pallet-message-queue = { path = "../../../../substrate/frame/message-queue" }
sp-std = { path = "../../../../substrate/primitives/std" }
Expand All @@ -35,6 +37,18 @@ polkadot-runtime-parachains = { path = "../../../runtime/parachains" }
polkadot-parachain-primitives = { path = "../../../parachain" }

[features]
default = ["try-runtime"]
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
try-runtime = [
"frame-executive/try-runtime",
"frame-support/try-runtime",
"frame-system/try-runtime",
"frame-try-runtime/try-runtime",
"pallet-balances/try-runtime",
"pallet-message-queue/try-runtime",
"pallet-xcm/try-runtime",
"polkadot-runtime-parachains/try-runtime",
"sp-runtime/try-runtime",
]
runtime-benchmarks = [
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
Expand Down
41 changes: 38 additions & 3 deletions polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ use polkadot_parachain_primitives::primitives::Id as ParaId;
use sp_runtime::{traits::AccountIdConversion, BuildStorage};
use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt};

use frame_support::assert_ok;
use frame_support::{
assert_ok,
traits::{IntegrityTest, TryState, TryStateSelect::All},
};
use xcm::{latest::prelude::*, MAX_XCM_DECODE_DEPTH};

use arbitrary::{Arbitrary, Error, Unstructured};
Expand Down Expand Up @@ -98,7 +101,7 @@ impl<'a> Arbitrary<'a> for XcmMessage {
if let Ok(message) =
DecodeLimit::decode_with_depth_limit(MAX_XCM_DECODE_DEPTH, &mut encoded_message)
{
return Ok(XcmMessage { source, destination, message })
return Ok(XcmMessage { source, destination, message });
}
Err(Error::IncorrectFormat)
}
Expand Down Expand Up @@ -148,13 +151,33 @@ pub fn relay_ext() -> sp_io::TestExternalities {
pub type RelayChainPalletXcm = pallet_xcm::Pallet<relay_chain::Runtime>;
pub type ParachainPalletXcm = pallet_xcm::Pallet<parachain::Runtime>;

// We check XCM messages recursively for blocklisted messages
fn recursively_matches_blocklisted_messages(message: &Instruction<()>) -> bool {
match message {
DepositReserveAsset { xcm, .. } |
ExportMessage { xcm, .. } |
InitiateReserveWithdraw { xcm, .. } |
InitiateTeleport { xcm, .. } |
TransferReserveAsset { xcm, .. } |
SetErrorHandler(xcm) |
SetAppendix(xcm) => xcm.iter().any(recursively_matches_blocklisted_messages),
// The blocklisted message is the Transact instruction.
m => matches!(m, Transact { .. }),
}
}

fn run_input(xcm_messages: [XcmMessage; 5]) {
MockNet::reset();

#[cfg(not(fuzzing))]
println!();

for xcm_message in xcm_messages {
if xcm_message.message.iter().any(recursively_matches_blocklisted_messages) {
println!(" skipping message\n");
continue;
}

if xcm_message.source % 4 == 0 {
// We get the destination for the message
let parachain_id = (xcm_message.destination % 3) + 1;
Expand Down Expand Up @@ -197,8 +220,20 @@ fn run_input(xcm_messages: [XcmMessage; 5]) {
}
#[cfg(not(fuzzing))]
println!();
// We run integrity tests and try_runtime invariants
[ParaA::execute_with, ParaB::execute_with, ParaC::execute_with].iter().for_each(
|execute_with| {
execute_with(|| {
parachain::AllPalletsWithSystem::try_state(Default::default(), All).unwrap();
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
parachain::AllPalletsWithSystem::integrity_test();
});
},
);
Relay::execute_with(|| {
relay_chain::AllPalletsWithSystem::try_state(Default::default(), All).unwrap();
relay_chain::AllPalletsWithSystem::integrity_test();
});
}
Relay::execute_with(|| {});
}

fn main() {
Expand Down
44 changes: 17 additions & 27 deletions polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ use frame_support::{
};

use frame_system::EnsureRoot;
use sp_core::{ConstU32, H256};
use sp_core::ConstU32;
use sp_runtime::{
traits::{Hash, IdentityLookup},
AccountId32,
generic,
traits::{AccountIdLookup, BlakeTwo256, Hash, IdentifyAccount, Verify},
MultiAddress, MultiSignature,
};
use sp_std::prelude::*;

Expand All @@ -47,38 +48,29 @@ use xcm_builder::{
};
use xcm_executor::{Config, XcmExecutor};

pub type AccountId = AccountId32;
pub type SignedExtra = (frame_system::CheckNonZeroSender<Runtime>,);

pub type BlockNumber = u64;
pub type Address = MultiAddress<AccountId, ()>;
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
pub type UncheckedExtrinsic =
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
pub type Block = generic::Block<Header, UncheckedExtrinsic>;

pub type Signature = MultiSignature;
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
pub type Balance = u128;

parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const BlockHashCount: u32 = 250;
}

#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)]
impl frame_system::Config for Runtime {
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type Nonce = u64;
type Hash = H256;
type Hashing = ::sp_runtime::traits::BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Lookup = AccountIdLookup<AccountId, ()>;
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
type Block = Block;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = BlockHashCount;
type BlockWeights = ();
type BlockLength = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type OnKilledAccount = ();
type DbWeight = ();
type BaseCallFilter = Everything;
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = frame_support::traits::ConstU32<16>;
}

parameter_types! {
Expand Down Expand Up @@ -356,8 +348,6 @@ impl pallet_xcm::Config for Runtime {
type AdminOrigin = EnsureRoot<AccountId>;
}

type Block = frame_system::mocking::MockBlock<Runtime>;

construct_runtime!(
pub enum Runtime
{
Expand Down
45 changes: 19 additions & 26 deletions polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ use frame_support::{
};

use frame_system::EnsureRoot;
use sp_core::{ConstU32, H256};
use sp_runtime::{traits::IdentityLookup, AccountId32};
use sp_core::ConstU32;
use sp_runtime::{
generic,
traits::{BlakeTwo256, IdentifyAccount, Verify},
MultiAddress, MultiSignature,
};

use polkadot_parachain_primitives::primitives::Id as ParaId;
use polkadot_runtime_parachains::{
Expand All @@ -43,38 +47,29 @@ use xcm_builder::{
};
use xcm_executor::{Config, XcmExecutor};

pub type AccountId = AccountId32;
pub type SignedExtra = (frame_system::CheckNonZeroSender<Runtime>,);

pub type BlockNumber = u64;
pub type Address = MultiAddress<AccountId, ()>;
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
pub type UncheckedExtrinsic =
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
pub type Block = generic::Block<Header, UncheckedExtrinsic>;

pub type Signature = MultiSignature;
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
pub type Balance = u128;

parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const BlockHashCount: u32 = 250;
}

#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)]
impl frame_system::Config for Runtime {
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type Nonce = u64;
type Hash = H256;
type Hashing = ::sp_runtime::traits::BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Lookup = sp_runtime::traits::AccountIdLookup<AccountId, ()>;
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
type Block = Block;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = BlockHashCount;
type BlockWeights = ();
type BlockLength = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type OnKilledAccount = ();
type DbWeight = ();
type BaseCallFilter = Everything;
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = ConstU32<16>;
}

parameter_types! {
Expand Down Expand Up @@ -202,8 +197,6 @@ parameter_types! {

impl origin::Config for Runtime {}

type Block = frame_system::mocking::MockBlock<Runtime>;

parameter_types! {
/// Amount of weight that can be spent per block to service messages.
pub MessageQueueServiceWeight: Weight = Weight::from_parts(1_000_000_000, 1_000_000);
Expand Down
Loading