Compare commits

..

No commits in common. "1196cc9faa816a703006a1fb13bc636b3b3beda7" and "e73f3855fdb2271f1316e7e4091153ff968449b5" have entirely different histories.

11 changed files with 138 additions and 217 deletions

8
Cargo.lock generated
View File

@ -1186,7 +1186,7 @@ dependencies = [
[[package]] [[package]]
name = "casper-runtime" name = "casper-runtime"
version = "3.5.21" version = "3.5.20"
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.6" version = "0.1.5"
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.24" version = "0.3.23"
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.22" version = "0.3.21"
dependencies = [ dependencies = [
"frame-support", "frame-support",
"sp-runtime 31.0.1", "sp-runtime 31.0.1",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-networks" name = "ghost-networks"
version = "0.1.6" version = "0.1.5"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true
edition.workspace = true edition.workspace = true

View File

@ -631,52 +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>, ()> { ) -> Result<(BalanceOf<T>, BalanceOf<T>), ()> {
let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
match gatekeeper_amount.checked_add(amount) {
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
},
None => Err(())
}
})?;
Ok(new_gatekeeper_amount)
}
fn decrease_gatekeeper_amount(
network_id: &T::NetworkId,
amount: &BalanceOf<T>,
) -> Result<BalanceOf<T>, ()> {
let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
match gatekeeper_amount.checked_sub(amount) {
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
},
None => Err(())
}
})?;
Ok(new_gatekeeper_amount)
}
fn accumulate_outgoing_imbalance(amount: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
let new_bridged_out_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
match bridged_imbalance.bridged_out.checked_add(amount) {
Some(value) => {
(*bridged_imbalance).bridged_out = value;
Ok(value)
},
None => Err(())
}
})?;
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| { let new_bridged_in_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
match bridged_imbalance.bridged_in.checked_add(amount) { match bridged_imbalance.bridged_in.checked_add(amount) {
Some(value) => { Some(value) => {
@ -687,7 +642,44 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
} }
})?; })?;
Ok(new_bridged_in_amount) let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
match gatekeeper_amount.checked_add(amount) {
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
},
None => Err(())
}
})?;
Ok((new_gatekeeper_amount, new_bridged_in_amount))
}
fn decrease_gatekeeper_amount(
network_id: &T::NetworkId,
amount: &BalanceOf<T>,
) -> Result<(BalanceOf<T>, BalanceOf<T>), ()> {
let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
match gatekeeper_amount.checked_sub(amount) {
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
},
None => Err(())
}
})?;
let new_bridged_out_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
match bridged_imbalance.bridged_out.checked_add(amount) {
Some(value) => {
(*bridged_imbalance).bridged_out = value;
Ok(value)
},
None => Err(())
}
})?;
Ok((new_gatekeeper_amount, new_bridged_out_amount))
} }
fn accumulate_commission(commission: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> { fn accumulate_commission(commission: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {

View File

@ -656,6 +656,8 @@ 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));
@ -663,26 +665,9 @@ 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);
}); });
} }
@ -723,7 +708,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,
@ -732,33 +717,16 @@ 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); ), (0, commission));
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);
}); });
} }
@ -769,16 +737,18 @@ 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_ok!(GhostNetworks::increase_gatekeeper_amount( assert_err!(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,
@ -787,18 +757,12 @@ fn bridged_amount_overflow_and_underflow_emits_error() {
&chain_id_first, &chain_id_first,
&commission, &commission,
), ()); ), ());
assert_err!(GhostNetworks::decrease_gatekeeper_amount(
&chain_id_second,
&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_first), commission);
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id_second), 0); assert_eq!(GatekeeperAmount::<Test>::get(&chain_id_second), 0);
assert_err!(GhostNetworks::decrease_gatekeeper_amount(
&chain_id_second,
&commission,
), ());
}); });
} }
@ -827,6 +791,7 @@ 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;
@ -867,7 +832,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::accumulate_incoming_imbalance(&amount)); assert_ok!(GhostNetworks::increase_gatekeeper_amount(&chain_id, &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,
@ -952,13 +917,14 @@ 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::accumulate_incoming_imbalance(&amount)); assert_ok!(GhostNetworks::increase_gatekeeper_amount(&chain_id, &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,

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-slow-clap" name = "ghost-slow-clap"
version = "0.3.24" version = "0.3.23"
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

View File

@ -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::{BlockNumberProvider, Convert, Saturating}, traits::{CheckedSub, BlockNumberProvider, Convert, Saturating},
}; };
use sp_std::{ use sp_std::{
vec::Vec, prelude::*, vec::Vec, prelude::*,
@ -330,7 +330,6 @@ pub mod pallet {
UnregisteredClapRemove, UnregisteredClapRemove,
TooMuchAuthorities, TooMuchAuthorities,
CouldNotAccumulateCommission, CouldNotAccumulateCommission,
CouldNotAccumulateIncomingImbalance,
CouldNotIncreaseGatekeeperAmount, CouldNotIncreaseGatekeeperAmount,
} }
@ -488,7 +487,7 @@ pub mod pallet {
ValidTransaction::with_tag_prefix("SlowClap") ValidTransaction::with_tag_prefix("SlowClap")
.priority(T::UnsignedPriority::get()) .priority(T::UnsignedPriority::get())
.and_provides(signature) .and_provides(authority)
.longevity(LOCK_BLOCK_EXPIRATION) .longevity(LOCK_BLOCK_EXPIRATION)
.propagate(true) .propagate(true)
.build() .build()
@ -581,21 +580,25 @@ 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 _ = T::NetworkDataHandler::increase_gatekeeper_amount(&clap.network_id, &clap.amount) let final_amount = 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;
@ -712,7 +715,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, to_block), 0 => (to_block, new_evm_block),
_ => (from_block, estimated_block), _ => (from_block, estimated_block),
}, },
None => (estimated_block, estimated_block), None => (estimated_block, estimated_block),
@ -785,7 +788,6 @@ 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)?;
} }
@ -800,7 +802,6 @@ 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)

View File

@ -151,13 +151,12 @@ fn should_make_http_call_for_block_number() {
evm_block_response(&mut state.write()); evm_block_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| { 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)?; let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body).unwrap();
assert_eq!(raw_response.len(), 45usize); // precalculated assert_eq!(raw_response.len(), 45usize); // precalculated
Ok(())
}); });
} }
@ -169,17 +168,17 @@ fn should_make_http_call_for_logs() {
evm_logs_response(&mut state.write()); evm_logs_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| { t.execute_with(|| {
let from_block: u64 = 20335770; let from_block: u64 = 420;
let to_block: u64 = 20335858; 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 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(())
}); });
} }
@ -191,23 +190,23 @@ fn should_make_http_call_and_parse_block_number() {
evm_block_response(&mut state.write()); evm_block_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| { 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)?; let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body).unwrap();
let evm_block_number = SlowClap::apply_evm_response(&raw_response, 69, Default::default(), 420, 1)?; let evm_block_number = SlowClap::apply_evm_response(
&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, _) = TestTransactionPoolExt::new(); let (pool, _state) = 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()));
@ -216,34 +215,19 @@ fn should_make_http_call_and_parse_logs() {
evm_logs_response(&mut state.write()); evm_logs_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| { t.execute_with(|| {
let session_index = advance_session_and_get_index(); let from_block: u64 = 420;
let to_block: u64 = 1337;
let rpc_endpoint = get_rpc_endpoint(); let rpc_endpoint = get_rpc_endpoint();
let from_block: u64 = 20335770; let network_data = prepare_evm_network(Some(1), None);
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, &raw_response, 69, Default::default(), 420, 1).unwrap_or(20335745);
1,
UintAuthorityId::from(2),
session_index,
network_id,
)?;
assert_eq!(evm_block_number, 0); assert_eq!(evm_block_number, 0);
Ok(())
}); });
} }
@ -281,7 +265,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); assert_eq!(Networks::gatekeeper_amount(network_id), amount.saturating_div(2));
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);
}); });
@ -610,7 +594,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>::CouldNotAccumulateIncomingImbalance); Error::<Runtime>::CouldNotIncreaseGatekeeperAmount);
} }
} }
@ -633,19 +617,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(1_000_000_000)); let _ = prepare_evm_network(Some(network_id), Some(500_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); assert_eq!(Networks::accumulated_commission(), amount.saturating_div(2));
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, (total_issuance + amount).into(),
0), (420000000000000, 0)); // precomputed values 0), (1260099399952u128, 208739900600048u128)); // 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());
@ -809,36 +793,10 @@ fn should_emit_event_on_each_clap_and_on_applause() {
}); });
} }
#[test] // TODO: multiple logs will create multiple records
fn should_not_fail_on_sub_existential_balance() { // TODO: errors should be checked as much as possible
let (network_id, transaction_hash, unique_transaction_hash) // TODO: offences generated as expected
= generate_unique_hash(None, None, None, None); // TODO: deal with below existential amount after commission
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();
@ -934,11 +892,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":"0x1364c9a","toBlock":"0x1364cf2","address":"0x4d224452801ACEd8B2F0aebE155379bb5D594381","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]}]}"#.to_vec(); 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_response = br#"{ let expected_response = br#"{
"id":0,
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id":0,
"result":[ "result":[
{ {
"address":"0x4d224452801aced8b2f0aebe155379bb5d594381", "address":"0x4d224452801aced8b2f0aebe155379bb5d594381",
@ -980,10 +938,6 @@ 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,

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-traits" name = "ghost-traits"
version = "0.3.22" version = "0.3.21"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true
edition.workspace = true edition.workspace = true

View File

@ -28,12 +28,14 @@ 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(chain_id: &Self::NetworkId, amount: &Balance) -> Result<Balance, ()>; fn increase_gatekeeper_amount(
fn decrease_gatekeeper_amount(chain_id: &Self::NetworkId, amount: &Balance) -> Result<Balance, ()>; chain_id: &Self::NetworkId,
amount: &Balance,
fn accumulate_outgoing_imbalance(amount: &Balance) -> Result<Balance, ()>; ) -> Result<(Balance, Balance), ()>;
fn accumulate_incoming_imbalance(amount: &Balance) -> Result<Balance, ()>; fn decrease_gatekeeper_amount(
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();

View File

@ -1,6 +1,6 @@
[package] [package]
name = "casper-runtime" name = "casper-runtime"
version = "3.5.21" version = "3.5.20"
build = "build.rs" build = "build.rs"
description = "Runtime of the Casper Network" description = "Runtime of the Casper Network"
edition.workspace = true edition.workspace = true

View File

@ -1035,7 +1035,6 @@ 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>>,
@ -1074,11 +1073,14 @@ 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 = TransactionPriority::MAX; pub const SlowClapUnsignedPriority: TransactionPriority =
TransactionPriority::max_value();
} }
impl ghost_slow_clap::Config for Runtime { impl ghost_slow_clap::Config for Runtime {
@ -1093,11 +1095,15 @@ 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 WeightInfo = Default::default(); type UnsignedPriority = SlowClapUnsignedPriority;
type TreasuryPalletId = TreasuryPalletId;
type WeightInfo = weights::ghost_slow_clap::WeightInfo<Runtime>;
} }
construct_runtime! { construct_runtime! {