use crate::model::*; use borsh::{BorshDeserialize, BorshSerialize}; use kaspa_consensus_core::api::stats::BlockCount; use kaspa_core::debug; use kaspa_notify::subscription::{Command, context::SubscriptionContext, single::UtxosChangedSubscription}; use kaspa_utils::hex::ToHex; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::{ fmt::{Display, Formatter}, sync::Arc, }; use workflow_serializer::prelude::*; pub type RpcExtraData = Vec; /// SubmitBlockRequest requests to submit a block into the DAG. /// Blocks are generally expected to have been generated using the getBlockTemplate call. /// /// See: [`GetBlockTemplateRequest`] #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SubmitBlockRequest { pub block: RpcRawBlock, #[serde(alias = "allowNonDAABlocks")] pub allow_non_daa_blocks: bool, } impl SubmitBlockRequest { pub fn new(block: RpcRawBlock, allow_non_daa_blocks: bool) -> Self { Self { block, allow_non_daa_blocks } } } impl Serializer for SubmitBlockRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(RpcRawBlock, &self.block, writer)?; store!(bool, &self.allow_non_daa_blocks, writer)?; Ok(()) } } impl Deserializer for SubmitBlockRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let block = deserialize!(RpcRawBlock, reader)?; let allow_non_daa_blocks = load!(bool, reader)?; Ok(Self { block, allow_non_daa_blocks }) } } #[derive(Clone, Copy, Eq, PartialEq, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize)] #[serde(rename_all = "camelCase")] #[borsh(use_discriminant = true)] pub enum SubmitBlockRejectReason { BlockInvalid = 1, IsInIBD = 2, RouteIsFull = 3, } impl SubmitBlockRejectReason { fn as_str(&self) -> &'static str { // see app\appmessage\rpc_submit_block.go, line 35 match self { SubmitBlockRejectReason::BlockInvalid => "block is invalid", SubmitBlockRejectReason::IsInIBD => "node is not synced", SubmitBlockRejectReason::RouteIsFull => "route is full", } } } impl Display for SubmitBlockRejectReason { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(self.as_str()) } } #[derive(Eq, PartialEq, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize)] #[serde(rename_all = "lowercase")] #[serde(tag = "type", content = "reason")] #[borsh(use_discriminant = true)] pub enum SubmitBlockReport { Success, Reject(SubmitBlockRejectReason), } impl SubmitBlockReport { pub fn is_success(&self) -> bool { *self == SubmitBlockReport::Success } } #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SubmitBlockResponse { pub report: SubmitBlockReport, } impl Serializer for SubmitBlockResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(SubmitBlockReport, &self.report, writer)?; Ok(()) } } impl Deserializer for SubmitBlockResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let report = load!(SubmitBlockReport, reader)?; Ok(Self { report }) } } /// GetBlockTemplateRequest requests a current block template. /// Callers are expected to solve the block template and submit it using the submitBlock call /// /// See: [`SubmitBlockRequest`] #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlockTemplateRequest { /// Which kaspa address should the coinbase block reward transaction pay into pub pay_address: RpcAddress, // TODO: replace with hex serialization pub extra_data: RpcExtraData, } impl GetBlockTemplateRequest { pub fn new(pay_address: RpcAddress, extra_data: RpcExtraData) -> Self { Self { pay_address, extra_data } } } impl Serializer for GetBlockTemplateRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcAddress, &self.pay_address, writer)?; store!(RpcExtraData, &self.extra_data, writer)?; Ok(()) } } impl Deserializer for GetBlockTemplateRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let pay_address = load!(RpcAddress, reader)?; let extra_data = load!(RpcExtraData, reader)?; Ok(Self { pay_address, extra_data }) } } #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlockTemplateResponse { pub block: RpcRawBlock, /// Whether kaspad thinks that it's synced. /// Callers are discouraged (but not forbidden) from solving blocks when kaspad is not synced. /// That is because when kaspad isn't in sync with the rest of the network there's a high /// chance the block will never be accepted, thus the solving effort would have been wasted. pub is_synced: bool, } impl Serializer for GetBlockTemplateResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(RpcRawBlock, &self.block, writer)?; store!(bool, &self.is_synced, writer)?; Ok(()) } } impl Deserializer for GetBlockTemplateResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let block = deserialize!(RpcRawBlock, reader)?; let is_synced = load!(bool, reader)?; Ok(Self { block, is_synced }) } } /// GetBlockRequest requests information about a specific block #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlockRequest { /// The hash of the requested block pub hash: RpcHash, /// Whether to include transaction data in the response pub include_transactions: bool, } impl GetBlockRequest { pub fn new(hash: RpcHash, include_transactions: bool) -> Self { Self { hash, include_transactions } } } impl Serializer for GetBlockRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.hash, writer)?; store!(bool, &self.include_transactions, writer)?; Ok(()) } } impl Deserializer for GetBlockRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let hash = load!(RpcHash, reader)?; let include_transactions = load!(bool, reader)?; Ok(Self { hash, include_transactions }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlockResponse { pub block: RpcBlock, } impl Serializer for GetBlockResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(RpcBlock, &self.block, writer)?; Ok(()) } } impl Deserializer for GetBlockResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let block = deserialize!(RpcBlock, reader)?; Ok(Self { block }) } } /// GetInfoRequest returns info about the node. #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetInfoRequest {} impl Serializer for GetInfoRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetInfoRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetInfoResponse { pub p2p_id: String, pub mempool_size: u64, pub server_version: String, pub is_utxo_indexed: bool, pub is_synced: bool, pub has_notify_command: bool, pub has_message_id: bool, } impl Serializer for GetInfoResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(String, &self.p2p_id, writer)?; store!(u64, &self.mempool_size, writer)?; store!(String, &self.server_version, writer)?; store!(bool, &self.is_utxo_indexed, writer)?; store!(bool, &self.is_synced, writer)?; store!(bool, &self.has_notify_command, writer)?; store!(bool, &self.has_message_id, writer)?; Ok(()) } } impl Deserializer for GetInfoResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let p2p_id = load!(String, reader)?; let mempool_size = load!(u64, reader)?; let server_version = load!(String, reader)?; let is_utxo_indexed = load!(bool, reader)?; let is_synced = load!(bool, reader)?; let has_notify_command = load!(bool, reader)?; let has_message_id = load!(bool, reader)?; Ok(Self { p2p_id, mempool_size, server_version, is_utxo_indexed, is_synced, has_notify_command, has_message_id }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetCurrentNetworkRequest {} impl Serializer for GetCurrentNetworkRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetCurrentNetworkRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetCurrentNetworkResponse { pub network: RpcNetworkType, } impl GetCurrentNetworkResponse { pub fn new(network: RpcNetworkType) -> Self { Self { network } } } impl Serializer for GetCurrentNetworkResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcNetworkType, &self.network, writer)?; Ok(()) } } impl Deserializer for GetCurrentNetworkResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let network = load!(RpcNetworkType, reader)?; Ok(Self { network }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetPeerAddressesRequest {} impl Serializer for GetPeerAddressesRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetPeerAddressesRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetPeerAddressesResponse { pub known_addresses: Vec, pub banned_addresses: Vec, } impl GetPeerAddressesResponse { pub fn new(known_addresses: Vec, banned_addresses: Vec) -> Self { Self { known_addresses, banned_addresses } } } impl Serializer for GetPeerAddressesResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.known_addresses, writer)?; store!(Vec, &self.banned_addresses, writer)?; Ok(()) } } impl Deserializer for GetPeerAddressesResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let known_addresses = load!(Vec, reader)?; let banned_addresses = load!(Vec, reader)?; Ok(Self { known_addresses, banned_addresses }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSinkRequest {} impl Serializer for GetSinkRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetSinkRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSinkResponse { pub sink: RpcHash, } impl GetSinkResponse { pub fn new(selected_tip_hash: RpcHash) -> Self { Self { sink: selected_tip_hash } } } impl Serializer for GetSinkResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.sink, writer)?; Ok(()) } } impl Deserializer for GetSinkResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let sink = load!(RpcHash, reader)?; Ok(Self { sink }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetMempoolEntryRequest { pub transaction_id: RpcTransactionId, pub include_orphan_pool: bool, // TODO: replace with `include_transaction_pool` pub filter_transaction_pool: bool, } impl GetMempoolEntryRequest { pub fn new(transaction_id: RpcTransactionId, include_orphan_pool: bool, filter_transaction_pool: bool) -> Self { Self { transaction_id, include_orphan_pool, filter_transaction_pool } } } impl Serializer for GetMempoolEntryRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcTransactionId, &self.transaction_id, writer)?; store!(bool, &self.include_orphan_pool, writer)?; store!(bool, &self.filter_transaction_pool, writer)?; Ok(()) } } impl Deserializer for GetMempoolEntryRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let transaction_id = load!(RpcTransactionId, reader)?; let include_orphan_pool = load!(bool, reader)?; let filter_transaction_pool = load!(bool, reader)?; Ok(Self { transaction_id, include_orphan_pool, filter_transaction_pool }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetMempoolEntryResponse { pub mempool_entry: RpcMempoolEntry, } impl GetMempoolEntryResponse { pub fn new(mempool_entry: RpcMempoolEntry) -> Self { Self { mempool_entry } } } impl Serializer for GetMempoolEntryResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(RpcMempoolEntry, &self.mempool_entry, writer)?; Ok(()) } } impl Deserializer for GetMempoolEntryResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let mempool_entry = deserialize!(RpcMempoolEntry, reader)?; Ok(Self { mempool_entry }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetMempoolEntriesRequest { pub include_orphan_pool: bool, // TODO: replace with `include_transaction_pool` pub filter_transaction_pool: bool, } impl GetMempoolEntriesRequest { pub fn new(include_orphan_pool: bool, filter_transaction_pool: bool) -> Self { Self { include_orphan_pool, filter_transaction_pool } } } impl Serializer for GetMempoolEntriesRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(bool, &self.include_orphan_pool, writer)?; store!(bool, &self.filter_transaction_pool, writer)?; Ok(()) } } impl Deserializer for GetMempoolEntriesRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let include_orphan_pool = load!(bool, reader)?; let filter_transaction_pool = load!(bool, reader)?; Ok(Self { include_orphan_pool, filter_transaction_pool }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetMempoolEntriesResponse { pub mempool_entries: Vec, } impl GetMempoolEntriesResponse { pub fn new(mempool_entries: Vec) -> Self { Self { mempool_entries } } } impl Serializer for GetMempoolEntriesResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(Vec, &self.mempool_entries, writer)?; Ok(()) } } impl Deserializer for GetMempoolEntriesResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let mempool_entries = deserialize!(Vec, reader)?; Ok(Self { mempool_entries }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetConnectedPeerInfoRequest {} impl Serializer for GetConnectedPeerInfoRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetConnectedPeerInfoRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetConnectedPeerInfoResponse { pub peer_info: Vec, } impl GetConnectedPeerInfoResponse { pub fn new(peer_info: Vec) -> Self { Self { peer_info } } } impl Serializer for GetConnectedPeerInfoResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.peer_info, writer)?; Ok(()) } } impl Deserializer for GetConnectedPeerInfoResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let peer_info = load!(Vec, reader)?; Ok(Self { peer_info }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct AddPeerRequest { pub peer_address: RpcContextualPeerAddress, pub is_permanent: bool, } impl AddPeerRequest { pub fn new(peer_address: RpcContextualPeerAddress, is_permanent: bool) -> Self { Self { peer_address, is_permanent } } } impl Serializer for AddPeerRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcContextualPeerAddress, &self.peer_address, writer)?; store!(bool, &self.is_permanent, writer)?; Ok(()) } } impl Deserializer for AddPeerRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let peer_address = load!(RpcContextualPeerAddress, reader)?; let is_permanent = load!(bool, reader)?; Ok(Self { peer_address, is_permanent }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct AddPeerResponse {} impl Serializer for AddPeerResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for AddPeerResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SubmitTransactionRequest { pub transaction: RpcTransaction, pub allow_orphan: bool, } impl SubmitTransactionRequest { pub fn new(transaction: RpcTransaction, allow_orphan: bool) -> Self { Self { transaction, allow_orphan } } } impl Serializer for SubmitTransactionRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(RpcTransaction, &self.transaction, writer)?; store!(bool, &self.allow_orphan, writer)?; Ok(()) } } impl Deserializer for SubmitTransactionRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let transaction = deserialize!(RpcTransaction, reader)?; let allow_orphan = load!(bool, reader)?; Ok(Self { transaction, allow_orphan }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SubmitTransactionResponse { pub transaction_id: RpcTransactionId, } impl SubmitTransactionResponse { pub fn new(transaction_id: RpcTransactionId) -> Self { Self { transaction_id } } } impl Serializer for SubmitTransactionResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcTransactionId, &self.transaction_id, writer)?; Ok(()) } } impl Deserializer for SubmitTransactionResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let transaction_id = load!(RpcTransactionId, reader)?; Ok(Self { transaction_id }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SubmitTransactionReplacementRequest { pub transaction: RpcTransaction, } impl SubmitTransactionReplacementRequest { pub fn new(transaction: RpcTransaction) -> Self { Self { transaction } } } impl Serializer for SubmitTransactionReplacementRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(RpcTransaction, &self.transaction, writer)?; Ok(()) } } impl Deserializer for SubmitTransactionReplacementRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let transaction = deserialize!(RpcTransaction, reader)?; Ok(Self { transaction }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SubmitTransactionReplacementResponse { pub transaction_id: RpcTransactionId, pub replaced_transaction: RpcTransaction, } impl SubmitTransactionReplacementResponse { pub fn new(transaction_id: RpcTransactionId, replaced_transaction: RpcTransaction) -> Self { Self { transaction_id, replaced_transaction } } } impl Serializer for SubmitTransactionReplacementResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcTransactionId, &self.transaction_id, writer)?; serialize!(RpcTransaction, &self.replaced_transaction, writer)?; Ok(()) } } impl Deserializer for SubmitTransactionReplacementResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let transaction_id = load!(RpcTransactionId, reader)?; let replaced_transaction = deserialize!(RpcTransaction, reader)?; Ok(Self { transaction_id, replaced_transaction }) } } #[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize)] #[serde(rename_all = "camelCase")] pub struct GetSubnetworkRequest { pub subnetwork_id: RpcSubnetworkId, } impl GetSubnetworkRequest { pub fn new(subnetwork_id: RpcSubnetworkId) -> Self { Self { subnetwork_id } } } impl Serializer for GetSubnetworkRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcSubnetworkId, &self.subnetwork_id, writer)?; Ok(()) } } impl Deserializer for GetSubnetworkRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let subnetwork_id = load!(RpcSubnetworkId, reader)?; Ok(Self { subnetwork_id }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSubnetworkResponse { pub gas_limit: u64, } impl GetSubnetworkResponse { pub fn new(gas_limit: u64) -> Self { Self { gas_limit } } } impl Serializer for GetSubnetworkResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.gas_limit, writer)?; Ok(()) } } impl Deserializer for GetSubnetworkResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let gas_limit = load!(u64, reader)?; Ok(Self { gas_limit }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetVirtualChainFromBlockRequest { pub start_hash: RpcHash, pub include_accepted_transaction_ids: bool, pub min_confirmation_count: Option, } impl GetVirtualChainFromBlockRequest { pub fn new(start_hash: RpcHash, include_accepted_transaction_ids: bool, min_confirmation_count: Option) -> Self { Self { start_hash, include_accepted_transaction_ids, min_confirmation_count } } } impl Serializer for GetVirtualChainFromBlockRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &2, writer)?; store!(RpcHash, &self.start_hash, writer)?; store!(bool, &self.include_accepted_transaction_ids, writer)?; store!(Option, &self.min_confirmation_count, writer)?; Ok(()) } } impl Deserializer for GetVirtualChainFromBlockRequest { fn deserialize(reader: &mut R) -> std::io::Result { let version = load!(u16, reader)?; let start_hash = load!(RpcHash, reader)?; let include_accepted_transaction_ids = load!(bool, reader)?; let min_confirmation_count = if version > 1 { load!(Option, reader)? } else { None }; Ok(Self { start_hash, include_accepted_transaction_ids, min_confirmation_count }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetVirtualChainFromBlockResponse { pub removed_chain_block_hashes: Vec, pub added_chain_block_hashes: Vec, pub accepted_transaction_ids: Vec, } impl GetVirtualChainFromBlockResponse { pub fn new( removed_chain_block_hashes: Vec, added_chain_block_hashes: Vec, accepted_transaction_ids: Vec, ) -> Self { Self { removed_chain_block_hashes, added_chain_block_hashes, accepted_transaction_ids } } } impl Serializer for GetVirtualChainFromBlockResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.removed_chain_block_hashes, writer)?; store!(Vec, &self.added_chain_block_hashes, writer)?; store!(Vec, &self.accepted_transaction_ids, writer)?; Ok(()) } } impl Deserializer for GetVirtualChainFromBlockResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let removed_chain_block_hashes = load!(Vec, reader)?; let added_chain_block_hashes = load!(Vec, reader)?; let accepted_transaction_ids = load!(Vec, reader)?; Ok(Self { removed_chain_block_hashes, added_chain_block_hashes, accepted_transaction_ids }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlocksRequest { pub low_hash: Option, pub include_blocks: bool, pub include_transactions: bool, } impl GetBlocksRequest { pub fn new(low_hash: Option, include_blocks: bool, include_transactions: bool) -> Self { Self { low_hash, include_blocks, include_transactions } } } impl Serializer for GetBlocksRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Option, &self.low_hash, writer)?; store!(bool, &self.include_blocks, writer)?; store!(bool, &self.include_transactions, writer)?; Ok(()) } } impl Deserializer for GetBlocksRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let low_hash = load!(Option, reader)?; let include_blocks = load!(bool, reader)?; let include_transactions = load!(bool, reader)?; Ok(Self { low_hash, include_blocks, include_transactions }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlocksResponse { pub block_hashes: Vec, pub blocks: Vec, } impl GetBlocksResponse { pub fn new(block_hashes: Vec, blocks: Vec) -> Self { Self { block_hashes, blocks } } } impl Serializer for GetBlocksResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.block_hashes, writer)?; serialize!(Vec, &self.blocks, writer)?; Ok(()) } } impl Deserializer for GetBlocksResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let block_hashes = load!(Vec, reader)?; let blocks = deserialize!(Vec, reader)?; Ok(Self { block_hashes, blocks }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlockCountRequest {} impl Serializer for GetBlockCountRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetBlockCountRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } pub type GetBlockCountResponse = BlockCount; #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlockDagInfoRequest {} impl Serializer for GetBlockDagInfoRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetBlockDagInfoRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlockDagInfoResponse { pub network: RpcNetworkId, pub block_count: u64, pub header_count: u64, pub tip_hashes: Vec, pub difficulty: f64, pub past_median_time: u64, // NOTE: i64 in gRPC protowire pub virtual_parent_hashes: Vec, pub pruning_point_hash: RpcHash, pub virtual_daa_score: u64, pub sink: RpcHash, } impl GetBlockDagInfoResponse { pub fn new( network: RpcNetworkId, block_count: u64, header_count: u64, tip_hashes: Vec, difficulty: f64, past_median_time: u64, virtual_parent_hashes: Vec, pruning_point_hash: RpcHash, virtual_daa_score: u64, sink: RpcHash, ) -> Self { Self { network, block_count, header_count, tip_hashes, difficulty, past_median_time, virtual_parent_hashes, pruning_point_hash, virtual_daa_score, sink, } } } impl Serializer for GetBlockDagInfoResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcNetworkId, &self.network, writer)?; store!(u64, &self.block_count, writer)?; store!(u64, &self.header_count, writer)?; store!(Vec, &self.tip_hashes, writer)?; store!(f64, &self.difficulty, writer)?; store!(u64, &self.past_median_time, writer)?; store!(Vec, &self.virtual_parent_hashes, writer)?; store!(RpcHash, &self.pruning_point_hash, writer)?; store!(u64, &self.virtual_daa_score, writer)?; store!(RpcHash, &self.sink, writer)?; Ok(()) } } impl Deserializer for GetBlockDagInfoResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let network = load!(RpcNetworkId, reader)?; let block_count = load!(u64, reader)?; let header_count = load!(u64, reader)?; let tip_hashes = load!(Vec, reader)?; let difficulty = load!(f64, reader)?; let past_median_time = load!(u64, reader)?; let virtual_parent_hashes = load!(Vec, reader)?; let pruning_point_hash = load!(RpcHash, reader)?; let virtual_daa_score = load!(u64, reader)?; let sink = load!(RpcHash, reader)?; Ok(Self { network, block_count, header_count, tip_hashes, difficulty, past_median_time, virtual_parent_hashes, pruning_point_hash, virtual_daa_score, sink, }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ResolveFinalityConflictRequest { pub finality_block_hash: RpcHash, } impl ResolveFinalityConflictRequest { pub fn new(finality_block_hash: RpcHash) -> Self { Self { finality_block_hash } } } impl Serializer for ResolveFinalityConflictRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.finality_block_hash, writer)?; Ok(()) } } impl Deserializer for ResolveFinalityConflictRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let finality_block_hash = load!(RpcHash, reader)?; Ok(Self { finality_block_hash }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ResolveFinalityConflictResponse {} impl Serializer for ResolveFinalityConflictResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for ResolveFinalityConflictResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ShutdownRequest {} impl Serializer for ShutdownRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for ShutdownRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ShutdownResponse {} impl Serializer for ShutdownResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for ShutdownResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetHeadersRequest { pub start_hash: RpcHash, pub limit: u64, pub is_ascending: bool, } impl GetHeadersRequest { pub fn new(start_hash: RpcHash, limit: u64, is_ascending: bool) -> Self { Self { start_hash, limit, is_ascending } } } impl Serializer for GetHeadersRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.start_hash, writer)?; store!(u64, &self.limit, writer)?; store!(bool, &self.is_ascending, writer)?; Ok(()) } } impl Deserializer for GetHeadersRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let start_hash = load!(RpcHash, reader)?; let limit = load!(u64, reader)?; let is_ascending = load!(bool, reader)?; Ok(Self { start_hash, limit, is_ascending }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetHeadersResponse { pub headers: Vec, } impl GetHeadersResponse { pub fn new(headers: Vec) -> Self { Self { headers } } } impl Serializer for GetHeadersResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.headers, writer)?; Ok(()) } } impl Deserializer for GetHeadersResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let headers = load!(Vec, reader)?; Ok(Self { headers }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBalanceByAddressRequest { pub address: RpcAddress, } impl GetBalanceByAddressRequest { pub fn new(address: RpcAddress) -> Self { Self { address } } } impl Serializer for GetBalanceByAddressRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcAddress, &self.address, writer)?; Ok(()) } } impl Deserializer for GetBalanceByAddressRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let address = load!(RpcAddress, reader)?; Ok(Self { address }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBalanceByAddressResponse { pub balance: u64, } impl GetBalanceByAddressResponse { pub fn new(balance: u64) -> Self { Self { balance } } } impl Serializer for GetBalanceByAddressResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.balance, writer)?; Ok(()) } } impl Deserializer for GetBalanceByAddressResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let balance = load!(u64, reader)?; Ok(Self { balance }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBalancesByAddressesRequest { pub addresses: Vec, } impl GetBalancesByAddressesRequest { pub fn new(addresses: Vec) -> Self { Self { addresses } } } impl Serializer for GetBalancesByAddressesRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.addresses, writer)?; Ok(()) } } impl Deserializer for GetBalancesByAddressesRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let addresses = load!(Vec, reader)?; Ok(Self { addresses }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBalancesByAddressesResponse { pub entries: Vec, } impl GetBalancesByAddressesResponse { pub fn new(entries: Vec) -> Self { Self { entries } } } impl Serializer for GetBalancesByAddressesResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(Vec, &self.entries, writer)?; Ok(()) } } impl Deserializer for GetBalancesByAddressesResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let entries = deserialize!(Vec, reader)?; Ok(Self { entries }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSinkBlueScoreRequest {} impl Serializer for GetSinkBlueScoreRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetSinkBlueScoreRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSinkBlueScoreResponse { pub blue_score: u64, } impl GetSinkBlueScoreResponse { pub fn new(blue_score: u64) -> Self { Self { blue_score } } } impl Serializer for GetSinkBlueScoreResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.blue_score, writer)?; Ok(()) } } impl Deserializer for GetSinkBlueScoreResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let blue_score = load!(u64, reader)?; Ok(Self { blue_score }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetUtxosByAddressesRequest { pub addresses: Vec, } impl GetUtxosByAddressesRequest { pub fn new(addresses: Vec) -> Self { Self { addresses } } } impl Serializer for GetUtxosByAddressesRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.addresses, writer)?; Ok(()) } } impl Deserializer for GetUtxosByAddressesRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let addresses = load!(Vec, reader)?; Ok(Self { addresses }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetUtxosByAddressesResponse { pub entries: Vec, } impl GetUtxosByAddressesResponse { pub fn new(entries: Vec) -> Self { Self { entries } } } impl Serializer for GetUtxosByAddressesResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(Vec, &self.entries, writer)?; Ok(()) } } impl Deserializer for GetUtxosByAddressesResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let entries = deserialize!(Vec, reader)?; Ok(Self { entries }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetUtxosByAddressesV2Request { /// Addresses to query UTXOs for. pub addresses: Vec, /// Inclusive DAA-score range start; None defaults to 0. pub from_daa_score: Option, /// Inclusive DAA-score range end; None defaults to u64::MAX. pub to_daa_score: Option, // Cursor start position; None starts from the beginning. pub cursor: Option, // Maximum number of entries to return; None defaults to 1k entries. >5k entries requires `--unsaferpc` flag on a default node. pub limit: Option, } impl GetUtxosByAddressesV2Request { pub fn new( addresses: Vec, from_daa_score: Option, to_daa_score: Option, cursor: Option, limit: Option, ) -> Self { Self { addresses, from_daa_score, to_daa_score, cursor, limit } } } impl Serializer for GetUtxosByAddressesV2Request { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.addresses, writer)?; store!(Option, &self.from_daa_score, writer)?; store!(Option, &self.to_daa_score, writer)?; store!(Option, &self.cursor, writer)?; store!(Option, &self.limit, writer)?; Ok(()) } } impl Deserializer for GetUtxosByAddressesV2Request { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let addresses = load!(Vec, reader)?; let from_daa_score = load!(Option, reader)?; let to_daa_score = load!(Option, reader)?; let cursor = load!(Option, reader)?; let limit = load!(Option, reader)?; Ok(Self { addresses, from_daa_score, to_daa_score, cursor, limit }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetUtxosByAddressesV2Response { /// UTXO entries for the requested addresses and DAA-score range. pub entries: Vec, /// Cursor address for the next page; None means there is no next page. pub next_cursor: Option, } impl GetUtxosByAddressesV2Response { pub fn new(entries: Vec, next_cursor: Option) -> Self { Self { entries, next_cursor } } } impl Serializer for GetUtxosByAddressesV2Response { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(Vec, &self.entries, writer)?; serialize!(Option, &self.next_cursor, writer)?; Ok(()) } } impl Deserializer for GetUtxosByAddressesV2Response { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let entries = deserialize!(Vec, reader)?; let next_cursor = deserialize!(Option, reader)?; Ok(Self { entries, next_cursor }) } } /// Represents a UTXO entry of a covenant id returned by the `GetUtxosByCovenantIds` RPC. #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct RpcUtxosByCovenantIdsEntry { pub address: Option, pub outpoint: RpcTransactionOutpoint, pub utxo_entry: RpcUtxoEntry, } impl Serializer for RpcUtxosByCovenantIdsEntry { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u8, &1, writer)?; // version store!(Option, &self.address, writer)?; serialize!(RpcTransactionOutpoint, &self.outpoint, writer)?; serialize!(RpcUtxoEntry, &self.utxo_entry, writer) } } impl Deserializer for RpcUtxosByCovenantIdsEntry { fn deserialize(reader: &mut R) -> std::io::Result { let _version: u8 = load!(u8, reader)?; let address = load!(Option, reader)?; let outpoint = deserialize!(RpcTransactionOutpoint, reader)?; let utxo_entry = deserialize!(RpcUtxoEntry, reader)?; Ok(Self { address, outpoint, utxo_entry }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetUtxosByCovenantIdsRequest { /// Covenant ids to query UTXOs for. pub covenant_ids: Vec, /// Script public keys to include; an empty list includes every script public key. pub script_public_keys: Vec, /// Inclusive DAA-score range start; None defaults to 0. pub from_daa_score: Option, /// Inclusive DAA-score range end; None defaults to u64::MAX. pub to_daa_score: Option, /// Cursor start position; None starts from the beginning. pub cursor: Option, /// Budget of weighted db operations spent for the page; a seek costs 10 units, an iterator advance costs 1. None defaults to 1k units. Entries per page never exceed the budget. >5k units requires `--unsaferpc` flag on a default node. pub budget: Option, } impl GetUtxosByCovenantIdsRequest { pub fn new( covenant_ids: Vec, script_public_keys: Vec, from_daa_score: Option, to_daa_score: Option, cursor: Option, budget: Option, ) -> Self { Self { covenant_ids, script_public_keys, from_daa_score, to_daa_score, cursor, budget } } } impl Serializer for GetUtxosByCovenantIdsRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.covenant_ids, writer)?; store!(Vec, &self.script_public_keys, writer)?; store!(Option, &self.from_daa_score, writer)?; store!(Option, &self.to_daa_score, writer)?; store!(Option, &self.cursor, writer)?; store!(Option, &self.budget, writer)?; Ok(()) } } impl Deserializer for GetUtxosByCovenantIdsRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let covenant_ids = load!(Vec, reader)?; let script_public_keys = load!(Vec, reader)?; let from_daa_score = load!(Option, reader)?; let to_daa_score = load!(Option, reader)?; let cursor = load!(Option, reader)?; let budget = load!(Option, reader)?; Ok(Self { covenant_ids, script_public_keys, from_daa_score, to_daa_score, cursor, budget }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetUtxosByCovenantIdsResponse { /// UTXO entries for the requested covenant ids and DAA-score range, in ascending covenant id order. pub entries: Vec, /// Cursor for the next page; None means there is no next page. pub next_cursor: Option, } impl GetUtxosByCovenantIdsResponse { pub fn new(entries: Vec, next_cursor: Option) -> Self { Self { entries, next_cursor } } } impl Serializer for GetUtxosByCovenantIdsResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(Vec, &self.entries, writer)?; serialize!(Option, &self.next_cursor, writer)?; Ok(()) } } impl Deserializer for GetUtxosByCovenantIdsResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let entries = deserialize!(Vec, reader)?; let next_cursor = deserialize!(Option, reader)?; Ok(Self { entries, next_cursor }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct BanRequest { pub ip: RpcIpAddress, } impl BanRequest { pub fn new(ip: RpcIpAddress) -> Self { Self { ip } } } impl Serializer for BanRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcIpAddress, &self.ip, writer)?; Ok(()) } } impl Deserializer for BanRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let ip = load!(RpcIpAddress, reader)?; Ok(Self { ip }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct BanResponse {} impl Serializer for BanResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for BanResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct UnbanRequest { pub ip: RpcIpAddress, } impl UnbanRequest { pub fn new(ip: RpcIpAddress) -> Self { Self { ip } } } impl Serializer for UnbanRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcIpAddress, &self.ip, writer)?; Ok(()) } } impl Deserializer for UnbanRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let ip = load!(RpcIpAddress, reader)?; Ok(Self { ip }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct UnbanResponse {} impl Serializer for UnbanResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for UnbanResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct EstimateNetworkHashesPerSecondRequest { pub window_size: u32, pub start_hash: Option, } impl EstimateNetworkHashesPerSecondRequest { pub fn new(window_size: u32, start_hash: Option) -> Self { Self { window_size, start_hash } } } impl Serializer for EstimateNetworkHashesPerSecondRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u32, &self.window_size, writer)?; store!(Option, &self.start_hash, writer)?; Ok(()) } } impl Deserializer for EstimateNetworkHashesPerSecondRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let window_size = load!(u32, reader)?; let start_hash = load!(Option, reader)?; Ok(Self { window_size, start_hash }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct EstimateNetworkHashesPerSecondResponse { pub network_hashes_per_second: u64, } impl EstimateNetworkHashesPerSecondResponse { pub fn new(network_hashes_per_second: u64) -> Self { Self { network_hashes_per_second } } } impl Serializer for EstimateNetworkHashesPerSecondResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.network_hashes_per_second, writer)?; Ok(()) } } impl Deserializer for EstimateNetworkHashesPerSecondResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let network_hashes_per_second = load!(u64, reader)?; Ok(Self { network_hashes_per_second }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetMempoolEntriesByAddressesRequest { pub addresses: Vec, pub include_orphan_pool: bool, // TODO: replace with `include_transaction_pool` pub filter_transaction_pool: bool, } impl GetMempoolEntriesByAddressesRequest { pub fn new(addresses: Vec, include_orphan_pool: bool, filter_transaction_pool: bool) -> Self { Self { addresses, include_orphan_pool, filter_transaction_pool } } } impl Serializer for GetMempoolEntriesByAddressesRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.addresses, writer)?; store!(bool, &self.include_orphan_pool, writer)?; store!(bool, &self.filter_transaction_pool, writer)?; Ok(()) } } impl Deserializer for GetMempoolEntriesByAddressesRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let addresses = load!(Vec, reader)?; let include_orphan_pool = load!(bool, reader)?; let filter_transaction_pool = load!(bool, reader)?; Ok(Self { addresses, include_orphan_pool, filter_transaction_pool }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetMempoolEntriesByAddressesResponse { pub entries: Vec, } impl GetMempoolEntriesByAddressesResponse { pub fn new(entries: Vec) -> Self { Self { entries } } } impl Serializer for GetMempoolEntriesByAddressesResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(Vec, &self.entries, writer)?; Ok(()) } } impl Deserializer for GetMempoolEntriesByAddressesResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let entries = deserialize!(Vec, reader)?; Ok(Self { entries }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetCoinSupplyRequest {} impl Serializer for GetCoinSupplyRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetCoinSupplyRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetCoinSupplyResponse { pub max_sompi: u64, pub circulating_sompi: u64, } impl GetCoinSupplyResponse { pub fn new(max_sompi: u64, circulating_sompi: u64) -> Self { Self { max_sompi, circulating_sompi } } } impl Serializer for GetCoinSupplyResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.max_sompi, writer)?; store!(u64, &self.circulating_sompi, writer)?; Ok(()) } } impl Deserializer for GetCoinSupplyResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let max_sompi = load!(u64, reader)?; let circulating_sompi = load!(u64, reader)?; Ok(Self { max_sompi, circulating_sompi }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct PingRequest {} impl Serializer for PingRequest { fn serialize(&self, _writer: &mut W) -> std::io::Result<()> { Ok(()) } } impl Deserializer for PingRequest { fn deserialize(_reader: &mut R) -> std::io::Result { Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct PingResponse {} impl Serializer for PingResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u8, &1, writer)?; Ok(()) } } impl Deserializer for PingResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u8, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize)] #[serde(rename_all = "camelCase")] pub struct ConnectionsProfileData { pub cpu_usage: f32, pub memory_usage: u64, } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetConnectionsRequest { pub include_profile_data: bool, } impl Serializer for GetConnectionsRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u8, &1, writer)?; store!(bool, &self.include_profile_data, writer)?; Ok(()) } } impl Deserializer for GetConnectionsRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u8, reader)?; let include_profile_data = load!(bool, reader)?; Ok(Self { include_profile_data }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetConnectionsResponse { pub clients: u32, pub peers: u16, pub profile_data: Option, } impl Serializer for GetConnectionsResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u32, &self.clients, writer)?; store!(u16, &self.peers, writer)?; store!(Option, &self.profile_data, writer)?; Ok(()) } } impl Deserializer for GetConnectionsResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let clients = load!(u32, reader)?; let peers = load!(u16, reader)?; let extra = load!(Option, reader)?; Ok(Self { clients, peers, profile_data: extra }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSystemInfoRequest {} impl Serializer for GetSystemInfoRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetSystemInfoRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSystemInfoResponse { pub version: String, pub system_id: Option>, pub git_hash: Option>, pub cpu_physical_cores: u16, pub total_memory: u64, pub fd_limit: u32, pub proxy_socket_limit_per_cpu_core: Option, } impl std::fmt::Debug for GetSystemInfoResponse { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("GetSystemInfoResponse") .field("version", &self.version) .field("system_id", &self.system_id.as_ref().map(|id| id.to_hex())) .field("git_hash", &self.git_hash.as_ref().map(|hash| hash.to_hex())) .field("cpu_physical_cores", &self.cpu_physical_cores) .field("total_memory", &self.total_memory) .field("fd_limit", &self.fd_limit) .field("proxy_socket_limit_per_cpu_core", &self.proxy_socket_limit_per_cpu_core) .finish() } } impl Serializer for GetSystemInfoResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &2, writer)?; store!(String, &self.version, writer)?; store!(Option>, &self.system_id, writer)?; store!(Option>, &self.git_hash, writer)?; store!(u16, &self.cpu_physical_cores, writer)?; store!(u64, &self.total_memory, writer)?; store!(u32, &self.fd_limit, writer)?; store!(Option, &self.proxy_socket_limit_per_cpu_core, writer)?; Ok(()) } } impl Deserializer for GetSystemInfoResponse { fn deserialize(reader: &mut R) -> std::io::Result { let payload_version = load!(u16, reader)?; let version = load!(String, reader)?; let system_id = load!(Option>, reader)?; let git_hash = load!(Option>, reader)?; let cpu_physical_cores = load!(u16, reader)?; let total_memory = load!(u64, reader)?; let fd_limit = load!(u32, reader)?; let proxy_socket_limit_per_cpu_core = if payload_version > 1 { load!(Option, reader)? } else { None }; Ok(Self { version, system_id, git_hash, cpu_physical_cores, total_memory, fd_limit, proxy_socket_limit_per_cpu_core }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetMetricsRequest { pub process_metrics: bool, pub connection_metrics: bool, pub bandwidth_metrics: bool, pub consensus_metrics: bool, pub storage_metrics: bool, pub custom_metrics: bool, } impl Serializer for GetMetricsRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(bool, &self.process_metrics, writer)?; store!(bool, &self.connection_metrics, writer)?; store!(bool, &self.bandwidth_metrics, writer)?; store!(bool, &self.consensus_metrics, writer)?; store!(bool, &self.storage_metrics, writer)?; store!(bool, &self.custom_metrics, writer)?; Ok(()) } } impl Deserializer for GetMetricsRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let process_metrics = load!(bool, reader)?; let connection_metrics = load!(bool, reader)?; let bandwidth_metrics = load!(bool, reader)?; let consensus_metrics = load!(bool, reader)?; let storage_metrics = load!(bool, reader)?; let custom_metrics = load!(bool, reader)?; Ok(Self { process_metrics, connection_metrics, bandwidth_metrics, consensus_metrics, storage_metrics, custom_metrics }) } } #[derive(Default, Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ProcessMetrics { pub resident_set_size: u64, pub virtual_memory_size: u64, pub core_num: u32, pub cpu_usage: f32, pub fd_num: u32, pub disk_io_read_bytes: u64, pub disk_io_write_bytes: u64, pub disk_io_read_per_sec: f32, pub disk_io_write_per_sec: f32, } impl Serializer for ProcessMetrics { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.resident_set_size, writer)?; store!(u64, &self.virtual_memory_size, writer)?; store!(u32, &self.core_num, writer)?; store!(f32, &self.cpu_usage, writer)?; store!(u32, &self.fd_num, writer)?; store!(u64, &self.disk_io_read_bytes, writer)?; store!(u64, &self.disk_io_write_bytes, writer)?; store!(f32, &self.disk_io_read_per_sec, writer)?; store!(f32, &self.disk_io_write_per_sec, writer)?; Ok(()) } } impl Deserializer for ProcessMetrics { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let resident_set_size = load!(u64, reader)?; let virtual_memory_size = load!(u64, reader)?; let core_num = load!(u32, reader)?; let cpu_usage = load!(f32, reader)?; let fd_num = load!(u32, reader)?; let disk_io_read_bytes = load!(u64, reader)?; let disk_io_write_bytes = load!(u64, reader)?; let disk_io_read_per_sec = load!(f32, reader)?; let disk_io_write_per_sec = load!(f32, reader)?; Ok(Self { resident_set_size, virtual_memory_size, core_num, cpu_usage, fd_num, disk_io_read_bytes, disk_io_write_bytes, disk_io_read_per_sec, disk_io_write_per_sec, }) } } #[derive(Default, Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ConnectionMetrics { pub borsh_live_connections: u32, pub borsh_connection_attempts: u64, pub borsh_handshake_failures: u64, pub json_live_connections: u32, pub json_connection_attempts: u64, pub json_handshake_failures: u64, pub active_peers: u32, } impl Serializer for ConnectionMetrics { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u32, &self.borsh_live_connections, writer)?; store!(u64, &self.borsh_connection_attempts, writer)?; store!(u64, &self.borsh_handshake_failures, writer)?; store!(u32, &self.json_live_connections, writer)?; store!(u64, &self.json_connection_attempts, writer)?; store!(u64, &self.json_handshake_failures, writer)?; store!(u32, &self.active_peers, writer)?; Ok(()) } } impl Deserializer for ConnectionMetrics { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let borsh_live_connections = load!(u32, reader)?; let borsh_connection_attempts = load!(u64, reader)?; let borsh_handshake_failures = load!(u64, reader)?; let json_live_connections = load!(u32, reader)?; let json_connection_attempts = load!(u64, reader)?; let json_handshake_failures = load!(u64, reader)?; let active_peers = load!(u32, reader)?; Ok(Self { borsh_live_connections, borsh_connection_attempts, borsh_handshake_failures, json_live_connections, json_connection_attempts, json_handshake_failures, active_peers, }) } } #[derive(Default, Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct BandwidthMetrics { pub borsh_bytes_tx: u64, pub borsh_bytes_rx: u64, pub json_bytes_tx: u64, pub json_bytes_rx: u64, pub p2p_bytes_tx: u64, pub p2p_bytes_rx: u64, pub grpc_bytes_tx: u64, pub grpc_bytes_rx: u64, } impl Serializer for BandwidthMetrics { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.borsh_bytes_tx, writer)?; store!(u64, &self.borsh_bytes_rx, writer)?; store!(u64, &self.json_bytes_tx, writer)?; store!(u64, &self.json_bytes_rx, writer)?; store!(u64, &self.p2p_bytes_tx, writer)?; store!(u64, &self.p2p_bytes_rx, writer)?; store!(u64, &self.grpc_bytes_tx, writer)?; store!(u64, &self.grpc_bytes_rx, writer)?; Ok(()) } } impl Deserializer for BandwidthMetrics { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let borsh_bytes_tx = load!(u64, reader)?; let borsh_bytes_rx = load!(u64, reader)?; let json_bytes_tx = load!(u64, reader)?; let json_bytes_rx = load!(u64, reader)?; let p2p_bytes_tx = load!(u64, reader)?; let p2p_bytes_rx = load!(u64, reader)?; let grpc_bytes_tx = load!(u64, reader)?; let grpc_bytes_rx = load!(u64, reader)?; Ok(Self { borsh_bytes_tx, borsh_bytes_rx, json_bytes_tx, json_bytes_rx, p2p_bytes_tx, p2p_bytes_rx, grpc_bytes_tx, grpc_bytes_rx, }) } } #[derive(Default, Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ConsensusMetrics { pub node_blocks_submitted_count: u64, pub node_headers_processed_count: u64, pub node_dependencies_processed_count: u64, pub node_bodies_processed_count: u64, pub node_transactions_processed_count: u64, pub node_chain_blocks_processed_count: u64, pub node_mass_processed_count: u64, pub node_database_blocks_count: u64, pub node_database_headers_count: u64, pub network_mempool_size: u64, pub network_tip_hashes_count: u32, pub network_difficulty: f64, pub network_past_median_time: u64, pub network_virtual_parent_hashes_count: u32, pub network_virtual_daa_score: u64, } impl Serializer for ConsensusMetrics { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.node_blocks_submitted_count, writer)?; store!(u64, &self.node_headers_processed_count, writer)?; store!(u64, &self.node_dependencies_processed_count, writer)?; store!(u64, &self.node_bodies_processed_count, writer)?; store!(u64, &self.node_transactions_processed_count, writer)?; store!(u64, &self.node_chain_blocks_processed_count, writer)?; store!(u64, &self.node_mass_processed_count, writer)?; store!(u64, &self.node_database_blocks_count, writer)?; store!(u64, &self.node_database_headers_count, writer)?; store!(u64, &self.network_mempool_size, writer)?; store!(u32, &self.network_tip_hashes_count, writer)?; store!(f64, &self.network_difficulty, writer)?; store!(u64, &self.network_past_median_time, writer)?; store!(u32, &self.network_virtual_parent_hashes_count, writer)?; store!(u64, &self.network_virtual_daa_score, writer)?; Ok(()) } } impl Deserializer for ConsensusMetrics { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let node_blocks_submitted_count = load!(u64, reader)?; let node_headers_processed_count = load!(u64, reader)?; let node_dependencies_processed_count = load!(u64, reader)?; let node_bodies_processed_count = load!(u64, reader)?; let node_transactions_processed_count = load!(u64, reader)?; let node_chain_blocks_processed_count = load!(u64, reader)?; let node_mass_processed_count = load!(u64, reader)?; let node_database_blocks_count = load!(u64, reader)?; let node_database_headers_count = load!(u64, reader)?; let network_mempool_size = load!(u64, reader)?; let network_tip_hashes_count = load!(u32, reader)?; let network_difficulty = load!(f64, reader)?; let network_past_median_time = load!(u64, reader)?; let network_virtual_parent_hashes_count = load!(u32, reader)?; let network_virtual_daa_score = load!(u64, reader)?; Ok(Self { node_blocks_submitted_count, node_headers_processed_count, node_dependencies_processed_count, node_bodies_processed_count, node_transactions_processed_count, node_chain_blocks_processed_count, node_mass_processed_count, node_database_blocks_count, node_database_headers_count, network_mempool_size, network_tip_hashes_count, network_difficulty, network_past_median_time, network_virtual_parent_hashes_count, network_virtual_daa_score, }) } } #[derive(Default, Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct StorageMetrics { pub storage_size_bytes: u64, } impl Serializer for StorageMetrics { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.storage_size_bytes, writer)?; Ok(()) } } impl Deserializer for StorageMetrics { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let storage_size_bytes = load!(u64, reader)?; Ok(Self { storage_size_bytes }) } } // TODO: Custom metrics dictionary #[derive(Clone, Debug, Serialize, Deserialize)] pub enum CustomMetricValue { Placeholder, } impl Serializer for CustomMetricValue { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for CustomMetricValue { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(CustomMetricValue::Placeholder) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetMetricsResponse { pub server_time: u64, pub process_metrics: Option, pub connection_metrics: Option, pub bandwidth_metrics: Option, pub consensus_metrics: Option, pub storage_metrics: Option, // TODO: this is currently a placeholder pub custom_metrics: Option>, } impl GetMetricsResponse { pub fn new( server_time: u64, process_metrics: Option, connection_metrics: Option, bandwidth_metrics: Option, consensus_metrics: Option, storage_metrics: Option, custom_metrics: Option>, ) -> Self { Self { process_metrics, connection_metrics, bandwidth_metrics, consensus_metrics, storage_metrics, server_time, custom_metrics, } } } impl Serializer for GetMetricsResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.server_time, writer)?; serialize!(Option, &self.process_metrics, writer)?; serialize!(Option, &self.connection_metrics, writer)?; serialize!(Option, &self.bandwidth_metrics, writer)?; serialize!(Option, &self.consensus_metrics, writer)?; serialize!(Option, &self.storage_metrics, writer)?; serialize!(Option>, &self.custom_metrics, writer)?; Ok(()) } } impl Deserializer for GetMetricsResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let server_time = load!(u64, reader)?; let process_metrics = deserialize!(Option, reader)?; let connection_metrics = deserialize!(Option, reader)?; let bandwidth_metrics = deserialize!(Option, reader)?; let consensus_metrics = deserialize!(Option, reader)?; let storage_metrics = deserialize!(Option, reader)?; let custom_metrics = deserialize!(Option>, reader)?; Ok(Self { server_time, process_metrics, connection_metrics, bandwidth_metrics, consensus_metrics, storage_metrics, custom_metrics, }) } } #[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize)] #[serde(rename_all = "camelCase")] #[borsh(use_discriminant = true)] pub enum RpcCaps { Full = 0, Blocks, UtxoIndex, Mempool, Metrics, Visualizer, Mining, } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetServerInfoRequest {} impl Serializer for GetServerInfoRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetServerInfoRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetServerInfoResponse { pub rpc_api_version: u16, pub rpc_api_revision: u16, pub server_version: String, pub network_id: RpcNetworkId, pub has_utxo_index: bool, pub is_synced: bool, pub virtual_daa_score: u64, } impl Serializer for GetServerInfoResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u16, &self.rpc_api_version, writer)?; store!(u16, &self.rpc_api_revision, writer)?; store!(String, &self.server_version, writer)?; store!(RpcNetworkId, &self.network_id, writer)?; store!(bool, &self.has_utxo_index, writer)?; store!(bool, &self.is_synced, writer)?; store!(u64, &self.virtual_daa_score, writer)?; Ok(()) } } impl Deserializer for GetServerInfoResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let rpc_api_version = load!(u16, reader)?; let rpc_api_revision = load!(u16, reader)?; let server_version = load!(String, reader)?; let network_id = load!(RpcNetworkId, reader)?; let has_utxo_index = load!(bool, reader)?; let is_synced = load!(bool, reader)?; let virtual_daa_score = load!(u64, reader)?; Ok(Self { rpc_api_version, rpc_api_revision, server_version, network_id, has_utxo_index, is_synced, virtual_daa_score }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSyncStatusRequest {} impl Serializer for GetSyncStatusRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetSyncStatusRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSyncStatusResponse { pub is_synced: bool, } impl Serializer for GetSyncStatusResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(bool, &self.is_synced, writer)?; Ok(()) } } impl Deserializer for GetSyncStatusResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let is_synced = load!(bool, reader)?; Ok(Self { is_synced }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetDaaScoreTimestampEstimateRequest { pub daa_scores: Vec, } impl GetDaaScoreTimestampEstimateRequest { pub fn new(daa_scores: Vec) -> Self { Self { daa_scores } } } impl Serializer for GetDaaScoreTimestampEstimateRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.daa_scores, writer)?; Ok(()) } } impl Deserializer for GetDaaScoreTimestampEstimateRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let daa_scores = load!(Vec, reader)?; Ok(Self { daa_scores }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetDaaScoreTimestampEstimateResponse { pub timestamps: Vec, } impl GetDaaScoreTimestampEstimateResponse { pub fn new(timestamps: Vec) -> Self { Self { timestamps } } } impl Serializer for GetDaaScoreTimestampEstimateResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.timestamps, writer)?; Ok(()) } } impl Deserializer for GetDaaScoreTimestampEstimateResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let timestamps = load!(Vec, reader)?; Ok(Self { timestamps }) } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Fee rate estimations #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetFeeEstimateRequest {} impl Serializer for GetFeeEstimateRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for GetFeeEstimateRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetFeeEstimateResponse { pub estimate: RpcFeeEstimate, } impl Serializer for GetFeeEstimateResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(RpcFeeEstimate, &self.estimate, writer)?; Ok(()) } } impl Deserializer for GetFeeEstimateResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let estimate = deserialize!(RpcFeeEstimate, reader)?; Ok(Self { estimate }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetFeeEstimateExperimentalRequest { pub verbose: bool, } impl Serializer for GetFeeEstimateExperimentalRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(bool, &self.verbose, writer)?; Ok(()) } } impl Deserializer for GetFeeEstimateExperimentalRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let verbose = load!(bool, reader)?; Ok(Self { verbose }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetFeeEstimateExperimentalResponse { /// The usual feerate estimate response pub estimate: RpcFeeEstimate, /// Experimental verbose data pub verbose: Option, } impl Serializer for GetFeeEstimateExperimentalResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(RpcFeeEstimate, &self.estimate, writer)?; serialize!(Option, &self.verbose, writer)?; Ok(()) } } impl Deserializer for GetFeeEstimateExperimentalResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let estimate = deserialize!(RpcFeeEstimate, reader)?; let verbose = deserialize!(Option, reader)?; Ok(Self { estimate, verbose }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetCurrentBlockColorRequest { pub hash: RpcHash, } impl Serializer for GetCurrentBlockColorRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.hash, writer)?; Ok(()) } } impl Deserializer for GetCurrentBlockColorRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let hash = load!(RpcHash, reader)?; Ok(Self { hash }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetCurrentBlockColorResponse { pub blue: bool, } impl Serializer for GetCurrentBlockColorResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(bool, &self.blue, writer)?; Ok(()) } } impl Deserializer for GetCurrentBlockColorResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let blue = load!(bool, reader)?; Ok(Self { blue }) } } #[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize)] #[serde(rename_all = "lowercase")] #[borsh(use_discriminant = true)] #[repr(i32)] pub enum RpcBlockColor { Unknown = 0, Blue = 1, Red = 2, } impl From for i32 { fn from(value: RpcBlockColor) -> Self { value as i32 } } impl From for RpcBlockColor { fn from(value: i32) -> Self { match value { 1 => Self::Blue, 2 => Self::Red, _ => Self::Unknown, } } } impl Serializer for RpcBlockColor { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u8, &1, writer)?; store!(i32, &i32::from(*self), writer)?; Ok(()) } } impl Deserializer for RpcBlockColor { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u8, reader)?; let value = load!(i32, reader)?; Ok(RpcBlockColor::from(value)) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlockRewardInfoRequest { pub hash: RpcHash, } impl GetBlockRewardInfoRequest { pub fn new(hash: RpcHash) -> Self { Self { hash } } } impl Serializer for GetBlockRewardInfoRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.hash, writer)?; Ok(()) } } impl Deserializer for GetBlockRewardInfoRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let hash = load!(RpcHash, reader)?; Ok(Self { hash }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetBlockRewardInfoResponse { pub header: RpcHeader, pub block_color: RpcBlockColor, /// guaranteed to be populated when block color != Unknown pub confirmation_count: Option, /// guaranteed to be populated when block color != Unknown pub merging_chain_block_hash: Option, /// guaranteed to be populated when block color == Blue pub reward_amount: Option, } impl GetBlockRewardInfoResponse { pub fn new( header: RpcHeader, block_color: RpcBlockColor, confirmation_count: Option, merging_chain_block_hash: Option, reward_amount: Option, ) -> Self { Self { header, block_color, confirmation_count, merging_chain_block_hash, reward_amount } } } impl Serializer for GetBlockRewardInfoResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHeader, &self.header, writer)?; store!(RpcBlockColor, &self.block_color, writer)?; store!(Option, &self.confirmation_count, writer)?; store!(Option, &self.merging_chain_block_hash, writer)?; store!(Option, &self.reward_amount, writer)?; Ok(()) } } impl Deserializer for GetBlockRewardInfoResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let header = load!(RpcHeader, reader)?; let block_color = load!(RpcBlockColor, reader)?; let confirmation_count = load!(Option, reader)?; let merging_chain_block_hash = load!(Option, reader)?; let reward_amount = load!(Option, reader)?; Ok(Self { header, block_color, confirmation_count, merging_chain_block_hash, reward_amount }) } } /// Requests fully populated transactions accepted by the specified block. /// The request must contain 1-8192 unique transaction IDs. Results follow the requested order. /// Typical mergesets contain far fewer transactions; larger batches can be split into multiple /// calls using the same accepting-block selector. /// /// A DAA-score selector must identify the accepting block in the node's current virtual selected-parent /// chain at query time. A reorg can change the accepting block and its DAA score, causing a lookup /// using a previously observed score to fail. /// /// To retrieve a UTXO's creating transaction, obtain the UTXO from a UTXO-change notification or a /// UTXO/covenant index query, then use its outpoint's transaction ID and its entry's `block_daa_score`. /// The transaction must still be within the node's retained history. For newly observed UTXOs, /// consider waiting 1-2 seconds for the accepting block to stabilize, or handle lookup failures by /// refreshing the UTXO data and retrying with its current score if it is still present. This delay /// reduces small-reorg races; it does not guarantee finality. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetTransactionsByAcceptingBlockRequest { pub accepting_block: RpcAcceptingBlock, pub transaction_ids: Vec, } impl GetTransactionsByAcceptingBlockRequest { pub fn new(accepting_block: RpcAcceptingBlock, transaction_ids: Vec) -> Self { Self { accepting_block, transaction_ids } } } impl Serializer for GetTransactionsByAcceptingBlockRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(RpcAcceptingBlock, &self.accepting_block, writer)?; store!(Vec, &self.transaction_ids, writer)?; Ok(()) } } impl Deserializer for GetTransactionsByAcceptingBlockRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let accepting_block = deserialize!(RpcAcceptingBlock, reader)?; let transaction_ids = load!(Vec, reader)?; Ok(Self { accepting_block, transaction_ids }) } } /// Full transactions with populated input UTXOs. Containing-block metadata is not supplied. #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetTransactionsByAcceptingBlockResponse { pub transactions: Vec, } impl Serializer for GetTransactionsByAcceptingBlockResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(Vec, &self.transactions, writer)?; Ok(()) } } impl Deserializer for GetTransactionsByAcceptingBlockResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let transactions = deserialize!(Vec, reader)?; Ok(Self { transactions }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetUtxoReturnAddressRequest { pub txid: RpcHash, pub accepting_block_daa_score: u64, } impl GetUtxoReturnAddressRequest { pub fn new(txid: RpcHash, accepting_block_daa_score: u64) -> Self { Self { txid, accepting_block_daa_score } } } impl Serializer for GetUtxoReturnAddressRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.txid, writer)?; store!(u64, &self.accepting_block_daa_score, writer)?; Ok(()) } } impl Deserializer for GetUtxoReturnAddressRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let txid = load!(RpcHash, reader)?; let accepting_block_daa_score = load!(u64, reader)?; Ok(Self { txid, accepting_block_daa_score }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetUtxoReturnAddressResponse { pub return_address: RpcAddress, } impl GetUtxoReturnAddressResponse { pub fn new(return_address: RpcAddress) -> Self { Self { return_address } } } impl Serializer for GetUtxoReturnAddressResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcAddress, &self.return_address, writer)?; Ok(()) } } impl Deserializer for GetUtxoReturnAddressResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let return_address = load!(RpcAddress, reader)?; Ok(Self { return_address }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetVirtualChainFromBlockV2Request { pub start_hash: RpcHash, pub data_verbosity_level: Option, pub min_confirmation_count: Option, } impl GetVirtualChainFromBlockV2Request { pub fn new(start_hash: RpcHash, data_verbosity_level: Option, min_confirmation_count: Option) -> Self { Self { start_hash, data_verbosity_level, min_confirmation_count } } } impl Serializer for GetVirtualChainFromBlockV2Request { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.start_hash, writer)?; serialize!(Option, &self.data_verbosity_level, writer)?; store!(Option, &self.min_confirmation_count, writer)?; Ok(()) } } impl Deserializer for GetVirtualChainFromBlockV2Request { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let start_hash = load!(RpcHash, reader)?; let data_verbosity_level = deserialize!(Option, reader)?; let min_confirmation_count = load!(Option, reader)?; Ok(Self { start_hash, data_verbosity_level, min_confirmation_count }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetVirtualChainFromBlockV2Response { /// always present, no matter the verbosity level pub removed_chain_block_hashes: Arc>, /// always present, no matter the verbosity level pub added_chain_block_hashes: Arc>, /// struct properties are optionally returned depending on the verbosity level pub chain_block_accepted_transactions: Arc>, } impl Serializer for GetVirtualChainFromBlockV2Response { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.removed_chain_block_hashes, writer)?; store!(Vec, &self.added_chain_block_hashes, writer)?; serialize!(Vec, &self.chain_block_accepted_transactions, writer)?; Ok(()) } } impl Deserializer for GetVirtualChainFromBlockV2Response { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let removed_chain_block_hashes = load!(Vec, reader)?; let added_chain_block_hashes = load!(Vec, reader)?; let chain_block_accepted_transactions = deserialize!(Vec, reader)?; Ok(Self { removed_chain_block_hashes: removed_chain_block_hashes.into(), added_chain_block_hashes: added_chain_block_hashes.into(), chain_block_accepted_transactions: chain_block_accepted_transactions.into(), }) } } // ---------------------------------------------------------------------------- // Subscriptions & notifications // ---------------------------------------------------------------------------- // ~~~~~~~~~~~~~~~~~~~~~~ // BlockAddedNotification /// NotifyBlockAddedRequest registers this connection for blockAdded notifications. /// /// See: BlockAddedNotification #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyBlockAddedRequest { pub command: Command, } impl NotifyBlockAddedRequest { pub fn new(command: Command) -> Self { Self { command } } } impl Serializer for NotifyBlockAddedRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Command, &self.command, writer)?; Ok(()) } } impl Deserializer for NotifyBlockAddedRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let command = load!(Command, reader)?; Ok(Self { command }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyBlockAddedResponse {} impl Serializer for NotifyBlockAddedResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for NotifyBlockAddedResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } /// BlockAddedNotification is sent whenever a blocks has been added (NOT accepted) /// into the DAG. /// /// See: NotifyBlockAddedRequest #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct BlockAddedNotification { pub block: Arc, } impl Serializer for BlockAddedNotification { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(RpcBlock, &self.block, writer)?; Ok(()) } } impl Deserializer for BlockAddedNotification { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let block = deserialize!(RpcBlock, reader)?; Ok(Self { block: block.into() }) } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // VirtualChainChangedNotification // NotifyVirtualChainChangedRequest registers this connection for // virtualDaaScoreChanged notifications. // // See: VirtualChainChangedNotification #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyVirtualChainChangedRequest { pub include_accepted_transaction_ids: bool, pub command: Command, } impl NotifyVirtualChainChangedRequest { pub fn new(include_accepted_transaction_ids: bool, command: Command) -> Self { Self { include_accepted_transaction_ids, command } } } impl Serializer for NotifyVirtualChainChangedRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(bool, &self.include_accepted_transaction_ids, writer)?; store!(Command, &self.command, writer)?; Ok(()) } } impl Deserializer for NotifyVirtualChainChangedRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let include_accepted_transaction_ids = load!(bool, reader)?; let command = load!(Command, reader)?; Ok(Self { include_accepted_transaction_ids, command }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyVirtualChainChangedResponse {} impl Serializer for NotifyVirtualChainChangedResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for NotifyVirtualChainChangedResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } // VirtualChainChangedNotification is sent whenever the DAG's selected parent // chain had changed. // // See: NotifyVirtualChainChangedRequest #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct VirtualChainChangedNotification { pub removed_chain_block_hashes: Arc>, pub added_chain_block_hashes: Arc>, pub accepted_transaction_ids: Arc>, } impl Serializer for VirtualChainChangedNotification { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.removed_chain_block_hashes, writer)?; store!(Vec, &self.added_chain_block_hashes, writer)?; store!(Vec, &self.accepted_transaction_ids, writer)?; Ok(()) } } impl Deserializer for VirtualChainChangedNotification { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let removed_chain_block_hashes = load!(Vec, reader)?; let added_chain_block_hashes = load!(Vec, reader)?; let accepted_transaction_ids = load!(Vec, reader)?; Ok(Self { removed_chain_block_hashes: removed_chain_block_hashes.into(), added_chain_block_hashes: added_chain_block_hashes.into(), accepted_transaction_ids: accepted_transaction_ids.into(), }) } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // FinalityConflictNotification #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyFinalityConflictRequest { pub command: Command, } impl NotifyFinalityConflictRequest { pub fn new(command: Command) -> Self { Self { command } } } impl Serializer for NotifyFinalityConflictRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Command, &self.command, writer)?; Ok(()) } } impl Deserializer for NotifyFinalityConflictRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let command = load!(Command, reader)?; Ok(Self { command }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyFinalityConflictResponse {} impl Serializer for NotifyFinalityConflictResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for NotifyFinalityConflictResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct FinalityConflictNotification { pub violating_block_hash: RpcHash, } impl Serializer for FinalityConflictNotification { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.violating_block_hash, writer)?; Ok(()) } } impl Deserializer for FinalityConflictNotification { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let violating_block_hash = load!(RpcHash, reader)?; Ok(Self { violating_block_hash }) } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // FinalityConflictResolvedNotification #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyFinalityConflictResolvedRequest { pub command: Command, } impl NotifyFinalityConflictResolvedRequest { pub fn new(command: Command) -> Self { Self { command } } } impl Serializer for NotifyFinalityConflictResolvedRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Command, &self.command, writer)?; Ok(()) } } impl Deserializer for NotifyFinalityConflictResolvedRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let command = load!(Command, reader)?; Ok(Self { command }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyFinalityConflictResolvedResponse {} impl Serializer for NotifyFinalityConflictResolvedResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for NotifyFinalityConflictResolvedResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct FinalityConflictResolvedNotification { pub finality_block_hash: RpcHash, } impl Serializer for FinalityConflictResolvedNotification { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.finality_block_hash, writer)?; Ok(()) } } impl Deserializer for FinalityConflictResolvedNotification { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let finality_block_hash = load!(RpcHash, reader)?; Ok(Self { finality_block_hash }) } } // ~~~~~~~~~~~~~~~~~~~~~~~~ // UtxosChangedNotification // NotifyUtxosChangedRequestMessage registers this connection for utxoChanged notifications // for the given addresses. Depending on the provided `command`, notifications will // start or stop for the provided `addresses`. // // If `addresses` is empty, the notifications will start or stop for all addresses. // // This call is only available when this kaspad was started with `--utxoindex` // // See: UtxosChangedNotification #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyUtxosChangedRequest { pub addresses: Vec, pub command: Command, } impl NotifyUtxosChangedRequest { pub fn new(addresses: Vec, command: Command) -> Self { Self { addresses, command } } } impl Serializer for NotifyUtxosChangedRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.addresses, writer)?; store!(Command, &self.command, writer)?; Ok(()) } } impl Deserializer for NotifyUtxosChangedRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let addresses = load!(Vec, reader)?; let command = load!(Command, reader)?; Ok(Self { addresses, command }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyUtxosChangedResponse {} impl Serializer for NotifyUtxosChangedResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for NotifyUtxosChangedResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } // UtxosChangedNotificationMessage is sent whenever the UTXO index had been updated. // // See: NotifyUtxosChangedRequest #[derive(Clone, Debug, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct UtxosChangedNotification { pub added: Arc>, pub removed: Arc>, } impl UtxosChangedNotification { pub(crate) fn apply_utxos_changed_subscription( &self, subscription: &UtxosChangedSubscription, context: &SubscriptionContext, ) -> Option { if subscription.to_all() { Some(self.clone()) } else { let added = Self::filter_utxos(&self.added, subscription, context); let removed = Self::filter_utxos(&self.removed, subscription, context); if added.is_empty() && removed.is_empty() { None } else { debug!("CRPC, Creating UtxosChanged notifications with {} added and {} removed utxos", added.len(), removed.len()); Some(Self { added: Arc::new(added), removed: Arc::new(removed) }) } } } fn filter_utxos( utxo_set: &[RpcUtxosByAddressesEntry], subscription: &UtxosChangedSubscription, context: &SubscriptionContext, ) -> Vec { let subscription_data = subscription.data(); utxo_set.iter().filter(|x| subscription_data.contains(&x.utxo_entry.script_public_key, context)).cloned().collect() } } impl Serializer for UtxosChangedNotification { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; serialize!(Vec, &self.added, writer)?; serialize!(Vec, &self.removed, writer)?; Ok(()) } } impl Deserializer for UtxosChangedNotification { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let added = deserialize!(Vec, reader)?; let removed = deserialize!(Vec, reader)?; Ok(Self { added: added.into(), removed: removed.into() }) } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // SinkBlueScoreChangedNotification // NotifySinkBlueScoreChangedRequest registers this connection for // sinkBlueScoreChanged notifications. // // See: SinkBlueScoreChangedNotification #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifySinkBlueScoreChangedRequest { pub command: Command, } impl NotifySinkBlueScoreChangedRequest { pub fn new(command: Command) -> Self { Self { command } } } impl Serializer for NotifySinkBlueScoreChangedRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Command, &self.command, writer)?; Ok(()) } } impl Deserializer for NotifySinkBlueScoreChangedRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let command = load!(Command, reader)?; Ok(Self { command }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifySinkBlueScoreChangedResponse {} impl Serializer for NotifySinkBlueScoreChangedResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for NotifySinkBlueScoreChangedResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } // SinkBlueScoreChangedNotification is sent whenever the blue score // of the virtual's selected parent changes. // /// See: NotifySinkBlueScoreChangedRequest #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SinkBlueScoreChangedNotification { pub sink_blue_score: u64, } impl Serializer for SinkBlueScoreChangedNotification { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.sink_blue_score, writer)?; Ok(()) } } impl Deserializer for SinkBlueScoreChangedNotification { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let sink_blue_score = load!(u64, reader)?; Ok(Self { sink_blue_score }) } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // VirtualDaaScoreChangedNotification // NotifyVirtualDaaScoreChangedRequest registers this connection for // virtualDaaScoreChanged notifications. // // See: VirtualDaaScoreChangedNotification #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyVirtualDaaScoreChangedRequest { pub command: Command, } impl NotifyVirtualDaaScoreChangedRequest { pub fn new(command: Command) -> Self { Self { command } } } impl Serializer for NotifyVirtualDaaScoreChangedRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Command, &self.command, writer)?; Ok(()) } } impl Deserializer for NotifyVirtualDaaScoreChangedRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let command = load!(Command, reader)?; Ok(Self { command }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyVirtualDaaScoreChangedResponse {} impl Serializer for NotifyVirtualDaaScoreChangedResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for NotifyVirtualDaaScoreChangedResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } // VirtualDaaScoreChangedNotification is sent whenever the DAA score // of the virtual changes. // // See NotifyVirtualDaaScoreChangedRequest #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct VirtualDaaScoreChangedNotification { pub virtual_daa_score: u64, } impl Serializer for VirtualDaaScoreChangedNotification { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.virtual_daa_score, writer)?; Ok(()) } } impl Deserializer for VirtualDaaScoreChangedNotification { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let virtual_daa_score = load!(u64, reader)?; Ok(Self { virtual_daa_score }) } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PruningPointUtxoSetOverrideNotification #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyPruningPointUtxoSetOverrideRequest { pub command: Command, } impl NotifyPruningPointUtxoSetOverrideRequest { pub fn new(command: Command) -> Self { Self { command } } } impl Serializer for NotifyPruningPointUtxoSetOverrideRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Command, &self.command, writer)?; Ok(()) } } impl Deserializer for NotifyPruningPointUtxoSetOverrideRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let command = load!(Command, reader)?; Ok(Self { command }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyPruningPointUtxoSetOverrideResponse {} impl Serializer for NotifyPruningPointUtxoSetOverrideResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for NotifyPruningPointUtxoSetOverrideResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct PruningPointUtxoSetOverrideNotification {} impl Serializer for PruningPointUtxoSetOverrideNotification { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for PruningPointUtxoSetOverrideNotification { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NewBlockTemplateNotification /// NotifyNewBlockTemplateRequest registers this connection for blockAdded notifications. /// /// See: NewBlockTemplateNotification #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyNewBlockTemplateRequest { pub command: Command, } impl NotifyNewBlockTemplateRequest { pub fn new(command: Command) -> Self { Self { command } } } impl Serializer for NotifyNewBlockTemplateRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Command, &self.command, writer)?; Ok(()) } } impl Deserializer for NotifyNewBlockTemplateRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let command = load!(Command, reader)?; Ok(Self { command }) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotifyNewBlockTemplateResponse {} impl Serializer for NotifyNewBlockTemplateResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for NotifyNewBlockTemplateResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } /// NewBlockTemplateNotification is sent whenever a blocks has been added (NOT accepted) /// into the DAG. /// /// See: NotifyNewBlockTemplateRequest #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NewBlockTemplateNotification {} impl Serializer for NewBlockTemplateNotification { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; Ok(()) } } impl Deserializer for NewBlockTemplateNotification { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; Ok(Self {}) } } /// /// wRPC response for RpcApiOps::Subscribe request /// #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SubscribeResponse { id: u64, } impl SubscribeResponse { pub fn new(id: u64) -> Self { Self { id } } } impl Serializer for SubscribeResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(u64, &self.id, writer)?; Ok(()) } } impl Deserializer for SubscribeResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let id = load!(u64, reader)?; Ok(Self { id }) } } /// /// wRPC response for RpcApiOps::Unsubscribe request /// #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct UnsubscribeResponse {} impl Serializer for UnsubscribeResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer) } } impl Deserializer for UnsubscribeResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader); Ok(Self {}) } } /// Request data needed to prove a single KIP-21 lane's state against the /// `seq_commit` carried in `block_hash`'s header. /// /// `block_hash` must be a chain (selected-parent-chain) block. #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSeqCommitLaneProofRequest { pub block_hash: RpcHash, pub lane_key: RpcHash, } impl GetSeqCommitLaneProofRequest { pub fn new(block_hash: RpcHash, lane_key: RpcHash) -> Self { Self { block_hash, lane_key } } } impl Serializer for GetSeqCommitLaneProofRequest { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(RpcHash, &self.block_hash, writer)?; store!(RpcHash, &self.lane_key, writer)?; Ok(()) } } impl Deserializer for GetSeqCommitLaneProofRequest { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let block_hash = load!(RpcHash, reader)?; let lane_key = load!(RpcHash, reader)?; Ok(Self { block_hash, lane_key }) } } /// Self-contained witness a client can verify locally against the block header's /// `seq_commit` (= `accepted_id_merkle_root`). /// /// `smt_proof` is the `OwnedSmtProof` wire format (`bitmap || terminal || siblings`), /// parsed via `kaspa_smt::proof::OwnedSmtProof::from_bytes`. /// #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct RpcLaneEntry { pub tip: RpcHash, pub blue_score: u64, } impl Serializer for RpcLaneEntry { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u8, &1, writer)?; store!(RpcHash, &self.tip, writer)?; store!(u64, &self.blue_score, writer)?; Ok(()) } } impl Deserializer for RpcLaneEntry { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u8, reader)?; let tip = load!(RpcHash, reader)?; let blue_score = load!(u64, reader)?; Ok(Self { tip, blue_score }) } } /// When the lane has no entry in the active-lanes SMT at this block's POV, /// `lane` is `None` and `smt_proof` is a non-inclusion proof. /// /// `inactivity_shortcut` (KIP-21): the `accepted_id_merkle_root` of the anchor /// block. Folded into `activity_root = H_activity_root(inactivity_shortcut, lanes_root)` /// during seq_commit verification. #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct GetSeqCommitLaneProofResponse { pub smt_proof: Vec, pub lane: Option, pub payload_and_ctx_digest: RpcHash, pub parent_seq_commit: RpcHash, pub inactivity_shortcut: RpcHash, } impl Serializer for GetSeqCommitLaneProofResponse { fn serialize(&self, writer: &mut W) -> std::io::Result<()> { store!(u16, &1, writer)?; store!(Vec, &self.smt_proof, writer)?; serialize!(Option, &self.lane, writer)?; store!(RpcHash, &self.payload_and_ctx_digest, writer)?; store!(RpcHash, &self.parent_seq_commit, writer)?; store!(RpcHash, &self.inactivity_shortcut, writer)?; Ok(()) } } impl Deserializer for GetSeqCommitLaneProofResponse { fn deserialize(reader: &mut R) -> std::io::Result { let _version = load!(u16, reader)?; let smt_proof = load!(Vec, reader)?; let lane = deserialize!(Option, reader)?; let payload_and_ctx_digest = load!(RpcHash, reader)?; let parent_seq_commit = load!(RpcHash, reader)?; let inactivity_shortcut = load!(RpcHash, reader)?; Ok(Self { smt_proof, lane, payload_and_ctx_digest, parent_seq_commit, inactivity_shortcut }) } }