Submerge Mycelium Specification
Mycelium is a data processing system that aggregates and indexes cross-chain messages (XCM) across the Polkadot ecosystem. It enables seamless interoperability, real-time tracking, and structured access to cross-chain data and transactions.
Each supported chain will be indexed individually and Crystal APIs have been created. This documentation outlines the intuition behind the system design and details the implementation logic for indexing and processing cross-chain messages.
To track XCM messages involving the Relay Chain, we need to monitor three types of message passing:
- UMP (Upward Message Passing): Messages from a parachain to the Relay Chain.
- DMP (Downward Message Passing): Messages from the Relay Chain to a parachain.
- XCMP (Cross-Chain Message Passing): Messages from one parachain to another, which are routed through the Relay Chain.
For each of these, we will monitor specific events and extrinsics to identify the XCM messages and track their lifecycle.
Polkadot Relay Chain
1. Upward Message Passing (UMP): Parachain to Relay Chain
These are messages originating from a parachain and destined for the Relay Chain.
- Listen for the
messageQueue.Processed(for XCM v3, v4 and v5, not sure about corelation key) andump.ExecutedUpward(for other XCM versions,message_idin it as acts as corelation key) event on the Polkadot Relay Chain.
2. Downward Message Passing (DMP): Relay Chain to Parachain
These are messages sent from the Relay Chain to a specific parachain.
- Listen for
xcmPallet.Attemptedevent on the Polkadot Relay Chain (can not find corelation key)
3. Cross-Chain Message Passing (XCMP/HRMP): Parachain to Parachain
These messages are routed through the Relay Chain but are not executed there. The Relay Chain acts as a transport layer.
- What to look for: The Relay Chain's role in XCMP is to pass messages from an origin parachain's upward queue to a destination parachain's downward queue. However, direct tracing is more efficient at the parachain level.
xcmPallet.Attempted
{
"docs": "Execution of an XCM message was attempted.",
"args_name": [
"outcome"
],
"args_type_name": [
"xcm::latest::Outcome"
]
}
{
"docs": "Execution of an XCM message was attempted.\n\n\\[ outcome \\]",
"args_name": [
""
],
"args_type_name": [
"xcm::latest::Outcome"
]
}
ump.ExecutedUpward
{
"docs": "Upward message executed with the given outcome.\n\\[ id, outcome \\]",
"args_name": [
"",
""
],
"args_type_name": [
"MessageId",
"Outcome"
]
}
ump.UpwardMessagesReceived
{
"docs": "Some upward messages have been received and will be processed.\n\\[ para, count, size \\]",
"args_name": [
"",
"",
""
],
"args_type_name": [
"ParaId",
"u32",
"u32"
]
}
messageQueue.Processed (Introduced in v1000001)
{
"docs": "Message is processed.",
"args_name": [
"id",
"origin",
"weight_used",
"success"
],
"args_type_name": [
"[u8; 32]",
"MessageOriginOf",
"Weight",
"bool"
]
}
{
"docs": "Message is processed.",
"args_name": [
"id",
"origin",
"weight_used",
"success"
],
"args_type_name": [
"H256",
"MessageOriginOf",
"Weight",
"bool"
]
}
Polkadot Asset Hub
-
Asset Hub to Parachain/Relay
-
Listen for
polkadotXcm.Attemptedevent. Find other events for this extrinsic and look forparachainSystem.UpwardMessageSent. For reserve transfers, eventxcmpqueue.XcmpMessageSentwould have message hash. -
When destination chain is Relay
- For XCM V2, not sure how to find corelation key. For XCM v3 and above,
parachainSystem.UpwardMessageSentwould havemessage_hashwhich acts as corelation key.
- For XCM V2, not sure how to find corelation key. For XCM v3 and above,
-
When destination chain is any system parachain
- For XCM v3 and above,
xcmpqueue.XcmpMessageSent.UpwardMessageSentwould havemessage_hashwhich acts as corelation key. Also, the fact is, chains which we are targeting used XCM v3 or above only so no need to check what would be corelation key for below XCM v3.
- For XCM v3 and above,
-
-
Parachain/Relay to Asset Hub
-
Listen for
messageQueue.processed(for XCM v4 and v5) orDmpqueue.ExecutedDownward(for older XCM versions) event -
When source was Relay chain
- For XCM v2,
dmp.ExecutedDownwardhasmessage_idwhich acts as corelation key. For XCM v3,message_hashindmp.ExecutedDownWardis corelation key. For XCM v4 and above,messageQueue.Processedhasmessage_idwhich matches withSetTopicvalue in source XCM instructions.
- For XCM v2,
-
When source was any system chain
- For XCM v3, event
xcmpQueue.Successhasmessage_hashwhich is the key. - else
messageQueue.Processedhasmessage_idbut it's not corelation key. However, on source chain,polkadotXcm.Sentevent hasmessage_idin it's args which is exactly same as destmessage_idbutSetTopicvalue in source XCM instructions orxcmpQueue.XcmpMessageSentvalue matches with destinationmessage_id.
- For XCM v3, event
-
Polkadot Bridge Hub
-
Bridge Hub to Parachain/Relay
- Listen for
polkadotXcm.Attempted(when destination is Relay) andxcmpqueue.XcmpMessageSent(when destination is other system chain, hasmessage_hashdirectly in it which acts as corelation key) event. Find other events for this extrinsic and look forparachainSystem.UpwardMessageSentwhich hasmessage_hash.
- Listen for
-
Parachain/Relay to Bridge Hub
- Listen for
messageQueue.processed(for XCM v4 and v5, not sure how to get corelation key) ordmpQueue.ExecutedDownward(for older XCM versions,message_idin it's parameters acts as corelation key) event.
- Listen for
Polkadot Collectives
-
Collectives to Parachain/Relay
-
When destination is Relay
- Listen for
polkadotXcm.Attempted. Find other events in extrinsic and getmessage_hashfromparachainSystem.UpwardMessageSentevent. But for XCM v2, not sure how to getmessage_hashbecause noparachainSystem.UpwardMessageSentevent for XCM v2.
- Listen for
-
When destination is system chain
- Listen for event
xcmpqueue.XcmpMessageSent, would havemessage_hashwhich is corelation key.
- Listen for event
-
-
Parachain/Relay to Collectives
- If source chain is Polkadot Relay, Listen for
messageQueue.processed(for XCM v4 and v5, and not sure how to get corelation key for this) orDmpqueue.ExecutedDownward(message_idis corelation key for older XCM versions) event. - else listen for
messageQueue.processed(for XCM v4 and v5, and not sure for key) orxcmpqueue.success(message_hashis key, for other XCM versions).
- If source chain is Polkadot Relay, Listen for
Polkadot Coretime
-
Coretime to Parachain/Relay
- Exactly same as Collectives
-
Parachain/Relay to Coretime
- Listen for
messageQueue.processed(need to find corelation key for this)
- Listen for
parachainsystem.UpwardMessageSent: Stays same for all runtimes
{
messageHash: {
type: 'Some',
value: '0x54e2d0ea97d34f069b8b0d79a0e5ba4901946b065fb9a102aa094888de4429cb'
}
}
xcmpqueue.XcmpMessageSent: Stays same for all runtimes
{
messageHash: '0x494920be50870cc9623154a2ae42519175272c0d1f4b3ad9dd54792cf21a57c9'
}
messageQueue.Processed: Stays same for all runtime
{
id: '0x894f9b5b5c7f0fdad7c87affee713c59f41d9d4bb21018a1fe669789100a00c8',
origin: { type: 'Sibling', value: '1000' },
success: true,
weightUsed: { proofSize: '3465', refTime: '32930000' }
}
{
id: '0x4a00b223eb85be70f7aec13fc8cdc6e9c3203f1fe4e8352e59ec7a85ae1e28dc',
origin: { type: 'Parent', value: [] },
success: true,
weightUsed: { proofSize: '0', refTime: '123620000' }
}
Polkadot People
-
People to Parachain/Relay
- Exactly same as Collectives
-
Parachain/Relay to People
- Listen for
messageQueue.processed. Works for all XCM versions. (need to check for corelation key)
- Listen for
Caveat
-
Mostly, we are tracking XCM on chain with events, but important thing is, we should know which extrinsic emitted the event. Need to properly maintain event->extrinsic mapping.
- This could be made with Crystal APIs itself. For every block, we can find all events (with
/blocks/:block_ref/events). In response, we get extrinsic hash. All other events emitted from the extrinsic can be found with/extrinsics/:extrinsic_hash/eventsand more details about extrinsic itself can be found with/extrinsics/:extrinsic_hash. With this, we can properly establish event->extrinsic mapping.
- This could be made with Crystal APIs itself. For every block, we can find all events (with
-
Most of the
messageQueue.processedhas aidparameter in it, but it does not match with actual corelation key which we can use to find source chain XCM details. Need to look into it.- Rule of thumb is, For XCM v3+,
messageQueue.processedhasmessage_idwhich should be match againstSetTopicvalue in XCM instruction for source chain. For XCM v2 or less,.sentevent hasmessage_idwhich matches with destination so it could be used as corelation key.
- Rule of thumb is, For XCM v3+,