Support for 3 async cores#131
Open
ilchu wants to merge 2 commits into
Open
Conversation
Switch both runtimes from 6s blocks to 2s blocks with 3 cores assigned per parachain, mirroring polkadot-bulletin-chain PRs #417 (slot-based authoring) and #231 (2s + 3 cores). Closes #113. Runtime changes (both web3-storage and Paseo): - MILLISECS_PER_BLOCK: 6000 -> 2000 - BLOCK_PROCESSING_VELOCITY: 1 -> 3 (3 parachain blocks per relay slot) - UNINCLUDED_SEGMENT_CAPACITY: 3 -> (3 + RELAY_PARENT_OFFSET) * VELOCITY = 12 - New RELAY_PARENT_OFFSET = 1, wired into cumulus_pallet_parachain_system::Config and the RelayParentOffsetApi runtime impl (slot-based authoring requirement) - RELAY_CHAIN_SLOT_DURATION_MILLIS stays 6000 (relay slot is independent) - spec_version: 1 -> 2 Storage-pallet checkpoint cadence is now wall-clock-coupled so it survives block-time changes: DefaultCheckpointInterval = 10 * MINUTES, DefaultCheckpointGrace = 2 * MINUTES (resolves to the prior 100/20 blocks at 6s and 300/60 at 2s — same ~10 min cadence either way). All other timeouts in storage.rs (ChallengeTimeout, SettlementTimeout, RequestTimeout, DeregisterAnnouncementPeriod) auto-rescale via HOURS. Zombienet topology (zombienet.toml + zombienet/storage-paseo-local.toml): - 6 relay validators (alice, bob, charlie, dave, eve, ferdie) to support 3-core scheduling - Relay genesis patched with scheduler_params.num_cores = 3 and async_backing_params (allowed_ancestry_len = 6, max_candidate_depth = 6) - Parachain num_cores = 3; second collator (bob) added - Both collators run with --authoring=slot-based New examples/papi/assign-cores.js + `just assign-cores` recipe: zombienet's `num_cores=3` only sets the relay-side budget; actual assignment of cores to a para needs an explicit Coretime::assign_core extrinsic. The script sudo-batches one assign_core per core (mirrors polkadot-bulletin-chain's examples/assign_cores.js). Use after `just start-chain` to realize full 3-core throughput locally. Verified: - cargo fmt / check / clippy --all-features clean on both runtimes - RPC reports AuraApi::slot_duration() = 2000 ms and RelayParentOffsetApi::relay_parent_offset() = 1 - Relay availability_cores shows para 4000 occupying cores 0/1/2 after assign-cores - ~2.5-2.85s avg parachain block production (sampled over 60-91s windows) - fs-demo-ci (Rust subxt L1) passes end-to-end Known limitation: The PAPI demos under examples/papi/ are still on polkadot-api 1.23 while the rest of the repo is on 2.x. At 2s blocks PAPI 1.23's chainHead pin window evicts the runtime-context block before `getValue()` can resolve, producing BlockNotPinnedError. Migrating examples/papi/ to PAPI 2.x is substantive (event payload reshape, H256 -> SizedHex<N>, signature enum form, etc.) and tracked as follow-up; just demo will be red on dev until that lands.
Brings examples/papi in line with the rest of the repo (the UIs are
already on polkadot-api@^2.1.0 + @polkadot-api/cli@^0.20.4) and gets the
PAPI demo working under 2-second blocks.
The previous full-flow.js failure modes on this branch (BlockNotPinnedError
on the first storage query after a tx) turned out to be two separate
issues, both of which are addressed here:
- Event watching destabilises chainHead. On PAPI 2.x, a global
`api.event.X.Y.watch().subscribe()` interferes with the pinned-block
set; subsequent `api.query.X.Y.getValue(...)` then throws
`BlockNotPinnedError ... (getRuntimeCtx)`. `watchDefendedEvents` is
removed — `respondToChallenge` already returns the ChallengeDefended
event extracted from its own extrinsic events, so the demo counts
those instead.
- finalizedBlock$ is now a BehaviorSubject. `waitForNextBlock` /
`waitForBlock` declared `const sub = papi.finalizedBlock$.subscribe(...)`
and referenced `sub` from inside the callback. On 2.x the BehaviorSubject
fires synchronously on subscribe, before the `const` is assigned — TDZ
ReferenceError. Switched to a `let sub; sub = papi.finalizedBlock$.subscribe(...)`
pattern guarded by a `resolved` flag.
Type/shape adjustments to match the 2.x generated descriptors
(`SizedHex<N>` replaces `Binary` for `H256` / `[u8; N]` fields,
anonymous enums take `{ type, value }` object form):
- `mmr_root`, `data_root`, peaks, siblings: drop
`Binary.fromBytes(hexToBytes(...))`, pass the raw hex string straight
through.
- `provider_signature`: drop `Enum("Sr25519", Binary.fromBytes(...))`,
use `{ type: "Sr25519", value: hexSignature }` (MultiSignature is an
AnonymousEnum in the descriptors).
- `respond_to_challenge` response: same — `{ type: "Proof", value: proof }`.
- `chunk_data`: `Uint8Array` field, pass raw `Uint8Array` instead of
`Binary.fromBytes(...)` (the descriptor type check now rejects Binary
where Uint8Array is required).
Other plumbing for the version bump:
- `requireOneEvent` now returns `matched[0].payload` — 2.x wraps filtered
events as `{ original, payload }`.
- Import path `polkadot-api/ws-provider` → `polkadot-api/ws` (and in
assign-cores.js).
- `papi:generate` script: trailing `&& papi` is a no-op on 2.x; replace
with `&& papi generate`.
Verified end-to-end against a running zombienet (chain producing at
~2.5–2.8 s/block after `just assign-cores`):
- `just demo`: all 8 steps green, "PASSED: Provider received payment!"
- `just drain-tx-pool-then fs-demo-ci`: passes
- `just drain-tx-pool-then s3-demo-ci`: passes
Collaborator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Switches both runtimes from 6-second to 2-second blocks with 3 relay cores assigned per parachain, matching what polkadot-bulletin-chain PRs #417 (slot-based authoring) and #231 (2 s + 3 cores) did for Bulletin.
Closes #113.
Runtime changes (runtime/ + runtimes/web3-storage-paseo/)
pallet_aura::AllowMultipleBlocksPerSlot = true, FixedVelocityConsensusHook, and the RelayParentOffsetApi shell were all already in place — they just needed the new constants threaded through.
Storage-pallet checkpoint cadence (storage.rs × 2)
DefaultCheckpointInterval / DefaultCheckpointGrace were raw block counts (100 / 20); without re-expressing them, they would fire 3× more often under 2 s blocks and triple the CheckpointReward / CheckpointMissPenalty token flow per hour. Switched to:
pub const DefaultCheckpointInterval: BlockNumber = 10 * MINUTES;
pub const DefaultCheckpointGrace: BlockNumber = 2 * MINUTES;
These resolve to today's 100 / 20 at 6 s and 300 / 60 at 2 s — same ~10-minute cadence either way, and they survive future block-time changes. All other storage timeouts (ChallengeTimeout, SettlementTimeout, RequestTimeout, DeregisterAnnouncementPeriod)
auto-rescale through HOURS.
Zombienet topology (zombienet.toml, zombienet/storage-paseo-local.toml)
3-core scheduling needs more validators and explicit core capacity:
New examples/papi/assign-cores.js + just assign-cores
num_cores = 3 in genesis only sets the relay-side budget; cores still have to be assigned to a specific para via the relay's Coretime::assign_core extrinsic before the parachain can actually use them. Without this step block production stays at ~12 s/block. The
script sudo-batches one assign_core per core (same pattern as Bulletin's examples/assign_cores.js). After just start-chain, run just assign-cores once and the parachain settles at ~2 s blocks.
examples/papi migrated to polkadot-api 2.x
The rest of the repo (user-interfaces/*) was already on polkadot-api@^2.1.0 + @polkadot-api/cli@^0.20.4; only examples/papi/ was lagging on 1.23. At 2 s blocks the old version's chainHead pin window evicts the runtime-context anchor block faster than getValue()
can resolve, so this needed to come along. The bump landed two underlying fixes worth calling out:
returns the ChallengeDefended event extracted from its own extrinsic events, so the demo counts those.
flag.
Type-shape adjustments to match 2.x's generated descriptors: SizedHex for H256 / fixed-byte fields (pass raw hex string, not Binary), AnonymousEnum object form { type, value } for MultiSignature and respond_to_challenge's response, raw Uint8Array for
chunk_data. Plus housekeeping: polkadot-api/ws-provider → polkadot-api/ws, papi:generate script now runs papi generate (the trailing papi was a no-op on 2.x), and requireOneEvent returns matched[0].payload (2.x wraps filtered events as { original, payload }).
Verified
Against a running local zombienet, with just assign-cores applied: