mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 10:01:17 +00:00
Add Deposit and Withdraw Events to Balances Pallet (#9425)
* add Deposit and Withdraw events to balances + add deposit_event() calls where appropriate to signal fund movement + adjust and extend tests * line length * move events to the end to avoid changing indices * bump spec_version * cargo fmt * adjust block import bench to new event count * fix node executor tests * adjust import bench comment * fix typo and formatting * adjust event number * fix copy pasta * fix contracts pallets tests * cargo fmt * WIP fix events in tests * fix offences tests * fix tests * cargo +nightly fmt * fix contracts pallets tests * cargo +nightly fmt * fix offences tests * formatting and compile fixes Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
@@ -135,18 +135,20 @@ impl core::Benchmark for ImportBenchmark {
|
||||
.inspect_state(|| {
|
||||
match self.block_type {
|
||||
BlockType::RandomTransfersKeepAlive => {
|
||||
// should be 5 per signed extrinsic + 1 per unsigned
|
||||
// should be 7 per signed extrinsic + 1 per unsigned
|
||||
// we have 1 unsigned and the rest are signed in the block
|
||||
// those 5 events per signed are:
|
||||
// - new account (RawEvent::NewAccount) as we always transfer fund to
|
||||
// non-existant account
|
||||
// - endowed (RawEvent::Endowed) for this new account
|
||||
// - successful transfer (RawEvent::Transfer) for this transfer operation
|
||||
// - deposit event for charging transaction fee
|
||||
// those 7 events per signed are:
|
||||
// - withdraw (Balances::Withdraw) for charging the transaction fee
|
||||
// - new account (System::NewAccount) as we always transfer fund to
|
||||
// non-existent account
|
||||
// - endowed (Balances::Endowed) for this new account
|
||||
// - successful transfer (Event::Transfer) for this transfer operation
|
||||
// - 2x deposit (Balances::Deposit and Treasury::Deposit) for depositing
|
||||
// the transaction fee into the treasury
|
||||
// - extrinsic success
|
||||
assert_eq!(
|
||||
node_runtime::System::events().len(),
|
||||
(self.block.extrinsics.len() - 1) * 5 + 1,
|
||||
(self.block.extrinsics.len() - 1) * 7 + 1,
|
||||
);
|
||||
},
|
||||
BlockType::Noop => {
|
||||
|
||||
@@ -385,6 +385,11 @@ fn full_native_block_import_works() {
|
||||
})),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
event: Event::Balances(pallet_balances::Event::Withdraw(alice().into(), fees)),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
event: Event::Balances(pallet_balances::Event::Transfer(
|
||||
@@ -394,6 +399,14 @@ fn full_native_block_import_works() {
|
||||
)),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
event: Event::Balances(pallet_balances::Event::Deposit(
|
||||
pallet_treasury::Pallet::<Runtime>::account_id(),
|
||||
fees * 8 / 10,
|
||||
)),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
event: Event::Treasury(pallet_treasury::Event::Deposit(fees * 8 / 10)),
|
||||
@@ -439,6 +452,11 @@ fn full_native_block_import_works() {
|
||||
})),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
event: Event::Balances(pallet_balances::Event::Withdraw(bob().into(), fees)),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
event: Event::Balances(pallet_balances::Event::Transfer(
|
||||
@@ -448,6 +466,14 @@ fn full_native_block_import_works() {
|
||||
)),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
event: Event::Balances(pallet_balances::Event::Deposit(
|
||||
pallet_treasury::Pallet::<Runtime>::account_id(),
|
||||
fees * 8 / 10,
|
||||
)),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(1),
|
||||
event: Event::Treasury(pallet_treasury::Event::Deposit(fees * 8 / 10)),
|
||||
@@ -461,6 +487,11 @@ fn full_native_block_import_works() {
|
||||
})),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(2),
|
||||
event: Event::Balances(pallet_balances::Event::Withdraw(alice().into(), fees)),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(2),
|
||||
event: Event::Balances(pallet_balances::Event::Transfer(
|
||||
@@ -470,6 +501,14 @@ fn full_native_block_import_works() {
|
||||
)),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(2),
|
||||
event: Event::Balances(pallet_balances::Event::Deposit(
|
||||
pallet_treasury::Pallet::<Runtime>::account_id(),
|
||||
fees * 8 / 10,
|
||||
)),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(2),
|
||||
event: Event::Treasury(pallet_treasury::Event::Deposit(fees * 8 / 10)),
|
||||
|
||||
@@ -121,8 +121,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
// and set impl_version to 0. If only runtime
|
||||
// implementation changes and behavior does not, then leave spec_version as
|
||||
// is and increment impl_version.
|
||||
spec_version: 267,
|
||||
impl_version: 1,
|
||||
spec_version: 268,
|
||||
impl_version: 0,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
transaction_version: 2,
|
||||
};
|
||||
|
||||
@@ -463,8 +463,6 @@ pub mod pallet {
|
||||
Transfer(T::AccountId, T::AccountId, T::Balance),
|
||||
/// A balance was set by root. \[who, free, reserved\]
|
||||
BalanceSet(T::AccountId, T::Balance, T::Balance),
|
||||
/// Some amount was deposited (e.g. for transaction fees). \[who, deposit\]
|
||||
Deposit(T::AccountId, T::Balance),
|
||||
/// Some balance was reserved (moved from free to reserved). \[who, value\]
|
||||
Reserved(T::AccountId, T::Balance),
|
||||
/// Some balance was unreserved (moved from reserved to free). \[who, value\]
|
||||
@@ -473,6 +471,14 @@ pub mod pallet {
|
||||
/// Final argument indicates the destination balance type.
|
||||
/// \[from, to, balance, destination_status\]
|
||||
ReserveRepatriated(T::AccountId, T::AccountId, T::Balance, Status),
|
||||
/// Some amount was deposited into the account (e.g. for transaction fees). \[who,
|
||||
/// deposit\]
|
||||
Deposit(T::AccountId, T::Balance),
|
||||
/// Some amount was withdrawn from the account (e.g. for transaction fees). \[who, value\]
|
||||
Withdraw(T::AccountId, T::Balance),
|
||||
/// Some amount was removed from the account (e.g. for misbehavior). \[who,
|
||||
/// amount_slashed\]
|
||||
Slashed(T::AccountId, T::Balance),
|
||||
}
|
||||
|
||||
/// Old name generated by `decl_event`.
|
||||
@@ -1103,6 +1109,7 @@ impl<T: Config<I>, I: 'static> fungible::Mutate<T::AccountId> for Pallet<T, I> {
|
||||
Ok(())
|
||||
})?;
|
||||
TotalIssuance::<T, I>::mutate(|t| *t += amount);
|
||||
Self::deposit_event(Event::Deposit(who.clone(), amount));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1123,6 +1130,7 @@ impl<T: Config<I>, I: 'static> fungible::Mutate<T::AccountId> for Pallet<T, I> {
|
||||
},
|
||||
)?;
|
||||
TotalIssuance::<T, I>::mutate(|t| *t -= actual);
|
||||
Self::deposit_event(Event::Withdraw(who.clone(), amount));
|
||||
Ok(actual)
|
||||
}
|
||||
}
|
||||
@@ -1141,7 +1149,10 @@ impl<T: Config<I>, I: 'static> fungible::Transfer<T::AccountId> for Pallet<T, I>
|
||||
|
||||
impl<T: Config<I>, I: 'static> fungible::Unbalanced<T::AccountId> for Pallet<T, I> {
|
||||
fn set_balance(who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
|
||||
Self::mutate_account(who, |account| account.free = amount)?;
|
||||
Self::mutate_account(who, |account| {
|
||||
account.free = amount;
|
||||
Self::deposit_event(Event::BalanceSet(who.clone(), account.free, account.reserved));
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1583,7 +1594,13 @@ where
|
||||
}
|
||||
},
|
||||
) {
|
||||
Ok(r) => return r,
|
||||
Ok((imbalance, not_slashed)) => {
|
||||
Self::deposit_event(Event::Slashed(
|
||||
who.clone(),
|
||||
value.saturating_sub(not_slashed),
|
||||
));
|
||||
return (imbalance, not_slashed)
|
||||
},
|
||||
Err(_) => (),
|
||||
}
|
||||
}
|
||||
@@ -1608,6 +1625,7 @@ where
|
||||
|account, is_new| -> Result<Self::PositiveImbalance, DispatchError> {
|
||||
ensure!(!is_new, Error::<T, I>::DeadAccount);
|
||||
account.free = account.free.checked_add(&value).ok_or(ArithmeticError::Overflow)?;
|
||||
Self::deposit_event(Event::Deposit(who.clone(), value));
|
||||
Ok(PositiveImbalance::new(value))
|
||||
},
|
||||
)
|
||||
@@ -1640,6 +1658,7 @@ where
|
||||
None => return Ok(Self::PositiveImbalance::zero()),
|
||||
};
|
||||
|
||||
Self::deposit_event(Event::Deposit(who.clone(), value));
|
||||
Ok(PositiveImbalance::new(value))
|
||||
},
|
||||
)
|
||||
@@ -1677,6 +1696,7 @@ where
|
||||
|
||||
account.free = new_free_account;
|
||||
|
||||
Self::deposit_event(Event::Withdraw(who.clone(), value));
|
||||
Ok(NegativeImbalance::new(value))
|
||||
},
|
||||
)
|
||||
@@ -1709,6 +1729,7 @@ where
|
||||
SignedImbalance::Negative(NegativeImbalance::new(account.free - value))
|
||||
};
|
||||
account.free = value;
|
||||
Self::deposit_event(Event::BalanceSet(who.clone(), account.free, account.reserved));
|
||||
Ok(imbalance)
|
||||
},
|
||||
)
|
||||
@@ -1824,7 +1845,13 @@ where
|
||||
// underflow should never happen, but it if does, there's nothing to be done here.
|
||||
(NegativeImbalance::new(actual), value - actual)
|
||||
}) {
|
||||
Ok(r) => return r,
|
||||
Ok((imbalance, not_slashed)) => {
|
||||
Self::deposit_event(Event::Slashed(
|
||||
who.clone(),
|
||||
value.saturating_sub(not_slashed),
|
||||
));
|
||||
return (imbalance, not_slashed)
|
||||
},
|
||||
Err(_) => (),
|
||||
}
|
||||
}
|
||||
@@ -1965,6 +1992,7 @@ where
|
||||
// `actual <= to_change` and `to_change <= amount`; qed;
|
||||
reserves[index].amount -= actual;
|
||||
|
||||
Self::deposit_event(Event::Slashed(who.clone(), actual));
|
||||
(imb, value - actual)
|
||||
},
|
||||
Err(_) => (NegativeImbalance::zero(), value),
|
||||
|
||||
@@ -314,6 +314,7 @@ macro_rules! decl_tests {
|
||||
<$ext_builder>::default().monied(true).build().execute_with(|| {
|
||||
assert_eq!(Balances::total_balance(&1), 10);
|
||||
assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop));
|
||||
System::assert_last_event(Event::Balances(crate::Event::Deposit(1, 10)));
|
||||
assert_eq!(Balances::total_balance(&1), 20);
|
||||
assert_eq!(<TotalIssuance<$test>>::get(), 120);
|
||||
});
|
||||
@@ -341,6 +342,7 @@ macro_rules! decl_tests {
|
||||
fn balance_works() {
|
||||
<$ext_builder>::default().build().execute_with(|| {
|
||||
let _ = Balances::deposit_creating(&1, 42);
|
||||
System::assert_has_event(Event::Balances(crate::Event::Deposit(1, 42)));
|
||||
assert_eq!(Balances::free_balance(1), 42);
|
||||
assert_eq!(Balances::reserved_balance(1), 0);
|
||||
assert_eq!(Balances::total_balance(&1), 42);
|
||||
@@ -435,6 +437,19 @@ macro_rules! decl_tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn withdrawing_balance_should_work() {
|
||||
<$ext_builder>::default().build().execute_with(|| {
|
||||
let _ = Balances::deposit_creating(&2, 111);
|
||||
let _ = Balances::withdraw(
|
||||
&2, 11, WithdrawReasons::TRANSFER, ExistenceRequirement::KeepAlive
|
||||
);
|
||||
System::assert_last_event(Event::Balances(crate::Event::Withdraw(2, 11)));
|
||||
assert_eq!(Balances::free_balance(2), 100);
|
||||
assert_eq!(<TotalIssuance<$test>>::get(), 100);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slashing_incomplete_balance_should_work() {
|
||||
<$ext_builder>::default().build().execute_with(|| {
|
||||
@@ -749,6 +764,7 @@ macro_rules! decl_tests {
|
||||
[
|
||||
Event::System(system::Event::KilledAccount(1)),
|
||||
Event::Balances(crate::Event::DustLost(1, 99)),
|
||||
Event::Balances(crate::Event::Slashed(1, 1)),
|
||||
]
|
||||
);
|
||||
});
|
||||
@@ -777,7 +793,8 @@ macro_rules! decl_tests {
|
||||
assert_eq!(
|
||||
events(),
|
||||
[
|
||||
Event::System(system::Event::KilledAccount(1))
|
||||
Event::System(system::Event::KilledAccount(1)),
|
||||
Event::Balances(crate::Event::Slashed(1, 100)),
|
||||
]
|
||||
);
|
||||
});
|
||||
@@ -797,6 +814,7 @@ macro_rules! decl_tests {
|
||||
assert_eq!(Balances::slash(&1, 900), (NegativeImbalance::new(900), 0));
|
||||
// Account is still alive
|
||||
assert!(System::account_exists(&1));
|
||||
System::assert_last_event(Event::Balances(crate::Event::Slashed(1, 900)));
|
||||
|
||||
// SCENARIO: Slash will kill account because not enough balance left.
|
||||
assert_ok!(Balances::set_balance(Origin::root(), 1, 1_000, 0));
|
||||
|
||||
@@ -173,7 +173,7 @@ fn emit_events_with_no_existential_deposit_suicide_with_dust() {
|
||||
assert_eq!(res, (NegativeImbalance::new(98), 0));
|
||||
|
||||
// no events
|
||||
assert_eq!(events(), []);
|
||||
assert_eq!(events(), [Event::Balances(crate::Event::Slashed(1, 98))]);
|
||||
|
||||
let res = Balances::slash(&1, 1);
|
||||
assert_eq!(res, (NegativeImbalance::new(1), 0));
|
||||
@@ -183,6 +183,7 @@ fn emit_events_with_no_existential_deposit_suicide_with_dust() {
|
||||
[
|
||||
Event::System(system::Event::KilledAccount(1)),
|
||||
Event::Balances(crate::Event::DustLost(1, 1)),
|
||||
Event::Balances(crate::Event::Slashed(1, 1)),
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
@@ -167,11 +167,11 @@ fn transfer_dust_removal_tst1_should_work() {
|
||||
assert_eq!(Balances::free_balance(&1), 1050);
|
||||
|
||||
// Verify the events
|
||||
// Number of events expected is 8
|
||||
assert_eq!(System::events().len(), 11);
|
||||
assert_eq!(System::events().len(), 12);
|
||||
|
||||
System::assert_has_event(Event::Balances(crate::Event::Transfer(2, 3, 450)));
|
||||
System::assert_has_event(Event::Balances(crate::Event::DustLost(2, 50)));
|
||||
System::assert_has_event(Event::Balances(crate::Event::Deposit(1, 50)));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -195,11 +195,11 @@ fn transfer_dust_removal_tst2_should_work() {
|
||||
assert_eq!(Balances::free_balance(&1), 1500);
|
||||
|
||||
// Verify the events
|
||||
// Number of events expected is 8
|
||||
assert_eq!(System::events().len(), 9);
|
||||
assert_eq!(System::events().len(), 10);
|
||||
|
||||
System::assert_has_event(Event::Balances(crate::Event::Transfer(2, 1, 450)));
|
||||
System::assert_has_event(Event::Balances(crate::Event::DustLost(2, 50)));
|
||||
System::assert_has_event(Event::Balances(crate::Event::Deposit(1, 50)));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -232,8 +232,7 @@ fn repatriating_reserved_balance_dust_removal_should_work() {
|
||||
assert_eq!(Balances::free_balance(1), 1500);
|
||||
|
||||
// Verify the events
|
||||
// Number of events expected is 10
|
||||
assert_eq!(System::events().len(), 10);
|
||||
assert_eq!(System::events().len(), 11);
|
||||
|
||||
System::assert_has_event(Event::Balances(crate::Event::ReserveRepatriated(
|
||||
2,
|
||||
@@ -241,7 +240,7 @@ fn repatriating_reserved_balance_dust_removal_should_work() {
|
||||
450,
|
||||
Status::Free,
|
||||
)));
|
||||
|
||||
System::assert_last_event(Event::Balances(crate::Event::DustLost(2, 50)));
|
||||
System::assert_has_event(Event::Balances(crate::Event::DustLost(2, 50)));
|
||||
System::assert_last_event(Event::Balances(crate::Event::Deposit(1, 50)));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -444,6 +444,11 @@ fn instantiate_and_call_and_deposit_event() {
|
||||
assert_eq!(
|
||||
System::events(),
|
||||
vec![
|
||||
EventRecord {
|
||||
phase: Phase::Initialization,
|
||||
event: Event::Balances(pallet_balances::Event::Deposit(ALICE, 1_000_000)),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::Initialization,
|
||||
event: Event::System(frame_system::Event::NewAccount(ALICE.clone())),
|
||||
|
||||
@@ -224,27 +224,49 @@ fn check_events<T: Config, I: Iterator<Item = <T as SystemConfig>::Event>>(expec
|
||||
.map(|frame_system::EventRecord { event, .. }| event)
|
||||
.collect::<Vec<_>>();
|
||||
let expected = expected.collect::<Vec<_>>();
|
||||
let lengths = (events.len(), expected.len());
|
||||
let length_mismatch = if lengths.0 != lengths.1 {
|
||||
fn pretty<D: std::fmt::Debug>(header: &str, ev: &[D]) {
|
||||
println!("{}", header);
|
||||
for (idx, ev) in ev.iter().enumerate() {
|
||||
println!("\t[{:04}] {:?}", idx, ev);
|
||||
}
|
||||
|
||||
fn pretty<D: std::fmt::Debug>(header: &str, ev: &[D], offset: usize) {
|
||||
println!("{}", header);
|
||||
for (idx, ev) in ev.iter().enumerate() {
|
||||
println!("\t[{:04}] {:?}", idx + offset, ev);
|
||||
}
|
||||
pretty("--Got:", &events);
|
||||
pretty("--Expected:", &expected);
|
||||
format!("Mismatching length. Got: {}, expected: {}", lengths.0, lengths.1)
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
}
|
||||
fn print_events<D: std::fmt::Debug>(idx: usize, events: &[D], expected: &[D]) {
|
||||
let window = 10;
|
||||
let start = idx.saturating_sub(window / 2);
|
||||
let end_got = (idx + window / 2).min(events.len());
|
||||
pretty("Got(window):", &events[start..end_got], start);
|
||||
let end_expected = (idx + window / 2).min(expected.len());
|
||||
pretty("Expected(window):", &expected[start..end_expected], start);
|
||||
println!("---------------");
|
||||
let start_got = events.len().saturating_sub(window);
|
||||
pretty("Got(end):", &events[start_got..], start_got);
|
||||
let start_expected = expected.len().saturating_sub(window);
|
||||
pretty("Expected(end):", &expected[start_expected..], start_expected);
|
||||
}
|
||||
let events_copy = events.clone();
|
||||
let expected_copy = expected.clone();
|
||||
|
||||
for (idx, (a, b)) in events.into_iter().zip(expected).enumerate() {
|
||||
assert_eq!(a, b, "Mismatch at: {}. {}", idx, length_mismatch);
|
||||
if a != b {
|
||||
print_events(idx, &events_copy, &expected_copy);
|
||||
println!("Mismatch at: {}", idx);
|
||||
println!(" Got: {:?}", b);
|
||||
println!("Expected: {:?}", a);
|
||||
if events_copy.len() != expected_copy.len() {
|
||||
println!(
|
||||
"Mismatching lengths. Got: {}, Expected: {}",
|
||||
events_copy.len(),
|
||||
expected_copy.len()
|
||||
)
|
||||
}
|
||||
panic!("Mismatching events.");
|
||||
}
|
||||
}
|
||||
|
||||
if !length_mismatch.is_empty() {
|
||||
panic!("{}", length_mismatch);
|
||||
if events_copy.len() != expected_copy.len() {
|
||||
print_events(0, &events_copy, &expected_copy);
|
||||
panic!("Mismatching lengths. Got: {}, Expected: {}", events_copy.len(), expected_copy.len())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,46 +310,74 @@ benchmarks! {
|
||||
let bond_amount: u32 = UniqueSaturatedInto::<u32>::unique_saturated_into(bond_amount::<T>());
|
||||
let slash_amount = slash_fraction * bond_amount;
|
||||
let reward_amount = slash_amount * (1 + n) / 2;
|
||||
let reward = reward_amount / r;
|
||||
let slash = |id| core::iter::once(
|
||||
<T as StakingConfig>::Event::from(StakingEvent::<T>::Slashed(id, BalanceOf::<T>::from(slash_amount)))
|
||||
);
|
||||
let balance_slash = |id| core::iter::once(
|
||||
<T as BalancesConfig>::Event::from(pallet_balances::Event::<T>::Slashed(id, slash_amount.into()))
|
||||
);
|
||||
let chill = |id| core::iter::once(
|
||||
<T as StakingConfig>::Event::from(StakingEvent::<T>::Chilled(id))
|
||||
);
|
||||
let mut slash_events = raw_offenders.into_iter()
|
||||
let balance_deposit = |id, amount: u32|
|
||||
<T as BalancesConfig>::Event::from(pallet_balances::Event::<T>::Deposit(id, amount.into()));
|
||||
let mut first = true;
|
||||
let slash_events = raw_offenders.into_iter()
|
||||
.flat_map(|offender| {
|
||||
let nom_slashes = offender.nominator_stashes.into_iter().flat_map(|nom| slash(nom));
|
||||
chill(offender.stash.clone())
|
||||
.chain(slash(offender.stash))
|
||||
.chain(nom_slashes)
|
||||
let nom_slashes = offender.nominator_stashes.into_iter().flat_map(|nom| {
|
||||
balance_slash(nom.clone()).map(Into::into)
|
||||
.chain(slash(nom.clone()).map(Into::into))
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
let mut events = chill(offender.stash.clone()).map(Into::into)
|
||||
.chain(balance_slash(offender.stash.clone()).map(Into::into))
|
||||
.chain(slash(offender.stash.clone()).map(Into::into))
|
||||
.chain(nom_slashes.into_iter())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// the first deposit creates endowed events, see `endowed_reward_events`
|
||||
if first {
|
||||
first = false;
|
||||
let mut reward_events = reporters.clone().into_iter()
|
||||
.flat_map(|reporter| vec![
|
||||
balance_deposit(reporter.clone(), reward.into()).into(),
|
||||
frame_system::Event::<T>::NewAccount(reporter.clone()).into(),
|
||||
<T as BalancesConfig>::Event::from(
|
||||
pallet_balances::Event::<T>::Endowed(reporter.clone(), reward.into())
|
||||
).into(),
|
||||
])
|
||||
.collect::<Vec<_>>();
|
||||
events.append(&mut reward_events);
|
||||
events.into_iter()
|
||||
} else {
|
||||
let mut reward_events = reporters.clone().into_iter()
|
||||
.map(|reporter| balance_deposit(reporter, reward.into()).into())
|
||||
.collect::<Vec<_>>();
|
||||
events.append(&mut reward_events);
|
||||
events.into_iter()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let reward_events = reporters.into_iter()
|
||||
.flat_map(|reporter| vec![
|
||||
frame_system::Event::<T>::NewAccount(reporter.clone()).into(),
|
||||
<T as BalancesConfig>::Event::from(
|
||||
pallet_balances::Event::<T>::Endowed(reporter, (reward_amount / r).into())
|
||||
).into()
|
||||
]);
|
||||
|
||||
// Rewards are applied after first offender and it's nominators.
|
||||
// We split after: offender slash + offender chill + nominator slashes.
|
||||
let slash_rest = slash_events.split_off(2 + n as usize);
|
||||
|
||||
// make sure that all slashes have been applied
|
||||
|
||||
#[cfg(test)]
|
||||
check_events::<T, _>(
|
||||
std::iter::empty()
|
||||
.chain(slash_events.into_iter().map(Into::into))
|
||||
.chain(reward_events)
|
||||
.chain(slash_rest.into_iter().map(Into::into))
|
||||
.chain(std::iter::once(<T as OffencesConfig>::Event::from(
|
||||
pallet_offences::Event::Offence(
|
||||
UnresponsivenessOffence::<T>::ID,
|
||||
0_u32.to_le_bytes().to_vec(),
|
||||
)
|
||||
).into()))
|
||||
);
|
||||
{
|
||||
// In case of error it's useful to see the inputs
|
||||
println!("Inputs: r: {}, o: {}, n: {}", r, o, n);
|
||||
// make sure that all slashes have been applied
|
||||
check_events::<T, _>(
|
||||
std::iter::empty()
|
||||
.chain(slash_events.into_iter().map(Into::into))
|
||||
.chain(std::iter::once(<T as OffencesConfig>::Event::from(
|
||||
pallet_offences::Event::Offence(
|
||||
UnresponsivenessOffence::<T>::ID,
|
||||
0_u32.to_le_bytes().to_vec(),
|
||||
)
|
||||
).into()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
report_offence_grandpa {
|
||||
@@ -358,10 +408,10 @@ benchmarks! {
|
||||
assert_eq!(
|
||||
System::<T>::event_count(), 0
|
||||
+ 1 // offence
|
||||
+ 2 // reporter (reward + endowment)
|
||||
+ 1 // offenders slashed
|
||||
+ 3 // reporter (reward + endowment)
|
||||
+ 2 // offenders slashed
|
||||
+ 1 // offenders chilled
|
||||
+ n // nominators slashed
|
||||
+ 2 * n // nominators slashed
|
||||
);
|
||||
}
|
||||
|
||||
@@ -393,10 +443,10 @@ benchmarks! {
|
||||
assert_eq!(
|
||||
System::<T>::event_count(), 0
|
||||
+ 1 // offence
|
||||
+ 2 // reporter (reward + endowment)
|
||||
+ 1 // offenders slashed
|
||||
+ 3 // reporter (reward + endowment)
|
||||
+ 2 // offenders slashed
|
||||
+ 1 // offenders chilled
|
||||
+ n // nominators slashed
|
||||
+ 2 * n // nominators slashed
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user