-
Notifications
You must be signed in to change notification settings - Fork 19
Vesting #429
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Vesting #429
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
a4f37c3
Initial vesting pallet implementation
MOZGIII 43004f4
Add the unlock call
MOZGIII 670fd3e
Drop SchedulingDriverWeightInfo
MOZGIII 3a15b07
Add tests and benchmarks
MOZGIII f17418f
Rework the vesting to move the balance calculation into the schedule
MOZGIII d6651e3
Comment out the event checks temporarily
MOZGIII 2c333af
Add lock_under_vesting_can_lock_balance_greater_than_free_balance test
MOZGIII 63bffaf
Add the vesting scheduling mechanisms
MOZGIII 9d4cf9b
Fix a typo
MOZGIII e2e9d02
Add pallet-chain-start-moment
MOZGIII 775fe8f
Make the starting point value optional at the timestamp driver
MOZGIII 871cc88
Fix the chain start moment capture logic and tests
MOZGIII c67a8c0
Correct the edge case calculations at SimpleFracScaler
MOZGIII c622663
Implement tests and better error communication at FracScale
MOZGIII cc67f75
Add test for linear schedule
MOZGIII f1a3cbd
Reserve the weight at pallet-chain-start-moment
MOZGIII 6eca387
Add logic_all_zeroes test at crates/vesting-schedule-linear/src/lib.rs
MOZGIII 2aa0832
Add vesting-scheduling-timestamp tests
MOZGIII cf932b4
Revert "Comment out the event checks temporarily"
MOZGIII e5acd7d
Enable the events in tests
MOZGIII b340fb4
Drop thiserror from FracScaleError
MOZGIII 2dff1f8
Fix a typo at crates/pallet-vesting/src/lib.rs
MOZGIII dd81fdb
Drop unused error enum
MOZGIII 7e4bbff
Add unlock_no_vesting_error test
MOZGIII 7ad2c60
Fix a typo at crates/pallet-vesting/src/traits.rs
MOZGIII 1ff41be
Fix the typos and logical mistakes in the comments
MOZGIII 4dc1087
Correct the TIME_NOW_BEFORE_THE_STARTING_POINT_ERROR
MOZGIII 08d3b8c
Test the TIME_NOW_BEFORE_THE_STARTING_POINT_ERROR
MOZGIII 24bd94a
Proper loking of mocks at tests
MOZGIII 29135fb
Add multi_linear_scarting_point_check test
MOZGIII 7a19ef4
Currect the multi_linear_returns_time_now_before_the_starting_point_e…
MOZGIII 3a1550f
Revert "Currect the multi_linear_returns_time_now_before_the_starting…
MOZGIII 73dc57f
Fix the compute_result fn
MOZGIII b6a2580
Fix a typo at test name
MOZGIII 2a61847
Add multi_linear_returns_starting_point_not_defined_error_error test
MOZGIII 1a23e19
Correct the locking at vesting-scheduling-timestamp test mocks
MOZGIII File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| [package] | ||
| name = "pallet-chain-start-moment" | ||
| version = "0.1.0" | ||
| edition = "2021" | ||
| publish = false | ||
|
|
||
| [dependencies] | ||
| codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } | ||
| frame-support = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } | ||
| frame-system = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } | ||
| scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } | ||
|
|
||
| [dev-dependencies] | ||
| pallet-timestamp = { git = "https://github.com/humanode-network/substrate", branch = "master" } | ||
| sp-core = { git = "https://github.com/humanode-network/substrate", branch = "master" } | ||
|
|
||
| [features] | ||
| default = ["std"] | ||
| std = [ | ||
| "codec/std", | ||
| "scale-info/std", | ||
| "frame-support/std", | ||
| "frame-system/std", | ||
| ] | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| //! A pallet that captures the moment of the chain start. | ||
|
|
||
| #![cfg_attr(not(feature = "std"), no_std)] | ||
|
|
||
| use frame_support::traits::{StorageVersion, Time}; | ||
|
|
||
| pub use self::pallet::*; | ||
|
|
||
| #[cfg(test)] | ||
| mod mock; | ||
| #[cfg(test)] | ||
| mod tests; | ||
|
|
||
| /// The current storage version. | ||
| const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); | ||
|
|
||
| // We have to temporarily allow some clippy lints. Later on we'll send patches to substrate to | ||
| // fix them at their end. | ||
| #[allow(clippy::missing_docs_in_private_items)] | ||
| #[frame_support::pallet] | ||
| pub mod pallet { | ||
| use frame_support::pallet_prelude::*; | ||
| use frame_system::pallet_prelude::*; | ||
|
|
||
| use super::*; | ||
|
|
||
| #[pallet::pallet] | ||
| #[pallet::storage_version(STORAGE_VERSION)] | ||
| #[pallet::generate_store(pub(super) trait Store)] | ||
| pub struct Pallet<T>(_); | ||
|
|
||
| #[pallet::config] | ||
| pub trait Config: frame_system::Config { | ||
| /// A type representing the time moment and providing the current time. | ||
| type Time: Time; | ||
| } | ||
|
|
||
| /// The captured chain start moment. | ||
| #[pallet::storage] | ||
| #[pallet::getter(fn chain_start)] | ||
| pub type ChainStart<T> = StorageValue<_, <<T as Config>::Time as Time>::Moment, OptionQuery>; | ||
|
|
||
| #[pallet::hooks] | ||
| impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> { | ||
| fn on_initialize(n: BlockNumberFor<T>) -> Weight { | ||
| if n != 1u8.into() { | ||
| return 0; | ||
| } | ||
| <T as frame_system::Config>::DbWeight::get().writes(1) | ||
| } | ||
|
|
||
| fn on_finalize(n: BlockNumberFor<T>) { | ||
| if n != 1u8.into() { | ||
| return; | ||
| } | ||
|
|
||
| let now = T::Time::now(); | ||
|
|
||
| // Ensure that the chain start is properly initialized. | ||
| assert_ne!( | ||
| now, | ||
| 0u8.into(), | ||
| "the chain start moment is zero, it is not right" | ||
| ); | ||
|
|
||
| <ChainStart<T>>::put(now); | ||
| } | ||
| } | ||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| //! The mock for the pallet. | ||
|
|
||
| use frame_support::{ | ||
| sp_io, | ||
| sp_runtime::{ | ||
| testing::Header, | ||
| traits::{BlakeTwo256, IdentityLookup}, | ||
| BuildStorage, | ||
| }, | ||
| traits::{ConstU32, ConstU64}, | ||
| }; | ||
| use sp_core::H256; | ||
|
|
||
| use crate::{self as pallet_chain_start_moment}; | ||
|
|
||
| pub type UnixMilliseconds = u64; | ||
|
|
||
| type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>; | ||
| type Block = frame_system::mocking::MockBlock<Test>; | ||
|
|
||
| frame_support::construct_runtime!( | ||
| pub enum Test where | ||
| Block = Block, | ||
| NodeBlock = Block, | ||
| UncheckedExtrinsic = UncheckedExtrinsic, | ||
| { | ||
| System: frame_system::{Pallet, Call, Config, Storage, Event<T>}, | ||
| Timestamp: pallet_timestamp::{Pallet}, | ||
| ChainStartMoment: pallet_chain_start_moment::{Pallet, Storage}, | ||
| } | ||
| ); | ||
|
|
||
| impl frame_system::Config for Test { | ||
| type BaseCallFilter = frame_support::traits::Everything; | ||
| type BlockWeights = (); | ||
| type BlockLength = (); | ||
| type DbWeight = (); | ||
| type Origin = Origin; | ||
| type Call = Call; | ||
| type Index = u64; | ||
| type BlockNumber = u64; | ||
| type Hash = H256; | ||
| type Hashing = BlakeTwo256; | ||
| type AccountId = u64; | ||
| type Lookup = IdentityLookup<u64>; | ||
| type Header = Header; | ||
| type Event = Event; | ||
| type BlockHashCount = ConstU64<250>; | ||
| type Version = (); | ||
| type PalletInfo = PalletInfo; | ||
| type AccountData = (); | ||
| type OnNewAccount = (); | ||
| type OnKilledAccount = (); | ||
| type SystemWeightInfo = (); | ||
| type SS58Prefix = (); | ||
| type OnSetCode = (); | ||
| type MaxConsumers = ConstU32<16>; | ||
| } | ||
|
|
||
| impl pallet_timestamp::Config for Test { | ||
| type Moment = UnixMilliseconds; | ||
| type OnTimestampSet = (); | ||
| type MinimumPeriod = ConstU64<5>; | ||
| type WeightInfo = (); | ||
| } | ||
|
|
||
| impl pallet_chain_start_moment::Config for Test { | ||
| type Time = Timestamp; | ||
| } | ||
|
|
||
| pub fn new_test_ext() -> sp_io::TestExternalities { | ||
| let genesis_config = GenesisConfig { | ||
| system: Default::default(), | ||
| }; | ||
| new_test_ext_with(genesis_config) | ||
| } | ||
|
|
||
| // This function basically just builds a genesis storage key/value store according to | ||
| // our desired mockup. | ||
| pub fn new_test_ext_with(genesis_config: GenesisConfig) -> sp_io::TestExternalities { | ||
| let storage = genesis_config.build_storage().unwrap(); | ||
| storage.into() | ||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| use frame_support::traits::Hooks; | ||
|
|
||
| use crate::mock::*; | ||
|
|
||
| fn set_timestamp(inc: UnixMilliseconds) { | ||
| Timestamp::set(Origin::none(), inc).unwrap(); | ||
| } | ||
|
|
||
| fn switch_block() { | ||
| if System::block_number() != 0 { | ||
| Timestamp::on_finalize(System::block_number()); | ||
| ChainStartMoment::on_finalize(System::block_number()); | ||
| System::on_finalize(System::block_number()); | ||
| } | ||
| System::set_block_number(System::block_number() + 1); | ||
| System::on_initialize(System::block_number()); | ||
| Timestamp::on_initialize(System::block_number()); | ||
| ChainStartMoment::on_initialize(System::block_number()); | ||
| } | ||
|
|
||
| /// This test verifies that the chain start moment is not set at genesis. | ||
| #[test] | ||
| fn value_is_not_set_at_genesis() { | ||
| // Build the state from the config. | ||
| new_test_ext().execute_with(move || { | ||
| // Assert the state. | ||
| assert_eq!(ChainStartMoment::chain_start(), None); | ||
| }) | ||
| } | ||
|
|
||
| /// This test verifies that the chain start moment is set at the very first block. | ||
| #[test] | ||
| fn value_is_set_at_first_block() { | ||
| // Build the state from the config. | ||
| new_test_ext().execute_with(move || { | ||
| // Block 0. | ||
| // Ensure we don't have any timestamp set first. | ||
| assert_eq!(ChainStartMoment::chain_start(), None); | ||
|
|
||
| // Block 0 -> 1. | ||
| switch_block(); | ||
| set_timestamp(100); | ||
| assert_eq!(ChainStartMoment::chain_start(), None,); | ||
|
|
||
| // Block 1 -> 2. | ||
| switch_block(); | ||
| assert_eq!( | ||
| ChainStartMoment::chain_start(), | ||
| Some(100), | ||
| "the chain start must be set correctly right after the first block has been finalized" | ||
| ); | ||
| }) | ||
| } | ||
|
|
||
| /// This test verifies that the chain start moment is not written to after the first block. | ||
| #[test] | ||
| fn value_does_not_get_written_after_the_first_block() { | ||
| // Build the state from the config. | ||
| new_test_ext().execute_with(move || { | ||
| // Block 0 -> 1. | ||
| switch_block(); | ||
|
|
||
| set_timestamp(100); | ||
|
|
||
| // Block 1 -> 2. | ||
| switch_block(); | ||
|
|
||
| set_timestamp(106); | ||
|
|
||
| // Block 2 -> 3. | ||
| switch_block(); | ||
|
|
||
| // Assert the state. | ||
| assert_eq!( | ||
| ChainStartMoment::chain_start(), | ||
| Some(100), | ||
| "the chain start moment must've been recorded at the first block" | ||
| ); | ||
| }) | ||
| } | ||
|
|
||
| /// This test verifies that the chain start moment is valid when capture it. | ||
| #[test] | ||
| #[should_panic = "the chain start moment is zero, it is not right"] | ||
| fn value_is_properly_checked() { | ||
| // Build the state from the config. | ||
| new_test_ext().execute_with(move || { | ||
| // Block 0 -> 1. | ||
| switch_block(); | ||
|
|
||
| set_timestamp(0); | ||
|
|
||
| // Block 1 -> 2. | ||
| switch_block(); | ||
| }) | ||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| [package] | ||
| name = "pallet-vesting" | ||
| version = "0.1.0" | ||
| edition = "2021" | ||
| publish = false | ||
|
|
||
| [dependencies] | ||
| codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } | ||
| frame-benchmarking = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master", optional = true } | ||
| frame-support = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } | ||
| frame-system = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" } | ||
| scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } | ||
| serde = { version = "1", optional = true } | ||
|
|
||
| [dev-dependencies] | ||
| mockall = "0.11" | ||
| once_cell = "1" | ||
| pallet-balances = { git = "https://github.com/humanode-network/substrate", branch = "master" } | ||
| sp-core = { git = "https://github.com/humanode-network/substrate", branch = "master" } | ||
|
|
||
| [features] | ||
| default = ["std"] | ||
| runtime-benchmarks = [ | ||
| "frame-benchmarking/runtime-benchmarks", | ||
| "frame-support/runtime-benchmarks", | ||
| "frame-system/runtime-benchmarks", | ||
| ] | ||
| std = [ | ||
| "codec/std", | ||
| "frame-benchmarking/std", | ||
| "frame-support/std", | ||
| "frame-system/std", | ||
| "serde", | ||
| ] |
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.