Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

pallet-vesting: Support multiple, merge-able vesting schedules #9202

Merged
167 commits merged into from
Aug 24, 2021

Conversation

emostov
Copy link
Contributor

@emostov emostov commented Jun 25, 2021

closes: #7101
polkadot companion: paritytech/polkadot#3407

Features

  • Support multiple vesting schedules per account. Each account is allowed up to MaxVestingSchedules, which is a configurable pallet constant.
  • A user can merge two schedules together to create a new schedule. See the new merge_schedules extrinsic

Follow up work

  • Look into adding a vesting derive to polkadot-js that helps with understanding the affects of merging a schedule

TODO:

  • make sure all instances of per_block are replace with One::one if it equals 0. (pallet-vesting: Support multiple, merge-able vesting schedules #9202 (comment))
  • weights
  • polkadot companion
  • migration (check if any faulty schedules exist in polkadot)
  • make sure tests cover (checked everything expect still need to figure out how force invalid vec length)
    • all dispatcherror paths are checked as noop <-- (a lot, and its important)
      • max length
      • validation of input ✔️
      • etc
    • shows single vesting is working just like before ✔️
    • shows multiple vesting works as expected ✔️
      • as a vesting ends, the vec is auto cleaned up
      • the last assertion at the end of N blocks is that the user has no vesting storage item left ✔️
    • merges two ongoing vesting schedules ✔️
    • merges one ended and one ongoing schedule ✔️
    • merges two ended schedules ✔️
    • merge ongoing and yet to be started schedule ✔️
    • merge ended and yet to be started schedule ✔️
    • merge 2 not yet started schedules ✔️
    • Check div by zero ✔️

@github-actions github-actions bot added A0-please_review Pull request needs code review. A7-needspolkadotpr labels Jun 25, 2021
@emostov emostov added C3-medium PR touches the given topic and has a medium impact on builders. D5-nicetohaveaudit ⚠️ PR contains trivial changes to logic that should be properly reviewed. labels Jun 25, 2021
frame/vesting/src/lib.rs Outdated Show resolved Hide resolved
frame/vesting/src/lib.rs Outdated Show resolved Hide resolved
@emostov emostov changed the title [DRAFT] Support multiple, merge-able vesting schedules Support multiple, merge-able vesting schedules Jun 29, 2021
frame/vesting/src/lib.rs Outdated Show resolved Hide resolved
frame/vesting/src/lib.rs Outdated Show resolved Hide resolved
frame/vesting/src/lib.rs Outdated Show resolved Hide resolved
frame/vesting/src/lib.rs Outdated Show resolved Hide resolved
frame/vesting/src/lib.rs Outdated Show resolved Hide resolved
@joao-paulo-parity
Copy link
Contributor

/try-runtime queue --block-at 0x4ac69a84e6f37b800a735453b078a645368a226ae7c82eb7ce4315c250e07a49 --url ws://polkadot on-runtime-upgrade live

@command-bot
Copy link

command-bot bot commented Aug 16, 2021

Preparing try-runtime command for branch: "zeke-multi-vest-2". Comment will be updated.
Executing cargo run --quiet --features=try-runtime try-runtime --block-at 0x4ac69a84e6f37b800a735453b078a645368a226ae7c82eb7ce4315c250e07a49 --url ws://try-runtime-polkadot-node-0:9944 on-runtime-upgrade live
The logs for this command should be available on Grafana for the data source loki.parity-chains and query {container=~"try-runtime"}

@paritytech paritytech deleted a comment from command-bot bot Aug 16, 2021
@paritytech paritytech deleted a comment from command-bot bot Aug 16, 2021
@command-bot
Copy link

command-bot bot commented Aug 16, 2021

@joao-paulo-parity Results are ready for cargo run --quiet --features=try-runtime try-runtime --block-at 0x4ac69a84e6f37b800a735453b078a645368a226ae7c82eb7ce4315c250e07a49 --url ws://try-runtime-polkadot-node-0:9944 on-runtime-upgrade live

Output
2021-08-16 13:43:04 scraping key-pairs from remote @ 0x4ac69a84e6f37b800a735453b078a645368a226ae7c82eb7ce4315c250e07a49    
2021-08-16 13:43:04 downloading data for all modules.    
2021-08-16 13:46:48 Querying a total of 737373 keys    
2021-08-16 13:50:30 extending externalities with 1 manually injected key-values    
2021-08-16 13:50:30 injecting a total of 737375 keys    
2021-08-16 13:57:59 ⚠️ System declares internal migrations (which *might* execute). On-chain `<wasm:stripped>` vs current storage version `<wasm:stripped>`    
2021-08-16 13:57:59 ✅ no migration for TransactionStorage    
2021-08-16 13:57:59 ✅ no migration for Uniques    
2021-08-16 13:57:59 ✅ no migration for Gilt    
2021-08-16 13:57:59 ✅ no migration for Lottery    
2021-08-16 13:57:59 ✅ no migration for Mmr    
2021-08-16 13:57:59 ✅ no migration for Assets    
2021-08-16 13:57:59 ✅ no migration for Tips    
2021-08-16 13:57:59 ✅ no migration for Bounties    
2021-08-16 13:57:59 ✅ no migration for Multisig    
2021-08-16 13:57:59 ✅ no migration for Proxy    
2021-08-16 13:57:59 ✅ no migration for Scheduler    
2021-08-16 13:57:59 ⚠️ Vesting declares internal migrations (which *might* execute). On-chain `<wasm:stripped>` vs current storage version `<wasm:stripped>`    
2021-08-16 13:57:59 ✅ no migration for Recovery    
2021-08-16 13:57:59 ✅ no migration for Society    
2021-08-16 13:57:59 ✅ no migration for Identity    
2021-08-16 13:57:59 ✅ no migration for RandomnessCollectiveFlip    
2021-08-16 13:57:59 ✅ no migration for Historical    
2021-08-16 13:57:59 ⚠️ Offences declares internal migrations (which *might* execute). On-chain `<wasm:stripped>` vs current storage version `<wasm:stripped>`    
2021-08-16 13:57:59 have 0 deferred offences, applying.    
2021-08-16 13:57:59 ✅ no migration for AuthorityDiscovery    
2021-08-16 13:57:59 ✅ no migration for ImOnline    
2021-08-16 13:57:59 ✅ no migration for Sudo    
2021-08-16 13:57:59 ⚠️ Contracts declares internal migrations (which *might* execute). On-chain `<wasm:stripped>` vs current storage version `<wasm:stripped>`    
2021-08-16 13:57:59 ✅ no migration for Treasury    
2021-08-16 13:57:59 ✅ no migration for Grandpa    
2021-08-16 13:57:59 ✅ no migration for TechnicalMembership    
2021-08-16 13:57:59 ✅ no migration for Elections    
2021-08-16 13:57:59 ✅ no migration for TechnicalCommittee    
2021-08-16 13:57:59 ✅ no migration for Council    
2021-08-16 13:57:59 ✅ no migration for Democracy    
2021-08-16 13:57:59 ✅ no migration for Session    
2021-08-16 13:57:59 ⚠️ Staking declares internal migrations (which *might* execute). On-chain `<wasm:stripped>` vs current storage version `<wasm:stripped>`    
2021-08-16 13:57:59 ✅ no migration for ElectionProviderMultiPhase    
2021-08-16 13:57:59 ✅ no migration for TransactionPayment    
2021-08-16 13:57:59 ✅ no migration for Balances    
2021-08-16 13:57:59 ✅ no migration for Indices    
2021-08-16 13:57:59 ✅ no migration for Authorship    
2021-08-16 13:57:59 ✅ no migration for Timestamp    
2021-08-16 13:57:59 ✅ no migration for Babe    
2021-08-16 13:57:59 ✅ no migration for Utility    
2021-08-16 13:57:59 TryRuntime_on_runtime_upgrade executed without errors. Consumed weight = 20582400000000, total weight = 512000000000000 (0.0402)

@kianenigma
Copy link
Contributor

/try-runtime queue --execution Native -lremote-ext=debug,executor=trace,runtime=trace --block-at 0x4ac69a84e6f37b800a735453b078a645368a226ae7c82eb7ce4315c250e07a49 --url ws://polkadot on-runtime-upgrade live -m Vesting

@command-bot
Copy link

command-bot bot commented Aug 16, 2021

Preparing try-runtime command for branch: "zeke-multi-vest-2". Comment will be updated.
Executing cargo run --quiet --features=try-runtime try-runtime --execution Native -lremote-ext=debug,executor=trace,runtime=trace --block-at 0x4ac69a84e6f37b800a735453b078a645368a226ae7c82eb7ce4315c250e07a49 --url ws://try-runtime-polkadot-node-0:9944 on-runtime-upgrade live -m Vesting
The logs for this command should be available on Grafana for the data source loki.parity-chains and query {container=~"try-runtime"}

@command-bot
Copy link

command-bot bot commented Aug 16, 2021

@kianenigma Results are ready for cargo run --quiet --features=try-runtime try-runtime --execution Native -lremote-ext=debug,executor=trace,runtime=trace --block-at 0x4ac69a84e6f37b800a735453b078a645368a226ae7c82eb7ce4315c250e07a49 --url ws://try-runtime-polkadot-node-0:9944 on-runtime-upgrade live -m Vesting

Output
2021-08-16 14:35:02.102 DEBUG main runtime::staking: [0] 💸 Starting the first era.    
2021-08-16 14:35:02.107 TRACE main runtime::staking: [0] 💸 planning new session 1 at genesis    
2021-08-16 14:35:02.108 TRACE main runtime::staking: [0] 💸 starting session 0    
2021-08-16 14:35:02.112  INFO main remote-ext: initializing remote client to "ws://try-runtime-polkadot-node-0:9944"    
2021-08-16 14:35:02.208  INFO main remote-ext: scraping key-pairs from remote @ 0x4ac69a84e6f37b800a735453b078a645368a226ae7c82eb7ce4315c250e07a49    
2021-08-16 14:35:02.808 DEBUG main remote-ext: new total = 512, full page received: 5f27b51b5ec208ee9cb25b55d87282435f27b51b5ec208ee9cb25b55d8728243c85ed78a521e571727319a52fdc1839aeaea825970fd6591d65d4758c7f3770437a5249f994f19df934134faa288d602    
2021-08-16 14:35:02.983 DEBUG main remote-ext: last page received: 130    
2021-08-16 14:35:02.984  INFO main remote-ext: Querying a total of 642 keys    
2021-08-16 14:35:03.599  INFO main remote-ext: downloaded data for module Vesting (count: 642 / prefix: 5f27b51b5ec208ee9cb25b55d8728243).    
2021-08-16 14:35:03.600 DEBUG main remote-ext: adding data for hashed key: 26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8    
2021-08-16 14:35:03.603  INFO main remote-ext: extending externalities with 1 manually injected key-values    
2021-08-16 14:35:03.607  INFO main remote-ext: injecting a total of 644 keys    
2021-08-16 14:36:27.344 TRACE main executor: Request for native execution succeeded (native: node-267 (substrate-node-0.tx2.au10), chain: node-267 (substrate-node-0.tx2.au10))    
2021-08-16 14:36:27.345 DEBUG main runtime::vesting: migration: Vesting storage version v1 PRE migration checks succesful!    
2021-08-16 14:36:27.345  INFO main runtime::frame-support: ⚠️ System declares internal migrations (which *might* execute). On-chain `StorageVersion(0)` vs current storage version `StorageVersion(0)`    
2021-08-16 14:36:27.346  INFO main runtime::frame-support: ✅ no migration for TransactionStorage    
2021-08-16 14:36:27.346  INFO main runtime::frame-support: ✅ no migration for Uniques    
2021-08-16 14:36:27.346  INFO main runtime::frame-support: ✅ no migration for Gilt    
2021-08-16 14:36:27.346  INFO main runtime::frame-support: ✅ no migration for Lottery    
2021-08-16 14:36:27.346  INFO main runtime::frame-support: ✅ no migration for Mmr    
2021-08-16 14:36:27.347  INFO main runtime::frame-support: ✅ no migration for Assets    
2021-08-16 14:36:27.347  INFO main runtime::frame-support: ✅ no migration for Tips    
2021-08-16 14:36:27.347  INFO main runtime::frame-support: ✅ no migration for Bounties    
2021-08-16 14:36:27.347  INFO main runtime::frame-support: ✅ no migration for Multisig    
2021-08-16 14:36:27.347  INFO main runtime::frame-support: ✅ no migration for Proxy    
2021-08-16 14:36:27.347  INFO main runtime::frame-support: ✅ no migration for Scheduler    
2021-08-16 14:36:27.348  INFO main runtime::frame-support: ⚠️ Vesting declares internal migrations (which *might* execute). On-chain `StorageVersion(0)` vs current storage version `StorageVersion(0)`    
2021-08-16 14:36:27.464  INFO main runtime::frame-support: ✅ no migration for Recovery    
2021-08-16 14:36:27.464  INFO main runtime::frame-support: ✅ no migration for Society    
2021-08-16 14:36:27.464  INFO main runtime::frame-support: ✅ no migration for Identity    
2021-08-16 14:36:27.464  INFO main runtime::frame-support: ✅ no migration for RandomnessCollectiveFlip    
2021-08-16 14:36:27.464  INFO main runtime::frame-support: ✅ no migration for Historical    
2021-08-16 14:36:27.464  INFO main runtime::frame-support: ⚠️ Offences declares internal migrations (which *might* execute). On-chain `StorageVersion(0)` vs current storage version `StorageVersion(0)`    
2021-08-16 14:36:27.464  INFO main runtime::offences: have 0 deferred offences, applying.    
2021-08-16 14:36:27.465  INFO main runtime::frame-support: ✅ no migration for AuthorityDiscovery    
2021-08-16 14:36:27.465  INFO main runtime::frame-support: ✅ no migration for ImOnline    
2021-08-16 14:36:27.465  INFO main runtime::frame-support: ✅ no migration for Sudo    
2021-08-16 14:36:27.465  INFO main runtime::frame-support: ⚠️ Contracts declares internal migrations (which *might* execute). On-chain `StorageVersion(0)` vs current storage version `StorageVersion(4)`    
2021-08-16 14:36:27.465  INFO main runtime::frame-support: ✅ no migration for Treasury    
2021-08-16 14:36:27.466  INFO main runtime::frame-support: ✅ no migration for Grandpa    
2021-08-16 14:36:27.466  INFO main runtime::frame-support: ✅ no migration for TechnicalMembership    
2021-08-16 14:36:27.466  INFO main runtime::frame-support: ✅ no migration for Elections    
2021-08-16 14:36:27.466  INFO main runtime::frame-support: ✅ no migration for TechnicalCommittee    
2021-08-16 14:36:27.466  INFO main runtime::frame-support: ✅ no migration for Council    
2021-08-16 14:36:27.466  INFO main runtime::frame-support: ✅ no migration for Democracy    
2021-08-16 14:36:27.466  INFO main runtime::frame-support: ✅ no migration for Session    
2021-08-16 14:36:27.467  INFO main runtime::frame-support: ⚠️ Staking declares internal migrations (which *might* execute). On-chain `StorageVersion(0)` vs current storage version `StorageVersion(0)`    
2021-08-16 14:36:27.467  INFO main runtime::frame-support: ✅ no migration for ElectionProviderMultiPhase    
2021-08-16 14:36:27.467  INFO main runtime::frame-support: ✅ no migration for TransactionPayment    
2021-08-16 14:36:27.467  INFO main runtime::frame-support: ✅ no migration for Balances    
2021-08-16 14:36:27.467  INFO main runtime::frame-support: ✅ no migration for Indices    
2021-08-16 14:36:27.468  INFO main runtime::frame-support: ✅ no migration for Authorship    
2021-08-16 14:36:27.468  INFO main runtime::frame-support: ✅ no migration for Timestamp    
2021-08-16 14:36:27.468  INFO main runtime::frame-support: ✅ no migration for Babe    
2021-08-16 14:36:27.468  INFO main runtime::frame-support: ✅ no migration for Utility    
2021-08-16 14:36:27.539 DEBUG main runtime::vesting: migration: Vesting storage version v1 POST migration checks successful!    
2021-08-16 14:36:27.540  INFO main try_runtime_cli: TryRuntime_on_runtime_upgrade executed without errors. Consumed weight = 532582400000000, total weight = 512000000000000 (1.0402)

@emostov
Copy link
Contributor Author

emostov commented Aug 18, 2021

bot merge

@ghost
Copy link

ghost commented Aug 18, 2021

Trying merge.

@emostov
Copy link
Contributor Author

emostov commented Aug 19, 2021

bot merge

@ghost
Copy link

ghost commented Aug 19, 2021

Waiting for commit status.

@ghost
Copy link

ghost commented Aug 19, 2021

Merge aborted: Checks failed for 140af31

@emostov
Copy link
Contributor Author

emostov commented Aug 19, 2021

bot merge

@ghost
Copy link

ghost commented Aug 19, 2021

Merge aborted: Checks failed for 140af31

@emostov
Copy link
Contributor Author

emostov commented Aug 24, 2021

bot merge

@ghost
Copy link

ghost commented Aug 24, 2021

Trying merge.

@ghost ghost merged commit 60c6ec7 into master Aug 24, 2021
@ghost ghost deleted the zeke-multi-vest-2 branch August 24, 2021 00:15
Wizdave97 pushed a commit to Wizdave97/substrate that referenced this pull request Aug 25, 2021
…ytech#9202)

* Support multiple, mergable vesting schedules

* Update node runtime

* Remove some TODO design questions and put them as commennts

* Update frame/vesting/src/benchmarking.rs

* Syntax and comment clean up

* Create filter enum for removing schedules

* Dry vesting calls with do_vest

* Improve old benchmarks to account for max schedules

* Update WeightInfo trait and make dummy fns

* Add merge_schedule weights

* Explicitly test multiple vesting scheudles

* Make new vesting tests more more clear

* Apply suggestions from code review

* Update remove_vesting_schedule to error with no index

* Try reduce spacing diff

* Apply suggestions from code review

* Use get on vesting for bounds check; check origin first

* No filter tuple; various simplifications

* unwrap or default when getting user schedules

* spaces be gone

* ReadMe fixes

* Update frame/vesting/src/lib.rs

Co-authored-by: Peter Goodspeed-Niklaus <[email protected]>

* address some comments for docs

* merge sched docs

* Apply suggestions from code review

Co-authored-by: Shawn Tabrizi <[email protected]>

* log error when trying to push to vesting vec

* use let Some, not is_some

* remove_vesting_schedule u32, not optin

* new not try_new, create validate builder; VestingInfo

* Merge prep: break out tests and mock

* Add files forgot to include in merge

* revert some accidental changes to merged files

* Revert remaining accidental file changes

* More revert of accidental file change

* Try to reduce diff on tests

* namespace Vesting; check key when key should not exist;

* ending_block throws error on per_block of 0

* Try improve merge vesting info comment

* Update frame/vesting/src/lib.rs

Co-authored-by: Kian Paimani <[email protected]>

* add validate + correct; handle duration > blocknumber

* Move vesting_info module to its own file

* Seperate Vesting/locks updates from writing

* Add can_add_vesting schedule

* Adjust min vested transfer to be greater than all ED

* Initial integrity test impl

* merge_finished_and_yet_to_be_started_schedules

* Make sure to assert storage items are cleaned up

* Migration initial impl (not tested)

* Correct try-runtime hooks

* Apply suggestions from code review

Co-authored-by: Shawn Tabrizi <[email protected]>

* header

* WIP: improve benchmarks

* Benchmarking working

* benchmarking: step over max schedules

* cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_vesting --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/vesting/src/weights.rs --template=./.maintain/frame-weight-template.hbs

* Simplify APIs by accepting vec; convert to bounded on write

* Test:  build_genesis_has_storage_version_v1

* Test more error cases

* Hack to get polkadot weights to work; should revert later

* Improve benchmarking; works on polkadot

* cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_vesting --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/vesting/src/weights.rs --template=./.maintain/frame-weight-template.hbs

* WIP override storage

* Set storage not working example

* Remove unused tests

* VestingInfo: make public, derive MaxEndcodedLen

* Rename ending_block to ending_block_as_balance

* Superificial improvements

* Check for end block infinite, not just duration

* More superficial update

* Update tests

* Test vest with multi schedule

* Don't use half max balance in benchmarks

* Use debug_assert when locked is unexpected 0

* Implement exec_action

* Simplify per_block calc in vesting_info

* VestingInfo.validate in add_vesting_schedule & can_add_vesting_schedule

* Simplify post migrate check

* Remove merge event

* Minor benchmarking updates

* Remove VestingInfo.correct

* per_block accesor max with 1

* Improve comment

* Remoe debug

* Fix add schedule comment

* Apply suggestions from code review

Co-authored-by: Peter Goodspeed-Niklaus <[email protected]>

* no ref for should_remove param

* Remove unused vestingaction derive

* Asserts to show balance unlock in merge benchmark

* Remove unused imports

* trivial

* Fix benchmark asserts to handle non-multiple of 20 locked

* Add generate_storage_info

* migration :facepalm

* Remove per_block 0 logic

* Update frame/vesting/src/lib.rs

* Do not check for ending later than greatest block

* Apply suggestions from code review

* Benchmarks: simplify vesting schedule creation

* Add log back for migration

* Add note in ext docs explaining that all schedules will vest

* Make integrity test work

* Improve integrity test

* Remove unnescary type param from VestingInfo::new

* Remove unnescary resut for ending_block_as_balance

* Remove T param from ending_block_as_balance

* Reduce visibility of raw_per_block

* Remove unused type param for validate

* update old comment

* Make log a dep; log warn in migrate

* VestingInfo.validate returns Err(()), no T type param

* Try improve report_schedule_updates

* is_valid, not validate

* revert node runtime reorg;

* change schedule validity check to just warning

* Simplify merge_vesting_info return type

* Apply suggestions from code review

* Apply suggestions from code review

Co-authored-by: Kian Paimani <[email protected]>

* Add warning for migration

* Fix indentation

* Delete duplicate warnings

* Reduce diff in node runtime

* Fix benchmark build

* Upgrade cargo.toml to use 4.0.0-dev

* Cleanup

* MaxVestingSchedulesGetter initial impl

* MinVestedTransfer getter inintial impl

* Test MaxVestingSchedules & MinVestedTransfer getters; use getters in benchmarks

* Run cargo fmt

* Revert MinVestedTransfer & MaxVestingSchedules getters; Add integrity test

* Make MAX_VESTING_SCHEDULES a const

* fmt

* WIP: benchmark improvements

* Finish benchmark update

* Add test for transfer to account with less than ed

* Rm min_new_account_transfer; move sp-io to dev-dep

* Reduce cargo.toml diff

* Explain MAX_VESTING_SCHEDULES choice

* Fix after merge

* Try fix CI complaints

* cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_vesting --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/vesting/src/weights.rs --template=./.maintain/frame-weight-template.hbs

* cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_vesting --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/vesting/src/weights.rs --template=./.maintain/frame-weight-template.hbs

* fmt

* trigger

* fmt

Co-authored-by: Parity Bot <[email protected]>
Co-authored-by: Peter Goodspeed-Niklaus <[email protected]>
Co-authored-by: Shawn Tabrizi <[email protected]>
Co-authored-by: Kian Paimani <[email protected]>
Co-authored-by: kianenigma <[email protected]>
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review. C3-medium PR touches the given topic and has a medium impact on builders. D1-audited 👍 PR contains changes to fund-managing logic that has been properly reviewed and externally audited
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support Multiple Vesting Schedules in Vesting Pallet
6 participants