Skip to content

Commit

Permalink
Fee tracker ES for BTC
Browse files Browse the repository at this point in the history
  • Loading branch information
marcellorigotti committed Feb 21, 2025
1 parent bcca1cf commit 727bcf9
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 14 deletions.
2 changes: 1 addition & 1 deletion engine/src/elections/voter_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,5 @@ macro_rules! generate_voter_api_tuple_impls {
generate_voter_api_tuple_impls!(tuple_1_impls: ((A, A0)));
generate_voter_api_tuple_impls!(tuple_3_impls: ((A, A0), (B, B0), (C, C0)));
generate_voter_api_tuple_impls!(tuple_4_impls: ((A, A0), (B, B0), (C, C0), (D, D0)));
generate_voter_api_tuple_impls!(tuple_5_impls: ((A, A0), (B, B0), (C, C0), (D, D0), (EE, E0)));
generate_voter_api_tuple_impls!(tuple_6_impls: ((A, A0), (B, B0), (C, C0), (D, D0), (EE, E0), (FF, F0)));
generate_voter_api_tuple_impls!(tuple_7_impls: ((A, A0), (B, B0), (C, C0), (D, D0), (EE, E0), (FF, F0), (GG, G0)));
26 changes: 25 additions & 1 deletion engine/src/witness/btc_e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ use anyhow::Result;

use sp_core::H256;
use state_chain_runtime::chainflip::bitcoin_elections::{
BitcoinEgressWitnessingES, BitcoinVaultDepositWitnessingES,
BitcoinEgressWitnessingES, BitcoinFeeTracking, BitcoinVaultDepositWitnessingES,
};
use std::sync::Arc;
use tracing::warn;

use crate::{
btc::retry_rpc::BtcRetryRpcClient,
Expand Down Expand Up @@ -254,6 +255,28 @@ impl VoterApi<BitcoinEgressWitnessingES> for BitcoinEgressWitnessingVoter {
}
}

#[derive(Clone)]
pub struct BitcoinFeeVoter {
client: BtcRetryRpcClient,
}

#[async_trait::async_trait]
impl VoterApi<BitcoinFeeTracking> for crate::witness::btc_e::BitcoinFeeVoter {
async fn vote(
&self,
_settings: <BitcoinFeeTracking as ElectoralSystemTypes>::ElectoralSettings,
_properties: <BitcoinFeeTracking as ElectoralSystemTypes>::ElectionProperties,
) -> Result<Option<VoteOf<BitcoinFeeTracking>>, anyhow::Error> {
if let Some(fee) = self.client.next_block_fee_rate().await {
warn!("Fee are: {fee:#?}");
Ok(Some(fee))
} else {
warn!("No fees available");
Ok(None)
}
}
}

#[derive(Clone)]
pub struct BitcoinLivenessVoter {
client: BtcRetryRpcClient,
Expand Down Expand Up @@ -296,6 +319,7 @@ where
BitcoinDepositChannelWitnessingVoter { client: client.clone() },
BitcoinVaultDepositWitnessingVoter { client: client.clone() },
BitcoinEgressWitnessingVoter { client: client.clone() },
BitcoinFeeVoter { client: client.clone() },
BitcoinLivenessVoter { client },
)),
)
Expand Down
10 changes: 10 additions & 0 deletions state-chain/pallets/cf-chain-tracking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,16 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {

Ok(())
}

pub fn inner_update_fee(new_fee: <T::TargetChain as Chain>::TrackedData) -> DispatchResult {
CurrentChainState::<T, I>::try_mutate::<_, Error<T, I>, _>(|previous_chain_state| {
previous_chain_state.as_mut().unwrap().tracked_data = new_fee;

Ok(())
})?;

Ok(())
}
}

impl<T: Config<I>, I: 'static> GetBlockHeight<T::TargetChain> for Pallet<T, I> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,5 +490,5 @@ macro_rules! generate_electoral_system_tuple_impls {
generate_electoral_system_tuple_impls!(tuple_1_impls: ((A, A0)));
generate_electoral_system_tuple_impls!(tuple_3_impls: ((A, A0), (B, B0), (C, C0)));
generate_electoral_system_tuple_impls!(tuple_4_impls: ((A, A0), (B, B0), (C, C0), (D, D0)));
generate_electoral_system_tuple_impls!(tuple_5_impls: ((A, A0), (B, B0), (C, C0), (D, D0), (EE, E0)));
generate_electoral_system_tuple_impls!(tuple_6_impls: ((A, A0), (B, B0), (C, C0), (D, D0), (EE, E0), (FF, F0)));
generate_electoral_system_tuple_impls!(tuple_7_impls: ((A, A0), (B, B0), (C, C0), (D, D0), (EE, E0), (FF, F0), (GG, G0)));
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use frame_support::{
Parameter,
};
use itertools::Itertools;
use log::warn;
use sp_std::vec::Vec;

/// This electoral system calculates the median of all the authorities votes and stores the latest
Expand All @@ -22,15 +23,23 @@ use sp_std::vec::Vec;
///
/// `Settings` can be used by governance to provide information to authorities about exactly how
/// they should `vote`.
pub struct UnsafeMedian<Value, UnsynchronisedSettings, Settings, ValidatorId> {
_phantom: core::marker::PhantomData<(Value, UnsynchronisedSettings, Settings, ValidatorId)>,
///
pub trait UpdateFeeHook<Value> {
fn update_fee(fee: Value);
}
pub struct UnsafeMedian<Value, UnsynchronisedSettings, Settings, Hook, ValidatorId> {
_phantom:
core::marker::PhantomData<(Value, UnsynchronisedSettings, Settings, Hook, ValidatorId)>,
}
impl<
Value: Member + Parameter + MaybeSerializeDeserialize + Ord + BenchmarkValue,
UnsynchronisedSettings: Member + Parameter + MaybeSerializeDeserialize,
Settings: Member + Parameter + MaybeSerializeDeserialize + Eq,
Hook: UpdateFeeHook<Value> + 'static,
ValidatorId: Member + Parameter + Ord + MaybeSerializeDeserialize,
> ElectoralSystemTypes for UnsafeMedian<Value, UnsynchronisedSettings, Settings, ValidatorId>
> ElectoralSystemTypes
for UnsafeMedian<Value, UnsynchronisedSettings, Settings, Hook, ValidatorId>
{
type ValidatorId = ValidatorId;

Expand All @@ -54,8 +63,9 @@ impl<
Value: Member + Parameter + MaybeSerializeDeserialize + Ord + BenchmarkValue,
UnsynchronisedSettings: Member + Parameter + MaybeSerializeDeserialize,
Settings: Member + Parameter + MaybeSerializeDeserialize + Eq,
Hook: UpdateFeeHook<Value> + 'static,
ValidatorId: Member + Parameter + Ord + MaybeSerializeDeserialize,
> ElectoralSystem for UnsafeMedian<Value, UnsynchronisedSettings, Settings, ValidatorId>
> ElectoralSystem for UnsafeMedian<Value, UnsynchronisedSettings, Settings, Hook, ValidatorId>
{
fn generate_vote_properties(
_election_identifier: ElectionIdentifier<Self::ElectionIdentifierExtra>,
Expand All @@ -77,7 +87,9 @@ impl<
let election_access = ElectoralAccess::election_mut(election_identifier);
if let Some(consensus) = election_access.check_consensus()?.has_consensus() {
election_access.delete();
ElectoralAccess::set_unsynchronised_state(consensus)?;
ElectoralAccess::set_unsynchronised_state(consensus.clone())?;
warn!("Consensus reached: {consensus:#?}");
Hook::update_fee(consensus);
// TEMP: This is temporarily commented out.
// Currently we only use this for SolanaFeeTracking. We will be removing
// SolanaFeeTracking entirely, so for now, we just don't need to create elections,
Expand All @@ -88,6 +100,7 @@ impl<
} else {
// See comment above.
// elections ElectoralAccess::new_election((), (), ())?;
ElectoralAccess::new_election((), (), ())?;
}

Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,5 +287,5 @@ macro_rules! generate_vote_storage_tuple_impls {
generate_vote_storage_tuple_impls!(tuple_1_impls: (A));
generate_vote_storage_tuple_impls!(tuple_3_impls: (A, B, C));
generate_vote_storage_tuple_impls!(tuple_4_impls: (A, B, C, D));
generate_vote_storage_tuple_impls!(tuple_5_impls: (A, B, C, D, EE));
generate_vote_storage_tuple_impls!(tuple_6_impls: (A, B, C, D, EE, FF));
generate_vote_storage_tuple_impls!(tuple_7_impls: (A, B, C, D, EE, FF, GG));
45 changes: 41 additions & 4 deletions state-chain/runtime/src/chainflip/bitcoin_elections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use crate::{
use cf_chains::{
btc::{
self, deposit_address::DepositAddress, BitcoinFeeInfo, BitcoinTrackedData, BlockNumber,
Hash,
BtcAmount, Hash,
},
instances::BitcoinInstance,
Bitcoin,
Bitcoin, Chain,
};
use cf_primitives::{AccountId, ChannelId};
use cf_runtime_utilities::log_or_panic;
Expand All @@ -36,14 +36,15 @@ use pallet_cf_elections::{
},
},
composite::{
tuple_5_impls::{DerivedElectoralAccess, Hooks},
tuple_6_impls::{DerivedElectoralAccess, Hooks},
CompositeRunner,
},
liveness::Liveness,
state_machine::{
core::{ConstantIndex, Hook},
state_machine_es::{StateMachineES, StateMachineESInstance},
},
unsafe_median::{UnsafeMedian, UpdateFeeHook},
},
vote_storage, CorruptStorageError, ElectionIdentifier, InitialState, InitialStateOf,
RunnerStorageAccess,
Expand All @@ -63,6 +64,7 @@ pub type BitcoinElectoralSystemRunner = CompositeRunner<
BitcoinDepositChannelWitnessingES,
BitcoinVaultDepositWitnessingES,
BitcoinEgressWitnessingES,
BitcoinFeeTracking,
BitcoinLiveness,
),
<Runtime as Chainflip>::ValidatorId,
Expand Down Expand Up @@ -449,6 +451,24 @@ pub type BitcoinLiveness = Liveness<
<Runtime as Chainflip>::ValidatorId,
>;

pub struct BitcoinFeeUpdateHook;
impl UpdateFeeHook<BtcAmount> for BitcoinFeeUpdateHook {
fn update_fee(fee: BtcAmount) {
if let Err(err) = BitcoinChainTracking::inner_update_fee(BitcoinTrackedData {
btc_fee_info: BitcoinFeeInfo::new(fee),
}) {
log::error!("Failed to update chain state: {:?}", err);
}
}
}
pub type BitcoinFeeTracking = UnsafeMedian<
<Bitcoin as Chain>::ChainAmount,
BtcAmount,
(),
BitcoinFeeUpdateHook,
<Runtime as Chainflip>::ValidatorId,
>;

pub struct BitcoinElectionHooks;

impl
Expand All @@ -457,11 +477,12 @@ impl
BitcoinDepositChannelWitnessingES,
BitcoinVaultDepositWitnessingES,
BitcoinEgressWitnessingES,
BitcoinFeeTracking,
BitcoinLiveness,
> for BitcoinElectionHooks
{
fn on_finalize(
(block_height_tracking_identifiers, deposit_channel_witnessing_identifiers, vault_deposits_identifiers, egress_identifiers, liveness_identifiers): (
(block_height_tracking_identifiers, deposit_channel_witnessing_identifiers, vault_deposits_identifiers, egress_identifiers, fee_identifiers, liveness_identifiers): (
Vec<
ElectionIdentifier<
<BitcoinBlockHeightTrackingES as ElectoralSystemTypes>::ElectionIdentifierExtra,
Expand All @@ -482,6 +503,11 @@ impl
<BitcoinEgressWitnessingES as ElectoralSystemTypes>::ElectionIdentifierExtra,
>,
>,
Vec<
ElectionIdentifier<
<BitcoinFeeTracking as ElectoralSystemTypes>::ElectionIdentifierExtra,
>,
>,
Vec<
ElectionIdentifier<
<BitcoinLiveness as ElectoralSystemTypes>::ElectionIdentifierExtra,
Expand Down Expand Up @@ -528,6 +554,14 @@ impl
>,
>(egress_identifiers, &chain_progress)?;

BitcoinFeeTracking::on_finalize::<
DerivedElectoralAccess<
_,
BitcoinFeeTracking,
RunnerStorageAccess<Runtime, BitcoinInstance>,
>,
>(fee_identifiers, &())?;

BitcoinLiveness::on_finalize::<
DerivedElectoralAccess<
_,
Expand Down Expand Up @@ -555,20 +589,23 @@ pub fn initial_state() -> InitialStateOf<Runtime, BitcoinInstance> {
Default::default(),
Default::default(),
Default::default(),
Default::default(),
),
unsynchronised_settings: (
Default::default(),
// TODO: Write a migration to set this too.
BWSettings { max_concurrent_elections: 15 },
BWSettings { max_concurrent_elections: 15 },
BWSettings { max_concurrent_elections: 15 },
Default::default(),
(),
),
settings: (
Default::default(),
Default::default(),
Default::default(),
Default::default(),
Default::default(),
LIVENESS_CHECK_DURATION,
),
}
Expand Down
10 changes: 9 additions & 1 deletion state-chain/runtime/src/chainflip/solana_elections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,16 @@ pub type SolanaBlockHeightTracking = electoral_systems::monotonic_median::Monoto
SolanaBlockHeightTrackingHook,
<Runtime as Chainflip>::ValidatorId,
>;

pub struct SolanaFeeHook;
impl UpdateFeeHook<<Solana as Chain>::ChainAmount> for SolanaFeeHook {
fn update_fee(fee: <Solana as Chain>::ChainAmount) {}
}
pub type SolanaFeeTracking = electoral_systems::unsafe_median::UnsafeMedian<
<Solana as Chain>::ChainAmount,
SolanaFeeUnsynchronisedSettings,
(),
SolanaFeeHook,
<Runtime as Chainflip>::ValidatorId,
>;
pub type SolanaIngressTracking =
Expand Down Expand Up @@ -374,7 +380,9 @@ impl BenchmarkValue for SolanaIngressSettings {
}
}

use pallet_cf_elections::electoral_systems::composite::tuple_7_impls::DerivedElectoralAccess;
use pallet_cf_elections::electoral_systems::{
composite::tuple_7_impls::DerivedElectoralAccess, unsafe_median::UpdateFeeHook,
};

pub struct SolanaChainTrackingProvider;
impl GetBlockHeight<Solana> for SolanaChainTrackingProvider {
Expand Down

0 comments on commit 727bcf9

Please sign in to comment.