2

Recently, I did a reset to a local relay-chain and re-added the parachains with their old context.

One of those parachains has inbound downward messages which produces an invalid dmq_head and leads to the following error:

ERROR tokio-runtime-worker runtime: panicked at 'assertion failed: (left == right) left: 0xedf555dab20b5cb29a124c0f95b053efbb0f7ac8081f2a83196166cd7858f195, right: 0x0000000000000000000000000000000000000000000000000000000000000000'

Which happens here:

    // After hashing each message in the message queue chain submitted by the collator, we
    // should arrive to the MQC head provided by the relay chain.
    //
    // A mismatch means that at least some of the submitted messages were altered, omitted or
    // added improperly.
    assert_eq!(dmq_head.head(), expected_dmq_mqc_head);

How can I change the dmq_mqc_head of a given parachain in the relaychain?

2 Answers 2

2

I had this issue in the past. As you mentioned you have to modify the value of the dmq_head. In this case set it to 0.

The easiest way to do it is with PolkadotJS UI, First as you show get the storage key we need to change, going to query -> dmp -> downwardMessageQueueHeads -> your-parachain-id:

enter image description here

Copy the encoded storage key.

Now with Sudo -> System -> KillStorage (or SetStorage if you want to manually set one) -> Paste the encoded storage key: enter image description here

Is important to highlight that manually changing the storage is extremely dangerous, be sure you are using the right key.

1

After digging into the code, I figured that the expected_dmq_mqc_head value comes from a state proof of the relay-chain. All I had to do was computing the storage key and storing the expected dmq_mqc_head on that key.

Steps:

Compute storage key (for a parachain with id 2000, it will give 63f78c98723ddc9073523ef3beefda0c4d7fefc408aac59dbfe80a72ac8e3ce563f5a4efb16ffa83d007000)

/// The MQC head for the downward message queue of the given para. See more in the `Dmp` module.
///
/// The storage entry stores a `Hash`. This is polkadot hash which is at the moment
/// `blake2b-256`.
pub fn dmq_mqc_head(para_id: Id) -> Vec<u8> {
    let prefix = hex!["63f78c98723ddc9073523ef3beefda0c4d7fefc408aac59dbfe80a72ac8e3ce5"];

    para_id.using_encoded(|para_id: &[u8]| {
        prefix
            .as_ref()
            .iter()
            .chain(twox_64(para_id).iter())
            .chain(para_id.iter())
            .cloned()
            .collect()
    })
}

Call system > setStorage, where the key is the value computed above and the value is the expected dmq_head)

I am just providing this answer as a way of recovering a old parachain context on a new relay-chain, you will need ROOT access and this should always be avoided on production environments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.