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

Remove corrupted ledger migration #148

Merged
merged 5 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Runtimes

Work In Progress runtime for Paseo Polkadot community testnet.
Runtimes for Polkadot's community testnet.

## Structure

Expand All @@ -9,7 +9,9 @@ Work In Progress runtime for Paseo Polkadot community testnet.
│ ├── paseo
└── system-parachains
├── asset-hub-paseo
├── bp-asset-hub-paseo
├── bp-asset-hub-paseo
├── bridge-hub-paseo
├── bp-bridge-hub-paseo
│ ├── bp-bridge-hub-paseo
├── people-paseo
├── coretime-paseo
```
1 change: 1 addition & 0 deletions chain-spec-generator/src/relay_chain_specs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const DEFAULT_PROTOCOL_ID: &str = "pas";
pub fn paseo_chain_spec_properties() -> serde_json::map::Map<String, serde_json::Value> {
serde_json::json!({
"tokenDecimals": 10,
"ss58Format": 0,
})
.as_object()
.expect("Map given; qed")
Expand Down
24 changes: 15 additions & 9 deletions relay/paseo/src/genesis_config_presets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
use crate::*;
use babe_primitives::AuthorityId as BabeId;
use pallet_staking::{Forcing, StakerStatus};
use polkadot_primitives::{AccountPublic, AssignmentId, AsyncBackingParams};
use paseo_runtime_constants::currency::UNITS as PAS;
use polkadot_primitives::{AccountPublic, AssignmentId, AsyncBackingParams, ExecutorParam::{MaxMemoryPages, PvfExecTimeout}, PvfExecKind};
use runtime_parachains::configuration::HostConfiguration;
use sp_core::{sr25519, Pair, Public};
use sp_genesis_builder::PresetId;
Expand Down Expand Up @@ -89,26 +89,32 @@ fn testnet_accounts() -> Vec<AccountId> {
fn default_parachains_host_configuration() -> HostConfiguration<polkadot_primitives::BlockNumber> {
use polkadot_primitives::{MAX_CODE_SIZE, MAX_POV_SIZE};

let executor_parameteres = ExecutorParams::from(&[
MaxMemoryPages(8192),
PvfExecTimeout(PvfExecKind::Backing, 2500),
PvfExecTimeout(PvfExecKind::Approval, 15000),
][..]);

runtime_parachains::configuration::HostConfiguration {
validation_upgrade_cooldown: 2u32,
validation_upgrade_delay: 2,
code_retention_period: 1200,
max_code_size: MAX_CODE_SIZE,
max_pov_size: MAX_POV_SIZE,
max_head_data_size: 32 * 1024,
max_upward_queue_count: 8,
max_upward_queue_count: 174172,
max_upward_queue_size: 1024 * 1024,
max_downward_message_size: 1024 * 1024,
max_upward_message_size: 50 * 1024,
max_upward_message_num_per_candidate: 5,
max_upward_message_num_per_candidate: 16,
hrmp_sender_deposit: 0,
hrmp_recipient_deposit: 0,
hrmp_channel_max_capacity: 8,
hrmp_channel_max_total_size: 8 * 1024,
hrmp_max_parachain_inbound_channels: 4,
hrmp_channel_max_capacity: 1000,
hrmp_channel_max_total_size: 100 * 1024,
hrmp_max_parachain_inbound_channels: 10,
hrmp_channel_max_message_size: 1024 * 1024,
hrmp_max_parachain_outbound_channels: 4,
hrmp_max_message_num_per_candidate: 5,
hrmp_max_parachain_outbound_channels: 10,
hrmp_max_message_num_per_candidate: 10,
dispute_period: 6,
no_show_slots: 2,
n_delay_tranches: 25,
Expand All @@ -128,7 +134,7 @@ fn default_parachains_host_configuration() -> HostConfiguration<polkadot_primiti
max_candidate_depth: 3,
allowed_ancestry_len: 2,
},
executor_params: Default::default(),
executor_params: executor_parameteres,
max_validators: None,
pvf_voting_ttl: 2,
approval_voting_params: ApprovalVotingParams { max_approval_coalesce_count: 1 },
Expand Down
159 changes: 6 additions & 153 deletions relay/paseo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,7 @@ pub use pallet_timestamp::Call as TimestampCall;
pub use sp_runtime::BuildStorage;

/// Constant values used within the runtime.
use paseo_runtime_constants::{
currency::*, fee::*, system_parachain, time::*, TREASURY_PALLET_ID,
};
use paseo_runtime_constants::{currency::*, fee::*, system_parachain, time::*, TREASURY_PALLET_ID};

// Weights used in the runtime.
mod weights;
Expand Down Expand Up @@ -230,7 +228,7 @@ pub struct OriginPrivilegeCmp;
impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option<Ordering> {
if left == right {
return Some(Ordering::Equal)
return Some(Ordering::Equal);
}

match (left, right) {
Expand Down Expand Up @@ -1179,7 +1177,8 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
matches!(
c,
RuntimeCall::Staking(..) |
RuntimeCall::Session(..) | RuntimeCall::Utility(..) |
RuntimeCall::Session(..) |
RuntimeCall::Utility(..) |
RuntimeCall::FastUnstake(..) |
RuntimeCall::VoterList(..) |
RuntimeCall::NominationPools(..)
Expand Down Expand Up @@ -2058,158 +2057,12 @@ pub mod migrations {
GetLegacyLeaseImpl,
>,
CancelAuctions,
restore_corrupted_ledgers::Migrate<Runtime>,
);

/// Migrations/checks that do not need to be versioned and can run on every update.
pub type Permanent = (pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,);
}

/// Migration to fix current corrupted staking ledgers in Paseo.
///
/// It consists of:
/// * Call into `pallet_staking::Pallet::<T>::restore_ledger` with:
/// * Root origin;
/// * Default `None` paramters.
/// * Forces unstake of recovered ledger if the final restored ledger has higher stake than the
/// stash's free balance.
///
/// The stashes associated with corrupted ledgers that will be "migrated" are set in
/// [`CorruptedStashes`].
///
/// For more details about the corrupt ledgers issue, recovery and which stashes to migrate, check
/// <https://hackmd.io/m_h9DRutSZaUqCwM9tqZ3g?view>.
pub(crate) mod restore_corrupted_ledgers {
use super::*;

use frame_support::traits::Currency;
use frame_system::RawOrigin;

use pallet_staking::WeightInfo;
use sp_staking::StakingAccount;

parameter_types! {
pub CorruptedStashes: Vec<AccountId> = vec![
// stash account 138fZsNu67JFtiiWc1eWK2Ev5jCYT6ZirZM288tf99CUHk8K
hex_literal::hex!["5e510306a89f40e5520ae46adcc7a4a1bbacf27c86c163b0691bbbd7b5ef9c10"].into(),
// stash account 14kwUJW6rtjTVW3RusMecvTfDqjEMAt8W159jAGBJqPrwwvC
hex_literal::hex!["a6379e16c5dab15e384c71024e3c6667356a5487127c291e61eed3d8d6b335dd"].into(),
// stash account 13SvkXXNbFJ74pHDrkEnUw6AE8TVkLRRkUm2CMXsQtd4ibwq
hex_literal::hex!["6c3e8acb9225c2a6d22539e2c268c8721b016be1558b4aad4bed220dfbf01fea"].into(),
// stash account 12YcbjN5cvqM63oK7WMhNtpTQhtCrrUr4ntzqqrJ4EijvDE8
hex_literal::hex!["4458ad5f0c082da64610607beb9d3164a77f1ef7964b7871c1de182ea7213783"].into(),
];
}

pub struct Migrate<T>(sp_std::marker::PhantomData<T>);
impl<T: pallet_staking::Config> OnRuntimeUpgrade for Migrate<T> {
fn on_runtime_upgrade() -> Weight {
let mut total_weight: Weight = Default::default();
let mut ok_migration = 0;
let mut err_migration = 0;

for stash in CorruptedStashes::get().into_iter() {
let stash_account: T::AccountId = if let Ok(stash_account) =
T::AccountId::decode(&mut &Into::<[u8; 32]>::into(stash.clone())[..])
{
stash_account
} else {
log::error!(
target: LOG_TARGET,
"migrations::corrupted_ledgers: error converting account {:?}. skipping.",
stash.clone(),
);
err_migration += 1;
continue
};

// restore currupted ledger.
match pallet_staking::Pallet::<T>::restore_ledger(
RawOrigin::Root.into(),
stash_account.clone(),
None,
None,
None,
) {
Ok(_) => (), // proceed.
Err(err) => {
// note: after first migration run, restoring ledger will fail with
// `staking::pallet::Error::<T>CannotRestoreLedger`.
log::error!(
target: LOG_TARGET,
"migrations::corrupted_ledgers: error restoring ledger {:?}, unexpected (unless running try-state idempotency round).",
err
);
continue
},
};

// check if restored ledger total is higher than the stash's free balance. If
// that's the case, force unstake the ledger.
let weight = if let Ok(ledger) = pallet_staking::Pallet::<T>::ledger(
StakingAccount::Stash(stash_account.clone()),
) {
// force unstake the ledger.
if ledger.total > T::Currency::free_balance(&stash_account) {
let slashing_spans = 10; // default slashing spans for migration.
let _ = pallet_staking::Pallet::<T>::force_unstake(
RawOrigin::Root.into(),
stash_account.clone(),
slashing_spans,
)
.map_err(|err| {
log::error!(
target: LOG_TARGET,
"migrations::corrupted_ledgers: error force unstaking ledger, unexpected. {:?}",
err
);
err_migration += 1;
err
});

log::info!(
target: LOG_TARGET,
"migrations::corrupted_ledgers: ledger of {:?} restored (with force unstake).",
stash_account,
);
ok_migration += 1;

<T::WeightInfo>::restore_ledger()
.saturating_add(<T::WeightInfo>::force_unstake(slashing_spans))
} else {
log::info!(
target: LOG_TARGET,
"migrations::corrupted_ledgers: ledger of {:?} restored.",
stash,
);
ok_migration += 1;

<T::WeightInfo>::restore_ledger()
}
} else {
log::error!(
target: LOG_TARGET,
"migrations::corrupted_ledgers: ledger does not exist, unexpected."
);
err_migration += 1;
<T::WeightInfo>::restore_ledger()
};

total_weight.saturating_accrue(weight);
}

log::info!(
target: LOG_TARGET,
"migrations::corrupted_ledgers: done. success: {}, error: {}",
ok_migration,
err_migration
);

total_weight
}
}
}

/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
Expand Down Expand Up @@ -3550,7 +3403,7 @@ mod remote_tests {
#[tokio::test]
async fn dispatch_all_proposals() {
if var("RUN_OPENGOV_TEST").is_err() {
return
return;
}

sp_tracing::try_init_simple();
Expand Down Expand Up @@ -3596,7 +3449,7 @@ mod remote_tests {
#[tokio::test]
async fn run_migrations() {
if var("RUN_MIGRATION_TESTS").is_err() {
return
return;
}

sp_tracing::try_init_simple();
Expand Down