From 9ea7e6fb2a2ebf5423ec67406a4256932f82e55e Mon Sep 17 00:00:00 2001 From: Maxim Urschumzew Date: Tue, 29 Oct 2024 11:19:07 +0100 Subject: [PATCH] Add subscription endpoint for tainted transaction events. --- Cargo.lock | 1 + state-chain/custom-rpc/Cargo.toml | 1 + state-chain/custom-rpc/src/lib.rs | 20 +++++++++++++++++++- state-chain/runtime/src/lib.rs | 22 +++++++++++++++++++++- state-chain/runtime/src/runtime_apis.rs | 19 +++++++++++++++++++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d55f3124a8..f7f84d80d11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2559,6 +2559,7 @@ dependencies = [ "jsonrpsee 0.23.2", "log", "pallet-cf-governance", + "pallet-cf-ingress-egress", "pallet-cf-pools", "pallet-cf-swapping", "pallet-cf-witnesser", diff --git a/state-chain/custom-rpc/Cargo.toml b/state-chain/custom-rpc/Cargo.toml index 18fc15a7893..66d10ba3a1c 100644 --- a/state-chain/custom-rpc/Cargo.toml +++ b/state-chain/custom-rpc/Cargo.toml @@ -29,6 +29,7 @@ pallet-cf-governance = { workspace = true, default-features = true } pallet-cf-pools = { workspace = true, default-features = true } pallet-cf-witnesser = { workspace = true, default-features = true } pallet-cf-swapping = { workspace = true, default-features = true } +pallet-cf-ingress-egress = { workspace = true, default-features = true } sp-api = { workspace = true, default-features = true } sp-core = { workspace = true, default-features = true } diff --git a/state-chain/custom-rpc/src/lib.rs b/state-chain/custom-rpc/src/lib.rs index abfb3ace31b..d9586a212dd 100644 --- a/state-chain/custom-rpc/src/lib.rs +++ b/state-chain/custom-rpc/src/lib.rs @@ -53,7 +53,8 @@ use state_chain_runtime::{ runtime_apis::{ AuctionState, BoostPoolDepth, BoostPoolDetails, BrokerInfo, CustomRuntimeApi, DispatchErrorWithMessage, ElectoralRuntimeApi, FailingWitnessValidators, - LiquidityProviderBoostPoolInfo, LiquidityProviderInfo, RuntimeApiPenalty, ValidatorInfo, + LiquidityProviderBoostPoolInfo, LiquidityProviderInfo, RuntimeApiPenalty, + TaintedBtcTransactionEvent, ValidatorInfo, }, safe_mode::RuntimeSafeMode, Hash, NetworkFee, SolanaInstance, @@ -954,6 +955,9 @@ pub trait CustomApi { broker: state_chain_runtime::AccountId, at: Option, ) -> RpcResult::ChainAccount>>; + + #[subscription(name = "subscribe_tainted_btc_transaction_events", item = BlockUpdate>)] + fn cf_subscribe_tainted_btc_transaction_events(&self); } /// An RPC extension for the state chain node. @@ -1738,6 +1742,20 @@ where ) -> RpcResult> { self.with_runtime_api(at, |api, hash| api.cf_filter_votes(hash, validator, proposed_votes)) } + + fn cf_subscribe_tainted_btc_transaction_events( + &self, + sink: jsonrpsee::PendingSubscriptionSink, + ) { + self.new_subscription( + false, /* only_on_changes */ + true, /* end_on_error */ + sink, + |client, hash| { + Ok(client.runtime_api().cf_tainted_btc_transaction_events(hash)?) + }, + ) + } } impl CustomRpc diff --git a/state-chain/runtime/src/lib.rs b/state-chain/runtime/src/lib.rs index e042378fcf6..adf1b0ca23e 100644 --- a/state-chain/runtime/src/lib.rs +++ b/state-chain/runtime/src/lib.rs @@ -72,7 +72,7 @@ use pallet_cf_pools::{ PoolPriceV2, UnidirectionalPoolDepth, }; -use crate::chainflip::EvmLimit; +use crate::{chainflip::EvmLimit, runtime_apis::TaintedBtcTransactionEvent}; use pallet_cf_reputation::{ExclusionList, HeartbeatQualification, ReputationPointsQualification}; use pallet_cf_swapping::SwapLegInfo; @@ -2085,8 +2085,28 @@ impl_runtime_apis! { .map(|channel_details| channel_details.deposit_channel.address) .collect()) } + + fn cf_tainted_btc_transaction_events() -> Vec { + + System::read_events_no_consensus().filter_map(|event_record| { + if let RuntimeEvent::BitcoinIngressEgress(btc_ie_event) = event_record.event { + match btc_ie_event { + pallet_cf_ingress_egress::Event::TaintedTransactionReportExpired{ account_id, tx_id } => + Some(TaintedBtcTransactionEvent::TaintedTransactionReportExpired{ account_id, tx_id }), + pallet_cf_ingress_egress::Event::TaintedTransactionReportReceived{ account_id, tx_id, expires_at: _ } => + Some(TaintedBtcTransactionEvent::TaintedTransactionReportReceived{account_id, tx_id }), + pallet_cf_ingress_egress::Event::TaintedTransactionRejected{ broadcast_id, tx_id } => + Some(TaintedBtcTransactionEvent::TaintedTransactionRejected{ broadcast_id, tx_id: tx_id.utxo_id.tx_id }), + _ => None, + } + } else { + None + } + }).collect() + } } + impl monitoring_apis::MonitoringRuntimeApi for Runtime { fn cf_authorities() -> AuthoritiesInfo { diff --git a/state-chain/runtime/src/runtime_apis.rs b/state-chain/runtime/src/runtime_apis.rs index 4d1c9c819ba..0393ab212e6 100644 --- a/state-chain/runtime/src/runtime_apis.rs +++ b/state-chain/runtime/src/runtime_apis.rs @@ -183,6 +183,24 @@ pub struct FailingWitnessValidators { pub validators: Vec<(cf_primitives::AccountId, String, bool)>, } +#[derive(Serialize, Deserialize, Encode, Decode, Eq, PartialEq, TypeInfo, Debug, Clone)] +pub enum TaintedBtcTransactionEvent { + TaintedTransactionReportReceived { + account_id: ::AccountId, + tx_id: <::ChainCrypto as cf_chains::ChainCrypto>::TransactionInId, + }, + + TaintedTransactionReportExpired { + account_id: ::AccountId, + tx_id: <::ChainCrypto as cf_chains::ChainCrypto>::TransactionInId, + }, + + TaintedTransactionRejected { + broadcast_id: BroadcastId, + tx_id: <::ChainCrypto as cf_chains::ChainCrypto>::TransactionInId, + }, +} + decl_runtime_apis!( /// Definition for all runtime API interfaces. pub trait CustomRuntimeApi { @@ -312,6 +330,7 @@ decl_runtime_apis!( Vec<::ChainAccount>, DispatchErrorWithMessage, >; + fn cf_tainted_btc_transaction_events() -> Vec; } );