Skip to content

Commit de5998e

Browse files
committed
Add recursively_find_call to avoid known bugs
1 parent 3319d8c commit de5998e

File tree

4 files changed

+77
-61
lines changed

4 files changed

+77
-61
lines changed

fuzz/Cargo.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fuzz/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ pallet-balances = { git = "https://github.com/moondance-labs/polkadot-sdk", bran
6262
pallet-session = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
6363
pallet-timestamp = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
6464
pallet-utility = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
65+
pallet-proxy = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
66+
pallet-multisig = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
67+
pallet-xcm = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
68+
pallet-referenda = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
6569
parity-scale-codec = { version = "3.6.12", default-features = false, features = [ "derive", "max-encoded-len" ] }
6670
sc-chain-spec = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407" }
6771
sc-client-api = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
@@ -77,6 +81,7 @@ sp-runtime = { git = "https://github.com/moondance-labs/polkadot-sdk.git", branc
7781
sp-state-machine = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
7882
sp-storage = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
7983
sp-transaction-storage-proof = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", default-features = false }
84+
staging-xcm = { default-features = false, git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-stable2407", features = [ "std" ] }
8085

8186
bitvec = { version = "1.0.1", default-features = false, features = [ "alloc" ] }
8287
futures = "0.3.1"

fuzz/fuzz_targets/fuzz_raw.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use {
1212
AccountId, AllPalletsWithSystem, BlockNumber, Executive, Header, Runtime, RuntimeCall,
1313
RuntimeOrigin, Signature, UncheckedExtrinsic, SLOT_DURATION,
1414
},
15+
dp_container_chain_genesis_data::ContainerChainGenesisData,
1516
dp_core::well_known_keys::PARAS_HEADS_INDEX,
1617
frame_metadata::{v15::RuntimeMetadataV15, RuntimeMetadata, RuntimeMetadataPrefixed},
1718
frame_support::{
@@ -33,10 +34,9 @@ use {
3334
std::{
3435
any::TypeId,
3536
cell::Cell,
36-
time::{Duration, Instant},
3737
marker::PhantomData,
38+
time::{Duration, Instant},
3839
},
39-
dp_container_chain_genesis_data::ContainerChainGenesisData,
4040
};
4141

4242
// We use a simple Map-based Externalities implementation
@@ -259,9 +259,7 @@ pub fn get_from_seed<TPublic: Public + 'static>(seed: &str) -> <TPublic::Pair as
259259
.public()
260260
}
261261

262-
pub fn mock_container_chain_genesis_data(
263-
para_id: ParaId,
264-
) -> ContainerChainGenesisData {
262+
pub fn mock_container_chain_genesis_data(para_id: ParaId) -> ContainerChainGenesisData {
265263
ContainerChainGenesisData {
266264
storage: vec![],
267265
name: format!("Container Chain {}", para_id).into(),

fuzz/fuzz_targets/fuzz_starlight.rs

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,63 +2,55 @@
22
#![allow(clippy::absurd_extreme_comparisons)]
33
#![allow(clippy::not_unsafe_ptr_arg_deref)]
44

5-
//! Tanssi Runtime fuzz target. Generates random extrinsics and some mock relay validation data (but no sudo).
5+
//! Tanssi Runtime fuzz target. Generates random extrinsics and some pseudo-extrinsics.
66
//!
7-
//! Based on https://github.com/srlabs/substrate-runtime-fuzzer/blob/8d45d9960cff6f6c5aa8bf19808f84ef12b08535/node-template-fuzzer/src/main.rs
8-
9-
use std::iter;
10-
use sp_state_machine::BasicExternalities;
11-
use dancelight_runtime::Balance;
12-
use frame_system::Account;
13-
use dancelight_runtime::Balances;
14-
use pallet_balances::Holds;
15-
use pallet_balances::TotalIssuance;
16-
use dancelight_runtime::ParaInherent;
17-
use dancelight_runtime::Timestamp;
18-
use sp_consensus_babe::BABE_ENGINE_ID;
19-
use sp_consensus_babe::digests::PreDigest;
20-
use sp_core::H256;
21-
use sp_consensus_babe::digests::SecondaryPlainPreDigest;
22-
use primitives::ValidationCode;
23-
use pallet_configuration::HostConfiguration;
24-
use sp_runtime::Saturating;
25-
use primitives::{vstaging::SchedulerParams };
26-
use std::cmp::max;
27-
use dancelight_runtime::genesis_config_presets::get_authority_keys_from_seed;
28-
use polkadot_core_primitives::BlockNumber;
29-
use polkadot_core_primitives::Signature;
30-
use dancelight_runtime_constants::time::SLOT_DURATION;
7+
//! Based on https://github.com/srlabs/substrate-runtime-fuzzer/blob/2a42a8b750aff0e12eb0e09b33aea9825a40595a/runtimes/kusama/src/main.rs
8+
319
use {
3210
cumulus_primitives_core::ParaId,
3311
dancelight_runtime::{
34-
AccountId, AllPalletsWithSystem, Executive, Header, Runtime, RuntimeCall,
35-
RuntimeOrigin, UncheckedExtrinsic,
12+
genesis_config_presets::get_authority_keys_from_seed, AccountId, AllPalletsWithSystem,
13+
Balance, Balances, Executive, Header, ParaInherent, Runtime, RuntimeCall, RuntimeOrigin,
14+
Timestamp, UncheckedExtrinsic,
3615
},
16+
dancelight_runtime_constants::time::SLOT_DURATION,
17+
dp_container_chain_genesis_data::ContainerChainGenesisData,
3718
dp_core::well_known_keys::PARAS_HEADS_INDEX,
3819
frame_metadata::{v15::RuntimeMetadataV15, RuntimeMetadata, RuntimeMetadataPrefixed},
3920
frame_support::{
4021
dispatch::GetDispatchInfo,
4122
pallet_prelude::Weight,
42-
traits::{IntegrityTest, TryState, TryStateSelect},
23+
traits::{IntegrityTest, OriginTrait, TryState, TryStateSelect},
4324
weights::constants::WEIGHT_REF_TIME_PER_SECOND,
4425
Hashable,
4526
},
27+
frame_system::Account,
4628
nimbus_primitives::{NimbusId, NIMBUS_ENGINE_ID},
29+
pallet_balances::{Holds, TotalIssuance},
30+
pallet_configuration::HostConfiguration,
4731
parity_scale_codec::{DecodeLimit, Encode},
32+
polkadot_core_primitives::{BlockNumber, Signature},
33+
primitives::{vstaging::SchedulerParams, ValidationCode},
4834
sp_consensus_aura::{Slot, AURA_ENGINE_ID},
49-
sp_core::{sr25519, Decode, Get, Pair, Public},
35+
sp_consensus_babe::{
36+
digests::{PreDigest, SecondaryPlainPreDigest},
37+
BABE_ENGINE_ID,
38+
},
39+
sp_core::{sr25519, Decode, Get, Pair, Public, H256},
5040
sp_inherents::InherentDataProvider,
5141
sp_runtime::{
5242
traits::{Dispatchable, Header as HeaderT, IdentifyAccount, Verify},
53-
Digest, DigestItem, Perbill, Storage,
43+
Digest, DigestItem, Perbill, Saturating, Storage,
5444
},
45+
sp_state_machine::BasicExternalities,
5546
std::{
5647
any::TypeId,
5748
cell::Cell,
58-
time::{Duration, Instant},
49+
cmp::max,
50+
iter,
5951
marker::PhantomData,
52+
time::{Duration, Instant},
6053
},
61-
dp_container_chain_genesis_data::ContainerChainGenesisData,
6254
};
6355

6456
fn recursively_find_call(call: RuntimeCall, matches_on: fn(RuntimeCall) -> bool) -> bool {
@@ -73,21 +65,14 @@ fn recursively_find_call(call: RuntimeCall, matches_on: fn(RuntimeCall) -> bool)
7365
return true;
7466
}
7567
}
76-
}
77-
/*
78-
else if let RuntimeCall::Lottery(pallet_lottery::Call::buy_ticket { call })
79-
| RuntimeCall::Multisig(pallet_multisig::Call::as_multi_threshold_1 {
68+
} else if let RuntimeCall::Multisig(pallet_multisig::Call::as_multi_threshold_1 {
8069
call, ..
8170
})
8271
| RuntimeCall::Utility(pallet_utility::Call::as_derivative { call, .. })
83-
| RuntimeCall::Council(pallet_collective::Call::propose {
84-
proposal: call, ..
85-
}) = call
72+
| RuntimeCall::Proxy(pallet_proxy::Call::proxy { call, .. }) = call
8673
{
8774
return recursively_find_call(*call.clone(), matches_on);
88-
}
89-
*/
90-
else if matches_on(call) {
75+
} else if matches_on(call) {
9176
return true;
9277
}
9378
false
@@ -163,9 +148,7 @@ pub fn get_from_seed<TPublic: Public + 'static>(seed: &str) -> <TPublic::Pair as
163148
.public()
164149
}
165150

166-
pub fn mock_container_chain_genesis_data(
167-
para_id: ParaId,
168-
) -> ContainerChainGenesisData {
151+
pub fn mock_container_chain_genesis_data(para_id: ParaId) -> ContainerChainGenesisData {
169152
ContainerChainGenesisData {
170153
storage: vec![],
171154
name: format!("Container Chain {}", para_id).into(),
@@ -201,8 +184,7 @@ where
201184
///
202185
/// The input must be a tuple of individual keys (a single arg for now since we have just one key).
203186
pub fn template_session_keys(account: AccountId) -> dancelight_runtime::SessionKeys {
204-
let authority_keys =
205-
get_authority_keys_from_seed(&account.to_string(), None);
187+
let authority_keys = get_authority_keys_from_seed(&account.to_string(), None);
206188

207189
dancelight_runtime::SessionKeys {
208190
babe: authority_keys.babe.clone(),
@@ -230,7 +212,6 @@ pub fn invulnerables_from_seeds<S: AsRef<str>, I: Iterator<Item = S>>(
230212
.collect()
231213
}
232214

233-
234215
fn default_parachains_host_configuration(
235216
) -> runtime_parachains::configuration::HostConfiguration<primitives::BlockNumber> {
236217
use primitives::{
@@ -688,9 +669,40 @@ fn fuzz_main(data: &[u8]) {
688669
//println!("data: {:?}", data);
689670
let mut extrinsic_data = data;
690671
//#[allow(deprecated)]
691-
let extrinsics: Vec<(/* lapse */ u8, /* origin */ u8, ExtrOrPseudo)> = iter::from_fn(|| {
692-
DecodeLimit::decode_with_depth_limit(64, &mut extrinsic_data).ok()
693-
}).collect();
672+
let extrinsics: Vec<(/* lapse */ u8, /* origin */ u8, ExtrOrPseudo)> =
673+
iter::from_fn(|| DecodeLimit::decode_with_depth_limit(64, &mut extrinsic_data).ok())
674+
.filter(|(_, _, x)| match x {
675+
ExtrOrPseudo::Extr(x) => !recursively_find_call(x.clone(), |call| {
676+
// We filter out calls with Fungible(0) as they cause a debug crash
677+
matches!(call.clone(), RuntimeCall::XcmPallet(pallet_xcm::Call::execute { message, .. })
678+
if matches!(message.as_ref(), staging_xcm::VersionedXcm::V2(staging_xcm::v2::Xcm(msg))
679+
if msg.iter().any(|m| matches!(m, staging_xcm::opaque::v2::prelude::BuyExecution { fees: staging_xcm::v2::MultiAsset { fun, .. }, .. }
680+
if fun == &staging_xcm::v2::Fungibility::Fungible(0)
681+
)
682+
)) || matches!(message.as_ref(), staging_xcm::VersionedXcm::V3(staging_xcm::v3::Xcm(msg))
683+
if msg.iter().any(|m| matches!(m, staging_xcm::opaque::v3::prelude::BuyExecution { weight_limit: staging_xcm::opaque::v3::WeightLimit::Limited(weight), .. }
684+
if weight.ref_time() <= 1
685+
))
686+
)
687+
)
688+
|| matches!(call.clone(), RuntimeCall::XcmPallet(pallet_xcm::Call::transfer_assets_using_type_and_then { assets, ..})
689+
if staging_xcm::v2::MultiAssets::try_from(*assets.clone())
690+
.map(|assets| assets.inner().iter().any(|a| matches!(a, staging_xcm::v2::MultiAsset { fun, .. }
691+
if fun == &staging_xcm::v2::Fungibility::Fungible(0)
692+
))).unwrap_or(false)
693+
)
694+
|| matches!(call.clone(), RuntimeCall::System(_))
695+
|| matches!(
696+
&call,
697+
RuntimeCall::Referenda(pallet_referenda::Call::submit {
698+
proposal_origin: matching_origin,
699+
..
700+
}) if RuntimeOrigin::from(*matching_origin.clone()).caller() == RuntimeOrigin::root().caller()
701+
)
702+
}),
703+
ExtrOrPseudo::Pseudo(x) => true,
704+
})
705+
.collect();
694706

695707
if extrinsics.is_empty() {
696708
return;
@@ -736,9 +748,7 @@ fn fuzz_main(data: &[u8]) {
736748
Timestamp::set(RuntimeOrigin::none(), u64::from(block) * SLOT_DURATION).unwrap();
737749

738750
Executive::apply_extrinsic(UncheckedExtrinsic::new_unsigned(RuntimeCall::AuthorNoting(
739-
pallet_author_noting::Call::set_latest_author_data {
740-
data: (),
741-
},
751+
pallet_author_noting::Call::set_latest_author_data { data: () },
742752
)))
743753
.unwrap()
744754
.unwrap();
@@ -808,7 +818,6 @@ fn fuzz_main(data: &[u8]) {
808818
elapsed += now.elapsed();
809819

810820
log::debug!(" result: {res:?}");
811-
812821
}
813822
ExtrOrPseudo::Pseudo(fuzz_call) => {
814823
match fuzz_call {
@@ -828,7 +837,6 @@ fn fuzz_main(data: &[u8]) {
828837
}
829838
}
830839
}
831-
832840
}
833841

834842
finalize_block(elapsed);

0 commit comments

Comments
 (0)