fix: adapt runtime code and tests to Polkadot SDK stable2503 API changes

- Migrate pallet_referenda Track API: TracksInfo::tracks() now returns
  an Iterator<Item = Cow<Track>> instead of &[(Id, TrackInfo)].
  Use .collect(), track.id / track.info.* access pattern throughout.
- Convert TrackInfo.name from &str to [u8; 128] (str_array), using
  from_utf8() + trim_end_matches('\0') for string comparisons.
- Add authorization_list field to pallet_evm::Call::call (EIP-7702).
- Simplify ExistentialDeposit config: remove cfg split, use single
  ED=0 now that PR #7379 handles benchmarks with zero ED.
- Re-enable pallet_identity benchmark_helper and benchmark entries
  across mainnet and stagenet runtimes.
- Update pallet_collective alias comments re: PR #6435 status.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Steve Degosserie 2026-02-23 13:00:47 +01:00 committed by undercover-cactus
parent 68afceb1ba
commit a918792bff
23 changed files with 223 additions and 177 deletions

View file

@ -28,8 +28,7 @@ frame_benchmarking::define_benchmarks!(
// Substrate pallets
[pallet_balances, Balances]
[pallet_session, pallet_session_benchmarking::Pallet::<Runtime>]
// FIXME: benchmarking identity fail
// [pallet_identity, Identity]
[pallet_identity, Identity]
[pallet_im_online, ImOnline]
[pallet_multisig, Multisig]
[pallet_preimage, Preimage]

View file

@ -184,12 +184,14 @@ impl pallet_referenda::TracksInfo<Balance, BlockNumber> for TracksInfo {
/// To ensure voters are always locked into their vote
fn vote_locking_always_longer_than_enactment_period() {
for track in TRACKS_DATA {
let track_name = from_utf8(&track.info.name).unwrap();
let track_name = track_name.trim_end_matches('\0');
assert!(
<Runtime as pallet_conviction_voting::Config>::VoteLockingPeriod::get()
>= track.min_enactment_period,
>= track.info.min_enactment_period,
"Track {} has enactment period {} < vote locking period {}",
track.name,
track.min_enactment_period,
track_name,
track.info.min_enactment_period,
<Runtime as pallet_conviction_voting::Config>::VoteLockingPeriod::get(),
);
}
@ -198,9 +200,11 @@ fn vote_locking_always_longer_than_enactment_period() {
#[test]
fn all_tracks_have_origins() {
for track in TRACKS_DATA {
let track_name = from_utf8(&track.info.name).unwrap();
let track_name = track_name.trim_end_matches('\0');
// check name.into() is successful either converts into "root" or custom origin
let track_is_root = track.name == "root";
let track_has_custom_origin = custom_origins::Origin::from_str(track.name).is_ok();
let track_is_root = track_name == "root";
let track_has_custom_origin = custom_origins::Origin::from_str(track_name).is_ok();
assert!(track_is_root || track_has_custom_origin);
}
}

View file

@ -657,19 +657,17 @@ impl pallet_identity::Config for Runtime {
type UsernameDeposit = UsernameDeposit;
type UsernameGracePeriod = UsernameGracePeriod;
// TODO: Re-enable after upgrade to Polkadot SDK stable2412-8
// see https://github.com/paritytech/polkadot-sdk/releases/tag/polkadot-stable2412-8
// #[cfg(feature = "runtime-benchmarks")]
// fn benchmark_helper(message: &[u8]) -> (Vec<u8>, Vec<u8>) {
// let public = sp_io::crypto::ecdsa_generate(0.into(), None);
// let eth_signer: Self::SigningPublicKey = public.into();
// let hash_msg = sp_io::hashing::keccak_256(message);
// let signature = Self::OffchainSignature::new(
// sp_io::crypto::ecdsa_sign_prehashed(0.into(), &public, &hash_msg).unwrap(),
// );
#[cfg(feature = "runtime-benchmarks")]
fn benchmark_helper(message: &[u8]) -> (Vec<u8>, Vec<u8>) {
let public = sp_io::crypto::ecdsa_generate(0.into(), None);
let eth_signer: Self::SigningPublicKey = public.into();
let hash_msg = sp_io::hashing::keccak_256(message);
let signature = Self::OffchainSignature::new(
sp_io::crypto::ecdsa_sign_prehashed(0.into(), &public, &hash_msg).unwrap(),
);
// (eth_signer.encode(), signature.encode())
// }
(eth_signer.encode(), signature.encode())
}
}
parameter_types! {

View file

@ -31,7 +31,9 @@ pub mod weights;
pub use configs::governance;
pub use configs::Precompiles;
// TODO: Temporary workaround before upgrading to latest polkadot-sdk - fix https://github.com/paritytech/polkadot-sdk/pull/6435
// Aliases required by define_benchmarks! for pallet_collective instances.
// PR #6435 (in stable2503) fixes the underlying issue, so these can be removed
// when benchmarks are regenerated and weight files renamed accordingly.
#[allow(unused_imports)]
use pallet_collective as pallet_collective_treasury_council;
#[allow(unused_imports)]
@ -194,16 +196,10 @@ pub const NORMAL_BLOCK_WEIGHT: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_mul(3).s
pub const EXTRINSIC_BASE_WEIGHT: Weight = Weight::from_parts(10000 * WEIGHT_PER_GAS, 0);
// Existential deposit.
#[cfg(not(feature = "runtime-benchmarks"))]
// PR #7379 (included in stable2503) ensures benchmarks handle ED=0 internally.
parameter_types! {
pub const ExistentialDeposit: Balance = 0;
}
#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
// TODO: Change ED to 1 after upgrade to Polkadot SDK stable2503
// cfr. https://github.com/paritytech/polkadot-sdk/pull/7379
pub const ExistentialDeposit: Balance = 1;
}
/// The version information used to identify this runtime when compiled natively.
#[cfg(feature = "std")]

View file

@ -24,6 +24,7 @@
use crate::common::*;
use alloc::vec::Vec;
use core::str::from_utf8;
use datahaven_mainnet_runtime::{
configs::governance::council::{TechnicalMaxMembers, TechnicalMaxProposals},
governance::TracksInfo,
@ -443,29 +444,32 @@ fn benchmark_council_maximum_load() {
#[test]
fn benchmark_track_operations() {
ExtBuilder::governance().build().execute_with(|| {
let tracks = TracksInfo::tracks();
let tracks: Vec<_> = TracksInfo::tracks().collect();
println!("Testing {} governance tracks", tracks.len());
for (track_id, track_info) in tracks.iter() {
for track in tracks.iter() {
let track_name = from_utf8(&track.info.name).unwrap();
let track_name = track_name.trim_end_matches('\0');
let start_block = System::block_number();
// Create proposal for this track
let proposal = RuntimeCall::System(frame_system::Call::set_storage {
items: vec![(
format!(":track:{}:{}", track_id, track_info.name).into_bytes(),
format!(":track:{}:{}", track.id, track_name).into_bytes(),
b"test".to_vec(),
)],
});
let proposal_hash = make_proposal_hash(&proposal);
assert_ok!(Preimage::note_preimage(
RuntimeOrigin::signed(alice()),
proposal.encode()
));
let bounded_proposal = <Preimage as StorePreimage>::bound(proposal).unwrap();
// Map track to appropriate origin
let origin = if *track_id == 0 {
let origin = if track.id == 0 {
frame_system::RawOrigin::Root.into()
} else {
frame_system::RawOrigin::Signed(alice()).into()
@ -474,19 +478,19 @@ fn benchmark_track_operations() {
assert_ok!(Referenda::submit(
RuntimeOrigin::signed(alice()),
Box::new(origin),
DispatchTime::After(track_info.min_enactment_period),
Box::new(proposal_hash.into())
bounded_proposal,
DispatchTime::After(track.info.min_enactment_period),
));
assert_ok!(Referenda::place_decision_deposit(
RuntimeOrigin::signed(bob()),
*track_id as u32
track.id as u32
));
// Test voting on this track
assert_ok!(ConvictionVoting::vote(
RuntimeOrigin::signed(charlie()),
*track_id as u32,
track.id as u32,
AccountVote::Standard {
vote: Vote {
aye: true,
@ -500,11 +504,11 @@ fn benchmark_track_operations() {
println!(
"Track {} ({}): processed in {} blocks (max_deciding: {}, decision_deposit: {})",
track_id,
track_info.name,
track.id,
track_name,
end_block - start_block,
track_info.max_deciding,
track_info.decision_deposit
track.info.max_deciding,
track.info.decision_deposit
);
}
});

View file

@ -37,18 +37,21 @@ use pallet_conviction_voting::{AccountVote, Conviction, Event as ConvictionVotin
use pallet_preimage::Event as PreimageEvent;
use pallet_referenda::TracksInfo as TracksInfoTrait;
use pallet_referenda::{Event as ReferendaEvent, ReferendumInfo};
use core::str::from_utf8;
/// Test tracks info configuration
#[test]
fn tracks_info_configured_correctly() {
ExtBuilder::default().build().execute_with(|| {
let tracks = TracksInfo::tracks();
let tracks: Vec<_> = TracksInfo::tracks().collect();
// Should have 6 tracks as configured
assert_eq!(tracks.len(), 6);
// Verify track IDs and names
let track_names: Vec<&str> = tracks.iter().map(|(_, info)| info.name).collect();
let track_names: Vec<&str> = tracks.iter().map(|track| {
from_utf8(&track.info.name).unwrap().trim_end_matches('\0')
}).collect();
assert_eq!(
track_names,
vec![
@ -62,16 +65,14 @@ fn tracks_info_configured_correctly() {
);
// Verify root track has strictest requirements
let (root_id, root_info) = &tracks[0];
assert_eq!(*root_id, 0u16);
assert_eq!(root_info.max_deciding, 5);
assert_eq!(root_info.decision_deposit, 20 * KILOHAVE * SUPPLY_FACTOR); // 20 * KILO_HAVE
assert_eq!(tracks[0].id, 0u16);
assert_eq!(tracks[0].info.max_deciding, 5);
assert_eq!(tracks[0].info.decision_deposit, 20 * KILOHAVE * SUPPLY_FACTOR); // 20 * KILO_HAVE
// Verify general admin track
let (admin_id, admin_info) = &tracks[2];
assert_eq!(*admin_id, 2u16);
assert_eq!(admin_info.max_deciding, 10);
assert_eq!(admin_info.decision_deposit, 100 * HAVE * SUPPLY_FACTOR);
assert_eq!(tracks[2].id, 2u16);
assert_eq!(tracks[2].info.max_deciding, 10);
assert_eq!(tracks[2].info.decision_deposit, 100 * HAVE * SUPPLY_FACTOR);
});
}
@ -225,7 +226,8 @@ fn referendum_timing_works() {
));
// Advance time through prepare period (1 DAY for root track)
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.prepare_period + 1);
// Place decision deposit
@ -243,7 +245,8 @@ fn referendum_timing_works() {
}
// Advance time through decision period
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.decision_period + 1);
// Referendum should still exist (may have timed out)
@ -499,7 +502,8 @@ fn referendum_insufficient_support_fails() {
));
// Advance through the entire decision period
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.decision_period + track_info.confirm_period + 1);
// Should still be ongoing or rejected due to insufficient support
@ -578,7 +582,8 @@ fn decision_deposit_mechanics_work() {
}
// Advance time through prepare period (1 DAY for root track)
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.prepare_period + 1);
let alice_balance_before = Balances::free_balance(&alice());
@ -591,7 +596,8 @@ fn decision_deposit_mechanics_work() {
// Alice's balance should decrease by decision deposit
let alice_balance_after = Balances::free_balance(&alice());
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
assert_eq!(
alice_balance_before - alice_balance_after,
track_info.decision_deposit
@ -619,7 +625,8 @@ fn decision_deposit_mechanics_work() {
fn track_capacity_limits_enforced() {
ExtBuilder::default().build().execute_with(|| {
// Use root track which has max_deciding of 5 (more reasonable for testing)
let track_info = &TracksInfo::tracks()[0].1; // root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // root track
let max_deciding = track_info.max_deciding.min(5); // Use smaller number for testing
// Submit max_deciding referenda (but cap at 5 for scheduler limits)
@ -723,7 +730,8 @@ fn insufficient_balance_for_deposits() {
));
// Advance through prepare period
let track_info = &TracksInfo::tracks()[0].1;
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info;
advance_referendum_time(track_info.prepare_period + 1);
// Should fail to place decision deposit due to insufficient balance
@ -753,7 +761,8 @@ fn referendum_confirmation_period_works() {
DispatchTime::After(10)
));
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
// Advance through prepare period
advance_referendum_time(track_info.prepare_period + 1);
@ -821,7 +830,8 @@ fn split_votes_with_conviction() {
));
// Place decision deposit after prepare period
let track_info = &TracksInfo::tracks()[0].1;
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info;
advance_referendum_time(track_info.prepare_period + 1);
assert_ok!(Referenda::place_decision_deposit(
RuntimeOrigin::signed(alice()),

View file

@ -67,6 +67,7 @@ fn validate_transaction_fails_on_filtered_call() {
max_priority_fee_per_gas: Some(sp_core::U256::zero()),
nonce: None,
access_list: Vec::new(),
authorization_list: Vec::new(),
}
.into(),
);

View file

@ -73,6 +73,7 @@ fn author_does_receive_priority_fee() {
max_priority_fee_per_gas: Some(U256::from(200 * MILLIHAVE)),
nonce: Some(U256::from(0)),
access_list: Vec::new(),
authorization_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::RuntimeOrigin::root()));
@ -115,6 +116,7 @@ fn total_issuance_after_evm_transaction_with_priority_fee() {
max_priority_fee_per_gas: Some(U256::from(BASE_FEE_GENESIS)),
nonce: Some(U256::from(0)),
access_list: Vec::new(),
authorization_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::RuntimeOrigin::root()));
@ -184,6 +186,7 @@ fn total_issuance_after_evm_transaction_without_priority_fee() {
max_priority_fee_per_gas: None,
nonce: Some(U256::from(0)),
access_list: Vec::new(),
authorization_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::RuntimeOrigin::root()));

View file

@ -28,8 +28,7 @@ frame_benchmarking::define_benchmarks!(
// Substrate pallets
[pallet_balances, Balances]
[pallet_session, pallet_session_benchmarking::Pallet::<Runtime>]
// FIXME: benchmarking identity fail
// [pallet_identity, Identity]
[pallet_identity, Identity]
[pallet_im_online, ImOnline]
[pallet_multisig, Multisig]
[pallet_preimage, Preimage]

View file

@ -182,13 +182,15 @@ impl pallet_referenda::TracksInfo<Balance, BlockNumber> for TracksInfo {
#[test]
/// To ensure voters are always locked into their vote
fn vote_locking_always_longer_than_enactment_period() {
for (_, track) in TRACKS_DATA {
for track in TRACKS_DATA {
let track_name = from_utf8(&track.info.name).unwrap();
let track_name = track_name.trim_end_matches('\0');
assert!(
<Runtime as pallet_conviction_voting::Config>::VoteLockingPeriod::get()
>= track.min_enactment_period,
>= track.info.min_enactment_period,
"Track {} has enactment period {} < vote locking period {}",
track.name,
track.min_enactment_period,
track_name,
track.info.min_enactment_period,
<Runtime as pallet_conviction_voting::Config>::VoteLockingPeriod::get(),
);
}
@ -196,10 +198,12 @@ fn vote_locking_always_longer_than_enactment_period() {
#[test]
fn all_tracks_have_origins() {
for (_, track) in TRACKS_DATA {
for track in TRACKS_DATA {
let track_name = from_utf8(&track.info.name).unwrap();
let track_name = track_name.trim_end_matches('\0');
// check name.into() is successful either converts into "root" or custom origin
let track_is_root = track.name == "root";
let track_has_custom_origin = custom_origins::Origin::from_str(track.name).is_ok();
let track_is_root = track_name == "root";
let track_has_custom_origin = custom_origins::Origin::from_str(track_name).is_ok();
assert!(track_is_root || track_has_custom_origin);
}
}

View file

@ -657,19 +657,17 @@ impl pallet_identity::Config for Runtime {
type UsernameDeposit = UsernameDeposit;
type UsernameGracePeriod = UsernameGracePeriod;
// TODO: Re-enable after upgrade to Polkadot SDK stable2412-8
// see https://github.com/paritytech/polkadot-sdk/releases/tag/polkadot-stable2412-8
// #[cfg(feature = "runtime-benchmarks")]
// fn benchmark_helper(message: &[u8]) -> (Vec<u8>, Vec<u8>) {
// let public = sp_io::crypto::ecdsa_generate(0.into(), None);
// let eth_signer: Self::SigningPublicKey = public.into();
// let hash_msg = sp_io::hashing::keccak_256(message);
// let signature = Self::OffchainSignature::new(
// sp_io::crypto::ecdsa_sign_prehashed(0.into(), &public, &hash_msg).unwrap(),
// );
#[cfg(feature = "runtime-benchmarks")]
fn benchmark_helper(message: &[u8]) -> (Vec<u8>, Vec<u8>) {
let public = sp_io::crypto::ecdsa_generate(0.into(), None);
let eth_signer: Self::SigningPublicKey = public.into();
let hash_msg = sp_io::hashing::keccak_256(message);
let signature = Self::OffchainSignature::new(
sp_io::crypto::ecdsa_sign_prehashed(0.into(), &public, &hash_msg).unwrap(),
);
// (eth_signer.encode(), signature.encode())
// }
(eth_signer.encode(), signature.encode())
}
}
parameter_types! {

View file

@ -31,7 +31,9 @@ pub mod weights;
pub use configs::governance;
pub use configs::Precompiles;
// TODO: Temporary workaround before upgrading to latest polkadot-sdk - fix https://github.com/paritytech/polkadot-sdk/pull/6435
// Aliases required by define_benchmarks! for pallet_collective instances.
// PR #6435 (in stable2503) fixes the underlying issue, so these can be removed
// when benchmarks are regenerated and weight files renamed accordingly.
#[allow(unused_imports)]
use pallet_collective as pallet_collective_treasury_council;
#[allow(unused_imports)]
@ -196,16 +198,10 @@ pub const NORMAL_BLOCK_WEIGHT: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_mul(3).s
pub const EXTRINSIC_BASE_WEIGHT: Weight = Weight::from_parts(10000 * WEIGHT_PER_GAS, 0);
// Existential deposit.
#[cfg(not(feature = "runtime-benchmarks"))]
// PR #7379 (included in stable2503) ensures benchmarks handle ED=0 internally.
parameter_types! {
pub const ExistentialDeposit: Balance = 0;
}
#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
// TODO: Change ED to 1 after upgrade to Polkadot SDK stable2503
// cfr. https://github.com/paritytech/polkadot-sdk/pull/7379
pub const ExistentialDeposit: Balance = 1;
}
/// The version information used to identify this runtime when compiled natively.
#[cfg(feature = "std")]

View file

@ -24,6 +24,7 @@
use crate::common::*;
use alloc::vec::Vec;
use core::str::from_utf8;
use datahaven_stagenet_runtime::{
configs::governance::council::{TechnicalMaxMembers, TechnicalMaxProposals},
governance::TracksInfo,
@ -443,29 +444,32 @@ fn benchmark_council_maximum_load() {
#[test]
fn benchmark_track_operations() {
ExtBuilder::governance().build().execute_with(|| {
let tracks = TracksInfo::tracks();
let tracks: Vec<_> = TracksInfo::tracks().collect();
println!("Testing {} governance tracks", tracks.len());
for (track_id, track_info) in tracks.iter() {
for track in tracks.iter() {
let track_name = from_utf8(&track.info.name).unwrap();
let track_name = track_name.trim_end_matches('\0');
let start_block = System::block_number();
// Create proposal for this track
let proposal = RuntimeCall::System(frame_system::Call::set_storage {
items: vec![(
format!(":track:{}:{}", track_id, track_info.name).into_bytes(),
format!(":track:{}:{}", track.id, track_name).into_bytes(),
b"test".to_vec(),
)],
});
let proposal_hash = make_proposal_hash(&proposal);
assert_ok!(Preimage::note_preimage(
RuntimeOrigin::signed(alice()),
proposal.encode()
));
let bounded_proposal = <Preimage as StorePreimage>::bound(proposal).unwrap();
// Map track to appropriate origin
let origin = if *track_id == 0 {
let origin = if track.id == 0 {
frame_system::RawOrigin::Root.into()
} else {
frame_system::RawOrigin::Signed(alice()).into()
@ -474,19 +478,19 @@ fn benchmark_track_operations() {
assert_ok!(Referenda::submit(
RuntimeOrigin::signed(alice()),
Box::new(origin),
DispatchTime::After(track_info.min_enactment_period),
Box::new(proposal_hash.into())
bounded_proposal,
DispatchTime::After(track.info.min_enactment_period),
));
assert_ok!(Referenda::place_decision_deposit(
RuntimeOrigin::signed(bob()),
*track_id as u32
track.id as u32
));
// Test voting on this track
assert_ok!(ConvictionVoting::vote(
RuntimeOrigin::signed(charlie()),
*track_id as u32,
track.id as u32,
AccountVote::Standard {
vote: Vote {
aye: true,
@ -500,11 +504,11 @@ fn benchmark_track_operations() {
println!(
"Track {} ({}): processed in {} blocks (max_deciding: {}, decision_deposit: {})",
track_id,
track_info.name,
track.id,
track_name,
end_block - start_block,
track_info.max_deciding,
track_info.decision_deposit
track.info.max_deciding,
track.info.decision_deposit
);
}
});

View file

@ -37,18 +37,21 @@ use pallet_conviction_voting::{AccountVote, Conviction, Event as ConvictionVotin
use pallet_preimage::Event as PreimageEvent;
use pallet_referenda::TracksInfo as TracksInfoTrait;
use pallet_referenda::{Event as ReferendaEvent, ReferendumInfo};
use core::str::from_utf8;
/// Test tracks info configuration
#[test]
fn tracks_info_configured_correctly() {
ExtBuilder::default().build().execute_with(|| {
let tracks = TracksInfo::tracks();
let tracks: Vec<_> = TracksInfo::tracks().collect();
// Should have 6 tracks as configured
assert_eq!(tracks.len(), 6);
// Verify track IDs and names
let track_names: Vec<&str> = tracks.iter().map(|(_, info)| info.name).collect();
let track_names: Vec<&str> = tracks.iter().map(|track| {
from_utf8(&track.info.name).unwrap().trim_end_matches('\0')
}).collect();
assert_eq!(
track_names,
vec![
@ -62,16 +65,14 @@ fn tracks_info_configured_correctly() {
);
// Verify root track has strictest requirements
let (root_id, root_info) = &tracks[0];
assert_eq!(*root_id, 0u16);
assert_eq!(root_info.max_deciding, 5);
assert_eq!(root_info.decision_deposit, 100000 * HAVE * SUPPLY_FACTOR); // 100 * KILO_HAVE
assert_eq!(tracks[0].id, 0u16);
assert_eq!(tracks[0].info.max_deciding, 5);
assert_eq!(tracks[0].info.decision_deposit, 100000 * HAVE * SUPPLY_FACTOR); // 100 * KILO_HAVE
// Verify general admin track
let (admin_id, admin_info) = &tracks[2];
assert_eq!(*admin_id, 2u16);
assert_eq!(admin_info.max_deciding, 10);
assert_eq!(admin_info.decision_deposit, 500 * HAVE * SUPPLY_FACTOR);
assert_eq!(tracks[2].id, 2u16);
assert_eq!(tracks[2].info.max_deciding, 10);
assert_eq!(tracks[2].info.decision_deposit, 500 * HAVE * SUPPLY_FACTOR);
});
}
@ -225,7 +226,8 @@ fn referendum_timing_works() {
));
// Advance time through prepare period (1 DAY for root track)
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.prepare_period + 1);
// Place decision deposit
@ -243,7 +245,8 @@ fn referendum_timing_works() {
}
// Advance time through decision period
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.decision_period + 1);
// Referendum should still exist (may have timed out)
@ -499,7 +502,8 @@ fn referendum_insufficient_support_fails() {
));
// Advance through the entire decision period
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.decision_period + track_info.confirm_period + 1);
// Should still be ongoing or rejected due to insufficient support
@ -578,7 +582,8 @@ fn decision_deposit_mechanics_work() {
}
// Advance time through prepare period (1 DAY for root track)
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.prepare_period + 1);
let alice_balance_before = Balances::free_balance(&alice());
@ -591,7 +596,8 @@ fn decision_deposit_mechanics_work() {
// Alice's balance should decrease by decision deposit
let alice_balance_after = Balances::free_balance(&alice());
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
assert_eq!(
alice_balance_before - alice_balance_after,
track_info.decision_deposit
@ -619,7 +625,8 @@ fn decision_deposit_mechanics_work() {
fn track_capacity_limits_enforced() {
ExtBuilder::default().build().execute_with(|| {
// Use root track which has max_deciding of 5 (more reasonable for testing)
let track_info = &TracksInfo::tracks()[0].1; // root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // root track
let max_deciding = track_info.max_deciding.min(5); // Use smaller number for testing
// Submit max_deciding referenda (but cap at 5 for scheduler limits)
@ -723,7 +730,8 @@ fn insufficient_balance_for_deposits() {
));
// Advance through prepare period
let track_info = &TracksInfo::tracks()[0].1;
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info;
advance_referendum_time(track_info.prepare_period + 1);
// Should fail to place decision deposit due to insufficient balance
@ -753,7 +761,8 @@ fn referendum_confirmation_period_works() {
DispatchTime::After(10)
));
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
// Advance through prepare period
advance_referendum_time(track_info.prepare_period + 1);
@ -821,7 +830,8 @@ fn split_votes_with_conviction() {
));
// Place decision deposit after prepare period
let track_info = &TracksInfo::tracks()[0].1;
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info;
advance_referendum_time(track_info.prepare_period + 1);
assert_ok!(Referenda::place_decision_deposit(
RuntimeOrigin::signed(alice()),

View file

@ -66,6 +66,7 @@ fn validate_transaction_fails_on_filtered_call() {
max_priority_fee_per_gas: Some(sp_core::U256::zero()),
nonce: None,
access_list: Vec::new(),
authorization_list: Vec::new(),
}
.into(),
);

View file

@ -73,6 +73,7 @@ fn author_does_receive_priority_fee() {
max_priority_fee_per_gas: Some(U256::from(200 * MILLIHAVE)),
nonce: Some(U256::from(0)),
access_list: Vec::new(),
authorization_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::RuntimeOrigin::root()));
@ -115,6 +116,7 @@ fn total_issuance_after_evm_transaction_with_priority_fee() {
max_priority_fee_per_gas: Some(U256::from(BASE_FEE_GENESIS)),
nonce: Some(U256::from(0)),
access_list: Vec::new(),
authorization_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::RuntimeOrigin::root()));
@ -184,6 +186,7 @@ fn total_issuance_after_evm_transaction_without_priority_fee() {
max_priority_fee_per_gas: None,
nonce: Some(U256::from(0)),
access_list: Vec::new(),
authorization_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::RuntimeOrigin::root()));

View file

@ -183,12 +183,14 @@ impl pallet_referenda::TracksInfo<Balance, BlockNumber> for TracksInfo {
/// To ensure voters are always locked into their vote
fn vote_locking_always_longer_than_enactment_period() {
for track in TRACKS_DATA {
let track_name = from_utf8(&track.info.name).unwrap();
let track_name = track_name.trim_end_matches('\0');
assert!(
<Runtime as pallet_conviction_voting::Config>::VoteLockingPeriod::get()
>= track.min_enactment_period,
>= track.info.min_enactment_period,
"Track {} has enactment period {} < vote locking period {}",
track.name,
track.min_enactment_period,
track_name,
track.info.min_enactment_period,
<Runtime as pallet_conviction_voting::Config>::VoteLockingPeriod::get(),
);
}
@ -197,9 +199,11 @@ fn vote_locking_always_longer_than_enactment_period() {
#[test]
fn all_tracks_have_origins() {
for track in TRACKS_DATA {
let track_name = from_utf8(&track.info.name).unwrap();
let track_name = track_name.trim_end_matches('\0');
// check name.into() is successful either converts into "root" or custom origin
let track_is_root = track.name == str_array("root");
let track_has_custom_origin = custom_origins::Origin::from_str(track.name).is_ok();
let track_is_root = track_name == "root";
let track_has_custom_origin = custom_origins::Origin::from_str(track_name).is_ok();
assert!(track_is_root || track_has_custom_origin);
}
}

View file

@ -660,19 +660,17 @@ impl pallet_identity::Config for Runtime {
type UsernameDeposit = UsernameDeposit;
type UsernameGracePeriod = UsernameGracePeriod;
// TODO: Re-enable after upgrade to Polkadot SDK stable2412-8
// see https://github.com/paritytech/polkadot-sdk/releases/tag/polkadot-stable2412-8
// #[cfg(feature = "runtime-benchmarks")]
// fn benchmark_helper(message: &[u8]) -> (Vec<u8>, Vec<u8>) {
// let public = sp_io::crypto::ecdsa_generate(0.into(), None);
// let eth_signer: Self::SigningPublicKey = public.into();
// let hash_msg = sp_io::hashing::keccak_256(message);
// let signature = Self::OffchainSignature::new(
// sp_io::crypto::ecdsa_sign_prehashed(0.into(), &public, &hash_msg).unwrap(),
// );
#[cfg(feature = "runtime-benchmarks")]
fn benchmark_helper(message: &[u8]) -> (Vec<u8>, Vec<u8>) {
let public = sp_io::crypto::ecdsa_generate(0.into(), None);
let eth_signer: Self::SigningPublicKey = public.into();
let hash_msg = sp_io::hashing::keccak_256(message);
let signature = Self::OffchainSignature::new(
sp_io::crypto::ecdsa_sign_prehashed(0.into(), &public, &hash_msg).unwrap(),
);
// (eth_signer.encode(), signature.encode())
// }
(eth_signer.encode(), signature.encode())
}
}
parameter_types! {

View file

@ -31,7 +31,9 @@ pub mod weights;
pub use configs::governance;
pub use configs::Precompiles;
// TODO: Temporary workaround before upgrading to latest polkadot-sdk - fix https://github.com/paritytech/polkadot-sdk/pull/6435
// Aliases required by define_benchmarks! for pallet_collective instances.
// PR #6435 (in stable2503) fixes the underlying issue, so these can be removed
// when benchmarks are regenerated and weight files renamed accordingly.
#[allow(unused_imports)]
use pallet_collective as pallet_collective_treasury_council;
#[allow(unused_imports)]
@ -194,16 +196,10 @@ pub const NORMAL_BLOCK_WEIGHT: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_mul(3).s
pub const EXTRINSIC_BASE_WEIGHT: Weight = Weight::from_parts(10000 * WEIGHT_PER_GAS, 0);
// Existential deposit.
#[cfg(not(feature = "runtime-benchmarks"))]
// PR #7379 (included in stable2503) ensures benchmarks handle ED=0 internally.
parameter_types! {
pub const ExistentialDeposit: Balance = 0;
}
#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
// TODO: Change ED to 1 after upgrade to Polkadot SDK stable2503
// cfr. https://github.com/paritytech/polkadot-sdk/pull/7379
pub const ExistentialDeposit: Balance = 1;
}
/// The version information used to identify this runtime when compiled natively.
#[cfg(feature = "std")]

View file

@ -24,6 +24,7 @@
use crate::common::*;
use alloc::vec::Vec;
use core::str::from_utf8;
use datahaven_testnet_runtime::{
configs::governance::council::{TechnicalMaxMembers, TechnicalMaxProposals},
governance::TracksInfo,
@ -443,29 +444,32 @@ fn benchmark_council_maximum_load() {
#[test]
fn benchmark_track_operations() {
ExtBuilder::governance().build().execute_with(|| {
let tracks = TracksInfo::tracks();
let tracks: Vec<_> = TracksInfo::tracks().collect();
println!("Testing {} governance tracks", tracks.len());
for (track_id, track_info) in tracks.iter() {
for track in tracks.iter() {
let track_name = from_utf8(&track.info.name).unwrap();
let track_name = track_name.trim_end_matches('\0');
let start_block = System::block_number();
// Create proposal for this track
let proposal = RuntimeCall::System(frame_system::Call::set_storage {
items: vec![(
format!(":track:{}:{}", track_id, track_info.name).into_bytes(),
format!(":track:{}:{}", track.id, track_name).into_bytes(),
b"test".to_vec(),
)],
});
let proposal_hash = make_proposal_hash(&proposal);
assert_ok!(Preimage::note_preimage(
RuntimeOrigin::signed(alice()),
proposal.encode()
));
let bounded_proposal = <Preimage as StorePreimage>::bound(proposal).unwrap();
// Map track to appropriate origin
let origin = if *track_id == 0 {
let origin = if track.id == 0 {
frame_system::RawOrigin::Root.into()
} else {
frame_system::RawOrigin::Signed(alice()).into()
@ -474,19 +478,19 @@ fn benchmark_track_operations() {
assert_ok!(Referenda::submit(
RuntimeOrigin::signed(alice()),
Box::new(origin),
DispatchTime::After(track_info.min_enactment_period),
Box::new(proposal_hash.into())
bounded_proposal,
DispatchTime::After(track.info.min_enactment_period),
));
assert_ok!(Referenda::place_decision_deposit(
RuntimeOrigin::signed(bob()),
*track_id as u32
track.id as u32
));
// Test voting on this track
assert_ok!(ConvictionVoting::vote(
RuntimeOrigin::signed(charlie()),
*track_id as u32,
track.id as u32,
AccountVote::Standard {
vote: Vote {
aye: true,
@ -500,11 +504,11 @@ fn benchmark_track_operations() {
println!(
"Track {} ({}): processed in {} blocks (max_deciding: {}, decision_deposit: {})",
track_id,
track_info.name,
track.id,
track_name,
end_block - start_block,
track_info.max_deciding,
track_info.decision_deposit
track.info.max_deciding,
track.info.decision_deposit
);
}
});

View file

@ -37,18 +37,21 @@ use pallet_conviction_voting::{AccountVote, Conviction, Event as ConvictionVotin
use pallet_preimage::Event as PreimageEvent;
use pallet_referenda::TracksInfo as TracksInfoTrait;
use pallet_referenda::{Event as ReferendaEvent, ReferendumInfo};
use core::str::from_utf8;
/// Test tracks info configuration
#[test]
fn tracks_info_configured_correctly() {
ExtBuilder::default().build().execute_with(|| {
let tracks = TracksInfo::tracks();
let tracks: Vec<_> = TracksInfo::tracks().collect();
// Should have 6 tracks as configured
assert_eq!(tracks.len(), 6);
// Verify track IDs and names
let track_names: Vec<&str> = tracks.iter().map(|(_, info)| info.name).collect();
let track_names: Vec<&str> = tracks.iter().map(|track| {
from_utf8(&track.info.name).unwrap().trim_end_matches('\0')
}).collect();
assert_eq!(
track_names,
vec![
@ -62,16 +65,14 @@ fn tracks_info_configured_correctly() {
);
// Verify root track has strictest requirements
let (root_id, root_info) = &tracks[0];
assert_eq!(*root_id, 0u16);
assert_eq!(root_info.max_deciding, 5);
assert_eq!(root_info.decision_deposit, 100000 * HAVE * SUPPLY_FACTOR); // 100 * KILO_HAVE
assert_eq!(tracks[0].id, 0u16);
assert_eq!(tracks[0].info.max_deciding, 5);
assert_eq!(tracks[0].info.decision_deposit, 100000 * HAVE * SUPPLY_FACTOR); // 100 * KILO_HAVE
// Verify general admin track
let (admin_id, admin_info) = &tracks[2];
assert_eq!(*admin_id, 2u16);
assert_eq!(admin_info.max_deciding, 10);
assert_eq!(admin_info.decision_deposit, 500 * HAVE * SUPPLY_FACTOR);
assert_eq!(tracks[2].id, 2u16);
assert_eq!(tracks[2].info.max_deciding, 10);
assert_eq!(tracks[2].info.decision_deposit, 500 * HAVE * SUPPLY_FACTOR);
});
}
@ -225,7 +226,8 @@ fn referendum_timing_works() {
));
// Advance time through prepare period (1 DAY for root track)
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.prepare_period + 1);
// Place decision deposit
@ -243,7 +245,8 @@ fn referendum_timing_works() {
}
// Advance time through decision period
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.decision_period + 1);
// Referendum should still exist (may have timed out)
@ -499,7 +502,8 @@ fn referendum_insufficient_support_fails() {
));
// Advance through the entire decision period
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.decision_period + track_info.confirm_period + 1);
// Should still be ongoing or rejected due to insufficient support
@ -578,7 +582,8 @@ fn decision_deposit_mechanics_work() {
}
// Advance time through prepare period (1 DAY for root track)
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
advance_referendum_time(track_info.prepare_period + 1);
let alice_balance_before = Balances::free_balance(&alice());
@ -591,7 +596,8 @@ fn decision_deposit_mechanics_work() {
// Alice's balance should decrease by decision deposit
let alice_balance_after = Balances::free_balance(&alice());
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
assert_eq!(
alice_balance_before - alice_balance_after,
track_info.decision_deposit
@ -619,7 +625,8 @@ fn decision_deposit_mechanics_work() {
fn track_capacity_limits_enforced() {
ExtBuilder::default().build().execute_with(|| {
// Use root track which has max_deciding of 5 (more reasonable for testing)
let track_info = &TracksInfo::tracks()[0].1; // root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // root track
let max_deciding = track_info.max_deciding.min(5); // Use smaller number for testing
// Submit max_deciding referenda (but cap at 5 for scheduler limits)
@ -723,7 +730,8 @@ fn insufficient_balance_for_deposits() {
));
// Advance through prepare period
let track_info = &TracksInfo::tracks()[0].1;
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info;
advance_referendum_time(track_info.prepare_period + 1);
// Should fail to place decision deposit due to insufficient balance
@ -753,7 +761,8 @@ fn referendum_confirmation_period_works() {
DispatchTime::After(10)
));
let track_info = &TracksInfo::tracks()[0].1; // Root track
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info; // Root track
// Advance through prepare period
advance_referendum_time(track_info.prepare_period + 1);
@ -821,7 +830,8 @@ fn split_votes_with_conviction() {
));
// Place decision deposit after prepare period
let track_info = &TracksInfo::tracks()[0].1;
let tracks: Vec<_> = TracksInfo::tracks().collect();
let track_info = &tracks[0].info;
advance_referendum_time(track_info.prepare_period + 1);
assert_ok!(Referenda::place_decision_deposit(
RuntimeOrigin::signed(alice()),

View file

@ -67,6 +67,7 @@ fn validate_transaction_fails_on_filtered_call() {
max_priority_fee_per_gas: Some(sp_core::U256::zero()),
nonce: None,
access_list: Vec::new(),
authorization_list: Vec::new(),
}
.into(),
);

View file

@ -72,6 +72,7 @@ fn author_does_receive_priority_fee() {
max_priority_fee_per_gas: Some(U256::from(200 * MILLIHAVE)),
nonce: Some(U256::from(0)),
access_list: Vec::new(),
authorization_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::RuntimeOrigin::root()));
@ -114,6 +115,7 @@ fn total_issuance_after_evm_transaction_with_priority_fee() {
max_priority_fee_per_gas: Some(U256::from(BASE_FEE_GENESIS)),
nonce: Some(U256::from(0)),
access_list: Vec::new(),
authorization_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::RuntimeOrigin::root()));
@ -184,6 +186,7 @@ fn total_issuance_after_evm_transaction_without_priority_fee() {
max_priority_fee_per_gas: None,
nonce: Some(U256::from(0)),
access_list: Vec::new(),
authorization_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::RuntimeOrigin::root()));