From 18562050f605dd0e3cb2cd92fa25220bc61ecfbd Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 20 Nov 2025 10:34:18 +0000 Subject: [PATCH 1/2] weight export diagrams for staking-async PAPI tests --- .../runtimes/papi-tests/src/cmd.ts | 7 +- .../runtimes/papi-tests/src/export-diagram.ts | 313 ++++++++++++++++++ .../runtimes/papi-tests/src/test-case.ts | 47 ++- .../runtimes/papi-tests/src/utils.ts | 2 +- .../runtimes/papi-tests/tests/example.test.ts | 2 +- .../papi-tests/tests/prune-full-era.test.ts | 2 +- .../papi-tests/tests/signed-dev.test.ts | 2 + .../papi-tests/tests/signed-dot.test.ts | 5 +- .../papi-tests/tests/signed-ksm.test.ts | 7 +- .../papi-tests/tests/unsigned-dev.test.ts | 2 +- .../papi-tests/tests/vmp-spamming.test.ts | 2 +- .../runtimes/papi-tests/zn-m.toml | 1 + .../runtimes/papi-tests/zn-s.toml | 3 +- 13 files changed, 370 insertions(+), 25 deletions(-) create mode 100644 substrate/frame/staking-async/runtimes/papi-tests/src/export-diagram.ts diff --git a/substrate/frame/staking-async/runtimes/papi-tests/src/cmd.ts b/substrate/frame/staking-async/runtimes/papi-tests/src/cmd.ts index 200675d7ac895..01891effbd327 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/src/cmd.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/src/cmd.ts @@ -57,6 +57,7 @@ export async function runPresetUntilLaunched( // Extract log path from the last log command const lastCmd = logCmds[logCmds.length - 1]; const paraLog = lastCmd ? lastCmd.match(/tail -f\s+(.+\.log)/)?.[1] || null : null; + logger.verbose(`Parachain log file: ${paraLog}`); resolve({ killZn: () => { @@ -84,7 +85,7 @@ export async function spawnMiner(): Promise<() => void> { [ "--uri", "ws://127.0.0.1:9946", - "experimental-monitor-multi-block", + "monitor", "--seed-or-path", "//Bob", ], @@ -123,8 +124,8 @@ function prepPreset(paraPreset: Presets): void { `staging-chain-spec-builder`, ]); - cmd("rm", ["./parachain.json"]); - cmd("rm", ["./rc.json"]); + cmd("rm", ["-f", "./parachain.json"]); + cmd("rm", ["-f", "./rc.json"]); cmd(join(targetDir, "/release/chain-spec-builder"), [ "create", diff --git a/substrate/frame/staking-async/runtimes/papi-tests/src/export-diagram.ts b/substrate/frame/staking-async/runtimes/papi-tests/src/export-diagram.ts new file mode 100644 index 0000000000000..c6164d5beb765 --- /dev/null +++ b/substrate/frame/staking-async/runtimes/papi-tests/src/export-diagram.ts @@ -0,0 +1,313 @@ +import { writeFileSync } from "fs"; +import type { WeightSummary } from "./test-case"; + +/** + * Exports weight data to an interactive HTML chart using Chart.js. + * + * Creates a chart with three lines: + * 1. Sum of authorship data (header + extrinsics + proof) in KB + * 2. Compressed authorship data in KB + * 3. Onchain mandatory proof_size in KB + * + * Also annotates blocks that have matched events. + * + * @param paraSummary - Map of block numbers to weight summary data + * @param outputPath - Path where the HTML file should be saved (default: './weight-diagram.html') + */ +export function exportWeightDiagram( + paraSummary: Map, + outputPath: string = "./weight-diagram.html" +): void { + const blocks = Array.from(paraSummary.keys()).sort((a, b) => a - b); + + // Prepare data arrays + const authorshipSumData: (number | null)[] = []; + const compressedData: (number | null)[] = []; + const onchainMandatoryProofData: number[] = []; + const eventAnnotations: string[] = []; + const blockEventMap: { [key: number]: string } = {}; + + for (const block of blocks) { + const summary = paraSummary.get(block)!; + + // Calculate authorship sum (header + extrinsics + proof) + if (summary.authorshipWeights) { + const sum = + summary.authorshipWeights.header + + summary.authorshipWeights.extrinsics + + summary.authorshipWeights.proof; + authorshipSumData.push(sum); + compressedData.push(summary.authorshipWeights.compressed); + } else { + authorshipSumData.push(null); + compressedData.push(null); + } + + // Onchain mandatory proof_size (convert from bytes to KB) + const mandatoryProofKb = Number(summary.onchainWeights.mandatory.proof_size) / 1024; + onchainMandatoryProofData.push(mandatoryProofKb); + + // Create event annotation if there are matched events + if (summary.matchedEvent.length > 0) { + const events = summary.matchedEvent + .map(e => `${e.module}::${e.event}`) + .join(", "); + eventAnnotations.push(`Block ${block}: ${events}`); + blockEventMap[block] = events; + } + } + + // Generate HTML with Chart.js + const html = ` + + + + + Weight Diagram + + + + + + +
+

Parachain Weight Diagram

+
+ +
+
+ +
+ ${eventAnnotations.length > 0 ? ` +
+

Matched Events

+
    + ${eventAnnotations.map(e => `
  • ${e}
  • `).join('\n\t\t\t\t')} +
+
+ ` : ''} +
+ + +`; + + // Write the HTML file + writeFileSync(outputPath, html, 'utf-8'); + console.log(`Weight diagram exported to ${outputPath}`); +} diff --git a/substrate/frame/staking-async/runtimes/papi-tests/src/test-case.ts b/substrate/frame/staking-async/runtimes/papi-tests/src/test-case.ts index 40466bbc276ca..80771b74fd99b 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/src/test-case.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/src/test-case.ts @@ -53,6 +53,12 @@ interface IAuthorshipData { time: number; } +export interface WeightSummary { + authorshipWeights: IAuthorshipData; + onchainWeights: IWeight; + matchedEvent: IEvent[]; +} + /// Print an event. function pe(e: IEvent): string { return `${e.module} ${e.event} ${e.data ? safeJsonStringify(e.data) : "no data"}`; @@ -68,7 +74,7 @@ interface IObservableEvent { export class Observe { e: IObservableEvent; - onPass: () => void = () => {}; + onPass: () => void = () => { }; constructor( chain: Chain, @@ -76,16 +82,15 @@ export class Observe { event: string, dataCheck: ((data: any) => boolean) | undefined = undefined, byBlock: number | undefined = undefined, - onPass: () => void = () => {} + onPass: () => void = () => { } ) { this.e = { chain, module, event, dataCheck, byBlock }; this.onPass = onPass; } toString(): string { - return `Observe(${this.e.chain}, ${this.e.module}, ${this.e.event}, ${ - this.e.dataCheck ? "dataCheck" : "no dataCheck" - }, ${this.e.byBlock ? this.e.byBlock : "no byBlock"})`; + return `Observe(${this.e.chain}, ${this.e.module}, ${this.e.event}, ${this.e.dataCheck ? "dataCheck" : "no dataCheck" + }, ${this.e.byBlock ? this.e.byBlock : "no byBlock"})`; } static on(chain: Chain, mod: string, event: string): ObserveBuilder { @@ -99,7 +104,7 @@ export class ObserveBuilder { private event: string; private dataCheck?: (data: any) => boolean; private byBlockVal?: number; - private onPassCallback: () => void = () => {}; + private onPassCallback: () => void = () => { }; constructor(chain: Chain, module: string, event: string) { this.chain = chain; @@ -147,10 +152,11 @@ export class TestCase { eventSequence: Observe[]; onKill: () => void; allowPerChainInterleavedEvents: boolean = false; - private resolveTestPromise: (outcome: EventOutcome) => void = () => {}; + summary: Map = new Map(); + private resolveTestPromise: (outcome: EventOutcome) => void = () => { }; /// See `example.test.ts` for more info. - constructor(e: Observe[], interleave: boolean = false, onKill: () => void = () => {}) { + constructor(e: Observe[], interleave: boolean = false, onKill: () => void = () => { }) { this.eventSequence = e; this.onKill = onKill; this.allowPerChainInterleavedEvents = interleave; @@ -251,15 +257,28 @@ export class TestCase { this.resolveTestPromise(EventOutcome.TimedOut); } + if (blockData.chain == Chain.Parachain) { + this.summary.set(blockData.number, { + authorshipWeights: blockData.authorship!, + onchainWeights: blockData.weights, + matchedEvent: [], + }); + } + for (const e of blockData.events) { - this.onEvent(e, blockData); + if (this.onEvent(e, blockData) && blockData.chain == Chain.Parachain) { + const summary = this.summary.get(blockData.number)!; + summary.matchedEvent.push(e); + this.summary.set(blockData.number, summary); + } } } - onEvent(e: IEvent, blockData: IBlock) { + /// Returns `true` if the `e` matched and was processed. + onEvent(e: IEvent, blockData: IBlock): boolean { if (!this.eventSequence.length) { logger.warn(`No events to process for ${blockData.chain}, event: ${pe(e)}`); - return; + return false; } logger.verbose(`${this.commonLog(blockData)} Processing event: ${pe(e)}`); const [primary, maybeSecondary] = this.nextEvent(blockData.chain); @@ -273,19 +292,21 @@ export class TestCase { this.resolveTestPromise(EventOutcome.Done); } else { logger.verbose( - `Next expected event: ${this.eventSequence[0]!.toString()}, remaining events: ${ - this.eventSequence.length + `Next expected event: ${this.eventSequence[0]!.toString()}, remaining events: ${this.eventSequence.length }` ); } + return true; } else if (maybeSecondary && this.match(maybeSecondary.e, e, blockData.chain)) { maybeSecondary.onPass(); this.removeEvent(maybeSecondary); logger.info(`Secondary event passed`); // when we check secondary events, we must have at least 2 items in the list, so no // need to check for the end of list. + return true; } else { logger.debug(`event not relevant`); + return false; } } } diff --git a/substrate/frame/staking-async/runtimes/papi-tests/src/utils.ts b/substrate/frame/staking-async/runtimes/papi-tests/src/utils.ts index 4a0db0c822fb8..6f8ca6690c79b 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/src/utils.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/src/utils.ts @@ -14,7 +14,7 @@ import { sr25519CreateDerive } from "@polkadot-labs/hdkd"; import { DEV_PHRASE, entropyToMiniSecret, mnemonicToEntropy, type KeyPair } from "@polkadot-labs/hdkd-helpers"; import { getPolkadotSigner } from "polkadot-api/signer"; -export const GlobalTimeout = 30 * 60 * 1000; +export const GlobalTimeout = 45 * 60 * 1000; export const aliceStash = "5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY"; diff --git a/substrate/frame/staking-async/runtimes/papi-tests/tests/example.test.ts b/substrate/frame/staking-async/runtimes/papi-tests/tests/example.test.ts index a1477bd7a4aa2..95e7a388f4a30 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/tests/example.test.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/tests/example.test.ts @@ -7,7 +7,7 @@ import { getApis, GlobalTimeout, logger, nullifySigned } from "../src/utils"; /// This is the preset against which your test will run. See the README or `PResets` for more info. const PRESET: Presets = Presets.FakeKsm; -test( +test.skip( `example test with preset ${PRESET}`, async () => { /// We run the test with our defined preset. diff --git a/substrate/frame/staking-async/runtimes/papi-tests/tests/prune-full-era.test.ts b/substrate/frame/staking-async/runtimes/papi-tests/tests/prune-full-era.test.ts index 7a8f3ffba3967..6ad064f3c739a 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/tests/prune-full-era.test.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/tests/prune-full-era.test.ts @@ -7,7 +7,7 @@ import { commonSignedSteps } from "./common"; const PRESET: Presets = Presets.FakeDot; -test( +test.skip( `pruning era with signed (full solution) on ${PRESET}`, async () => { const { killZn, paraLog } = await runPresetUntilLaunched(PRESET); diff --git a/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-dev.test.ts b/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-dev.test.ts index 05e14640c94ca..2445c4d96b8d0 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-dev.test.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-dev.test.ts @@ -7,6 +7,7 @@ import { GlobalTimeout, } from "../src/utils"; import { commonSignedSteps } from "./common"; +import { exportWeightDiagram } from "../src/export-diagram"; const PRESET: Presets = Presets.FakeDev; test( @@ -26,6 +27,7 @@ test( ); const outcome = await runTest(testCase, apis, paraLog); + exportWeightDiagram(testCase.summary, `./signed-dev.html`); expect(outcome).toEqual(EventOutcome.Done); }, { timeout: GlobalTimeout } diff --git a/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-dot.test.ts b/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-dot.test.ts index 37a553b1bb61b..748d65eb7c3f5 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-dot.test.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-dot.test.ts @@ -4,6 +4,7 @@ import { runPresetUntilLaunched, spawnMiner } from "../src/cmd"; import { EventOutcome, runTest, TestCase } from "../src/test-case"; import { getApis, GlobalTimeout} from "../src/utils"; import { commonSignedSteps } from "./common"; +import { exportWeightDiagram } from "../src/export-diagram"; const PRESET: Presets = Presets.FakeDot; @@ -13,9 +14,10 @@ test( const { killZn, paraLog } = await runPresetUntilLaunched(PRESET); const apis = await getApis(); const killMiner = await spawnMiner(); + const expectedValidatorSetCount = await apis.paraApi.query.Staking.ValidatorCount.getValue(); const testCase = new TestCase( - commonSignedSteps(32, 500, apis), + commonSignedSteps(32, expectedValidatorSetCount, apis), true, () => { killMiner(); @@ -24,6 +26,7 @@ test( ); const outcome = await runTest(testCase, apis, paraLog); + exportWeightDiagram(testCase.summary, `./signed-dot.html`); expect(outcome).toEqual(EventOutcome.Done); }, { timeout: GlobalTimeout } diff --git a/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-ksm.test.ts b/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-ksm.test.ts index 20794c40ff5b7..7cf9bbdfa1329 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-ksm.test.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/tests/signed-ksm.test.ts @@ -4,18 +4,20 @@ import { runPresetUntilLaunched, spawnMiner } from "../src/cmd"; import { EventOutcome, runTest, TestCase } from "../src/test-case"; import { getApis, GlobalTimeout } from "../src/utils"; import { commonSignedSteps } from "./common"; +import { exportWeightDiagram } from "../src/export-diagram"; const PRESET: Presets = Presets.FakeKsm; test( `signed solution on ${PRESET}`, async () => { - const { killZn, paraLog } = await runPresetUntilLaunched(PRESET); + const { killZn, paraLog } = await runPresetUntilLaunched(PRESET); const apis = await getApis(); const killMiner = await spawnMiner(); + const expectedValidatorSetCount = await apis.paraApi.query.Staking.ValidatorCount.getValue(); const testCase = new TestCase( - commonSignedSteps(16, 1000, apis), + commonSignedSteps(16, expectedValidatorSetCount, apis), true, () => { killMiner(); @@ -24,6 +26,7 @@ test( ); const outcome = await runTest(testCase, apis, paraLog); + exportWeightDiagram(testCase.summary, `./signed-ksm.html`); expect(outcome).toEqual(EventOutcome.Done); }, { timeout: GlobalTimeout } diff --git a/substrate/frame/staking-async/runtimes/papi-tests/tests/unsigned-dev.test.ts b/substrate/frame/staking-async/runtimes/papi-tests/tests/unsigned-dev.test.ts index 57fc3b4acab8e..6b6bf804d7cdc 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/tests/unsigned-dev.test.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/tests/unsigned-dev.test.ts @@ -13,7 +13,7 @@ test( const { killZn, paraLog } = await runPresetUntilLaunched(PRESET); const apis = await getApis(); - const steps = commonUnsignedSteps(10, 4, 4, false, apis); + const steps = commonUnsignedSteps(10, 4, 4, true, apis); const testCase = new TestCase(steps, true, () => { killZn(); diff --git a/substrate/frame/staking-async/runtimes/papi-tests/tests/vmp-spamming.test.ts b/substrate/frame/staking-async/runtimes/papi-tests/tests/vmp-spamming.test.ts index 085d8ab73015e..f361d11a6b1bc 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/tests/vmp-spamming.test.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/tests/vmp-spamming.test.ts @@ -204,7 +204,7 @@ async function sendDown(api: TypedApi, count: number) { } } -test( +test.skip( `${PRESET} preset with vmp queues being spammed af`, async () => { const { killZn, paraLog } = await runPresetUntilLaunched(PRESET); diff --git a/substrate/frame/staking-async/runtimes/papi-tests/zn-m.toml b/substrate/frame/staking-async/runtimes/papi-tests/zn-m.toml index fbcf63376ebf0..884fa6248d487 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/zn-m.toml +++ b/substrate/frame/staking-async/runtimes/papi-tests/zn-m.toml @@ -31,6 +31,7 @@ id = 1100 chain_spec_path = "./parachain.json" [parachains.collator] +command = "polkadot-parachain" name = "charlie" rpc_port = 9946 args = [ diff --git a/substrate/frame/staking-async/runtimes/papi-tests/zn-s.toml b/substrate/frame/staking-async/runtimes/papi-tests/zn-s.toml index bb360ae7f0a9b..eb9e45aa921a1 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/zn-s.toml +++ b/substrate/frame/staking-async/runtimes/papi-tests/zn-s.toml @@ -23,8 +23,9 @@ id = 1100 chain_spec_path = "./parachain.json" [parachains.collator] +command = "polkadot-parachain" name = "charlie" rpc_port = 9946 args = [ - "-lruntime::system=debug,runtime::multiblock-election=trace,runtime::staking=debug,runtime::staking::rc-client=trace,runtime::rc-client=debug,xcm=trace,parachain-system=debug,runtime=info", + "-lruntime::system=debug,runtime::multiblock-election=trace,runtime::staking=debug,runtime::staking::rc-client=trace,runtime::rc-client=debug,xcm=debug,parachain-system=debug,runtime=info", ] From 99321e00b6bd0746f6c04b28a4318cb523679071 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 25 Feb 2026 13:12:35 +0000 Subject: [PATCH 2/2] enable pov reclai for EPMB + staking async --- Cargo.lock | 2 ++ .../election-provider-multi-block/Cargo.toml | 3 +++ .../election-provider-multi-block/src/lib.rs | 15 ++++++++++++++- substrate/frame/staking-async/Cargo.toml | 3 +++ .../staking-async/runtimes/papi-tests/.gitignore | 2 ++ substrate/frame/staking-async/src/pallet/mod.rs | 15 ++++++++++++++- 6 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d43ca259fb59..0a14bf9f624cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12325,6 +12325,7 @@ dependencies = [ name = "pallet-election-provider-multi-block" version = "0.9.0" dependencies = [ + "cumulus-primitives-storage-weight-reclaim", "frame-benchmarking", "frame-election-provider-support", "frame-support", @@ -13632,6 +13633,7 @@ name = "pallet-staking-async" version = "0.1.0" dependencies = [ "anyhow", + "cumulus-primitives-storage-weight-reclaim", "env_logger 0.11.3", "frame-benchmarking", "frame-election-provider-support", diff --git a/substrate/frame/election-provider-multi-block/Cargo.toml b/substrate/frame/election-provider-multi-block/Cargo.toml index 270b51373bee7..fee4108526213 100644 --- a/substrate/frame/election-provider-multi-block/Cargo.toml +++ b/substrate/frame/election-provider-multi-block/Cargo.toml @@ -34,6 +34,8 @@ sp-npos-elections = { workspace = true } sp-runtime = { workspace = true } sp-std = { workspace = true } +cumulus-primitives-storage-weight-reclaim = { workspace = true } + # Optional imports for benchmarking frame-benchmarking = { optional = true, workspace = true } rand = { features = ["alloc", "small_rng"], optional = true, workspace = true } @@ -64,6 +66,7 @@ std = [ "sp-runtime/std", "sp-std/std", "sp-tracing/std", + "cumulus-primitives-storage-weight-reclaim/std" ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index 7869c806fcca3..b5167529116c3 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -751,7 +751,20 @@ pub mod pallet { weight_meter.remaining() ); if weight_meter.can_consume(combined_weight) { - combined_exec(weight_meter); + use cumulus_primitives_storage_weight_reclaim::StorageWeightReclaimer; + let mut reclaimer = StorageWeightReclaimer::new(weight_meter); + // pass a dummy weight meter here, as we no longer want it to be consumed. + combined_exec(&mut WeightMeter::new()); + // and consume it here. + weight_meter.consume(combined_weight); + // then try and reclaim what you can. + let _reclaimed = reclaimer.reclaim_with_meter(weight_meter).defensive(); + crate::log!( + debug, + " weight left post refund: {:?}, reclaimed: {:?}", + weight_meter.remaining().proof_size(), + _reclaimed + ); } else { Self::deposit_event(Event::UnexpectedPhaseTransitionOutOfWeight { from: current_phase, diff --git a/substrate/frame/staking-async/Cargo.toml b/substrate/frame/staking-async/Cargo.toml index a852d8e87571b..4043e0456fc55 100644 --- a/substrate/frame/staking-async/Cargo.toml +++ b/substrate/frame/staking-async/Cargo.toml @@ -32,6 +32,8 @@ sp-npos-elections = { workspace = true } sp-runtime = { features = ["serde"], workspace = true } sp-staking = { features = ["serde"], workspace = true } +cumulus-primitives-storage-weight-reclaim = { workspace = true } + # Optional imports for benchmarking frame-benchmarking = { optional = true, workspace = true } @@ -71,6 +73,7 @@ std = [ "sp-runtime/std", "sp-staking/std", "sp-tracing/std", + "cumulus-primitives-storage-weight-reclaim/std" ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/substrate/frame/staking-async/runtimes/papi-tests/.gitignore b/substrate/frame/staking-async/runtimes/papi-tests/.gitignore index fd0c5bcc4e311..e1d424b75e334 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/.gitignore +++ b/substrate/frame/staking-async/runtimes/papi-tests/.gitignore @@ -37,3 +37,5 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json rc.json parachain.json miner.log + +./*.html diff --git a/substrate/frame/staking-async/src/pallet/mod.rs b/substrate/frame/staking-async/src/pallet/mod.rs index 9600b992feb56..68610652520ff 100644 --- a/substrate/frame/staking-async/src/pallet/mod.rs +++ b/substrate/frame/staking-async/src/pallet/mod.rs @@ -1491,7 +1491,20 @@ pub mod pallet { ); if weight_meter.can_consume(weight) { - exec(weight_meter); + use cumulus_primitives_storage_weight_reclaim::StorageWeightReclaimer; + let mut reclaimer = StorageWeightReclaimer::new(weight_meter); + // pass a dummy weight meter here, as we no longer want it to be consumed. + exec(&mut WeightMeter::new()); + // and consume it here. + weight_meter.consume(weight); + // then try and reclaim what you can. + let _reclaimed = reclaimer.reclaim_with_meter(weight_meter).defensive(); + crate::log!( + debug, + " weight left post refund: {:?}, reclaimed: {:?}", + weight_meter.remaining().proof_size(), + _reclaimed + ); } else { Self::deposit_event(Event::::Unexpected( UnexpectedKind::PagedElectionOutOfWeight {