State Transfer Playbook
1
2
2. Export Morse Snapshot State
export MAINNET_SNAPSHOT_HEIGHT="165497"
export MAINNET_SNAPSHOT_DATE="2025-04-15"
export MORSE_MAINNET_STATE_EXPORT_PATH="./morse_state_export_${MAINNET_SNAPSHOT_HEIGHT}_${MAINNET_SNAPSHOT_DATE}.json"ls "$SNAPSHOT_DIR"/data
# Expected output: application.db blockstore.db evidence.db state.db txindexer.dbpocket --datadir="$SNAPSHOT_DIR" util export-genesis-for-reset "$MAINNET_SNAPSHOT_HEIGHT" pocket > "$MORSE_MAINNET_STATE_EXPORT_PATH"# Check the file was created
jq -r '{root_keys: .|keys, num_auth_accounts: .app_state.auth.accounts|length, num_nodes: .app_state.pos.validators|length, num_applications: .app_state.application.applications|length}' "$MORSE_MAINNET_STATE_EXPORT_PATH"
# Example output:
{
"root_keys": [
"app_hash",
"app_state",
"chain_id",
"consensus_params",
"genesis_time"
],
"num_auth_accounts": 57630,
"num_nodes": 12161,
"num_applications": 2298
}3
3. Transform Morse Export to a Canonical Account State Import Message
export MSG_IMPORT_MORSE_ACCOUNTS_PATH="./msg_import_morse_accounts_${MAINNET_SNAPSHOT_HEIGHT}_${MAINNET_SNAPSHOT_DATE}.json"pocketd tx migration collect-morse-accounts "$MORSE_MAINNET_STATE_EXPORT_PATH" "$MSG_IMPORT_MORSE_ACCOUNTS_PATH"3.1 Copy and verify the state import message
# Copy files to migration directory
cp "$MORSE_MAINNET_STATE_EXPORT_PATH" ./tools/scripts/migration/
cp "$MSG_IMPORT_MORSE_ACCOUNTS_PATH" ./tools/scripts/migration/# Check the file was created, and that it contains the expected number of accounts and hash
jq -r '{num_morse_claimable_accounts: .morse_account_state.accounts|length, morse_account_state_hash: .morse_account_state_hash}' "$MSG_IMPORT_MORSE_ACCOUNTS_PATH"
# Example output:
{
"num_morse_claimable_accounts": 63802,
"morse_account_state_hash": "w5/Sf4c1L9/G5eYPC0wvrI3ynzwlnxcka0C8ULB9sMc="
}3.2 Optional on Shannon TestNet and mandatory on Shannon MainNet
# Use the prepared unstaking script
./tools/scripts/params/manual_unstake_prepared.sh "tools/scripts/migration/${MSG_IMPORT_MORSE_ACCOUNTS_PATH}"
# Update the hash after unstaking
./pocketd tx migration import-morse-accounts \
"tools/scripts/migration/${MSG_IMPORT_MORSE_ACCOUNTS_PATH}" \
--update-hash-only
# Beautify the JSON file
jq '.' "tools/scripts/migration/${MSG_IMPORT_MORSE_ACCOUNTS_PATH}" > temp.json && mv temp.json "tools/scripts/migration/${MSG_IMPORT_MORSE_ACCOUNTS_PATH}"
# Commit changes
git commit -am "Auto-unstaked validators and updated hash"
git push./tools/scripts/params/manual_unstake.sh \
"tools/scripts/migration/msg_import_morse_accounts_${MAINNET_SNAPSHOT_HEIGHT}_${MAINNET_SNAPSHOT_DATE}.json" \
'c409a9e0d1be8780fe0b29dcdf72f8a879fb110c,08e5727cd7fbc4bc97ef3246da7379043f949f70,278654d9daf0e0be2c4e4da5a26c3b4149c5f6d0,81522de7711246fca147a34173dd2a462dc77a5a,c86b27e72c32b64db3eae137ffa84fec007a9062,79cbe645f2b4fa767322faf59a0093e6b73a2383,a86b6a5517630a23aec3dc4e3479a5818c575ac2,882f3f23687a9f3dddf6c65d66e9e3184ca67573,96f2c414b6f3afbba7ba571b7de360709d614e62,05db988509a25dd812dfd1a421cbf47078301a16'# Clean up backup files
rm "tools/scripts/migration/msg_import_morse_accounts_${MAINNET_SNAPSHOT_HEIGHT}_${MAINNET_SNAPSHOT_DATE}.json.backup."*
# Review changes
git diff .
# Update hash and commit
./pocketd tx migration import-morse-accounts \
"tools/scripts/migration/msg_import_morse_accounts_${MAINNET_SNAPSHOT_HEIGHT}_${MAINNET_SNAPSHOT_DATE}.json" \
--update-hash-only
git commit -am "Auto-unstaked Morse validators for entity XXX"
git push3.3 Update migration artifacts in git
# Commit and push
git commit -am "Added Morse MainNet state export and import message"
git push4
5
5. Import Canonical State into Shannon
export IMPORT_MSG_PATH="tools/scripts/migration/${MSG_IMPORT_MORSE_ACCOUNTS_PATH}"
export GAS_FLAGS="--gas=auto --gas-prices=1upokt --gas-adjustment=1.5"# Port forward
kubectl port-forward pods/mainnet-validator1-pocketd-0 26658:26657 9091:9090 -n mainnet
# Run the command
pocketd tx migration import-morse-accounts \
"$IMPORT_MSG_PATH" \
--from=grove_mainnet_genesis \
--home=~/.pocket_prod --keyring-backend=test \
--node=http://localhost:26658 --chain-id=pocket-alpha \
$GAS_FLAGS# Port forward
kubectl port-forward pods/alpha-validator1-pocketd-0 26658:26657 9091:9090 -n testnet-alpha
# Run the command
pocketd tx migration import-morse-accounts \
"$IMPORT_MSG_PATH" \
--from=pnf_alpha \
--home=~/.pocket_prod --keyring-backend=test \
--node=http://localhost:26658 --chain-id=pocket-alpha \
$GAS_FLAGS# Port forward
kubectl port-forward pods/testnet-beta-validator1-pocketd-0 26658:26657 9091:9090 -n testnet-beta
pocketd tx migration import-morse-accounts "$IMPORT_MSG_PATH" \
--from=pokt1f0c9y7mahf2ya8tymy8g4rr75ezh3pkklu4c3e \
--home=~/.pocket_prod --keyring-backend=test \
--node=http://localhost:26658 --chain-id=pocket-beta \
$GAS_FLAGSpocketd tx migration import-morse-accounts \
"$IMPORT_MSG_PATH" \
--from=pnf \
--home=./localnet/pocketd --keyring-backend=test \
--node=http://localhost:26657 \
$GAS_FLAGS# LocalNet
pocketd tx migration import-morse-accounts "$MSG_IMPORT_MORSE_ACCOUNTS_PATH" --from pnf --home=./localnet/pocketd --network=local --gas=auto --gas-prices=1upokt --gas-adjustment=1.5
# Alpha TestNet
pocketd tx migration import-morse-accounts "$MSG_IMPORT_MORSE_ACCOUNTS_PATH" --from pokt1r6ja6rz6rpae58njfrsgs5n5sp3r36r2q9j04h --home=~/.pocket_prod --network=alpha --gas=auto --gas-prices=1upokt --gas-adjustment=1.5
# Beta TestNet
pocketd tx migration import-morse-accounts "$MSG_IMPORT_MORSE_ACCOUNTS_PATH" --from pokt1f0c9y7mahf2ya8tymy8g4rr75ezh3pkklu4c3e --home=~/.pocket_prod --network=beta --gas=auto --gas-prices=1upokt --gas-adjustment=1.5
# MainNet
pocketd tx migration import-morse-accounts "$MSG_IMPORT_MORSE_ACCOUNTS_PATH" --from pokt18808wvw0h4t450t06uvauny8lvscsxjfyua7vh --home=~/.pocket_prod --network=main --gas=auto --gas-prices=1upokt --gas-adjustment=1.56
6. Query Canonical State in Shannon
pocketd query migration list-morse-claimable-account# Example: Query an auto-unstaked account
export TEST_MORSE_ADDRESS="c409a9e0d1be8780fe0b29dcdf72f8a879fb110c"
pocketd query migration show-morse-claimable-account "$TEST_MORSE_ADDRESS"# LocalNet
pocketd query migration list-morse-claimable-account --node=http://localhost:26657
# Alpha TestNet
pocketd query migration list-morse-claimable-account --network=alpha
# Beta TestNet
pocketd query migration list-morse-claimable-account --network=beta
# MainNet
pocketd query migration list-morse-claimable-account --network=main# Query an account that was auto-unstaked
export TEST_MORSE_ADDRESS="c409a9e0d1be8780fe0b29dcdf72f8a879fb110c"
pocketd query migration show-morse-claimable-account "$TEST_MORSE_ADDRESS"
# Validate all accounts in the import message (LocalNet example)
pocketd tx migration import-morse-accounts \
"tools/scripts/migration/msg_import_morse_accounts_${MAINNET_SNAPSHOT_HEIGHT}_${MAINNET_SNAPSHOT_DATE}.json" \
--from=pnf \
--home=./localnet/pocketd --keyring-backend=test \
--node=http://localhost:26657 \
--gas=auto --gas-adjustment=1.57
7. Cleanup & Documentation
# Document the completed migration
echo "Snapshot Height: $MAINNET_SNAPSHOT_HEIGHT" >> tools/scripts/migration/README.md
echo "Snapshot Date: $MAINNET_SNAPSHOT_DATE" >> tools/scripts/migration/README.md
echo "Import Message: msg_import_morse_accounts_${MAINNET_SNAPSHOT_HEIGHT}_${MAINNET_SNAPSHOT_DATE}.json" >> tools/scripts/migration/README.md
# Final commit
git add tools/scripts/migration/README.md
git commit -m "Updated migration documentation for snapshot ${MAINNET_SNAPSHOT_HEIGHT}"
git pushState Validation: Morse Account Holders
Why Validate?
How to Validate
pocketd tx migration validate-morse-accounts "./msg_import_morse_accounts_${MAINNET_SNAPSHOT_HEIGHT}_${MAINNET_SNAPSHOT_DATE}.json" [morse_hex_address1, ...]Troubleshooting
Was this helpful?
