Skip to content

Commit

Permalink
Merge pull request #81 from AurevoirXavier/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
hackfisher authored Oct 12, 2019
2 parents 22e5565 + a2a5d22 commit 7eb971c
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 112 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ test-client
.DS_Store

# For cross compile
osxcross
darwin-x86_64
darwin-x86_64.tar.gz
linux-x86_64
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ cargo install --git https://github.com/alexcrichton/wasm-gc

### Build

Building with darwinia builder:
Building with darwinia-builder:
```bash
darwinia-builder --release --wasm
```
Expand Down
9 changes: 4 additions & 5 deletions srml/kton/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,7 @@ impl<T: Trait> Currency<T::AccountId> for Module<T> {

// TODO: add fee
fn transfer(transactor: &T::AccountId, dest: &T::AccountId, value: Self::Balance) -> Result {
let from_balance = Self::free_balance(transactor);
let to_balance = Self::free_balance(dest);

let new_from_balance = match from_balance.checked_sub(&value) {
let new_from_balance = match Self::free_balance(transactor).checked_sub(&value) {
None => return Err("balance too low to send value"),
Some(b) => b,
};
Expand All @@ -238,7 +235,7 @@ impl<T: Trait> Currency<T::AccountId> for Module<T> {

// NOTE: total stake being stored in the same type means that this could never overflow
// but better to be safe than sorry.
let new_to_balance = match to_balance.checked_add(&value) {
let new_to_balance = match Self::free_balance(dest).checked_add(&value) {
Some(b) => b,
None => return Err("destination balance too high to receive value"),
};
Expand Down Expand Up @@ -375,6 +372,7 @@ where
{
type Moment = T::BlockNumber;

// `amount` > `free_balance` is allowed
fn set_lock(
id: LockIdentifier,
who: &T::AccountId,
Expand Down Expand Up @@ -447,6 +445,7 @@ where
fn remove_lock(id: LockIdentifier, who: &T::AccountId) {
let now = <system::Module<T>>::block_number();
<Locks<T>>::mutate(who, |locks| {
// unexpired and mismatched id -> keep
locks.retain(|lock| (lock.until > now) && (lock.id != id));
});
}
Expand Down
4 changes: 2 additions & 2 deletions srml/kton/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use srml_support::impl_outer_origin;
use std::{cell::RefCell, collections::HashSet};
use substrate_primitives::{Blake2Hasher, H256};

const COIN: u64 = 1_000_000_000;
pub const COIN: u64 = 1_000_000_000;

thread_local! {
static SESSION: RefCell<(Vec<AccountId>, HashSet<AccountId>)> = RefCell::new(Default::default());
Expand Down Expand Up @@ -116,7 +116,7 @@ impl ExtBuilder {
(100, 2000 * balance_factor),
(101, 2000 * balance_factor),
],
vesting: vec![],
vesting: vec![(1, 0, 4)],
}
.assimilate_storage(&mut t, &mut c);
t.into()
Expand Down
227 changes: 160 additions & 67 deletions srml/kton/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use mock::{ExtBuilder, Kton, Origin, System};
use mock::{ExtBuilder, Kton, Origin, System, Test};
use runtime_io::with_externalities;
use srml_support::traits::{Currency, LockIdentifier, WithdrawReason, WithdrawReasons};
use srml_support::{assert_err, assert_noop, assert_ok};
Expand All @@ -11,55 +11,138 @@ const ID_3: LockIdentifier = *b"3 ";
#[test]
fn transfer_should_work() {
with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || {
//
Kton::deposit_creating(&1001, 100);
assert_err!(
Kton::transfer(Origin::signed(1001), 1000, 500),
"balance too low to send value"
);
assert_eq!(Kton::free_balance(&1000), 0);
let _ = Kton::deposit_creating(&666, 100);

assert_ok!(Kton::transfer(Origin::signed(666), 777, 50));
assert_eq!(Kton::total_balance(&666), 50);
assert_eq!(Kton::total_balance(&777), 50);

assert_ok!(Kton::transfer(Origin::signed(666), 777, 50));
assert_eq!(Kton::total_balance(&666), 0);
assert_eq!(Kton::total_balance(&777), 100);

assert_ok!(Kton::transfer(Origin::signed(666), 777, 0));
});
}

#[test]
fn lock_should_work() {
fn transfer_should_fail() {
with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || {
Kton::deposit_creating(&1001, 100);
Kton::set_lock(ID_1, &1001, 90, u64::max_value(), WithdrawReasons::all());
let _ = Kton::deposit_creating(&777, 1);
assert_err!(
Kton::transfer(Origin::signed(666), 777, 50),
"balance too low to send value"
);

let _ = Kton::deposit_creating(&666, u64::max_value());
assert_err!(
Kton::transfer(Origin::signed(777), 666, 1),
"destination balance too high to receive value"
);

assert_err!(
Kton::transfer(Origin::signed(1), 777, Kton::vesting_balance(&1)),
"vesting balance too high to send value"
);

Kton::set_lock(ID_1, &777, 1, u64::max_value(), WithdrawReasons::all());
assert_err!(
Kton::transfer(Origin::signed(1001), 1000, 20),
Kton::transfer(Origin::signed(777), 1, 1),
"account liquidity restrictions prevent withdrawal"
);
});
}

#[test]
fn lock_removal_should_work() {
fn set_lock_should_work() {
with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || {
Kton::deposit_creating(&1001, 10);
Kton::set_lock(ID_1, &1001, u64::max_value(), u64::max_value(), WithdrawReasons::all());
Kton::remove_lock(ID_1, &1001);
assert_ok!(<Kton as Currency<_>>::transfer(&1001, &1002, 1));
let lock_ids = [[0; 8], [1; 8], [2; 8], [3; 8]];
let balance_per_lock = Kton::free_balance(&1) / (lock_ids.len() as u64);

// account `1`'s vesting length
System::set_block_number(4);

{
let mut locks = vec![];
for lock_id in lock_ids.iter() {
Kton::set_lock(*lock_id, &1, balance_per_lock, u64::max_value(), WithdrawReasons::all());
locks.push(BalanceLock {
id: *lock_id,
amount: balance_per_lock,
until: u64::max_value(),
reasons: WithdrawReasons::all(),
});
assert_eq!(Kton::locks(&1), locks);
}
}

for _ in 0..lock_ids.len() - 1 {
assert_ok!(Kton::transfer(Origin::signed(1), 2, balance_per_lock));
}
assert_err!(
Kton::transfer(Origin::signed(1), 2, balance_per_lock),
"account liquidity restrictions prevent withdrawal"
);
});
}

#[test]
fn lock_replacement_should_work() {
fn remove_lock_should_work() {
with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || {
Kton::deposit_creating(&1001, 10);
Kton::set_lock(ID_1, &1001, u64::max_value(), u64::max_value(), WithdrawReasons::all());
Kton::set_lock(ID_1, &1001, 5, u64::max_value(), WithdrawReasons::all());
assert_ok!(<Kton as Currency<_>>::transfer(&1001, &1002, 1));
Kton::set_lock(ID_1, &2, u64::max_value(), u64::max_value(), WithdrawReasons::all());
Kton::set_lock(
ID_2,
&2,
u64::max_value(),
<system::Module<Test>>::block_number() + 1,
WithdrawReasons::all(),
);
// expired
Kton::set_lock(
ID_3,
&2,
u64::max_value(),
<system::Module<Test>>::block_number(),
WithdrawReasons::all(),
);

Kton::remove_lock(ID_1, &2);
assert_err!(
Kton::transfer(Origin::signed(2), 1, 1),
"account liquidity restrictions prevent withdrawal"
);

Kton::remove_lock(ID_2, &2);
assert_ok!(Kton::transfer(Origin::signed(2), 1, 1));
});
}

#[test]
fn double_locking_should_work() {
fn update_lock_should_work() {
with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || {
Kton::deposit_creating(&1001, 10);
Kton::set_lock(ID_1, &1001, 5, u64::max_value(), WithdrawReasons::all());
Kton::set_lock(ID_2, &1001, 5, u64::max_value(), WithdrawReasons::all());
assert_ok!(<Kton as Currency<_>>::transfer(&1001, &1002, 1));
let mut locks = vec![];
for id in 0..10 {
// until > 1
locks.push(BalanceLock {
id: [id; 8],
amount: 1,
until: 2,
reasons: WithdrawReasons::none(),
});
Kton::set_lock([id; 8], &1, 1, 2, WithdrawReasons::none());
}
let update_id = 4;
for amount in 32767..65535 {
let until = amount + 1;
locks[update_id as usize] = BalanceLock {
id: [update_id; 8],
amount,
until,
reasons: WithdrawReasons::all(),
};
Kton::set_lock([update_id; 8], &1, amount, until, WithdrawReasons::all());
assert_eq!(Kton::locks(&1), locks);
}
});
}

Expand All @@ -75,24 +158,57 @@ fn combination_locking_should_work() {
}

#[test]
fn lock_value_extension_should_work() {
fn extend_lock_should_work() {
with_externalities(&mut ExtBuilder::default().existential_deposit(0).build(), || {
Kton::deposit_creating(&1001, 10);
Kton::set_lock(ID_1, &1001, 5, u64::max_value(), WithdrawReasons::all());
assert_noop!(
<Kton as Currency<_>>::transfer(&1001, &1002, 6),
"account liquidity restrictions prevent withdrawal"
);
Kton::extend_lock(ID_1, &1001, 2, u64::max_value(), WithdrawReasons::all());
assert_noop!(
<Kton as Currency<_>>::transfer(&1001, &1002, 6),
"account liquidity restrictions prevent withdrawal"
);
Kton::extend_lock(ID_1, &1001, 8, u64::max_value(), WithdrawReasons::all());
assert_noop!(
<Kton as Currency<_>>::transfer(&1001, &1002, 3),
"account liquidity restrictions prevent withdrawal"
);
let mut locks = vec![];
{
let amount = 1;
let until = 2;
let reasons = WithdrawReasons::none();
for will_be_extended_id in 0..5 {
locks.push(BalanceLock {
id: [will_be_extended_id; 8],
amount,
until,
reasons,
});
Kton::set_lock([will_be_extended_id; 8], &1, amount, until, reasons);
}
}
{
let amount = 100;
let until = 100;
let reasons = WithdrawReasons::all();
for will_not_be_extended_id in 5..10 {
locks.push(BalanceLock {
id: [will_not_be_extended_id; 8],
amount,
until,
reasons,
});
Kton::set_lock([will_not_be_extended_id; 8], &1, amount, until, reasons);
}
}
{
let new_amount = 50;
let new_until = 50;
let new_reasons = WithdrawReason::Transfer.into();
for lock in locks.iter_mut() {
let BalanceLock {
id,
amount,
until,
reasons,
} = lock;
if *amount < new_amount {
*amount = new_amount;
*until = new_until;
*reasons = new_reasons;
}
Kton::extend_lock(*id, &1, new_amount, new_until, new_reasons);
}
assert_eq!(Kton::locks(&1), locks);
}
});
}

Expand Down Expand Up @@ -155,26 +271,3 @@ fn lock_reasons_extension_should_work() {
);
});
}

#[test]
fn balance_works() {
with_externalities(&mut ExtBuilder::default().build(), || {
let _ = Kton::deposit_creating(&1001, 100);
assert_eq!(Kton::free_balance(&1001), 100);
assert_eq!(Kton::reserved_balance(&1001), 0);
assert_eq!(Kton::total_balance(&1001), 100);
assert_eq!(Kton::free_balance(&1002), 0);
assert_eq!(Kton::reserved_balance(&1002), 0);
assert_eq!(Kton::total_balance(&1002), 0);
});
}

#[test]
fn balance_transfer_works() {
with_externalities(&mut ExtBuilder::default().build(), || {
let _ = Kton::deposit_creating(&1001, 111);
assert_ok!(Kton::transfer(Some(1001).into(), 1002, 69));
assert_eq!(Kton::total_balance(&1001), 42);
assert_eq!(Kton::total_balance(&1002), 69);
});
}
19 changes: 9 additions & 10 deletions srml/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -921,21 +921,20 @@ impl<T: Trait> Module<T> {
let mut ledger = Self::ledger(&controller).unwrap();

// slash ring
let ring_imbalance = if ledger.total_ring.is_zero() {
<RingNegativeImbalanceOf<T>>::zero()
} else {
let (ring_imbalance, _) = if !ledger.total_ring.is_zero() {
let slashable_ring = slash_ratio * ledger.total_ring;
let value_slashed = Self::slash_helper(&controller, &mut ledger, StakingBalance::Ring(slashable_ring));

T::Ring::slash(stash, value_slashed.0).0
};
let kton_imbalance = if ledger.total_kton.is_zero() {
<KtonNegativeImbalanceOf<T>>::zero()
T::Ring::slash(stash, value_slashed.0)
} else {
(<RingNegativeImbalanceOf<T>>::zero(), Zero::zero())
};

let (kton_imbalance, _) = if !ledger.total_kton.is_zero() {
let slashable_kton = slash_ratio * ledger.total_kton;
let value_slashed = Self::slash_helper(&controller, &mut ledger, StakingBalance::Kton(slashable_kton));

T::Kton::slash(stash, value_slashed.1).0
T::Kton::slash(stash, value_slashed.1)
} else {
(<KtonNegativeImbalanceOf<T>>::zero(), Zero::zero())
};

(ring_imbalance, kton_imbalance)
Expand Down
Loading

0 comments on commit 7eb971c

Please sign in to comment.