Compare commits
5 Commits
e73f3855fd
...
1196cc9faa
Author | SHA1 | Date | |
---|---|---|---|
1196cc9faa | |||
66fa8409fa | |||
5beb22f116 | |||
7be24ed139 | |||
b5fc86aa9e |
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -1186,7 +1186,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "casper-runtime"
|
name = "casper-runtime"
|
||||||
version = "3.5.20"
|
version = "3.5.21"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"casper-runtime-constants",
|
"casper-runtime-constants",
|
||||||
"frame-benchmarking",
|
"frame-benchmarking",
|
||||||
@ -3648,7 +3648,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-networks"
|
name = "ghost-networks"
|
||||||
version = "0.1.5"
|
version = "0.1.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"frame-benchmarking",
|
"frame-benchmarking",
|
||||||
"frame-support",
|
"frame-support",
|
||||||
@ -3834,7 +3834,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-slow-clap"
|
name = "ghost-slow-clap"
|
||||||
version = "0.3.23"
|
version = "0.3.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"frame-benchmarking",
|
"frame-benchmarking",
|
||||||
"frame-support",
|
"frame-support",
|
||||||
@ -3870,7 +3870,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-traits"
|
name = "ghost-traits"
|
||||||
version = "0.3.21"
|
version = "0.3.22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"frame-support",
|
"frame-support",
|
||||||
"sp-runtime 31.0.1",
|
"sp-runtime 31.0.1",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-networks"
|
name = "ghost-networks"
|
||||||
version = "0.1.5"
|
version = "0.1.6"
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
@ -631,17 +631,7 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
|
|||||||
fn increase_gatekeeper_amount(
|
fn increase_gatekeeper_amount(
|
||||||
network_id: &T::NetworkId,
|
network_id: &T::NetworkId,
|
||||||
amount: &BalanceOf<T>,
|
amount: &BalanceOf<T>,
|
||||||
) -> Result<(BalanceOf<T>, BalanceOf<T>), ()> {
|
) -> Result<BalanceOf<T>, ()> {
|
||||||
let new_bridged_in_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
|
|
||||||
match bridged_imbalance.bridged_in.checked_add(amount) {
|
|
||||||
Some(value) => {
|
|
||||||
(*bridged_imbalance).bridged_in = value;
|
|
||||||
Ok(value)
|
|
||||||
},
|
|
||||||
None => Err(())
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
|
let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
|
||||||
match gatekeeper_amount.checked_add(amount) {
|
match gatekeeper_amount.checked_add(amount) {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
@ -652,13 +642,13 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
|
|||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok((new_gatekeeper_amount, new_bridged_in_amount))
|
Ok(new_gatekeeper_amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrease_gatekeeper_amount(
|
fn decrease_gatekeeper_amount(
|
||||||
network_id: &T::NetworkId,
|
network_id: &T::NetworkId,
|
||||||
amount: &BalanceOf<T>,
|
amount: &BalanceOf<T>,
|
||||||
) -> Result<(BalanceOf<T>, BalanceOf<T>), ()> {
|
) -> Result<BalanceOf<T>, ()> {
|
||||||
let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
|
let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
|
||||||
match gatekeeper_amount.checked_sub(amount) {
|
match gatekeeper_amount.checked_sub(amount) {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
@ -669,6 +659,10 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
|
|||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
Ok(new_gatekeeper_amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn accumulate_outgoing_imbalance(amount: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
|
||||||
let new_bridged_out_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
|
let new_bridged_out_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
|
||||||
match bridged_imbalance.bridged_out.checked_add(amount) {
|
match bridged_imbalance.bridged_out.checked_add(amount) {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
@ -679,7 +673,21 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
|
|||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok((new_gatekeeper_amount, new_bridged_out_amount))
|
Ok(new_bridged_out_amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn accumulate_incoming_imbalance(amount: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
|
||||||
|
let new_bridged_in_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
|
||||||
|
match bridged_imbalance.bridged_in.checked_add(amount) {
|
||||||
|
Some(value) => {
|
||||||
|
(*bridged_imbalance).bridged_in = value;
|
||||||
|
Ok(value)
|
||||||
|
},
|
||||||
|
None => Err(())
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(new_bridged_in_amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accumulate_commission(commission: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
|
fn accumulate_commission(commission: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
|
||||||
|
@ -656,8 +656,6 @@ fn gatekeeper_amount_changes_correctly() {
|
|||||||
let result = amount_in - 3 * amount_out;
|
let result = amount_in - 3 * amount_out;
|
||||||
|
|
||||||
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), 0);
|
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), 0);
|
||||||
assert_eq!(BridgedImbalance::<Test>::get(),
|
|
||||||
BridgeAdjustment::default());
|
|
||||||
|
|
||||||
assert_ok!(GhostNetworks::increase_gatekeeper_amount(&chain_id, &amount_in));
|
assert_ok!(GhostNetworks::increase_gatekeeper_amount(&chain_id, &amount_in));
|
||||||
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(&chain_id, &amount_out));
|
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(&chain_id, &amount_out));
|
||||||
@ -665,9 +663,26 @@ fn gatekeeper_amount_changes_correctly() {
|
|||||||
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(&chain_id, &amount_out));
|
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(&chain_id, &amount_out));
|
||||||
|
|
||||||
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), result);
|
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), result);
|
||||||
assert_eq!(BridgedImbalance::<Test>::get(), BridgeAdjustment {
|
});
|
||||||
bridged_out: 3 * amount_out,
|
}
|
||||||
bridged_in: amount_in });
|
|
||||||
|
#[test]
|
||||||
|
fn bridged_imbalance_accumulated_correctly() {
|
||||||
|
ExtBuilder::build()
|
||||||
|
.execute_with(|| {
|
||||||
|
let amount_in: u128 = 420;
|
||||||
|
let amount_out: u128 = 69;
|
||||||
|
|
||||||
|
let imbalance_before = BridgedImbalance::<Test>::get();
|
||||||
|
assert_eq!(imbalance_before.bridged_in, 0);
|
||||||
|
assert_eq!(imbalance_before.bridged_out, 0);
|
||||||
|
|
||||||
|
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount_in));
|
||||||
|
assert_ok!(GhostNetworks::accumulate_outgoing_imbalance(&amount_out));
|
||||||
|
|
||||||
|
let imbalance_after = BridgedImbalance::<Test>::get();
|
||||||
|
assert_eq!(imbalance_after.bridged_in, amount_in);
|
||||||
|
assert_eq!(imbalance_after.bridged_out, amount_out);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,7 +723,7 @@ fn gatekeeper_amount_overflow_and_underflow_emits_error() {
|
|||||||
assert_ok!(GhostNetworks::increase_gatekeeper_amount(
|
assert_ok!(GhostNetworks::increase_gatekeeper_amount(
|
||||||
&chain_id,
|
&chain_id,
|
||||||
&commission,
|
&commission,
|
||||||
), (commission, commission));
|
), commission);
|
||||||
assert_err!(GhostNetworks::increase_gatekeeper_amount(
|
assert_err!(GhostNetworks::increase_gatekeeper_amount(
|
||||||
&chain_id,
|
&chain_id,
|
||||||
&commission,
|
&commission,
|
||||||
@ -717,16 +732,33 @@ fn gatekeeper_amount_overflow_and_underflow_emits_error() {
|
|||||||
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(
|
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(
|
||||||
&chain_id,
|
&chain_id,
|
||||||
&commission,
|
&commission,
|
||||||
), (0, commission));
|
), 0);
|
||||||
assert_err!(GhostNetworks::decrease_gatekeeper_amount(
|
assert_err!(GhostNetworks::decrease_gatekeeper_amount(
|
||||||
&chain_id,
|
&chain_id,
|
||||||
&commission,
|
&commission,
|
||||||
), ());
|
), ());
|
||||||
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), 0);
|
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), 0);
|
||||||
assert_eq!(BridgedImbalance::<Test>::get(), BridgeAdjustment {
|
|
||||||
bridged_out: commission,
|
|
||||||
bridged_in: commission,
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bridged_imbalance_overflow_emits_error() {
|
||||||
|
ExtBuilder::build()
|
||||||
|
.execute_with(|| {
|
||||||
|
let chain_id: u32 = 1;
|
||||||
|
let amount: u128 = u128::MAX - 69;
|
||||||
|
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), 0);
|
||||||
|
assert_ok!(GhostNetworks::accumulate_outgoing_imbalance(&amount), amount);
|
||||||
|
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount), amount);
|
||||||
|
|
||||||
|
assert_err!(GhostNetworks::accumulate_outgoing_imbalance(&amount), ());
|
||||||
|
assert_err!(GhostNetworks::accumulate_incoming_imbalance(&amount), ());
|
||||||
|
assert_err!(GhostNetworks::accumulate_outgoing_imbalance(&u128::MAX), ());
|
||||||
|
assert_err!(GhostNetworks::accumulate_incoming_imbalance(&u128::MAX), ());
|
||||||
|
|
||||||
|
let bridged_imbalance = BridgedImbalance::<Test>::get();
|
||||||
|
assert_eq!(bridged_imbalance.bridged_out, amount);
|
||||||
|
assert_eq!(bridged_imbalance.bridged_in, amount);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,18 +769,16 @@ fn bridged_amount_overflow_and_underflow_emits_error() {
|
|||||||
let chain_id_first: u32 = 1;
|
let chain_id_first: u32 = 1;
|
||||||
let chain_id_second: u32 = 2;
|
let chain_id_second: u32 = 2;
|
||||||
let commission: u128 = u128::MAX - 69;
|
let commission: u128 = u128::MAX - 69;
|
||||||
assert_eq!(BridgedImbalance::<Test>::get(), BridgeAdjustment {
|
|
||||||
bridged_out: 0,
|
|
||||||
bridged_in: 0,
|
|
||||||
});
|
|
||||||
assert_ok!(GhostNetworks::increase_gatekeeper_amount(
|
assert_ok!(GhostNetworks::increase_gatekeeper_amount(
|
||||||
&chain_id_first,
|
&chain_id_first,
|
||||||
&commission,
|
&commission,
|
||||||
), (commission, commission));
|
), commission);
|
||||||
assert_err!(GhostNetworks::increase_gatekeeper_amount(
|
assert_ok!(GhostNetworks::increase_gatekeeper_amount(
|
||||||
&chain_id_second,
|
&chain_id_second,
|
||||||
&commission,
|
&commission,
|
||||||
), ());
|
), commission);
|
||||||
|
|
||||||
assert_err!(GhostNetworks::increase_gatekeeper_amount(
|
assert_err!(GhostNetworks::increase_gatekeeper_amount(
|
||||||
&chain_id_first,
|
&chain_id_first,
|
||||||
&u128::MAX,
|
&u128::MAX,
|
||||||
@ -757,12 +787,18 @@ fn bridged_amount_overflow_and_underflow_emits_error() {
|
|||||||
&chain_id_first,
|
&chain_id_first,
|
||||||
&commission,
|
&commission,
|
||||||
), ());
|
), ());
|
||||||
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id_first), commission);
|
|
||||||
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id_second), 0);
|
|
||||||
assert_err!(GhostNetworks::decrease_gatekeeper_amount(
|
assert_err!(GhostNetworks::decrease_gatekeeper_amount(
|
||||||
&chain_id_second,
|
&chain_id_second,
|
||||||
&commission,
|
&u128::MAX,
|
||||||
), ());
|
), ());
|
||||||
|
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(
|
||||||
|
&chain_id_second,
|
||||||
|
&commission,
|
||||||
|
), 0);
|
||||||
|
|
||||||
|
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id_first), commission);
|
||||||
|
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id_second), 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,7 +827,6 @@ fn accumulated_commission_could_be_nullified() {
|
|||||||
fn bridged_inlation_reward_works() {
|
fn bridged_inlation_reward_works() {
|
||||||
ExtBuilder::build()
|
ExtBuilder::build()
|
||||||
.execute_with(|| {
|
.execute_with(|| {
|
||||||
let chain_id: u32 = 1;
|
|
||||||
let amount: u128 = 1337 * 1_000_000_000;
|
let amount: u128 = 1337 * 1_000_000_000;
|
||||||
let commission: u128 = amount / 100; // 1% commission
|
let commission: u128 = amount / 100; // 1% commission
|
||||||
let total_staked_ideal: u128 = 69;
|
let total_staked_ideal: u128 = 69;
|
||||||
@ -832,7 +867,7 @@ fn bridged_inlation_reward_works() {
|
|||||||
1, total_issuance * 1_000_000_000_000_000_000_000_000, 0), (0, 0));
|
1, total_issuance * 1_000_000_000_000_000_000_000_000, 0), (0, 0));
|
||||||
|
|
||||||
assert_ok!(GhostNetworks::accumulate_commission(&commission));
|
assert_ok!(GhostNetworks::accumulate_commission(&commission));
|
||||||
assert_ok!(GhostNetworks::increase_gatekeeper_amount(&chain_id, &amount));
|
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
|
||||||
|
|
||||||
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
|
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
|
||||||
total_staked_ideal * 1_000,
|
total_staked_ideal * 1_000,
|
||||||
@ -917,14 +952,13 @@ fn bridged_inlation_reward_works() {
|
|||||||
fn bridged_inflation_era_payout_triggers_need_of_nullification() {
|
fn bridged_inflation_era_payout_triggers_need_of_nullification() {
|
||||||
ExtBuilder::build()
|
ExtBuilder::build()
|
||||||
.execute_with(|| {
|
.execute_with(|| {
|
||||||
let chain_id: u32 = 1;
|
|
||||||
let amount: u128 = 1337 * 1_000_000_000;
|
let amount: u128 = 1337 * 1_000_000_000;
|
||||||
let commission: u128 = amount / 100; // 1% commission
|
let commission: u128 = amount / 100; // 1% commission
|
||||||
let total_staked_ideal: u128 = 69;
|
let total_staked_ideal: u128 = 69;
|
||||||
let total_issuance: u128 = 100;
|
let total_issuance: u128 = 100;
|
||||||
|
|
||||||
assert_ok!(GhostNetworks::accumulate_commission(&commission));
|
assert_ok!(GhostNetworks::accumulate_commission(&commission));
|
||||||
assert_ok!(GhostNetworks::increase_gatekeeper_amount(&chain_id, &amount));
|
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
|
||||||
assert_eq!(NullifyNeeded::<Test>::get(), false);
|
assert_eq!(NullifyNeeded::<Test>::get(), false);
|
||||||
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
|
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
|
||||||
total_staked_ideal * 1_000,
|
total_staked_ideal * 1_000,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-slow-clap"
|
name = "ghost-slow-clap"
|
||||||
version = "0.3.23"
|
version = "0.3.24"
|
||||||
description = "Applause protocol for the EVM bridge"
|
description = "Applause protocol for the EVM bridge"
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
|
@ -28,7 +28,7 @@ use sp_runtime::{
|
|||||||
self as rt_offchain, HttpError,
|
self as rt_offchain, HttpError,
|
||||||
storage::{MutateStorageError, StorageRetrievalError, StorageValueRef},
|
storage::{MutateStorageError, StorageRetrievalError, StorageValueRef},
|
||||||
},
|
},
|
||||||
traits::{CheckedSub, BlockNumberProvider, Convert, Saturating},
|
traits::{BlockNumberProvider, Convert, Saturating},
|
||||||
};
|
};
|
||||||
use sp_std::{
|
use sp_std::{
|
||||||
vec::Vec, prelude::*,
|
vec::Vec, prelude::*,
|
||||||
@ -330,6 +330,7 @@ pub mod pallet {
|
|||||||
UnregisteredClapRemove,
|
UnregisteredClapRemove,
|
||||||
TooMuchAuthorities,
|
TooMuchAuthorities,
|
||||||
CouldNotAccumulateCommission,
|
CouldNotAccumulateCommission,
|
||||||
|
CouldNotAccumulateIncomingImbalance,
|
||||||
CouldNotIncreaseGatekeeperAmount,
|
CouldNotIncreaseGatekeeperAmount,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,7 +488,7 @@ pub mod pallet {
|
|||||||
|
|
||||||
ValidTransaction::with_tag_prefix("SlowClap")
|
ValidTransaction::with_tag_prefix("SlowClap")
|
||||||
.priority(T::UnsignedPriority::get())
|
.priority(T::UnsignedPriority::get())
|
||||||
.and_provides(authority)
|
.and_provides(signature)
|
||||||
.longevity(LOCK_BLOCK_EXPIRATION)
|
.longevity(LOCK_BLOCK_EXPIRATION)
|
||||||
.propagate(true)
|
.propagate(true)
|
||||||
.build()
|
.build()
|
||||||
@ -580,25 +581,21 @@ impl<T: Config> Pallet<T> {
|
|||||||
.map(|network_data| Perbill::from_parts(network_data.incoming_fee))
|
.map(|network_data| Perbill::from_parts(network_data.incoming_fee))
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.mul_ceil(clap.amount);
|
.mul_ceil(clap.amount);
|
||||||
|
let final_amount = clap.amount.saturating_sub(commission);
|
||||||
|
|
||||||
let final_amount = clap.amount
|
let _ = T::NetworkDataHandler::increase_gatekeeper_amount(&clap.network_id, &clap.amount)
|
||||||
.checked_sub(&commission)
|
|
||||||
.map(|value| T::Currency::minimum_balance()
|
|
||||||
.lt(&value)
|
|
||||||
.then(|| value)
|
|
||||||
)
|
|
||||||
.flatten()
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let _ = T::NetworkDataHandler::increase_gatekeeper_amount(&clap.network_id, &final_amount)
|
|
||||||
.map_err(|_| Error::<T>::CouldNotIncreaseGatekeeperAmount)?;
|
.map_err(|_| Error::<T>::CouldNotIncreaseGatekeeperAmount)?;
|
||||||
|
let _ = T::NetworkDataHandler::accumulate_incoming_imbalance(&final_amount)
|
||||||
|
.map_err(|_| Error::<T>::CouldNotAccumulateIncomingImbalance)?;
|
||||||
let _ = T::NetworkDataHandler::accumulate_commission(&commission)
|
let _ = T::NetworkDataHandler::accumulate_commission(&commission)
|
||||||
.map_err(|_| Error::<T>::CouldNotAccumulateCommission)?;
|
.map_err(|_| Error::<T>::CouldNotAccumulateCommission)?;
|
||||||
|
|
||||||
|
if final_amount > T::Currency::minimum_balance() {
|
||||||
T::Currency::mint_into(
|
T::Currency::mint_into(
|
||||||
&clap.receiver,
|
&clap.receiver,
|
||||||
final_amount
|
final_amount
|
||||||
)?;
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
*is_applaused = true;
|
*is_applaused = true;
|
||||||
|
|
||||||
@ -715,7 +712,7 @@ impl<T: Config> Pallet<T> {
|
|||||||
|
|
||||||
Ok(match maybe_block_range {
|
Ok(match maybe_block_range {
|
||||||
Some((from_block, to_block)) => match new_evm_block {
|
Some((from_block, to_block)) => match new_evm_block {
|
||||||
0 => (to_block, new_evm_block),
|
0 => (to_block, to_block),
|
||||||
_ => (from_block, estimated_block),
|
_ => (from_block, estimated_block),
|
||||||
},
|
},
|
||||||
None => (estimated_block, estimated_block),
|
None => (estimated_block, estimated_block),
|
||||||
@ -788,6 +785,7 @@ impl<T: Config> Pallet<T> {
|
|||||||
let signature = authority_key.sign(&clap.encode())
|
let signature = authority_key.sign(&clap.encode())
|
||||||
.ok_or(OffchainErr::FailedSigning)?;
|
.ok_or(OffchainErr::FailedSigning)?;
|
||||||
let call = Call::slow_clap { clap, signature };
|
let call = Call::slow_clap { clap, signature };
|
||||||
|
|
||||||
SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into())
|
SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into())
|
||||||
.map_err(|_| OffchainErr::SubmitTransaction)?;
|
.map_err(|_| OffchainErr::SubmitTransaction)?;
|
||||||
}
|
}
|
||||||
@ -802,6 +800,7 @@ impl<T: Config> Pallet<T> {
|
|||||||
let authorities = Authorities::<T>::get(&session_index);
|
let authorities = Authorities::<T>::get(&session_index);
|
||||||
let mut local_authorities = T::AuthorityId::all();
|
let mut local_authorities = T::AuthorityId::all();
|
||||||
local_authorities.sort();
|
local_authorities.sort();
|
||||||
|
|
||||||
authorities.into_iter().enumerate().filter_map(move |(index, authority)| {
|
authorities.into_iter().enumerate().filter_map(move |(index, authority)| {
|
||||||
local_authorities
|
local_authorities
|
||||||
.binary_search(&authority)
|
.binary_search(&authority)
|
||||||
|
@ -151,12 +151,13 @@ fn should_make_http_call_for_block_number() {
|
|||||||
|
|
||||||
evm_block_response(&mut state.write());
|
evm_block_response(&mut state.write());
|
||||||
|
|
||||||
t.execute_with(|| {
|
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
|
||||||
let rpc_endpoint = get_rpc_endpoint();
|
let rpc_endpoint = get_rpc_endpoint();
|
||||||
let network_data = prepare_evm_network(Some(1), None);
|
let network_data = prepare_evm_network(Some(1), None);
|
||||||
let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
|
let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
|
||||||
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body).unwrap();
|
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
|
||||||
assert_eq!(raw_response.len(), 45usize); // precalculated
|
assert_eq!(raw_response.len(), 45usize); // precalculated
|
||||||
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,17 +169,17 @@ fn should_make_http_call_for_logs() {
|
|||||||
|
|
||||||
evm_logs_response(&mut state.write());
|
evm_logs_response(&mut state.write());
|
||||||
|
|
||||||
t.execute_with(|| {
|
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
|
||||||
let from_block: u64 = 420;
|
let from_block: u64 = 20335770;
|
||||||
let to_block: u64 = 1337;
|
let to_block: u64 = 20335858;
|
||||||
let rpc_endpoint = get_rpc_endpoint();
|
let rpc_endpoint = get_rpc_endpoint();
|
||||||
|
|
||||||
let network_data = prepare_evm_network(Some(1), None);
|
let network_data = prepare_evm_network(Some(1), None);
|
||||||
let request_body = SlowClap::prepare_request_body_for_latest_transfers(
|
let request_body = SlowClap::prepare_request_body_for_latest_transfers(
|
||||||
from_block, to_block, &network_data);
|
from_block, to_block, &network_data);
|
||||||
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)
|
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
|
||||||
.unwrap();
|
|
||||||
assert_eq!(raw_response.len(), 1805); // precalculated
|
assert_eq!(raw_response.len(), 1805); // precalculated
|
||||||
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,23 +191,23 @@ fn should_make_http_call_and_parse_block_number() {
|
|||||||
|
|
||||||
evm_block_response(&mut state.write());
|
evm_block_response(&mut state.write());
|
||||||
|
|
||||||
t.execute_with(|| {
|
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
|
||||||
let rpc_endpoint = get_rpc_endpoint();
|
let rpc_endpoint = get_rpc_endpoint();
|
||||||
let network_data = prepare_evm_network(Some(1), None);
|
let network_data = prepare_evm_network(Some(1), None);
|
||||||
|
|
||||||
let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
|
let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
|
||||||
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body).unwrap();
|
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
|
||||||
let evm_block_number = SlowClap::apply_evm_response(
|
let evm_block_number = SlowClap::apply_evm_response(&raw_response, 69, Default::default(), 420, 1)?;
|
||||||
&raw_response, 69, Default::default(), 420, 1).unwrap_or_default();
|
|
||||||
|
|
||||||
assert_eq!(evm_block_number, 20335745);
|
assert_eq!(evm_block_number, 20335745);
|
||||||
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_make_http_call_and_parse_logs() {
|
fn should_make_http_call_and_parse_logs() {
|
||||||
let (offchain, state) = TestOffchainExt::new();
|
let (offchain, state) = TestOffchainExt::new();
|
||||||
let (pool, _state) = TestTransactionPoolExt::new();
|
let (pool, _) = TestTransactionPoolExt::new();
|
||||||
let mut t = sp_io::TestExternalities::default();
|
let mut t = sp_io::TestExternalities::default();
|
||||||
|
|
||||||
t.register_extension(OffchainDbExt::new(offchain.clone()));
|
t.register_extension(OffchainDbExt::new(offchain.clone()));
|
||||||
@ -215,19 +216,34 @@ fn should_make_http_call_and_parse_logs() {
|
|||||||
|
|
||||||
evm_logs_response(&mut state.write());
|
evm_logs_response(&mut state.write());
|
||||||
|
|
||||||
t.execute_with(|| {
|
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
|
||||||
let from_block: u64 = 420;
|
let session_index = advance_session_and_get_index();
|
||||||
let to_block: u64 = 1337;
|
|
||||||
let rpc_endpoint = get_rpc_endpoint();
|
let rpc_endpoint = get_rpc_endpoint();
|
||||||
|
|
||||||
let network_data = prepare_evm_network(Some(1), None);
|
let from_block: u64 = 20335770;
|
||||||
|
let to_block: u64 = 20335858;
|
||||||
|
let network_id: u32 = 1;
|
||||||
|
|
||||||
|
let network_data = prepare_evm_network(Some(network_id), None);
|
||||||
let request_body = SlowClap::prepare_request_body_for_latest_transfers(
|
let request_body = SlowClap::prepare_request_body_for_latest_transfers(
|
||||||
from_block, to_block, &network_data);
|
from_block, to_block, &network_data);
|
||||||
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body).unwrap();
|
|
||||||
|
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
|
||||||
|
match SlowClap::parse_evm_response(&raw_response)? {
|
||||||
|
EvmResponseType::BlockNumber(_) => assert_eq!(1, 0), // force break
|
||||||
|
EvmResponseType::TransactionLogs(evm_logs) => assert_eq!(evm_logs.len(), 2),
|
||||||
|
}
|
||||||
|
|
||||||
let evm_block_number = SlowClap::apply_evm_response(
|
let evm_block_number = SlowClap::apply_evm_response(
|
||||||
&raw_response, 69, Default::default(), 420, 1).unwrap_or(20335745);
|
&raw_response,
|
||||||
|
1,
|
||||||
|
UintAuthorityId::from(2),
|
||||||
|
session_index,
|
||||||
|
network_id,
|
||||||
|
)?;
|
||||||
|
|
||||||
assert_eq!(evm_block_number, 0);
|
assert_eq!(evm_block_number, 0);
|
||||||
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +281,7 @@ fn should_increase_gatkeeper_amount_accordingly() {
|
|||||||
assert_ok!(do_clap_from(session_index, network_id, 1, false));
|
assert_ok!(do_clap_from(session_index, network_id, 1, false));
|
||||||
assert_ok!(do_clap_from(session_index, network_id, 2, false));
|
assert_ok!(do_clap_from(session_index, network_id, 2, false));
|
||||||
|
|
||||||
assert_eq!(Networks::gatekeeper_amount(network_id), amount.saturating_div(2));
|
assert_eq!(Networks::gatekeeper_amount(network_id), amount);
|
||||||
assert_eq!(Networks::bridged_imbalance().bridged_in, amount.saturating_div(2));
|
assert_eq!(Networks::bridged_imbalance().bridged_in, amount.saturating_div(2));
|
||||||
assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
|
assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
|
||||||
});
|
});
|
||||||
@ -594,7 +610,7 @@ fn should_throw_error_on_commission_overflow() {
|
|||||||
assert_ok!(SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature));
|
assert_ok!(SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature));
|
||||||
} else {
|
} else {
|
||||||
assert_err!(SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature),
|
assert_err!(SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature),
|
||||||
Error::<Runtime>::CouldNotIncreaseGatekeeperAmount);
|
Error::<Runtime>::CouldNotAccumulateIncomingImbalance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,19 +633,19 @@ fn should_nullify_commission_on_finalize() {
|
|||||||
let (_, _, amount) = get_mocked_metadata();
|
let (_, _, amount) = get_mocked_metadata();
|
||||||
|
|
||||||
new_test_ext().execute_with(|| {
|
new_test_ext().execute_with(|| {
|
||||||
let _ = prepare_evm_network(Some(network_id), Some(500_000_000));
|
let _ = prepare_evm_network(Some(network_id), Some(1_000_000_000));
|
||||||
let session_index = advance_session_and_get_index();
|
let session_index = advance_session_and_get_index();
|
||||||
|
|
||||||
assert_eq!(Networks::accumulated_commission(), 0);
|
assert_eq!(Networks::accumulated_commission(), 0);
|
||||||
assert_ok!(do_clap_from(session_index, network_id, 0, false));
|
assert_ok!(do_clap_from(session_index, network_id, 0, false));
|
||||||
assert_ok!(do_clap_from(session_index, network_id, 1, false));
|
assert_ok!(do_clap_from(session_index, network_id, 1, false));
|
||||||
assert_eq!(Networks::accumulated_commission(), amount.saturating_div(2));
|
assert_eq!(Networks::accumulated_commission(), amount);
|
||||||
assert_eq!(Networks::is_nullification_period(), false);
|
assert_eq!(Networks::is_nullification_period(), false);
|
||||||
|
|
||||||
assert_eq!(BridgedInflationCurve::<RewardCurve, Runtime>::era_payout(
|
assert_eq!(BridgedInflationCurve::<RewardCurve, Runtime>::era_payout(
|
||||||
total_staked,
|
total_staked,
|
||||||
(total_issuance + amount).into(),
|
total_issuance,
|
||||||
0), (1260099399952u128, 208739900600048u128)); // precomputed values
|
0), (420000000000000, 0)); // precomputed values
|
||||||
assert_eq!(Networks::is_nullification_period(), true);
|
assert_eq!(Networks::is_nullification_period(), true);
|
||||||
Networks::on_finalize(System::block_number());
|
Networks::on_finalize(System::block_number());
|
||||||
|
|
||||||
@ -793,10 +809,36 @@ fn should_emit_event_on_each_clap_and_on_applause() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: multiple logs will create multiple records
|
#[test]
|
||||||
// TODO: errors should be checked as much as possible
|
fn should_not_fail_on_sub_existential_balance() {
|
||||||
// TODO: offences generated as expected
|
let (network_id, transaction_hash, unique_transaction_hash)
|
||||||
// TODO: deal with below existential amount after commission
|
= generate_unique_hash(None, None, None, None);
|
||||||
|
let (_, receiver, amount) = get_mocked_metadata();
|
||||||
|
|
||||||
|
new_test_ext().execute_with(|| {
|
||||||
|
let _ = prepare_evm_network(Some(network_id), Some(1_000_000_000)); // 100%
|
||||||
|
let session_index = advance_session_and_get_index();
|
||||||
|
let received_claps_key = (session_index, transaction_hash, unique_transaction_hash);
|
||||||
|
|
||||||
|
assert_eq!(Networks::accumulated_commission(), 0);
|
||||||
|
assert_eq!(Networks::gatekeeper_amount(network_id), 0);
|
||||||
|
assert_eq!(Networks::bridged_imbalance().bridged_in, 0);
|
||||||
|
assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
|
||||||
|
assert_eq!(Balances::balance(&receiver), 0);
|
||||||
|
assert_eq!(SlowClap::applauses_for_transaction(&received_claps_key), false);
|
||||||
|
|
||||||
|
assert_ok!(do_clap_from(session_index, network_id, 0, false));
|
||||||
|
assert_ok!(do_clap_from(session_index, network_id, 1, false));
|
||||||
|
assert_ok!(do_clap_from(session_index, network_id, 2, false));
|
||||||
|
|
||||||
|
assert_eq!(Networks::accumulated_commission(), amount);
|
||||||
|
assert_eq!(Networks::gatekeeper_amount(network_id), amount);
|
||||||
|
assert_eq!(Networks::bridged_imbalance().bridged_in, 0);
|
||||||
|
assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
|
||||||
|
assert_eq!(Balances::balance(&receiver), 0);
|
||||||
|
assert_eq!(SlowClap::applauses_for_transaction(&received_claps_key), true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn advance_session_and_get_index() -> u32 {
|
fn advance_session_and_get_index() -> u32 {
|
||||||
advance_session();
|
advance_session();
|
||||||
@ -892,11 +934,11 @@ fn evm_block_response(state: &mut testing::OffchainState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn evm_logs_response(state: &mut testing::OffchainState) {
|
fn evm_logs_response(state: &mut testing::OffchainState) {
|
||||||
let expected_body = br#"{"id":0,"jsonrpc":"2.0","method":"eth_getLogs","params":[{"fromBlock":"0x1a4","toBlock":"0x539","address":"0x4d224452801ACEd8B2F0aebE155379bb5D594381","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]}]}"#.to_vec();
|
let expected_body = br#"{"id":0,"jsonrpc":"2.0","method":"eth_getLogs","params":[{"fromBlock":"0x1364c9a","toBlock":"0x1364cf2","address":"0x4d224452801ACEd8B2F0aebE155379bb5D594381","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]}]}"#.to_vec();
|
||||||
|
|
||||||
let expected_response = br#"{
|
let expected_response = br#"{
|
||||||
"jsonrpc":"2.0",
|
|
||||||
"id":0,
|
"id":0,
|
||||||
|
"jsonrpc":"2.0",
|
||||||
"result":[
|
"result":[
|
||||||
{
|
{
|
||||||
"address":"0x4d224452801aced8b2f0aebe155379bb5d594381",
|
"address":"0x4d224452801aced8b2f0aebe155379bb5d594381",
|
||||||
@ -938,6 +980,10 @@ fn evm_logs_response(state: &mut testing::OffchainState) {
|
|||||||
("Accept".to_string(), "application/json".to_string()),
|
("Accept".to_string(), "application/json".to_string()),
|
||||||
("Content-Type".to_string(), "application/json".to_string()),
|
("Content-Type".to_string(), "application/json".to_string()),
|
||||||
],
|
],
|
||||||
|
response_headers: vec![
|
||||||
|
("Accept".to_string(), "application/json".to_string()),
|
||||||
|
("Content-Type".to_string(), "application/json".to_string()),
|
||||||
|
],
|
||||||
body: expected_body,
|
body: expected_body,
|
||||||
response: Some(expected_response),
|
response: Some(expected_response),
|
||||||
sent: true,
|
sent: true,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-traits"
|
name = "ghost-traits"
|
||||||
version = "0.3.21"
|
version = "0.3.22"
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
@ -28,14 +28,12 @@ pub trait NetworkDataMutateHandler<Network, Balance>: NetworkDataInspectHandler<
|
|||||||
fn register(chain_id: Self::NetworkId, network: Network) -> DispatchResult;
|
fn register(chain_id: Self::NetworkId, network: Network) -> DispatchResult;
|
||||||
fn remove(chain_id: Self::NetworkId) -> DispatchResult;
|
fn remove(chain_id: Self::NetworkId) -> DispatchResult;
|
||||||
|
|
||||||
fn increase_gatekeeper_amount(
|
fn increase_gatekeeper_amount(chain_id: &Self::NetworkId, amount: &Balance) -> Result<Balance, ()>;
|
||||||
chain_id: &Self::NetworkId,
|
fn decrease_gatekeeper_amount(chain_id: &Self::NetworkId, amount: &Balance) -> Result<Balance, ()>;
|
||||||
amount: &Balance,
|
|
||||||
) -> Result<(Balance, Balance), ()>;
|
fn accumulate_outgoing_imbalance(amount: &Balance) -> Result<Balance, ()>;
|
||||||
fn decrease_gatekeeper_amount(
|
fn accumulate_incoming_imbalance(amount: &Balance) -> Result<Balance, ()>;
|
||||||
chain_id: &Self::NetworkId,
|
|
||||||
amount: &Balance,
|
|
||||||
) -> Result<(Balance, Balance), ()>;
|
|
||||||
fn accumulate_commission(commission: &Balance) -> Result<Balance, ()>;
|
fn accumulate_commission(commission: &Balance) -> Result<Balance, ()>;
|
||||||
fn nullify_commission();
|
fn nullify_commission();
|
||||||
fn trigger_nullification();
|
fn trigger_nullification();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "casper-runtime"
|
name = "casper-runtime"
|
||||||
version = "3.5.20"
|
version = "3.5.21"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
description = "Runtime of the Casper Network"
|
description = "Runtime of the Casper Network"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
@ -1035,6 +1035,7 @@ impl pallet_alliance::Config for Runtime {
|
|||||||
impl ghost_networks::Config for Runtime {
|
impl ghost_networks::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type NetworkId = u64;
|
type NetworkId = u64;
|
||||||
|
type Currency = Balances;
|
||||||
|
|
||||||
type RegisterOrigin = EitherOf<
|
type RegisterOrigin = EitherOf<
|
||||||
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
|
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
|
||||||
@ -1073,14 +1074,11 @@ impl ghost_claims::Config<CultCollectiveInstance> for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
// maximum number of claps in one tx
|
|
||||||
pub MaxNumberOfClaps: u32 = 5;
|
|
||||||
// will be used in `Perbill::from_percent()`
|
// will be used in `Perbill::from_percent()`
|
||||||
pub ApplauseThreshold: u32 = 70;
|
pub ApplauseThreshold: u32 = 70;
|
||||||
// will be used in `Perbill::from_percent()`
|
// will be used in `Perbill::from_percent()`
|
||||||
pub OffenceThreshold: u32 = 40;
|
pub OffenceThreshold: u32 = 40;
|
||||||
pub const SlowClapUnsignedPriority: TransactionPriority =
|
pub const SlowClapUnsignedPriority: TransactionPriority = TransactionPriority::MAX;
|
||||||
TransactionPriority::max_value();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ghost_slow_clap::Config for Runtime {
|
impl ghost_slow_clap::Config for Runtime {
|
||||||
@ -1095,15 +1093,11 @@ impl ghost_slow_clap::Config for Runtime {
|
|||||||
type ReportUnresponsiveness = Offences;
|
type ReportUnresponsiveness = Offences;
|
||||||
|
|
||||||
type MaxAuthorities = MaxAuthorities;
|
type MaxAuthorities = MaxAuthorities;
|
||||||
type MaxNumberOfClaps = MaxNumberOfClaps;
|
|
||||||
type ApplauseThreshold = ApplauseThreshold;
|
type ApplauseThreshold = ApplauseThreshold;
|
||||||
type MaxAuthorityInfoInSession = MaxAuthorities;
|
|
||||||
type OffenceThreshold = OffenceThreshold;
|
type OffenceThreshold = OffenceThreshold;
|
||||||
|
|
||||||
type UnsignedPriority = SlowClapUnsignedPriority;
|
type UnsignedPriority = SlowClapUnsignedPriority;
|
||||||
type TreasuryPalletId = TreasuryPalletId;
|
|
||||||
|
|
||||||
type WeightInfo = weights::ghost_slow_clap::WeightInfo<Runtime>;
|
type WeightInfo = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
construct_runtime! {
|
construct_runtime! {
|
||||||
|
Loading…
Reference in New Issue
Block a user