Skip to content

fix: decode parent block validation data after runtime upgrade#1004

Closed
manuelmauro wants to merge 2 commits intoAcalaNetwork:masterfrom
manuelmauro:fix/validation-data-upgrade-fallback
Closed

fix: decode parent block validation data after runtime upgrade#1004
manuelmauro wants to merge 2 commits intoAcalaNetwork:masterfrom
manuelmauro:fix/validation-data-upgrade-fallback

Conversation

@manuelmauro
Copy link

@manuelmauro manuelmauro commented Mar 10, 2026

Problem

When a block performs a runtime upgrade, getValidationData fails to decode the parent's setValidationData extrinsic. This breaks block building after any upgrade that changes the extrinsic format (e.g. the 1-arg → 2-arg change in polkadot-stable2512).

Root cause

  1. buildBlock creates the upgrade block with its storageDiff containing :code:

    new Block(chain, number, hash, head, { ..., storageDiff })
    
  2. In the Block constructor, #meta is first set to parentBlock.meta (the old/correct metadata), but then immediately reset because :code changed:

    this.#meta = parentBlock?.meta    // ← old metadata, correct for extrinsics
    // ...
    if (storageDiff[':code']) {
        this.#meta = undefined         // ← gone!
    }
  3. Later, when building the next block, getValidationData(parent) calls parent.meta. Since #meta is undefined, the getter lazily recomputes it by calling Metadata_metadata against the block's new wasm — returning post-upgrade metadata that doesn't match the extrinsics.

Fix

Add Block.extrinsicMeta — set from parentBlock.meta in the constructor and intentionally not reset when :code changes. For remote blocks without a known parent, it falls back to fetching the parent block's metadata.

In getValidationData, replace parent.metaparent.extrinsicMeta for extrinsic decoding.

Fixes #1003

manuelmauro added a commit to moonbeam-foundation/moonbeam that referenced this pull request Mar 10, 2026
…r runtime upgrade

After a runtime upgrade that changes the setValidationData extrinsic
format (1-arg → 2-arg in polkadot-stable2512), chopsticks couldn't
decode the parent block's validation data because block.meta returns
the post-upgrade metadata while the extrinsics use the pre-upgrade
format. This caused two failures:
1. Type decoding error on the parent block's setValidationData
2. Relay slot off-by-1 from the grandparent fallback path

The patch adds tryDecodeValidationData() which first tries the block's
own metadata, then falls back to the grandparent's (pre-upgrade)
metadata. This correctly decodes the validation data and keeps the
relay slot synchronized with the parachain timestamp.

Re-enables chopsticks-upgrade-test CI job.

Upstream PR: AcalaNetwork/chopsticks#1004
manuelmauro added a commit to moonbeam-foundation/moonbeam that referenced this pull request Mar 10, 2026
…r runtime upgrade

After a runtime upgrade that changes the setValidationData extrinsic
format (1-arg → 2-arg in polkadot-stable2512), chopsticks couldn't
decode the parent block's validation data because block.meta returns
the post-upgrade metadata while the extrinsics use the pre-upgrade
format. This caused two failures:
1. Type decoding error on the parent block's setValidationData
2. Relay slot off-by-1 from the grandparent fallback path

The patch adds tryDecodeValidationData() which first tries the block's
own metadata, then falls back to the grandparent's (pre-upgrade)
metadata. This correctly decodes the validation data and keeps the
relay slot synchronized with the parachain timestamp.

Re-enables chopsticks-upgrade-test CI job.

Upstream PR: AcalaNetwork/chopsticks#1004
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found 1 logic issue in the extrinsic decoding process.

@ermalkaleci
Copy link
Collaborator

This doesn't seem like a solid solution. The issue must be elsewhere since validation data is decoded with parents metadata

@manuelmauro manuelmauro force-pushed the fix/validation-data-upgrade-fallback branch from 7b8a399 to 685a8bf Compare March 11, 2026 07:51
After a runtime upgrade, Block.meta returns post-upgrade metadata
(recomputed from new wasm), but the block's extrinsics were encoded
with the pre-upgrade runtime. This caused getValidationData to fail
decoding the parent's setValidationData extrinsic when the format
changed (e.g. 1-arg to 2-arg in polkadot-stable2512).

Fix: add Block.extrinsicMeta that preserves the parent's metadata
through runtime upgrades, and use it in getValidationData for
extrinsic decoding.

Fixes AcalaNetwork#1003
@manuelmauro manuelmauro force-pushed the fix/validation-data-upgrade-fallback branch from 685a8bf to c8b2379 Compare March 11, 2026 07:52
The fix is validated via the moonbeam-stable2512 test suite. Remove
the moonbase-specific runtime blob, network config, and e2e test
from the chopsticks repo.
@manuelmauro
Copy link
Author

This doesn't seem like a solid solution. The issue must be elsewhere since validation data is decoded with parents metadata

Hi @ermalkaleci , thank you for your feedback! I tried a different approach.

@ermalkaleci
Copy link
Collaborator

It's working for your case because you're using grandparent block and it produces correct slot for your specific case. Implementation is incorrect.

@ermalkaleci
Copy link
Collaborator

can you provide runtime wasm so I can debug & fix it?

@manuelmauro
Copy link
Author

Thank you! We are experiencing the problem on this PR: moonbeam-foundation/moonbeam#3633 as you can see I patched the pnpm dependency with the changes here. To reproduce it is sufficient to remove the patch then run cd tests && moonwall test upgrade_moonbase. moonbeam_runtime.wasm.zip

@ermalkaleci
Copy link
Collaborator

Can't perform upgrade with uncompressed wasm (15Mb)

@manuelmauro
Copy link
Author

Can't perform upgrade with uncompressed wasm (15Mb)

Please, find the compressed one here
moonbeam_runtime.compact.compressed.wasm.zip

@ermalkaleci
Copy link
Collaborator

#1005 this should fix it

@manuelmauro
Copy link
Author

Thank you! This #1005 fixed the issue. Closing this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Block building fails after runtime upgrade with polkadot-stable2512 (setValidationData 2-arg format + slot mismatch)

2 participants