[DRAFT] Publish-only pubsub mechanism (Milestone 1) - Addresses #606 #9994
+1,358
−27
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.
This is a DRAFT PR for initial review and architectural alignment
This PR implements the first milestone (M1) of a publish-subscribe mechanism for parachains, addressing issue #606.
This milestone focuses exclusively on the publishing flow, allowing parachains to publish key-value data to the relay chain for consumption by other parachains.
Subsequent milestones:
will be delivered in follow-up PRs built on top of this foundation.
Review Focus
This is a design proposal and architectural review.
Please focus your attention on:
Not in scope for this review:
Context: Issue #606
The original issue identified the challenge of expensive inter-parachain communication. Current methods (XCM messages, off-chain protocols) are complex and inefficient for broadcasting data across multiple parachains.
The proposed solution from the discussion:
(key, value)
data to the relay chain via XCM instructionThis PR implements the core publishing mechanism as discussed, following the our best interpretation of XCM Publish instruction pattern suggested by @bkchr in the issue thread.
Architecture Overview
Publishing Flow
Components Implemented
1. XCM v5
Publish
InstructionLocation:
polkadot/xcm/src/v5/mod.rs
Publish { data: PublishData }
Allows parachains to publish bounded key-value data to the relay chain.
PublishData = BoundedVec<(BoundedVec<u8, 32>, BoundedVec<u8, 1024>), 16>
Note: The instruction is temporarily added to XCM v5 for testing and integration purposes. Final placement (potentially XCM v6) will be determined during the review process.
The instruction is intended to be called via
pallet-xcm
send
with the proper execution buy instructions.2. Broadcaster Pallet (Relay Chain)
Location:
polkadot/runtime/parachains/src/broadcaster/
Core pallet managing published data on the relay chain.
Key features:
(ChildInfo::new_default(b"pubsub" + para_id.encode()))
PublishedKeys
storage tracks all keys published by each parachain for enumerationStorage:
PublisherExists
: Tracks which parachains have published dataPublishedKeys
: Tracks all keys per publisher (for enumeration)Traits:
PublishSubscribe
: Used for exposing publish and subscribe operations for pallets to implement. Intended forpallet-broadcaster
but provided a trait for possible future integrations.Main function:
pub fn handle_publish(origin_para_id: ParaId, data: Vec<(Vec<u8>, Vec<u8>)>) -> DispatchResult
3. BroadcastHandler Trait & Adapter
Location:
polkadot/xcm/xcm-executor/src/traits/broadcast_handler.rs
polkadot/xcm/xcm-builder/src/broadcast_adapter.rs
BroadcastHandler
trait:ParachainBroadcastAdapter
:ParaId
from XCMLocation
4. XCM Executor Integration
Location:
polkadot/xcm/xcm-executor/src/lib.rs
The executor processes
Publish
instructions by callingConfig::BroadcastHandler::handle_publish()
.5. XCM Executor Config Trait Extension
Location:
polkadot/xcm/xcm-executor/src/config.rs
Added
BroadcastHandler
to the executor's Config trait:This requires all XCM executors to specify their broadcast handler implementation. Provided
()
implementation.6. ParachainHost Runtime API (v14 → v15)
Location:
API definition:
polkadot/primitives/src/runtime_api.rs
The ParachainHost runtime API was bumped to v15 with the addition of:
This method returns all published data from all publishers on the relay chain, which collators use to populate the inherent data. Exposed methods:
fn get_all_published_data(para_id: ParaId) -> Vec<(Vec, Vec)>
fn get_published_value(para_id: ParaId, key: Vec) -> Option<Vec>
Design note: Currently returns ALL published data. In M2 (Subscribe), this will be filtered to only return data from parachains the subscriber is subscribed to.
7. Relay Chain Interface Extension
Location:
cumulus/client/relay-chain-interface/src/lib.rs
Extended the RelayChainInterface trait with:
Implementations:
RelayChainInProcessInterface
- Direct runtime API callRelayChainRpcInterface
- RPC client call to relay chain nodeThis interface is used by collators in
cumulus/client/parachain-inherent/src/lib.rs
to fetch published data when building inherent data.8. ParachainInherentData Extension
Location:
cumulus/primitives/parachain-inherent/src/lib.rs
Added
published_data
field toParachainInherentData
:Design rationale: This follows the same pattern as existing message types
(downward_messages, horizontal_messages)
. A direct field in the inherent data structure.9. InboundPublishedData Wrapper
Location:
cumulus/pallets/parachain-system/src/parachain_inherent.rs
Wrapper type for published data validation:
Purpose: Aligns with the SDK's pattern of wrapping inbound data types (InboundDownwardMessage, InboundHrmpMessage) for consistency and future extensibility.
10. Parachain-System Integration
Location:
cumulus/pallets/parachain-system/src/lib.rs
Inherent creation
(set_validation_data)
:published_data
from collator via inherentNote: This milestone only implements the data reception path. Subscription tracking and change detection optimization will come in M2 and M3.
11. Collator-Side Fetching Logic
Location:
cumulus/client/parachain-inherent/src/lib.rs
Collators fetch published data when building inherent data:
This data is then included in the
ParachainInherentData
passed to the parachain runtime.12. Rococo Integration (Temporary)
Location:
polkadot/runtime/rococo/src/lib.rs
The broadcaster pallet is integrated into Rococo relay chain for testing purposes only.
Configuration:
Rationale: Enables reviewers to test the complete flow using Zombienet (config provided in pubsub-dev/zombienet.toml). This integration may be removed or moved to different chains in the final implementation.
Testing
Relevant testing following SDK patterns have been provided to the newly added components.
Local Testing with Zombienet
A Zombienet configuration is provided in pubsub-dev/ for local testing:
cd pubsub-dev
./build.sh # Build polkadot and polkadot-parachain
zombienet spawn zombienet.toml
This spins up:
Note: The pubsub-dev/ directory is for review testing only and will be removed after the review process.
Extrinsics:
Sovereign Account
:0x04030070617261e80300000000000000000000000000000000000000000000000000000b00407a10f35a
pallet-xcm
send
call:0x02003300050100050c000400000002286bee1300000002286bee003404143078313233143078313233
Known Limitations (To be addressed in follow-up PRs)
Closure
Please share any concerns, suggestions, or alternative approaches. This is an early-stage proposal and we welcome all input to align with the SDK's architecture and design principles.
Related: #606