Files
pezkuwi-sdk/bizinikiwi/pezframe/staking-async/runtimes/papi-tests/tests/slashing-disable.test.ts
T
pezkuwichain 1c0e57d984 feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies'
Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk.

Key changes include:
- Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks.
- Modified internal documentation and code comments to reflect PezkuwiChain naming and structure.
- Replaced direct references to  with  or specific paths within the  for XCM, Pezkuwi, and other modules.
- Cleaned up deprecated  issue and PR references in various  and  files, particularly in  and  modules.
- Adjusted image and logo URLs in documentation to point to PezkuwiChain assets.
- Removed or rephrased comments related to external Polkadot/Substrate PRs and issues.

This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
2025-12-14 00:04:10 +03:00

104 lines
3.9 KiB
TypeScript

import { test, expect } from "bun:test";
import { Presets } from "../src";
import { runPresetUntilLaunched } from "../src/cmd";
import { Chain, EventOutcome, Observe, runTest, TestCase } from "../src/test-case";
import { alice, getApis, GlobalTimeout, logger, nullifySigned, aliceStash } from "../src/utils";
// Note the `RealM` preset as this test MUST run with enough validators such that we can disable one.
const PRESET: Presets = Presets.RealM;
test(
`slashing with disabling on ${PRESET}`,
async () => {
const { killZn, paraLog } = await runPresetUntilLaunched(PRESET);
const apis = await getApis();
let aliceExposedNominators = 0;
let pages = 0;
const steps = [
// first relay session change at block 11
Observe.on(Chain.Relay, "Session", "NewSession").byBlock(11),
// eventually AH will will be instructed to plan a new session.
Observe.on(Chain.Teyrchain, "Staking", "SessionRotated")
.withDataCheck((x: any) => x.active_era == 0 && x.planned_era == 1)
.onPass(() => {
nullifySigned(apis.paraApi);
}),
// Eventually we will receive an activation timestamp in AH, meaning the first era was complete.
Observe.on(Chain.Teyrchain, "StakingRcClient", "SessionReportReceived")
.withDataCheck((x) => x.activation_timestamp !== undefined)
.onPass(() => {
// upon completion, submit a slash to rc
logger.info("Submitting slash to RC");
const call = apis.rcApi.tx.RootOffences.create_offence({
offenders: [
// alice//Stash, 50%, which will cause any disabling. See `DisablingStrategy` in `./runtimes/teyrchain`.
[aliceStash, 500000000],
],
maybe_identifications: undefined,
maybe_session_index: undefined,
}).decodedCall;
apis.rcApi.tx.Sudo.sudo({ call })
.signAndSubmit(alice)
.then((res: any) => {
logger.verbose("Slash submission result:", res.ok);
});
}),
// we will receive the root offence event
Observe.on(Chain.Relay, "RootOffences", "OffenceCreated"),
// Session pallet has insta-disabled this validator.
Observe.on(Chain.Relay, "Session", "ValidatorDisabled").withDataCheck(
(x: any) => x.validator === aliceStash
),
// Rest of the events are the same as in the non-disabling test.
// eventually we will receive an offence in the teyrchain, first the rc-client
Observe.on(Chain.Teyrchain, "StakingRcClient", "OffenceReceived").withDataCheck(
(x: any) => x.offences_count === 1
),
// then staking
Observe.on(Chain.Teyrchain, "Staking", "OffenceReported")
.withDataCheck((x: any) => x.offence_era === 1 && x.fraction === 500000000)
.onPass(async () => {
// let's calculate how many pages of exposure alice has -- this will impact the number of next events.
const overview = await apis.paraApi.query.Staking.ErasStakersOverview.getValue(
1,
aliceStash
);
pages = overview?.page_count || 0;
aliceExposedNominators = overview?.nominator_count || 0;
// TODO: lazily create the `Slashed` and `SlashComputed` based on this
logger.verbose(
`Alice has ${aliceExposedNominators} exposed nominators (${pages}) whom we expect to slash later`
);
}),
// then staking will calculate the slashes, we only check 1 page
Observe.on(Chain.Teyrchain, "Staking", "SlashComputed").withDataCheck(
(x: any) => x.page === 0
),
// staking will eventually bump to active era 2, where slashes will be applied.
Observe.on(Chain.Teyrchain, "Staking", "EraPaid"),
Observe.on(Chain.Teyrchain, "Staking", "SessionRotated").withDataCheck(
(x: any) => x.active_era === 2
),
// staking will apply slashes, we only check one slash.
Observe.on(Chain.Teyrchain, "Staking", "Slashed"),
];
const testCase = new TestCase(
steps.map((s) => s.build()),
true,
() => {
killZn();
}
);
const outcome = await runTest(testCase, apis, paraLog);
expect(outcome).toEqual(EventOutcome.Done);
},
{ timeout: GlobalTimeout }
);