Skip to content
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
4 changes: 4 additions & 0 deletions Cargo.lock

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

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ workspace = true
[dependencies]
codec = { features = ["derive", "max-encoded-len"], workspace = true }
hex-literal = { workspace = true, default-features = true }
log = { workspace = true }
scale-info = { features = ["derive"], workspace = true }
serde_json = { features = ["alloc"], workspace = true }
tracing = { workspace = true }
Expand Down Expand Up @@ -137,6 +138,7 @@ alloy-core = { workspace = true, features = ["sol-types"] }
asset-test-utils = { workspace = true, default-features = true }
pallet-revive-fixtures = { workspace = true, default-features = true }
parachains-runtimes-test-utils = { workspace = true, default-features = true }
sp-tracing = { workspace = true, default-features = true }

[build-dependencies]
substrate-wasm-builder = { optional = true, workspace = true, default-features = true }
Expand Down Expand Up @@ -301,6 +303,7 @@ std = [
"frame-system-rpc-runtime-api/std",
"frame-system/std",
"frame-try-runtime?/std",
"log/std",
"pallet-ah-ops/std",
"pallet-asset-conversion-ops/std",
"pallet-asset-conversion-tx-payment/std",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ impl pallet_staking_async_rc_client::Config for Runtime {
type RelayChainOrigin = EnsureRoot<AccountId>;
type AHStakingInterface = Staking;
type SendToRelayChain = StakingXcmToRelayChain;
type MaxValidatorSetRetries = ConstU32<64>;
}

#[derive(Encode, Decode)]
Expand Down Expand Up @@ -350,13 +351,13 @@ pub struct StakingXcmToRelayChain;

impl rc_client::SendToRelayChain for StakingXcmToRelayChain {
type AccountId = AccountId;
fn validator_set(report: rc_client::ValidatorSetReport<Self::AccountId>) {
fn validator_set(report: rc_client::ValidatorSetReport<Self::AccountId>) -> Result<(), ()> {
rc_client::XCMSender::<
xcm_config::XcmRouter,
RelayLocation,
rc_client::ValidatorSetReport<Self::AccountId>,
ValidatorSetToXcm,
>::split_then_send(report, Some(8));
>::send(report)
}
}

Expand Down
65 changes: 38 additions & 27 deletions polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ enum RcClientCalls<AccountId> {
#[codec(index = 0)]
RelaySessionReport(rc_client::SessionReport<AccountId>),
#[codec(index = 1)]
RelayNewOffence(SessionIndex, Vec<rc_client::Offence<AccountId>>),
RelayNewOffencePaged(Vec<(SessionIndex, rc_client::Offence<AccountId>)>),
}

pub struct AssetHubLocation;
Expand Down Expand Up @@ -844,42 +844,53 @@ impl sp_runtime::traits::Convert<rc_client::SessionReport<AccountId>, Xcm<()>>
}
}

pub struct StakingXcmToAssetHub;
impl ah_client::SendToAssetHub for StakingXcmToAssetHub {
type AccountId = AccountId;

fn relay_session_report(session_report: rc_client::SessionReport<Self::AccountId>) {
rc_client::XCMSender::<
xcm_config::XcmRouter,
AssetHubLocation,
rc_client::SessionReport<AccountId>,
SessionReportToXcm,
>::split_then_send(session_report, Some(8));
}

fn relay_new_offence(
session_index: SessionIndex,
offences: Vec<rc_client::Offence<Self::AccountId>>,
) {
let message = Xcm(vec![
pub struct QueuedOffenceToXcm;
impl sp_runtime::traits::Convert<Vec<ah_client::QueuedOffenceOf<Runtime>>, Xcm<()>>
for QueuedOffenceToXcm
{
fn convert(offences: Vec<ah_client::QueuedOffenceOf<Runtime>>) -> Xcm<()> {
Xcm(vec![
Instruction::UnpaidExecution {
weight_limit: WeightLimit::Unlimited,
check_origin: None,
},
Instruction::Transact {
origin_kind: OriginKind::Superuser,
fallback_max_weight: None,
call: AssetHubRuntimePallets::RcClient(RcClientCalls::RelayNewOffence(
session_index,
call: AssetHubRuntimePallets::RcClient(RcClientCalls::RelayNewOffencePaged(
offences,
))
.encode()
.into(),
},
]);
if let Err(err) = send_xcm::<xcm_config::XcmRouter>(AssetHubLocation::get(), message) {
log::error!(target: "runtime::ah-client", "Failed to send relay offence message: {:?}", err);
}
])
}
}

pub struct StakingXcmToAssetHub;
impl ah_client::SendToAssetHub for StakingXcmToAssetHub {
type AccountId = AccountId;

fn relay_session_report(
session_report: rc_client::SessionReport<Self::AccountId>,
) -> Result<(), ()> {
rc_client::XCMSender::<
xcm_config::XcmRouter,
AssetHubLocation,
rc_client::SessionReport<AccountId>,
SessionReportToXcm,
>::send(session_report)
}

fn relay_new_offence_paged(
offences: Vec<ah_client::QueuedOffenceOf<Runtime>>,
) -> Result<(), ()> {
rc_client::XCMSender::<
xcm_config::XcmRouter,
AssetHubLocation,
Vec<ah_client::QueuedOffenceOf<Runtime>>,
QueuedOffenceToXcm,
>::send(offences)
}
}

Expand All @@ -895,7 +906,8 @@ impl ah_client::Config for Runtime {
type PointsPerBlock = ConstU32<20>;
type MaxOffenceBatchSize = ConstU32<50>;
type Fallback = Staking;
type WeightInfo = ah_client::weights::SubstrateWeight<Runtime>;
type MaximumValidatorsWithPoints = ConstU32<{ MaxActiveValidators::get() * 4 }>;
type MaxSessionReportRetries = ConstU32<5>;
}

impl pallet_fast_unstake::Config for Runtime {
Expand Down Expand Up @@ -2145,7 +2157,6 @@ mod benches {
[pallet_scheduler, Scheduler]
[pallet_session, SessionBench::<Runtime>]
[pallet_staking, Staking]
[pallet_staking_async_ah_client, StakingAhClient]
[pallet_sudo, Sudo]
[frame_system, SystemBench::<Runtime>]
[frame_system_extensions, SystemExtensionsBench::<Runtime>]
Expand Down

This file was deleted.

45 changes: 45 additions & 0 deletions prdoc/pr_9619.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
title: '[AHM/Staking/VMP] Paginated Offence Reports + Retries for Validator Set'
doc:
- audience: Runtime Dev
description: |-
This PR makes the following changes:

#### Common

* `SendToRelayChain` and `SendToAssetHub` traits now return a result, allowing the caller to know if the underlying XCM was sent or not.

#### Offences

* `SendToAssetHub::relay_new_offence` is removed. Instead, we use the new `relay_new_offence_paged` which is a vector of self-contained offences, not requiring us to group offences per session in each message.
* Offences are not sent immediately anymore.
* Instead, they are stored in a paginated `OffenceSendQueue`.
* `on-init`, we grab one page of this storage map, and sent it.

#### Session Report
* Session reports now also have a retry mechanism.
* Upon each failure, we emit an `UnexpectedEvent`
* If our retries run out and we still can't send the session report, we will emit a different `UnexpectedEvent`. We also retore the validator points that we meant to send, and merge them back, so that they are sent in the next session report.

#### Validator Set
* Similar to offences, they are not sent immediately anymore.
* Instead, they are stored in a storage item, and are sent on subsequent on-inits.
* A maximum retry count is added.
crates:
- name: pallet-offences
bump: patch
- name: pallet-root-offences
bump: major
- name: pallet-staking-async-ah-client
bump: major
- name: pallet-staking-async
bump: patch
- name: westend-runtime
bump: minor
- name: pallet-staking-async-rc-client
bump: major
- name: pallet-staking-async-rc-runtime-constants
bump: patch
- name: asset-hub-westend-runtime
bump: minor
- name: pallet-election-provider-multi-block
bump: patch
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,6 @@ impl<T: crate::Config> Phase<T> {

fn are_we_done() -> Self {
let query = T::AreWeDone::get();
log!(debug, "Are we done? {:?}", query);
query
}

Expand Down
Loading
Loading