moonbeam icon indicating copy to clipboard operation
moonbeam copied to clipboard

Migrate Currency trait to Fungible trait

Open snowmead opened this issue 7 months ago • 7 comments

Migrate Parachain Staking from Currency to Fungible Trait

This PR migrates the parachain staking pallet from the deprecated Currency trait to the modern Fungible trait, replacing the old lock-based system with a freeze-based mechanism. We used freeze operations instead of holds to keep the same behaviour as did locks.

Key Changes

  1. Trait Migration: Updated the pallet to use Fungible trait with MutateFreeze instead of LockableCurrency

    • Replaced set_lock/remove_lock with set_freeze/thaw operations
    • Added FreezeReason enum with StakingCollator and StakingDelegator variants
  2. Lazy Migration: Implemented automatic migration that converts accounts during their next interaction

    • Added MigratedCandidates and MigratedDelegators storage to track migration status
    • Migration happens transparently when accounts perform staking operations
    • No runtime upgrade migration needed - accounts migrate on-demand
  3. Batch Migration Extrinsic: Added migrate_locks_to_freezes_batch (call index 33)

    • Allows manual migration of up to 100 accounts per transaction
    • Useful for maintainers to proactively migrate accounts
    • Supports both collator and delegator migration
  4. Helper Functions: Added migration-aware wrappers

    • freeze_extended: Checks and migrates locks before freezing
    • thaw_extended: Removes locks before thawing
    • balance_frozen_extended: Migrates and returns frozen balance

Runtime Impact

When the runtime is upgraded:

  • Existing stakers continue working without interruption
  • Accounts automatically migrate from locks to freezes when they interact with staking
  • No immediate action required from delegators or collators
  • Engineering team can use batch migration to proactively migrate accounts if desired

Testing

  • Added comprehensive lazy migration tests in test_lazy_migration.rs
  • Updated all existing staking tests to work with freezes instead of locks
  • Benchmarks updated to account for worst-case migration scenarios

⚠️ Breaking Changes ⚠️

After the migration, users who previously queried Balances.Locks for lock identifiers [stkngcol, stkngdel], should now query Balances.Freezes with the following freeze reasons [StakingCollator, StakingDelegator] instead. The frozen balance shown in System.Account remains unaffected by this change.

snowmead avatar May 28 '25 20:05 snowmead

WASM runtime size check:

Compared to target branch

Moonbase runtime: 1984 KB (-8 KB) ✅

Moonbeam runtime: 2108 KB (+8 KB) ⚠️

Moonriver runtime: 2108 KB (+8 KB) ⚠️

Compared to latest release (runtime-3900)

Moonbase runtime: 1984 KB (-376 KB compared to latest release) ✅

Moonbeam runtime: 2108 KB (-372 KB compared to latest release) ✅

Moonriver runtime: 2108 KB (-372 KB compared to latest release) ✅

github-actions[bot] avatar May 28 '25 20:05 github-actions[bot]

Coverage Report

@@                               Coverage Diff                               @@
##           master   snowmead/migrate-currency-trait-to-fungible      +/-   ##
===============================================================================
+ Coverage   74.50%                                        74.69%   +0.19%     
+ Files         396                                           397       +1     
+ Lines       95874                                         96541     +667     
===============================================================================
+ Hits        71424                                         72110     +686     
- Misses      24450                                         24431      -19     
Files Changed Coverage
/pallets/parachain-staking/src/lib.rs 93.26% (+1.52%) 🔼
/pallets/parachain-staking/src/mock.rs 98.61% (+0.17%) 🔼
/pallets/parachain-staking/src/types.rs 87.55% (-0.10%) 🔽
/pallets/parachain-staking/src/weights.rs 44.54% (+2.35%) 🔼
/runtime/moonbase/src/weights/pallet_parachain_staking.rs 23.40% (-0.17%) 🔽
/runtime/moonbeam/src/weights/pallet_parachain_staking.rs 23.40% (-0.17%) 🔽
/runtime/moonriver/src/weights/pallet_parachain_staking.rs 23.40% (-0.17%) 🔽

Coverage generated Fri Oct 24 13:09:51 UTC 2025

github-actions[bot] avatar May 28 '25 20:05 github-actions[bot]

@coderabbitai review

snowmead avatar Jun 11 '25 20:06 snowmead

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot] avatar Jun 11 '25 20:06 coderabbitai[bot]

Moonbase Weight Difference Report

File Extrinsic Old New Change Percent
runtime/moonbase/src/weights/pallet_parachain_staking.rs pay_one_collator_reward_best 62.29ms 97.19ms 56.02%
runtime/moonbase/src/weights/pallet_parachain_staking.rs execute_delegator_revoke_delegation_worst 1.42ms 1.52ms 7.02%

Moonriver Weight Difference Report

File Extrinsic Old New Change Percent
runtime/moonriver/src/weights/pallet_parachain_staking.rs pay_one_collator_reward_best 62.19ms 97.09ms 56.12%
runtime/moonriver/src/weights/pallet_parachain_staking.rs execute_delegator_revoke_delegation_worst 1.43ms 1.53ms 7.00%

Moonbeam Weight Difference Report

File Extrinsic Old New Change Percent
runtime/moonbeam/src/weights/pallet_parachain_staking.rs pay_one_collator_reward_best 62.23ms 97.13ms 56.08%
runtime/moonbeam/src/weights/pallet_parachain_staking.rs execute_delegator_revoke_delegation_worst 1.44ms 1.54ms 6.94%

github-actions[bot] avatar Jun 11 '25 20:06 github-actions[bot]

I added the breaking label because any runtime call that might cost more weight is a breaking change, and all staking calls might cost more in the worst case scenario

librelois avatar Jun 17 '25 13:06 librelois

While doing a second review to this PR I noticed we are ignoring some errors that can happen when removing freezes, this is not ideal. Currently, I took over this PR and will be applying a few improvements.

RomarQ avatar Oct 23 '25 11:10 RomarQ

[!IMPORTANT]

Review skipped

Auto reviews are limited based on label configuration.

:label: Required labels (at least one) (1)
  • agent-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment
  • [ ] Commit unit tests in branch snowmead/migrate-currency-trait-to-fungible

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Oct 23 '25 12:10 coderabbitai[bot]