Skip to content
Snippets Groups Projects
Commit aadf3e24 authored by Gav's avatar Gav
Browse files

Tests for staking reserved balances & slashing.

parent 8c0c5049
No related merge requests found
......@@ -112,6 +112,7 @@ pub fn bondage(who: &AccountId) -> Bondage {
}
#[derive(PartialEq, Copy, Clone)]
#[cfg_attr(test, derive(Debug))]
pub enum LockStatus {
Liquid,
LockedUntil(BlockNumber),
......@@ -486,11 +487,12 @@ pub mod internal {
}
/// Moves `value` from reserved balance to balance.
pub fn transfer_reserved_balance(slashed: &AccountId, beneficiary: &AccountId, value: Balance) {
pub fn transfer_reserved_balance(slashed: &AccountId, beneficiary: &AccountId, value: Balance) -> bool {
let b = reserved_balance(slashed);
let value = cmp::min(b, value);
set_reserved_balance(slashed, b - value);
set_free_balance(beneficiary, free_balance(beneficiary) + value);
let slash = cmp::min(b, value);
set_reserved_balance(slashed, b - slash);
set_free_balance(beneficiary, free_balance(beneficiary) + slash);
slash == value
}
}
......@@ -536,23 +538,19 @@ pub mod testing {
use super::*;
use runtime_io::{twox_128, TestExternalities};
use codec::{Joiner, KeyedVec};
use keyring::Keyring;
use keyring::Keyring::*;
use runtime::session;
pub fn externalities(session_length: u64, sessions_per_era: u64, current_era: u64) -> TestExternalities {
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let extras: TestExternalities = map![
twox_128(INTENTION_COUNT).to_vec() => vec![].and(&3u32),
twox_128(&0u32.to_keyed_vec(INTENTION_AT)).to_vec() => one.to_vec(),
twox_128(&1u32.to_keyed_vec(INTENTION_AT)).to_vec() => two.to_vec(),
twox_128(&2u32.to_keyed_vec(INTENTION_AT)).to_vec() => three.to_vec(),
twox_128(&0u32.to_keyed_vec(INTENTION_AT)).to_vec() => Alice.to_raw_public_vec(),
twox_128(&1u32.to_keyed_vec(INTENTION_AT)).to_vec() => Bob.to_raw_public_vec(),
twox_128(&2u32.to_keyed_vec(INTENTION_AT)).to_vec() => Charlie.to_raw_public_vec(),
twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&sessions_per_era),
twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&3u64),
twox_128(CURRENT_ERA).to_vec() => vec![].and(&current_era),
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
];
session::testing::externalities(session_length).into_iter().chain(extras.into_iter()).collect()
}
......@@ -567,18 +565,13 @@ mod tests {
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner};
use keyring::Keyring;
use keyring::Keyring::*;
use environment::with_env;
use demo_primitives::AccountId;
use runtime::{staking, session};
#[test]
fn staking_should_work() {
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let four = [4u8; 32];
let mut t: TestExternalities = map![
twox_128(session::SESSION_LENGTH).to_vec() => vec![].and(&1u64),
twox_128(session::VALIDATOR_COUNT).to_vec() => vec![].and(&2u32),
......@@ -588,10 +581,10 @@ mod tests {
twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&2u32),
twox_128(BONDING_DURATION).to_vec() => vec![].and(&3u64),
twox_128(TOTAL_STAKE).to_vec() => vec![].and(&100u64),
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&10u64),
twox_128(&two.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&20u64),
twox_128(&three.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&30u64),
twox_128(&four.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&40u64)
twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&10u64),
twox_128(&Bob.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&20u64),
twox_128(&Charlie.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&30u64),
twox_128(&Dave.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&40u64)
];
with_externalities(&mut t, || {
......@@ -602,48 +595,48 @@ mod tests {
// Block 1: Add three validators. No obvious change.
with_env(|e| e.block_number = 1);
stake(&one);
stake(&two);
stake(&four);
stake(&Alice);
stake(&Bob);
stake(&Dave);
check_new_era();
assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]);
// Block 2: New validator set now.
with_env(|e| e.block_number = 2);
check_new_era();
assert_eq!(session::validators(), vec![four.clone(), two.clone()]);
assert_eq!(session::validators(), vec![Dave.to_raw_public(), Bob.into()]);
// Block 3: Unstake highest, introduce another staker. No change yet.
with_env(|e| e.block_number = 3);
stake(&three);
unstake(&four);
stake(&Charlie);
unstake(&Dave);
check_new_era();
// Block 4: New era - validators change.
with_env(|e| e.block_number = 4);
check_new_era();
assert_eq!(session::validators(), vec![three.clone(), two.clone()]);
assert_eq!(session::validators(), vec![Charlie.to_raw_public(), Bob.into()]);
// Block 5: Transfer stake from highest to lowest. No change yet.
with_env(|e| e.block_number = 5);
transfer(&four, &one, 40);
transfer(&Dave, &Alice, 40);
check_new_era();
// Block 6: Lowest now validator.
with_env(|e| e.block_number = 6);
check_new_era();
assert_eq!(session::validators(), vec![one.clone(), three.clone()]);
assert_eq!(session::validators(), vec![Alice.to_raw_public(), Charlie.into()]);
// Block 7: Unstake three. No change yet.
with_env(|e| e.block_number = 7);
unstake(&three);
unstake(&Charlie);
check_new_era();
assert_eq!(session::validators(), vec![one.clone(), three.clone()]);
assert_eq!(session::validators(), vec![Alice.to_raw_public(), Charlie.into()]);
// Block 8: Back to one and two.
with_env(|e| e.block_number = 8);
check_new_era();
assert_eq!(session::validators(), vec![one.clone(), two.clone()]);
assert_eq!(session::validators(), vec![Alice.to_raw_public(), Bob.into()]);
});
}
......@@ -713,48 +706,173 @@ mod tests {
#[test]
fn staking_balance_works() {
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 42);
assert_eq!(free_balance(&Alice), 42);
assert_eq!(reserved_balance(&Alice), 0);
assert_eq!(balance(&Alice), 42);
assert_eq!(free_balance(&Bob), 0);
assert_eq!(reserved_balance(&Bob), 0);
assert_eq!(balance(&Bob), 0);
});
}
let mut t: TestExternalities = map![
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&42u64)
];
#[test]
fn staking_balance_transfer_works() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
transfer(&Alice, &Bob, 69);
assert_eq!(balance(&Alice), 42);
assert_eq!(balance(&Bob), 69);
});
}
with_externalities(&mut t, || {
assert_eq!(balance(&one), 42);
assert_eq!(balance(&two), 0);
#[test]
#[should_panic]
fn staking_balance_transfer_when_bonded_panics() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
stake(&Alice);
transfer(&Alice, &Bob, 69);
});
}
#[test]
fn staking_balance_transfer_works() {
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
fn reserving_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
let mut t: TestExternalities = map![
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64)
];
assert_eq!(balance(&Alice), 111);
assert_eq!(free_balance(&Alice), 111);
assert_eq!(reserved_balance(&Alice), 0);
with_externalities(&mut t, || {
transfer(&one, &two, 69);
assert_eq!(balance(&one), 42);
assert_eq!(balance(&two), 69);
reserve_balance(&Alice, 69);
assert_eq!(balance(&Alice), 111);
assert_eq!(free_balance(&Alice), 42);
assert_eq!(reserved_balance(&Alice), 69);
});
}
#[test]
#[should_panic]
fn staking_balance_transfer_when_bonded_doesnt_work() {
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
fn staking_balance_transfer_when_reserved_panics() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
reserve_balance(&Alice, 69);
transfer(&Alice, &Bob, 69);
});
}
#[test]
fn deducting_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
assert!(deduct_unbonded(&Alice, 69));
assert_eq!(free_balance(&Alice), 42);
});
}
#[test]
fn deducting_balance_should_fail_when_bonded() {
let mut t: TestExternalities = map![
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64)
twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64),
twox_128(&Alice.to_raw_public().to_keyed_vec(BONDAGE_OF)).to_vec() => vec![].and(&2u64)
];
with_externalities(&mut t, || {
stake(&one);
transfer(&one, &two, 69);
with_env(|e| e.block_number = 1);
assert_eq!(unlock_block(&Alice), LockStatus::LockedUntil(2));
assert!(!deduct_unbonded(&Alice, 69));
});
}
#[test]
fn refunding_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 42);
refund(&Alice, 69);
assert_eq!(free_balance(&Alice), 111);
});
}
#[test]
fn slashing_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
reserve_balance(&Alice, 69);
assert!(slash(&Alice, 69));
assert_eq!(free_balance(&Alice), 0);
assert_eq!(reserved_balance(&Alice), 42);
});
}
#[test]
fn slashing_incomplete_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 42);
reserve_balance(&Alice, 21);
assert!(!slash(&Alice, 69));
assert_eq!(free_balance(&Alice), 0);
assert_eq!(reserved_balance(&Alice), 0);
});
}
#[test]
fn unreserving_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
reserve_balance(&Alice, 111);
unreserve_balance(&Alice, 42);
assert_eq!(reserved_balance(&Alice), 69);
assert_eq!(free_balance(&Alice), 42);
});
}
#[test]
fn slashing_reserved_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
reserve_balance(&Alice, 111);
assert!(slash_reserved(&Alice, 42));
assert_eq!(reserved_balance(&Alice), 69);
assert_eq!(free_balance(&Alice), 0);
});
}
#[test]
fn slashing_incomplete_reserved_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
reserve_balance(&Alice, 42);
assert!(!slash_reserved(&Alice, 69));
assert_eq!(free_balance(&Alice), 69);
assert_eq!(reserved_balance(&Alice), 0);
});
}
#[test]
fn transferring_reserved_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
reserve_balance(&Alice, 111);
assert!(transfer_reserved_balance(&Alice, &Bob, 42));
assert_eq!(reserved_balance(&Alice), 69);
assert_eq!(free_balance(&Alice), 0);
assert_eq!(reserved_balance(&Bob), 0);
assert_eq!(free_balance(&Bob), 42);
});
}
#[test]
fn transferring_incomplete_reserved_balance_should_work() {
with_externalities(&mut TestExternalities::default(), || {
set_free_balance(&Alice, 111);
reserve_balance(&Alice, 42);
assert!(!transfer_reserved_balance(&Alice, &Bob, 69));
assert_eq!(reserved_balance(&Alice), 0);
assert_eq!(free_balance(&Alice), 69);
assert_eq!(reserved_balance(&Bob), 0);
assert_eq!(free_balance(&Bob), 42);
});
}
}
......@@ -243,7 +243,7 @@ mod tests {
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{Joiner, KeyedVec, Slicable};
use keyring::Keyring;
use keyring::Keyring::*;
use environment::with_env;
use primitives::hexdisplay::HexDisplay;
use demo_primitives::{Header, Digest, UncheckedTransaction, Transaction, Function};
......@@ -251,26 +251,23 @@ mod tests {
#[test]
fn staking_balance_transfer_dispatch_works() {
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t: TestExternalities = map![
twox_128(&one.to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
twox_128(&One.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
];
let tx = UncheckedTransaction {
transaction: Transaction {
signed: one.clone(),
signed: One.into(),
nonce: 0,
function: Function::StakingTransfer(two, 69),
function: Function::StakingTransfer(Two.into(), 69),
},
signature: hex!("5f9832c5a4a39e2dd4a3a0c5b400e9836beb362cb8f7d845a8291a2ae6fe366612e080e4acd0b5a75c3d0b6ee69614a68fb63698c1e76bf1f2dcd8fa617ddf05").into(),
};
with_externalities(&mut t, || {
internal::execute_transaction(tx, Header::from_block_number(1));
assert_eq!(staking::balance(&one), 42);
assert_eq!(staking::balance(&two), 69);
assert_eq!(staking::balance(&One), 42);
assert_eq!(staking::balance(&Two), 69);
});
}
......@@ -280,15 +277,12 @@ mod tests {
#[test]
fn block_import_works() {
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = new_test_ext();
let h = Header {
parent_hash: [69u8; 32].into(),
number: 1,
state_root: hex!("52eb24906a4110a605d29d4e2f01b43cb169d375d709b138cc8ce50ad5f7ce85").into(),
state_root: hex!("f4f6408fe3ce1d78d30bb7ed625b32f91e45b8b566023df309cfd93c6f4af9a4").into(),
transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
digest: Digest { logs: vec![], },
};
......@@ -306,9 +300,6 @@ mod tests {
#[test]
#[should_panic]
fn block_import_of_bad_state_root_fails() {
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = new_test_ext();
let h = Header {
......@@ -332,9 +323,6 @@ mod tests {
#[test]
#[should_panic]
fn block_import_of_bad_transaction_root_fails() {
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = new_test_ext();
let h = Header {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment