Skip to content

fix: state migration for layout that included used_aux_parent_blocks#141

Merged
karim-en merged 3 commits into
mainfrom
fix/migrate-used-aux-parent-blocks
Jun 11, 2026
Merged

fix: state migration for layout that included used_aux_parent_blocks#141
karim-en merged 3 commits into
mainfrom
fix/migrate-used-aux-parent-blocks

Conversation

@kiseln

@kiseln kiseln commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Problem

The zcash testnet relayer is down: every call to zcash-client.n-bridge.testnet panics with Cannot deserialize the contract state since the 2026-06-10 release deploy.

#116 removed the unconditional used_aux_parent_blocks: LookupSet<H256> field from the contract state struct without adding a migration. Any contract initialized between #101 (2025-06-06) and #116 (2026-03-18) carries that field in its on-chain state, so deploying current wasm over it makes borsh state deserialization fail on every method call.

Survey of all deployments:

account initialized state layout
btc-client.bridge.near 2024-09 current (migrated 2026-04-02)
btc-client-v4.testnet 2024-09 current (migrated 2026-03-27)
zcash-client.n-bridge.testnet 2025-06-27 old (used_aux_parent_blocks) — currently down
zcash-client.bridge.near 2025-08-20 old — breaks on next upgrade
litecoin-client.n-bridge.testnet 2025-07-06 old — breaks on next upgrade

Fix

migrate() (no arguments) auto-detects the stored state variant (borsh requires full buffer consumption, so exactly one layout can parse):

The pre-#97 layout (no network field) is not handled: no deployment is on it anymore.

Tests

Both tests pull the wasm currently deployed on mainnet, init it in a sandbox, upgrade to the locally built wasm and call migrate:

  • test_zcash::test_migration_from_mainnet_wasmzcash-client.bridge.near wasm (pre-Extra script_sig checks on Dogecoin Blocks submission  #116 layout): verifies calls fail before migration with the exact production error, succeed after, and that headers/submissions survive.
  • test_basics::test_migration_from_mainnet_wasmbtc-client.bridge.near wasm (already current layout): verifies the no-op path keeps state intact.

The wasm is fetched via plain JSON-RPC because near_workspaces::mainnet() (0.20.1) fails to parse responses from current mainnet nodes.

Deployment

After merge: make build-zcash, deploy to zcash-client.n-bridge.testnet with a batched migrate call ({}). The same migration is required for zcash-client.bridge.near and litecoin-client.n-bridge.testnet with their next upgrades.

Notes

🤖 Generated with Claude Code

PR #116 removed the unconditional `used_aux_parent_blocks: LookupSet<H256>`
field from the contract state without providing a migration. Contracts
initialized between #101 (2025-06-06) and #116 (2026-03-18) — e.g.
zcash-client.n-bridge.testnet — still carry that field on-chain, so
deploying current wasm over them panics on every call with
"Cannot deserialize the contract state".

Replace the previous migration (pre-`network` layout, already applied to
existing deployments) with one that reads the 9-field layout and drops
`used_aux_parent_blocks`. `network` is carried over from the old state,
so `migrate` no longer takes arguments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread contract/src/lib.rs Outdated
kiseln and others added 2 commits June 11, 2026 13:19
Keep both historical layouts: BtcLightClientV1 (pre-#97, no network) and
BtcLightClientV2 (#101..#116, with used_aux_parent_blocks). migrate()
detects which variant is stored — borsh requires full buffer consumption,
so exactly one layout parses. Already-current state is a no-op, making
re-runs safe. The network argument is only required for V1 state.

Tests pull the wasm currently deployed on mainnet, init it in a sandbox,
upgrade to the locally built wasm and call migrate:
- zcash (zcash-client.bridge.near, pre-#116 layout): repair path
- bitcoin (btc-client.bridge.near, current layout): no-op path

The wasm is fetched via plain RPC because near_workspaces::mainnet()
fails to parse responses from current mainnet nodes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
All btc contracts (mainnet and testnet) were migrated to the current
layout in March/April 2026; zcash and litecoin deployments are on the V2
layout. migrate() now takes no arguments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kiseln kiseln force-pushed the fix/migrate-used-aux-parent-blocks branch from 5940ece to 39f6ef1 Compare June 11, 2026 11:29
@kiseln kiseln requested a review from karim-en June 11, 2026 11:36
@karim-en karim-en merged commit 3e59d82 into main Jun 11, 2026
3 checks passed
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.

3 participants