use crate::{model::*, notify::connection::ChannelConnection, RpcResult};
use async_trait::async_trait;
use downcast::{downcast_sync, AnySync};
use kaspa_notify::{listener::ListenerId, scope::Scope, subscription::Command};
use std::sync::Arc;
#[async_trait]
pub trait RpcApi: Sync + Send + AnySync {
async fn ping(&self) -> RpcResult<()> {
self.ping_call(PingRequest {}).await?;
Ok(())
}
async fn ping_call(&self, request: PingRequest) -> RpcResult<PingResponse>;
async fn get_process_metrics(&self) -> RpcResult<GetProcessMetricsResponse> {
self.get_process_metrics_call(GetProcessMetricsRequest {}).await
}
async fn get_process_metrics_call(&self, request: GetProcessMetricsRequest) -> RpcResult<GetProcessMetricsResponse>;
async fn get_current_network(&self) -> RpcResult<RpcNetworkType> {
Ok(self.get_current_network_call(GetCurrentNetworkRequest {}).await?.network)
}
async fn get_current_network_call(&self, request: GetCurrentNetworkRequest) -> RpcResult<GetCurrentNetworkResponse>;
async fn submit_block(&self, block: RpcBlock, allow_non_daa_blocks: bool) -> RpcResult<SubmitBlockResponse> {
self.submit_block_call(SubmitBlockRequest::new(block, allow_non_daa_blocks)).await
}
async fn submit_block_call(&self, request: SubmitBlockRequest) -> RpcResult<SubmitBlockResponse>;
async fn get_block_template(&self, pay_address: RpcAddress, extra_data: RpcExtraData) -> RpcResult<GetBlockTemplateResponse> {
self.get_block_template_call(GetBlockTemplateRequest::new(pay_address, extra_data)).await
}
async fn get_block_template_call(&self, request: GetBlockTemplateRequest) -> RpcResult<GetBlockTemplateResponse>;
async fn get_peer_addresses(&self) -> RpcResult<GetPeerAddressesResponse> {
self.get_peer_addresses_call(GetPeerAddressesRequest {}).await
}
async fn get_peer_addresses_call(&self, request: GetPeerAddressesRequest) -> RpcResult<GetPeerAddressesResponse>;
async fn get_selected_tip_hash(&self) -> RpcResult<GetSelectedTipHashResponse> {
self.get_selected_tip_hash_call(GetSelectedTipHashRequest {}).await
}
async fn get_selected_tip_hash_call(&self, request: GetSelectedTipHashRequest) -> RpcResult<GetSelectedTipHashResponse>;
async fn get_mempool_entry(
&self,
transaction_id: RpcTransactionId,
include_orphan_pool: bool,
filter_transaction_pool: bool,
) -> RpcResult<RpcMempoolEntry> {
Ok(self
.get_mempool_entry_call(GetMempoolEntryRequest::new(transaction_id, include_orphan_pool, filter_transaction_pool))
.await?
.mempool_entry)
}
async fn get_mempool_entry_call(&self, request: GetMempoolEntryRequest) -> RpcResult<GetMempoolEntryResponse>;
async fn get_mempool_entries(&self, include_orphan_pool: bool, filter_transaction_pool: bool) -> RpcResult<Vec<RpcMempoolEntry>> {
Ok(self
.get_mempool_entries_call(GetMempoolEntriesRequest::new(include_orphan_pool, filter_transaction_pool))
.await?
.mempool_entries)
}
async fn get_mempool_entries_call(&self, request: GetMempoolEntriesRequest) -> RpcResult<GetMempoolEntriesResponse>;
async fn get_connected_peer_info(&self) -> RpcResult<GetConnectedPeerInfoResponse> {
self.get_connected_peer_info_call(GetConnectedPeerInfoRequest {}).await
}
async fn get_connected_peer_info_call(&self, request: GetConnectedPeerInfoRequest) -> RpcResult<GetConnectedPeerInfoResponse>;
async fn add_peer(&self, peer_address: RpcPeerAddress, is_permanent: bool) -> RpcResult<()> {
self.add_peer_call(AddPeerRequest::new(peer_address, is_permanent)).await?;
Ok(())
}
async fn add_peer_call(&self, request: AddPeerRequest) -> RpcResult<AddPeerResponse>;
async fn submit_transaction(&self, transaction: RpcTransaction, allow_orphan: bool) -> RpcResult<RpcTransactionId> {
Ok(self.submit_transaction_call(SubmitTransactionRequest { transaction, allow_orphan }).await?.transaction_id)
}
async fn submit_transaction_call(&self, request: SubmitTransactionRequest) -> RpcResult<SubmitTransactionResponse>;
async fn get_block(&self, hash: RpcHash, include_transactions: bool) -> RpcResult<RpcBlock> {
Ok(self.get_block_call(GetBlockRequest::new(hash, include_transactions)).await?.block)
}
async fn get_block_call(&self, request: GetBlockRequest) -> RpcResult<GetBlockResponse>;
async fn get_subnetwork(&self, subnetwork_id: RpcSubnetworkId) -> RpcResult<GetSubnetworkResponse> {
self.get_subnetwork_call(GetSubnetworkRequest::new(subnetwork_id)).await
}
async fn get_subnetwork_call(&self, request: GetSubnetworkRequest) -> RpcResult<GetSubnetworkResponse>;
async fn get_virtual_chain_from_block(
&self,
start_hash: RpcHash,
include_accepted_transaction_ids: bool,
) -> RpcResult<GetVirtualChainFromBlockResponse> {
self.get_virtual_chain_from_block_call(GetVirtualChainFromBlockRequest::new(start_hash, include_accepted_transaction_ids))
.await
}
async fn get_virtual_chain_from_block_call(
&self,
request: GetVirtualChainFromBlockRequest,
) -> RpcResult<GetVirtualChainFromBlockResponse>;
async fn get_blocks(
&self,
low_hash: Option<RpcHash>,
include_blocks: bool,
include_transactions: bool,
) -> RpcResult<GetBlocksResponse> {
self.get_blocks_call(GetBlocksRequest::new(low_hash, include_blocks, include_transactions)).await
}
async fn get_blocks_call(&self, request: GetBlocksRequest) -> RpcResult<GetBlocksResponse>;
async fn get_block_count(&self) -> RpcResult<GetBlockCountResponse> {
self.get_block_count_call(GetBlockCountRequest {}).await
}
async fn get_block_count_call(&self, request: GetBlockCountRequest) -> RpcResult<GetBlockCountResponse>;
async fn get_block_dag_info(&self) -> RpcResult<GetBlockDagInfoResponse> {
self.get_block_dag_info_call(GetBlockDagInfoRequest {}).await
}
async fn get_block_dag_info_call(&self, request: GetBlockDagInfoRequest) -> RpcResult<GetBlockDagInfoResponse>;
async fn resolve_finality_conflict(&self, finality_block_hash: RpcHash) -> RpcResult<()> {
self.resolve_finality_conflict_call(ResolveFinalityConflictRequest::new(finality_block_hash)).await?;
Ok(())
}
async fn resolve_finality_conflict_call(
&self,
request: ResolveFinalityConflictRequest,
) -> RpcResult<ResolveFinalityConflictResponse>;
async fn shutdown(&self) -> RpcResult<()> {
self.shutdown_call(ShutdownRequest {}).await?;
Ok(())
}
async fn shutdown_call(&self, request: ShutdownRequest) -> RpcResult<ShutdownResponse>;
async fn get_headers(&self, start_hash: RpcHash, limit: u64, is_ascending: bool) -> RpcResult<Vec<RpcHeader>> {
Ok(self.get_headers_call(GetHeadersRequest::new(start_hash, limit, is_ascending)).await?.headers)
}
async fn get_headers_call(&self, request: GetHeadersRequest) -> RpcResult<GetHeadersResponse>;
async fn get_balance_by_address(&self, address: RpcAddress) -> RpcResult<u64> {
Ok(self.get_balance_by_address_call(GetBalanceByAddressRequest::new(address)).await?.balance)
}
async fn get_balance_by_address_call(&self, request: GetBalanceByAddressRequest) -> RpcResult<GetBalanceByAddressResponse>;
async fn get_balances_by_addresses(&self, addresses: Vec<RpcAddress>) -> RpcResult<Vec<RpcBalancesByAddressesEntry>> {
Ok(self.get_balances_by_addresses_call(GetBalancesByAddressesRequest::new(addresses)).await?.entries)
}
async fn get_balances_by_addresses_call(
&self,
request: GetBalancesByAddressesRequest,
) -> RpcResult<GetBalancesByAddressesResponse>;
async fn get_utxos_by_addresses(&self, addresses: Vec<RpcAddress>) -> RpcResult<Vec<RpcUtxosByAddressesEntry>> {
Ok(self.get_utxos_by_addresses_call(GetUtxosByAddressesRequest::new(addresses)).await?.entries)
}
async fn get_utxos_by_addresses_call(&self, request: GetUtxosByAddressesRequest) -> RpcResult<GetUtxosByAddressesResponse>;
async fn get_sink_blue_score(&self) -> RpcResult<u64> {
Ok(self.get_sink_blue_score_call(GetSinkBlueScoreRequest {}).await?.blue_score)
}
async fn get_sink_blue_score_call(&self, request: GetSinkBlueScoreRequest) -> RpcResult<GetSinkBlueScoreResponse>;
async fn ban(&self, address: RpcPeerAddress) -> RpcResult<()> {
self.ban_call(BanRequest::new(address)).await?;
Ok(())
}
async fn ban_call(&self, request: BanRequest) -> RpcResult<BanResponse>;
async fn unban(&self, address: RpcPeerAddress) -> RpcResult<()> {
self.unban_call(UnbanRequest::new(address)).await?;
Ok(())
}
async fn unban_call(&self, request: UnbanRequest) -> RpcResult<UnbanResponse>;
async fn get_info_call(&self, request: GetInfoRequest) -> RpcResult<GetInfoResponse>;
async fn get_info(&self) -> RpcResult<GetInfoResponse> {
self.get_info_call(GetInfoRequest {}).await
}
async fn estimate_network_hashes_per_second(&self, window_size: u32, start_hash: RpcHash) -> RpcResult<u64> {
Ok(self
.estimate_network_hashes_per_second_call(EstimateNetworkHashesPerSecondRequest::new(window_size, start_hash))
.await?
.network_hashes_per_second)
}
async fn estimate_network_hashes_per_second_call(
&self,
request: EstimateNetworkHashesPerSecondRequest,
) -> RpcResult<EstimateNetworkHashesPerSecondResponse>;
async fn get_mempool_entries_by_addresses(
&self,
addresses: Vec<RpcAddress>,
include_orphan_pool: bool,
filter_transaction_pool: bool,
) -> RpcResult<Vec<RpcMempoolEntryByAddress>> {
Ok(self
.get_mempool_entries_by_addresses_call(GetMempoolEntriesByAddressesRequest::new(
addresses,
include_orphan_pool,
filter_transaction_pool,
))
.await?
.entries)
}
async fn get_mempool_entries_by_addresses_call(
&self,
request: GetMempoolEntriesByAddressesRequest,
) -> RpcResult<GetMempoolEntriesByAddressesResponse>;
async fn get_coin_supply(&self) -> RpcResult<GetCoinSupplyResponse> {
self.get_coin_supply_call(GetCoinSupplyRequest {}).await
}
async fn get_coin_supply_call(&self, request: GetCoinSupplyRequest) -> RpcResult<GetCoinSupplyResponse>;
fn register_new_listener(&self, connection: ChannelConnection) -> ListenerId;
async fn unregister_listener(&self, id: ListenerId) -> RpcResult<()>;
async fn start_notify(&self, id: ListenerId, scope: Scope) -> RpcResult<()>;
async fn stop_notify(&self, id: ListenerId, scope: Scope) -> RpcResult<()>;
async fn execute_subscribe_command(&self, id: ListenerId, scope: Scope, command: Command) -> RpcResult<()> {
match command {
Command::Start => self.start_notify(id, scope).await,
Command::Stop => self.stop_notify(id, scope).await,
}
}
}
pub type DynRpcService = Arc<dyn RpcApi>;
downcast_sync!(dyn RpcApi);