diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index 23526d9e88..dd1ae3b272 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -61,7 +61,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { impl_name: create_runtime_str!("substrate-node"), authoring_version: 10, spec_version: 28, - impl_version: 28, + impl_version: 29, apis: RUNTIME_API_VERSIONS, }; diff --git a/substrate/scripts/gitlab/check_runtime.sh b/substrate/scripts/gitlab/check_runtime.sh index c8c3023a9e..407643b155 100755 --- a/substrate/scripts/gitlab/check_runtime.sh +++ b/substrate/scripts/gitlab/check_runtime.sh @@ -105,8 +105,8 @@ else cat <<-EOT wasm source files changed but not the spec/impl version and the runtime - binary blob. If changes made do not alter logic, just bump `impl_version`. - If they do change logic, bump `spec_version` and rebuild wasm. + binary blob. If changes made do not alter logic, just bump 'impl_version'. + If they do change logic, bump 'spec_version' and rebuild wasm. source file directories: - node/src/runtime diff --git a/substrate/srml/balances/src/mock.rs b/substrate/srml/balances/src/mock.rs index 03d2acf862..14892313f9 100644 --- a/substrate/srml/balances/src/mock.rs +++ b/substrate/srml/balances/src/mock.rs @@ -58,6 +58,7 @@ pub struct ExtBuilder { transfer_fee: u64, creation_fee: u64, monied: bool, + vesting: bool, } impl Default for ExtBuilder { fn default() -> Self { @@ -66,6 +67,7 @@ impl Default for ExtBuilder { transfer_fee: 0, creation_fee: 0, monied: false, + vesting: false, } } } @@ -87,6 +89,10 @@ impl ExtBuilder { self.monied = monied; self } + pub fn vesting(mut self, vesting: bool) -> Self { + self.vesting = vesting; + self + } pub fn build(self) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; let balance_factor = if self.existential_deposit > 0 { @@ -105,7 +111,11 @@ impl ExtBuilder { existential_deposit: self.existential_deposit, transfer_fee: self.transfer_fee, creation_fee: self.creation_fee, - vesting: vec![], + vesting: if self.vesting && self.monied { + vec![(1, 0, 10), (2, 10, 20)] + } else { + vec![] + }, }.build_storage().unwrap().0); t.into() } diff --git a/substrate/srml/balances/src/tests.rs b/substrate/srml/balances/src/tests.rs index 6105d43759..8f6f87bcc5 100644 --- a/substrate/srml/balances/src/tests.rs +++ b/substrate/srml/balances/src/tests.rs @@ -372,3 +372,107 @@ fn transfer_overflow_isnt_exploitable() { } ); } + +#[test] +fn check_vesting_status() { + with_externalities( + &mut ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .vesting(true) + .build(), + || { + assert_eq!(System::block_number(), 1); + let user1_free_balance = Balances::free_balance(&1); + let user2_free_balance = Balances::free_balance(&2); + assert_eq!(user1_free_balance, 256 * 10); // Account 1 has free balance + assert_eq!(user2_free_balance, 256 * 20); // Account 2 has free balance + let user1_vesting_schedule = VestingSchedule { + offset: 256 * 10, + per_block: 256, + }; + let user2_vesting_schedule = VestingSchedule { + offset: 256 * 30, + per_block: 256, + }; + assert_eq!(Balances::vesting(&1), Some(user1_vesting_schedule)); // Account 1 has a vesting schedule + assert_eq!(Balances::vesting(&2), Some(user2_vesting_schedule)); // Account 2 has a vesting schedule + + assert_eq!(Balances::vesting_balance(&1), user1_free_balance - 256); // Account 1 has only 256 units vested at block 1 + + System::set_block_number(10); + assert_eq!(System::block_number(), 10); + + assert_eq!(Balances::vesting_balance(&1), 0); // Account 1 has fully vested by block 10 + assert_eq!(Balances::vesting_balance(&2), user2_free_balance); // Account 2 has started vesting by block 10 + + System::set_block_number(30); + assert_eq!(System::block_number(), 30); + + assert_eq!(Balances::vesting_balance(&1), 0); // Account 1 is still fully vested, and not negative + assert_eq!(Balances::vesting_balance(&2), 0); // Account 2 has fully vested by block 30 + + } + ); +} + +#[test] +fn unvested_balance_should_not_transfer() { + with_externalities( + &mut ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .vesting(true) + .build(), + || { + assert_eq!(System::block_number(), 1); + let user1_free_balance = Balances::free_balance(&1); + assert_eq!(user1_free_balance, 256 * 10); // Account 1 has free balance + assert_eq!(Balances::vesting_balance(&1), user1_free_balance - 256); // Account 1 has only 256 units vested at block 1 + assert_noop!( + Balances::transfer(Some(1).into(), 2, 256 * 2), + "vesting balance too high to send value" + ); // Account 1 cannot send more than vested amount + } + ); +} + +#[test] +fn vested_balance_should_transfer() { + with_externalities( + &mut ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .vesting(true) + .build(), + || { + System::set_block_number(5); + assert_eq!(System::block_number(), 5); + let user1_free_balance = Balances::free_balance(&1); + assert_eq!(user1_free_balance, 256 * 10); // Account 1 has free balance + + assert_eq!(Balances::vesting_balance(&1), user1_free_balance - 256 * 5); // Account 1 has 256 * 5 units vested at block 5 + assert_ok!(Balances::transfer(Some(1).into(), 2, 256 * 2)); // Account 1 can now send vested value + } + ); +} + +#[test] +fn extra_balance_should_transfer() { + with_externalities( + &mut ExtBuilder::default() + .existential_deposit(10) + .monied(true) + .vesting(true) + .build(), + || { + assert_eq!(System::block_number(), 1); + assert_ok!(Balances::transfer(Some(3).into(), 1, 256 * 10)); + let user1_free_balance = Balances::free_balance(&1); + assert_eq!(user1_free_balance, 256 * 20); // Account 1 has 2560 more free balance than normal + + assert_eq!(Balances::vesting_balance(&1), 256 * 10 - 256); // Account 1 has 256 units vested at block 1 + assert_ok!(Balances::transfer(Some(1).into(), 2, 256 * 5)); // Account 1 can send extra units gained + } + ); +} \ No newline at end of file