fix: state migration for layout that included used_aux_parent_blocks#141
Merged
Conversation
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>
olga24912
requested changes
Jun 11, 2026
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>
5940ece to
39f6ef1
Compare
olga24912
approved these changes
Jun 11, 2026
karim-en
approved these changes
Jun 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
The zcash testnet relayer is down: every call to
zcash-client.n-bridge.testnetpanics withCannot deserialize the contract statesince 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:
btc-client.bridge.nearbtc-client-v4.testnetzcash-client.n-bridge.testnetused_aux_parent_blocks) — currently downzcash-client.bridge.nearlitecoin-client.n-bridge.testnetFix
migrate()(no arguments) auto-detects the stored state variant (borsh requires full buffer consumption, so exactly one layout can parse):migrateis safeBtcLightClientV2(Support Dogecoin #101..Extra script_sig checks on Dogecoin Blocks submission #116, hasused_aux_parent_blocks) → drops the field,networkis carried over from stateThe pre-#97 layout (no
networkfield) 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_wasm—zcash-client.bridge.nearwasm (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_wasm—btc-client.bridge.nearwasm (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 tozcash-client.n-bridge.testnetwith a batchedmigratecall ({}). The same migration is required forzcash-client.bridge.nearandlitecoin-client.n-bridge.testnetwith their next upgrades.Notes
LookupSetprefix are left orphaned; only Dogecoin deployments ever wrote to it, and none exist. If a Dogecoin contract initialized in the Support Dogecoin #101..Extra script_sig checks on Dogecoin Blocks submission #116 era ever surfaces, it needs more than this:ExtendedHeaderalso lost itsaux_parent_blockfield in Extra script_sig checks on Dogecoin Blocks submission #116, so itsheaders_poolentries have a stale layout too.🤖 Generated with Claude Code