mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-11-16 15:58:17 +00:00
cuprated: internal signatures required for RPC pt. 2 (#320)
* apply diffs * clippy * fix tests * rpc: fix tests * remove `BlockchainManagerRequest::Overview` * cuprated/p2p: fix `ConnectionInfo` * move `CalculatePow` * remove `AddAuxPow` * move `Spans` and `NextNeededPruningSeed` * factor types into `cuprate-types` * scope cargo features * fix/doc type serde * Update binaries/cuprated/src/rpc/request/address_book.rs Co-authored-by: Boog900 <boog900@tutanota.com> * Update binaries/cuprated/src/rpc/request/blockchain_context.rs Co-authored-by: Boog900 <boog900@tutanota.com> * Update binaries/cuprated/src/rpc/request/blockchain_manager.rs Co-authored-by: Boog900 <boog900@tutanota.com> * fmt * txpool: collapse `TxEntry` * `ConnectionId` * fix import * fix bin --------- Co-authored-by: Boog900 <boog900@tutanota.com>
This commit is contained in:
parent
44981f2b24
commit
372cab24d7
35 changed files with 1028 additions and 285 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -865,6 +865,7 @@ dependencies = [
|
||||||
"cuprate-helper",
|
"cuprate-helper",
|
||||||
"cuprate-pruning",
|
"cuprate-pruning",
|
||||||
"cuprate-test-utils",
|
"cuprate-test-utils",
|
||||||
|
"cuprate-types",
|
||||||
"cuprate-wire",
|
"cuprate-wire",
|
||||||
"futures",
|
"futures",
|
||||||
"hex",
|
"hex",
|
||||||
|
@ -1026,6 +1027,7 @@ dependencies = [
|
||||||
"cuprate-consensus",
|
"cuprate-consensus",
|
||||||
"cuprate-consensus-context",
|
"cuprate-consensus-context",
|
||||||
"cuprate-consensus-rules",
|
"cuprate-consensus-rules",
|
||||||
|
"cuprate-constants",
|
||||||
"cuprate-cryptonight",
|
"cuprate-cryptonight",
|
||||||
"cuprate-dandelion-tower",
|
"cuprate-dandelion-tower",
|
||||||
"cuprate-database",
|
"cuprate-database",
|
||||||
|
|
|
@ -13,6 +13,7 @@ cuprate-consensus = { workspace = true }
|
||||||
cuprate-fast-sync = { workspace = true }
|
cuprate-fast-sync = { workspace = true }
|
||||||
cuprate-consensus-context = { workspace = true }
|
cuprate-consensus-context = { workspace = true }
|
||||||
cuprate-consensus-rules = { workspace = true }
|
cuprate-consensus-rules = { workspace = true }
|
||||||
|
cuprate-constants = { workspace = true }
|
||||||
cuprate-cryptonight = { workspace = true }
|
cuprate-cryptonight = { workspace = true }
|
||||||
cuprate-helper = { workspace = true }
|
cuprate-helper = { workspace = true }
|
||||||
cuprate-epee-encoding = { workspace = true }
|
cuprate-epee-encoding = { workspace = true }
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
unused_variables,
|
unused_variables,
|
||||||
clippy::needless_pass_by_value,
|
clippy::needless_pass_by_value,
|
||||||
clippy::unused_async,
|
clippy::unused_async,
|
||||||
|
clippy::diverging_sub_expression,
|
||||||
|
unused_mut,
|
||||||
|
clippy::let_unit_value,
|
||||||
|
clippy::needless_pass_by_ref_mut,
|
||||||
reason = "TODO: remove after v1.0.0"
|
reason = "TODO: remove after v1.0.0"
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//! Will contain the code to initiate the RPC and a request handler.
|
//! Will contain the code to initiate the RPC and a request handler.
|
||||||
|
|
||||||
mod bin;
|
mod bin;
|
||||||
|
mod constants;
|
||||||
mod handler;
|
mod handler;
|
||||||
mod json;
|
mod json;
|
||||||
mod other;
|
mod other;
|
||||||
|
|
5
binaries/cuprated/src/rpc/constants.rs
Normal file
5
binaries/cuprated/src/rpc/constants.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
//! Constants used within RPC.
|
||||||
|
|
||||||
|
/// The string message used in RPC response fields for when
|
||||||
|
/// `cuprated` does not support a field that `monerod` has.
|
||||||
|
pub(super) const FIELD_NOT_SUPPORTED: &str = "`cuprated` does not support this field.";
|
|
@ -8,6 +8,8 @@ use monero_serai::block::Block;
|
||||||
use tower::Service;
|
use tower::Service;
|
||||||
|
|
||||||
use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle};
|
use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle};
|
||||||
|
use cuprate_consensus::BlockChainContextService;
|
||||||
|
use cuprate_pruning::PruningSeed;
|
||||||
use cuprate_rpc_interface::RpcHandler;
|
use cuprate_rpc_interface::RpcHandler;
|
||||||
use cuprate_rpc_types::{
|
use cuprate_rpc_types::{
|
||||||
bin::{BinRequest, BinResponse},
|
bin::{BinRequest, BinResponse},
|
||||||
|
@ -15,6 +17,7 @@ use cuprate_rpc_types::{
|
||||||
other::{OtherRequest, OtherResponse},
|
other::{OtherRequest, OtherResponse},
|
||||||
};
|
};
|
||||||
use cuprate_txpool::service::{TxpoolReadHandle, TxpoolWriteHandle};
|
use cuprate_txpool::service::{TxpoolReadHandle, TxpoolWriteHandle};
|
||||||
|
use cuprate_types::{AddAuxPow, AuxPow, HardFork};
|
||||||
|
|
||||||
use crate::rpc::{bin, json, other};
|
use crate::rpc::{bin, json, other};
|
||||||
|
|
||||||
|
@ -54,6 +57,32 @@ pub enum BlockchainManagerRequest {
|
||||||
|
|
||||||
/// The height of the next block in the chain.
|
/// The height of the next block in the chain.
|
||||||
TargetHeight,
|
TargetHeight,
|
||||||
|
|
||||||
|
/// Generate new blocks.
|
||||||
|
///
|
||||||
|
/// This request is only for regtest, see RPC's `generateblocks`.
|
||||||
|
GenerateBlocks {
|
||||||
|
/// Number of the blocks to be generated.
|
||||||
|
amount_of_blocks: u64,
|
||||||
|
/// The previous block's hash.
|
||||||
|
prev_block: [u8; 32],
|
||||||
|
/// The starting value for the nonce.
|
||||||
|
starting_nonce: u32,
|
||||||
|
/// The address that will receive the coinbase reward.
|
||||||
|
wallet_address: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
// // TODO: the below requests actually belong to the block downloader/syncer:
|
||||||
|
// // <https://github.com/Cuprate/cuprate/pull/320#discussion_r1811089758>
|
||||||
|
// /// Get [`Span`] data.
|
||||||
|
// ///
|
||||||
|
// /// This is data that describes an active downloading process,
|
||||||
|
// /// if we are fully synced, this will return an empty [`Vec`].
|
||||||
|
// Spans,
|
||||||
|
|
||||||
|
//
|
||||||
|
/// Get the next [`PruningSeed`] needed for a pruned sync.
|
||||||
|
NextNeededPruningSeed,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TODO: use real type when public.
|
/// TODO: use real type when public.
|
||||||
|
@ -69,6 +98,9 @@ pub enum BlockchainManagerResponse {
|
||||||
/// Response to [`BlockchainManagerRequest::PopBlocks`]
|
/// Response to [`BlockchainManagerRequest::PopBlocks`]
|
||||||
PopBlocks { new_height: usize },
|
PopBlocks { new_height: usize },
|
||||||
|
|
||||||
|
/// Response to [`BlockchainManagerRequest::Prune`]
|
||||||
|
Prune(PruningSeed),
|
||||||
|
|
||||||
/// Response to [`BlockchainManagerRequest::Pruned`]
|
/// Response to [`BlockchainManagerRequest::Pruned`]
|
||||||
Pruned(bool),
|
Pruned(bool),
|
||||||
|
|
||||||
|
@ -83,6 +115,19 @@ pub enum BlockchainManagerResponse {
|
||||||
|
|
||||||
/// Response to [`BlockchainManagerRequest::TargetHeight`]
|
/// Response to [`BlockchainManagerRequest::TargetHeight`]
|
||||||
TargetHeight { height: usize },
|
TargetHeight { height: usize },
|
||||||
|
|
||||||
|
/// Response to [`BlockchainManagerRequest::GenerateBlocks`]
|
||||||
|
GenerateBlocks {
|
||||||
|
/// Hashes of the blocks generated.
|
||||||
|
blocks: Vec<[u8; 32]>,
|
||||||
|
/// The new top height. (TODO: is this correct?)
|
||||||
|
height: usize,
|
||||||
|
},
|
||||||
|
|
||||||
|
// /// Response to [`BlockchainManagerRequest::Spans`].
|
||||||
|
// Spans(Vec<Span<Z::Addr>>),
|
||||||
|
/// Response to [`BlockchainManagerRequest::NextNeededPruningSeed`].
|
||||||
|
NextNeededPruningSeed(PruningSeed),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TODO: use real type when public.
|
/// TODO: use real type when public.
|
||||||
|
@ -102,6 +147,9 @@ pub struct CupratedRpcHandler {
|
||||||
/// Read handle to the blockchain database.
|
/// Read handle to the blockchain database.
|
||||||
pub blockchain_read: BlockchainReadHandle,
|
pub blockchain_read: BlockchainReadHandle,
|
||||||
|
|
||||||
|
/// Handle to the blockchain context service.
|
||||||
|
pub blockchain_context: BlockChainContextService,
|
||||||
|
|
||||||
/// Handle to the blockchain manager.
|
/// Handle to the blockchain manager.
|
||||||
pub blockchain_manager: BlockchainManagerHandle,
|
pub blockchain_manager: BlockchainManagerHandle,
|
||||||
|
|
||||||
|
@ -117,6 +165,7 @@ impl CupratedRpcHandler {
|
||||||
pub const fn new(
|
pub const fn new(
|
||||||
restricted: bool,
|
restricted: bool,
|
||||||
blockchain_read: BlockchainReadHandle,
|
blockchain_read: BlockchainReadHandle,
|
||||||
|
blockchain_context: BlockChainContextService,
|
||||||
blockchain_manager: BlockchainManagerHandle,
|
blockchain_manager: BlockchainManagerHandle,
|
||||||
txpool_read: TxpoolReadHandle,
|
txpool_read: TxpoolReadHandle,
|
||||||
txpool_manager: std::convert::Infallible,
|
txpool_manager: std::convert::Infallible,
|
||||||
|
@ -124,6 +173,7 @@ impl CupratedRpcHandler {
|
||||||
Self {
|
Self {
|
||||||
restricted,
|
restricted,
|
||||||
blockchain_read,
|
blockchain_read,
|
||||||
|
blockchain_context,
|
||||||
blockchain_manager,
|
blockchain_manager,
|
||||||
txpool_read,
|
txpool_read,
|
||||||
txpool_manager,
|
txpool_manager,
|
||||||
|
|
|
@ -2,26 +2,33 @@
|
||||||
|
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::{anyhow, Error};
|
||||||
use tower::ServiceExt;
|
use tower::ServiceExt;
|
||||||
|
|
||||||
use cuprate_helper::cast::usize_to_u64;
|
use cuprate_helper::cast::usize_to_u64;
|
||||||
use cuprate_p2p_core::{
|
use cuprate_p2p_core::{
|
||||||
services::{AddressBookRequest, AddressBookResponse},
|
services::{AddressBookRequest, AddressBookResponse},
|
||||||
|
types::{BanState, ConnectionId},
|
||||||
AddressBook, NetworkZone,
|
AddressBook, NetworkZone,
|
||||||
};
|
};
|
||||||
|
use cuprate_pruning::PruningSeed;
|
||||||
|
use cuprate_rpc_types::misc::{ConnectionInfo, Span};
|
||||||
|
|
||||||
|
use crate::rpc::constants::FIELD_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
// FIXME: use `anyhow::Error` over `tower::BoxError` in address book.
|
||||||
|
|
||||||
/// [`AddressBookRequest::PeerlistSize`]
|
/// [`AddressBookRequest::PeerlistSize`]
|
||||||
pub(super) async fn peerlist_size<Z: NetworkZone>(
|
pub(crate) async fn peerlist_size<Z: NetworkZone>(
|
||||||
address_book: &mut impl AddressBook<Z>,
|
address_book: &mut impl AddressBook<Z>,
|
||||||
) -> Result<(u64, u64), Error> {
|
) -> Result<(u64, u64), Error> {
|
||||||
let AddressBookResponse::PeerlistSize { white, grey } = address_book
|
let AddressBookResponse::PeerlistSize { white, grey } = address_book
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
.call(AddressBookRequest::PeerlistSize)
|
.call(AddressBookRequest::PeerlistSize)
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -29,17 +36,74 @@ pub(super) async fn peerlist_size<Z: NetworkZone>(
|
||||||
Ok((usize_to_u64(white), usize_to_u64(grey)))
|
Ok((usize_to_u64(white), usize_to_u64(grey)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`AddressBookRequest::ConnectionInfo`]
|
||||||
|
pub(crate) async fn connection_info<Z: NetworkZone>(
|
||||||
|
address_book: &mut impl AddressBook<Z>,
|
||||||
|
) -> Result<Vec<ConnectionInfo>, Error> {
|
||||||
|
let AddressBookResponse::ConnectionInfo(vec) = address_book
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.map_err(|e| anyhow!(e))?
|
||||||
|
.call(AddressBookRequest::ConnectionInfo)
|
||||||
|
.await
|
||||||
|
.map_err(|e| anyhow!(e))?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME: impl this map somewhere instead of inline.
|
||||||
|
let vec = vec
|
||||||
|
.into_iter()
|
||||||
|
.map(|info| {
|
||||||
|
let (ip, port) = match info.socket_addr {
|
||||||
|
Some(socket) => (socket.ip().to_string(), socket.port().to_string()),
|
||||||
|
None => (String::new(), String::new()),
|
||||||
|
};
|
||||||
|
|
||||||
|
ConnectionInfo {
|
||||||
|
address: info.address.to_string(),
|
||||||
|
address_type: info.address_type,
|
||||||
|
avg_download: info.avg_download,
|
||||||
|
avg_upload: info.avg_upload,
|
||||||
|
connection_id: String::from(ConnectionId::DEFAULT_STR),
|
||||||
|
current_download: info.current_download,
|
||||||
|
current_upload: info.current_upload,
|
||||||
|
height: info.height,
|
||||||
|
host: info.host,
|
||||||
|
incoming: info.incoming,
|
||||||
|
ip,
|
||||||
|
live_time: info.live_time,
|
||||||
|
localhost: info.localhost,
|
||||||
|
local_ip: info.local_ip,
|
||||||
|
peer_id: hex::encode(info.peer_id.to_ne_bytes()),
|
||||||
|
port,
|
||||||
|
pruning_seed: info.pruning_seed.compress(),
|
||||||
|
recv_count: info.recv_count,
|
||||||
|
recv_idle_time: info.recv_idle_time,
|
||||||
|
rpc_credits_per_hash: info.rpc_credits_per_hash,
|
||||||
|
rpc_port: info.rpc_port,
|
||||||
|
send_count: info.send_count,
|
||||||
|
send_idle_time: info.send_idle_time,
|
||||||
|
state: info.state,
|
||||||
|
support_flags: info.support_flags,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(vec)
|
||||||
|
}
|
||||||
|
|
||||||
/// [`AddressBookRequest::ConnectionCount`]
|
/// [`AddressBookRequest::ConnectionCount`]
|
||||||
pub(super) async fn connection_count<Z: NetworkZone>(
|
pub(crate) async fn connection_count<Z: NetworkZone>(
|
||||||
address_book: &mut impl AddressBook<Z>,
|
address_book: &mut impl AddressBook<Z>,
|
||||||
) -> Result<(u64, u64), Error> {
|
) -> Result<(u64, u64), Error> {
|
||||||
let AddressBookResponse::ConnectionCount { incoming, outgoing } = address_book
|
let AddressBookResponse::ConnectionCount { incoming, outgoing } = address_book
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
.call(AddressBookRequest::ConnectionCount)
|
.call(AddressBookRequest::ConnectionCount)
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -48,17 +112,17 @@ pub(super) async fn connection_count<Z: NetworkZone>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`AddressBookRequest::SetBan`]
|
/// [`AddressBookRequest::SetBan`]
|
||||||
pub(super) async fn set_ban<Z: NetworkZone>(
|
pub(crate) async fn set_ban<Z: NetworkZone>(
|
||||||
address_book: &mut impl AddressBook<Z>,
|
address_book: &mut impl AddressBook<Z>,
|
||||||
peer: cuprate_p2p_core::ban::SetBan<Z::Addr>,
|
set_ban: cuprate_p2p_core::types::SetBan<Z::Addr>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let AddressBookResponse::Ok = address_book
|
let AddressBookResponse::Ok = address_book
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
.call(AddressBookRequest::SetBan(peer))
|
.call(AddressBookRequest::SetBan(set_ban))
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -67,17 +131,17 @@ pub(super) async fn set_ban<Z: NetworkZone>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`AddressBookRequest::GetBan`]
|
/// [`AddressBookRequest::GetBan`]
|
||||||
pub(super) async fn get_ban<Z: NetworkZone>(
|
pub(crate) async fn get_ban<Z: NetworkZone>(
|
||||||
address_book: &mut impl AddressBook<Z>,
|
address_book: &mut impl AddressBook<Z>,
|
||||||
peer: Z::Addr,
|
peer: Z::Addr,
|
||||||
) -> Result<Option<std::time::Instant>, Error> {
|
) -> Result<Option<std::time::Instant>, Error> {
|
||||||
let AddressBookResponse::GetBan { unban_instant } = address_book
|
let AddressBookResponse::GetBan { unban_instant } = address_book
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
.call(AddressBookRequest::GetBan(peer))
|
.call(AddressBookRequest::GetBan(peer))
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -86,19 +150,19 @@ pub(super) async fn get_ban<Z: NetworkZone>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`AddressBookRequest::GetBans`]
|
/// [`AddressBookRequest::GetBans`]
|
||||||
pub(super) async fn get_bans<Z: NetworkZone>(
|
pub(crate) async fn get_bans<Z: NetworkZone>(
|
||||||
address_book: &mut impl AddressBook<Z>,
|
address_book: &mut impl AddressBook<Z>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<Vec<BanState<Z::Addr>>, Error> {
|
||||||
let AddressBookResponse::GetBans(bans) = address_book
|
let AddressBookResponse::GetBans(bans) = address_book
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
.call(AddressBookRequest::GetBans)
|
.call(AddressBookRequest::GetBans)
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(todo!())
|
Ok(bans)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,61 @@
|
||||||
//! Functions for [`BlockchainReadRequest`].
|
//! Functions for [`BlockchainReadRequest`].
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{BTreeMap, HashMap, HashSet},
|
||||||
ops::Range,
|
ops::Range,
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use cuprate_blockchain::service::BlockchainReadHandle;
|
use monero_serai::block::Block;
|
||||||
use tower::{Service, ServiceExt};
|
use tower::{Service, ServiceExt};
|
||||||
|
|
||||||
|
use cuprate_blockchain::{service::BlockchainReadHandle, types::AltChainInfo};
|
||||||
use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
|
use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
|
||||||
use cuprate_types::{
|
use cuprate_types::{
|
||||||
blockchain::{BlockchainReadRequest, BlockchainResponse},
|
blockchain::{BlockchainReadRequest, BlockchainResponse},
|
||||||
Chain, CoinbaseTxSum, ExtendedBlockHeader, MinerData, OutputHistogramEntry,
|
Chain, ChainInfo, CoinbaseTxSum, ExtendedBlockHeader, HardFork, MinerData,
|
||||||
OutputHistogramInput, OutputOnChain,
|
OutputHistogramEntry, OutputHistogramInput, OutputOnChain,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::Block`].
|
||||||
|
pub(crate) async fn block(
|
||||||
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
|
height: u64,
|
||||||
|
) -> Result<Block, Error> {
|
||||||
|
let BlockchainResponse::Block(block) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::Block {
|
||||||
|
height: u64_to_usize(height),
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::BlockByHash`].
|
||||||
|
pub(crate) async fn block_by_hash(
|
||||||
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
|
hash: [u8; 32],
|
||||||
|
) -> Result<Block, Error> {
|
||||||
|
let BlockchainResponse::Block(block) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::BlockByHash(hash))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(block)
|
||||||
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::BlockExtendedHeader`].
|
/// [`BlockchainReadRequest::BlockExtendedHeader`].
|
||||||
pub(super) async fn block_extended_header(
|
pub(crate) async fn block_extended_header(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
height: u64,
|
height: u64,
|
||||||
) -> Result<ExtendedBlockHeader, Error> {
|
) -> Result<ExtendedBlockHeader, Error> {
|
||||||
let BlockchainResponse::BlockExtendedHeader(header) = blockchain_read
|
let BlockchainResponse::BlockExtendedHeader(header) = blockchain_read
|
||||||
|
@ -36,8 +73,8 @@ pub(super) async fn block_extended_header(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::BlockHash`].
|
/// [`BlockchainReadRequest::BlockHash`].
|
||||||
pub(super) async fn block_hash(
|
pub(crate) async fn block_hash(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
height: u64,
|
height: u64,
|
||||||
chain: Chain,
|
chain: Chain,
|
||||||
) -> Result<[u8; 32], Error> {
|
) -> Result<[u8; 32], Error> {
|
||||||
|
@ -57,8 +94,8 @@ pub(super) async fn block_hash(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::FindBlock`].
|
/// [`BlockchainReadRequest::FindBlock`].
|
||||||
pub(super) async fn find_block(
|
pub(crate) async fn find_block(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
block_hash: [u8; 32],
|
block_hash: [u8; 32],
|
||||||
) -> Result<Option<(Chain, usize)>, Error> {
|
) -> Result<Option<(Chain, usize)>, Error> {
|
||||||
let BlockchainResponse::FindBlock(option) = blockchain_read
|
let BlockchainResponse::FindBlock(option) = blockchain_read
|
||||||
|
@ -74,8 +111,8 @@ pub(super) async fn find_block(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::FilterUnknownHashes`].
|
/// [`BlockchainReadRequest::FilterUnknownHashes`].
|
||||||
pub(super) async fn filter_unknown_hashes(
|
pub(crate) async fn filter_unknown_hashes(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
block_hashes: HashSet<[u8; 32]>,
|
block_hashes: HashSet<[u8; 32]>,
|
||||||
) -> Result<HashSet<[u8; 32]>, Error> {
|
) -> Result<HashSet<[u8; 32]>, Error> {
|
||||||
let BlockchainResponse::FilterUnknownHashes(output) = blockchain_read
|
let BlockchainResponse::FilterUnknownHashes(output) = blockchain_read
|
||||||
|
@ -91,8 +128,8 @@ pub(super) async fn filter_unknown_hashes(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::BlockExtendedHeaderInRange`]
|
/// [`BlockchainReadRequest::BlockExtendedHeaderInRange`]
|
||||||
pub(super) async fn block_extended_header_in_range(
|
pub(crate) async fn block_extended_header_in_range(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
chain: Chain,
|
chain: Chain,
|
||||||
) -> Result<Vec<ExtendedBlockHeader>, Error> {
|
) -> Result<Vec<ExtendedBlockHeader>, Error> {
|
||||||
|
@ -111,8 +148,8 @@ pub(super) async fn block_extended_header_in_range(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::ChainHeight`].
|
/// [`BlockchainReadRequest::ChainHeight`].
|
||||||
pub(super) async fn chain_height(
|
pub(crate) async fn chain_height(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
) -> Result<(u64, [u8; 32]), Error> {
|
) -> Result<(u64, [u8; 32]), Error> {
|
||||||
let BlockchainResponse::ChainHeight(height, hash) = blockchain_read
|
let BlockchainResponse::ChainHeight(height, hash) = blockchain_read
|
||||||
.ready()
|
.ready()
|
||||||
|
@ -127,8 +164,8 @@ pub(super) async fn chain_height(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::GeneratedCoins`].
|
/// [`BlockchainReadRequest::GeneratedCoins`].
|
||||||
pub(super) async fn generated_coins(
|
pub(crate) async fn generated_coins(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
block_height: u64,
|
block_height: u64,
|
||||||
) -> Result<u64, Error> {
|
) -> Result<u64, Error> {
|
||||||
let BlockchainResponse::GeneratedCoins(generated_coins) = blockchain_read
|
let BlockchainResponse::GeneratedCoins(generated_coins) = blockchain_read
|
||||||
|
@ -146,8 +183,8 @@ pub(super) async fn generated_coins(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::Outputs`]
|
/// [`BlockchainReadRequest::Outputs`]
|
||||||
pub(super) async fn outputs(
|
pub(crate) async fn outputs(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
outputs: HashMap<u64, HashSet<u64>>,
|
outputs: HashMap<u64, HashSet<u64>>,
|
||||||
) -> Result<HashMap<u64, HashMap<u64, OutputOnChain>>, Error> {
|
) -> Result<HashMap<u64, HashMap<u64, OutputOnChain>>, Error> {
|
||||||
let BlockchainResponse::Outputs(outputs) = blockchain_read
|
let BlockchainResponse::Outputs(outputs) = blockchain_read
|
||||||
|
@ -163,8 +200,8 @@ pub(super) async fn outputs(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::NumberOutputsWithAmount`]
|
/// [`BlockchainReadRequest::NumberOutputsWithAmount`]
|
||||||
pub(super) async fn number_outputs_with_amount(
|
pub(crate) async fn number_outputs_with_amount(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
output_amounts: Vec<u64>,
|
output_amounts: Vec<u64>,
|
||||||
) -> Result<HashMap<u64, usize>, Error> {
|
) -> Result<HashMap<u64, usize>, Error> {
|
||||||
let BlockchainResponse::NumberOutputsWithAmount(map) = blockchain_read
|
let BlockchainResponse::NumberOutputsWithAmount(map) = blockchain_read
|
||||||
|
@ -182,8 +219,8 @@ pub(super) async fn number_outputs_with_amount(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::KeyImagesSpent`]
|
/// [`BlockchainReadRequest::KeyImagesSpent`]
|
||||||
pub(super) async fn key_images_spent(
|
pub(crate) async fn key_images_spent(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
key_images: HashSet<[u8; 32]>,
|
key_images: HashSet<[u8; 32]>,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let BlockchainResponse::KeyImagesSpent(is_spent) = blockchain_read
|
let BlockchainResponse::KeyImagesSpent(is_spent) = blockchain_read
|
||||||
|
@ -199,8 +236,8 @@ pub(super) async fn key_images_spent(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::CompactChainHistory`]
|
/// [`BlockchainReadRequest::CompactChainHistory`]
|
||||||
pub(super) async fn compact_chain_history(
|
pub(crate) async fn compact_chain_history(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
) -> Result<(Vec<[u8; 32]>, u128), Error> {
|
) -> Result<(Vec<[u8; 32]>, u128), Error> {
|
||||||
let BlockchainResponse::CompactChainHistory {
|
let BlockchainResponse::CompactChainHistory {
|
||||||
block_ids,
|
block_ids,
|
||||||
|
@ -218,8 +255,8 @@ pub(super) async fn compact_chain_history(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::FindFirstUnknown`]
|
/// [`BlockchainReadRequest::FindFirstUnknown`]
|
||||||
pub(super) async fn find_first_unknown(
|
pub(crate) async fn find_first_unknown(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
hashes: Vec<[u8; 32]>,
|
hashes: Vec<[u8; 32]>,
|
||||||
) -> Result<Option<(usize, u64)>, Error> {
|
) -> Result<Option<(usize, u64)>, Error> {
|
||||||
let BlockchainResponse::FindFirstUnknown(resp) = blockchain_read
|
let BlockchainResponse::FindFirstUnknown(resp) = blockchain_read
|
||||||
|
@ -235,8 +272,8 @@ pub(super) async fn find_first_unknown(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::TotalTxCount`]
|
/// [`BlockchainReadRequest::TotalTxCount`]
|
||||||
pub(super) async fn total_tx_count(
|
pub(crate) async fn total_tx_count(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
) -> Result<u64, Error> {
|
) -> Result<u64, Error> {
|
||||||
let BlockchainResponse::TotalTxCount(tx_count) = blockchain_read
|
let BlockchainResponse::TotalTxCount(tx_count) = blockchain_read
|
||||||
.ready()
|
.ready()
|
||||||
|
@ -251,8 +288,8 @@ pub(super) async fn total_tx_count(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::DatabaseSize`]
|
/// [`BlockchainReadRequest::DatabaseSize`]
|
||||||
pub(super) async fn database_size(
|
pub(crate) async fn database_size(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
) -> Result<(u64, u64), Error> {
|
) -> Result<(u64, u64), Error> {
|
||||||
let BlockchainResponse::DatabaseSize {
|
let BlockchainResponse::DatabaseSize {
|
||||||
database_size,
|
database_size,
|
||||||
|
@ -270,8 +307,8 @@ pub(super) async fn database_size(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::OutputHistogram`]
|
/// [`BlockchainReadRequest::OutputHistogram`]
|
||||||
pub(super) async fn output_histogram(
|
pub(crate) async fn output_histogram(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
input: OutputHistogramInput,
|
input: OutputHistogramInput,
|
||||||
) -> Result<Vec<OutputHistogramEntry>, Error> {
|
) -> Result<Vec<OutputHistogramEntry>, Error> {
|
||||||
let BlockchainResponse::OutputHistogram(histogram) = blockchain_read
|
let BlockchainResponse::OutputHistogram(histogram) = blockchain_read
|
||||||
|
@ -287,8 +324,8 @@ pub(super) async fn output_histogram(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::CoinbaseTxSum`]
|
/// [`BlockchainReadRequest::CoinbaseTxSum`]
|
||||||
pub(super) async fn coinbase_tx_sum(
|
pub(crate) async fn coinbase_tx_sum(
|
||||||
mut blockchain_read: BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
height: u64,
|
height: u64,
|
||||||
count: u64,
|
count: u64,
|
||||||
) -> Result<CoinbaseTxSum, Error> {
|
) -> Result<CoinbaseTxSum, Error> {
|
||||||
|
@ -306,3 +343,35 @@ pub(super) async fn coinbase_tx_sum(
|
||||||
|
|
||||||
Ok(sum)
|
Ok(sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::AltChains`]
|
||||||
|
pub(crate) async fn alt_chains(
|
||||||
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
|
) -> Result<Vec<ChainInfo>, Error> {
|
||||||
|
let BlockchainResponse::AltChains(vec) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::AltChains)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(vec)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::AltChainCount`]
|
||||||
|
pub(crate) async fn alt_chain_count(
|
||||||
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
let BlockchainResponse::AltChainCount(count) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::AltChainCount)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(usize_to_u64(count))
|
||||||
|
}
|
||||||
|
|
|
@ -2,27 +2,30 @@
|
||||||
|
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::{anyhow, Error};
|
||||||
|
use monero_serai::block::Block;
|
||||||
use tower::{Service, ServiceExt};
|
use tower::{Service, ServiceExt};
|
||||||
|
|
||||||
use cuprate_consensus_context::{
|
use cuprate_consensus_context::{
|
||||||
BlockChainContext, BlockChainContextRequest, BlockChainContextResponse,
|
BlockChainContext, BlockChainContextRequest, BlockChainContextResponse,
|
||||||
BlockChainContextService,
|
BlockChainContextService,
|
||||||
};
|
};
|
||||||
|
use cuprate_helper::cast::u64_to_usize;
|
||||||
use cuprate_types::{FeeEstimate, HardFork, HardForkInfo};
|
use cuprate_types::{FeeEstimate, HardFork, HardForkInfo};
|
||||||
|
|
||||||
|
// FIXME: use `anyhow::Error` over `tower::BoxError` in blockchain context.
|
||||||
|
|
||||||
/// [`BlockChainContextRequest::Context`].
|
/// [`BlockChainContextRequest::Context`].
|
||||||
pub(super) async fn context(
|
pub(crate) async fn context(
|
||||||
service: &mut BlockChainContextService,
|
blockchain_context: &mut BlockChainContextService,
|
||||||
height: u64,
|
|
||||||
) -> Result<BlockChainContext, Error> {
|
) -> Result<BlockChainContext, Error> {
|
||||||
let BlockChainContextResponse::Context(context) = service
|
let BlockChainContextResponse::Context(context) = blockchain_context
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
.call(BlockChainContextRequest::Context)
|
.call(BlockChainContextRequest::Context)
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -31,17 +34,17 @@ pub(super) async fn context(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockChainContextRequest::HardForkInfo`].
|
/// [`BlockChainContextRequest::HardForkInfo`].
|
||||||
pub(super) async fn hard_fork_info(
|
pub(crate) async fn hard_fork_info(
|
||||||
service: &mut BlockChainContextService,
|
blockchain_context: &mut BlockChainContextService,
|
||||||
hard_fork: HardFork,
|
hard_fork: HardFork,
|
||||||
) -> Result<HardForkInfo, Error> {
|
) -> Result<HardForkInfo, Error> {
|
||||||
let BlockChainContextResponse::HardForkInfo(hf_info) = service
|
let BlockChainContextResponse::HardForkInfo(hf_info) = blockchain_context
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
.call(BlockChainContextRequest::HardForkInfo(hard_fork))
|
.call(BlockChainContextRequest::HardForkInfo(hard_fork))
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -50,20 +53,47 @@ pub(super) async fn hard_fork_info(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockChainContextRequest::FeeEstimate`].
|
/// [`BlockChainContextRequest::FeeEstimate`].
|
||||||
pub(super) async fn fee_estimate(
|
pub(crate) async fn fee_estimate(
|
||||||
service: &mut BlockChainContextService,
|
blockchain_context: &mut BlockChainContextService,
|
||||||
grace_blocks: u64,
|
grace_blocks: u64,
|
||||||
) -> Result<FeeEstimate, Error> {
|
) -> Result<FeeEstimate, Error> {
|
||||||
let BlockChainContextResponse::FeeEstimate(fee) = service
|
let BlockChainContextResponse::FeeEstimate(fee) = blockchain_context
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
.call(BlockChainContextRequest::FeeEstimate { grace_blocks })
|
.call(BlockChainContextRequest::FeeEstimate { grace_blocks })
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(fee)
|
Ok(fee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`BlockChainContextRequest::CalculatePow`]
|
||||||
|
pub(crate) async fn calculate_pow(
|
||||||
|
blockchain_context: &mut BlockChainContextService,
|
||||||
|
hardfork: HardFork,
|
||||||
|
height: u64,
|
||||||
|
block: Box<Block>,
|
||||||
|
seed_hash: [u8; 32],
|
||||||
|
) -> Result<[u8; 32], Error> {
|
||||||
|
let BlockChainContextResponse::CalculatePow(hash) = blockchain_context
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.map_err(|e| anyhow!(e))?
|
||||||
|
.call(BlockChainContextRequest::CalculatePow {
|
||||||
|
hardfork,
|
||||||
|
height: u64_to_usize(height),
|
||||||
|
block,
|
||||||
|
seed_hash,
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(|e| anyhow!(e))?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(hash)
|
||||||
|
}
|
||||||
|
|
|
@ -5,13 +5,18 @@ use monero_serai::block::Block;
|
||||||
use tower::{Service, ServiceExt};
|
use tower::{Service, ServiceExt};
|
||||||
|
|
||||||
use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
|
use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
|
||||||
|
use cuprate_p2p_core::{types::ConnectionId, NetworkZone};
|
||||||
|
use cuprate_pruning::PruningSeed;
|
||||||
|
use cuprate_rpc_types::misc::Span;
|
||||||
|
use cuprate_types::{AddAuxPow, AuxPow, HardFork};
|
||||||
|
|
||||||
use crate::rpc::handler::{
|
use crate::rpc::{
|
||||||
BlockchainManagerHandle, BlockchainManagerRequest, BlockchainManagerResponse,
|
constants::FIELD_NOT_SUPPORTED,
|
||||||
|
handler::{BlockchainManagerHandle, BlockchainManagerRequest, BlockchainManagerResponse},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// [`BlockchainManagerRequest::PopBlocks`]
|
/// [`BlockchainManagerRequest::PopBlocks`]
|
||||||
pub(super) async fn pop_blocks(
|
pub(crate) async fn pop_blocks(
|
||||||
blockchain_manager: &mut BlockchainManagerHandle,
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
) -> Result<u64, Error> {
|
) -> Result<u64, Error> {
|
||||||
|
@ -30,8 +35,10 @@ pub(super) async fn pop_blocks(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainManagerRequest::Prune`]
|
/// [`BlockchainManagerRequest::Prune`]
|
||||||
pub(super) async fn prune(blockchain_manager: &mut BlockchainManagerHandle) -> Result<(), Error> {
|
pub(crate) async fn prune(
|
||||||
let BlockchainManagerResponse::Ok = blockchain_manager
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
) -> Result<PruningSeed, Error> {
|
||||||
|
let BlockchainManagerResponse::Prune(seed) = blockchain_manager
|
||||||
.ready()
|
.ready()
|
||||||
.await?
|
.await?
|
||||||
.call(BlockchainManagerRequest::Prune)
|
.call(BlockchainManagerRequest::Prune)
|
||||||
|
@ -40,11 +47,11 @@ pub(super) async fn prune(blockchain_manager: &mut BlockchainManagerHandle) -> R
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(seed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainManagerRequest::Pruned`]
|
/// [`BlockchainManagerRequest::Pruned`]
|
||||||
pub(super) async fn pruned(
|
pub(crate) async fn pruned(
|
||||||
blockchain_manager: &mut BlockchainManagerHandle,
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let BlockchainManagerResponse::Pruned(pruned) = blockchain_manager
|
let BlockchainManagerResponse::Pruned(pruned) = blockchain_manager
|
||||||
|
@ -60,7 +67,7 @@ pub(super) async fn pruned(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainManagerRequest::RelayBlock`]
|
/// [`BlockchainManagerRequest::RelayBlock`]
|
||||||
pub(super) async fn relay_block(
|
pub(crate) async fn relay_block(
|
||||||
blockchain_manager: &mut BlockchainManagerHandle,
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
block: Block,
|
block: Block,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
@ -77,7 +84,7 @@ pub(super) async fn relay_block(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainManagerRequest::Syncing`]
|
/// [`BlockchainManagerRequest::Syncing`]
|
||||||
pub(super) async fn syncing(
|
pub(crate) async fn syncing(
|
||||||
blockchain_manager: &mut BlockchainManagerHandle,
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let BlockchainManagerResponse::Syncing(syncing) = blockchain_manager
|
let BlockchainManagerResponse::Syncing(syncing) = blockchain_manager
|
||||||
|
@ -93,7 +100,7 @@ pub(super) async fn syncing(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainManagerRequest::Synced`]
|
/// [`BlockchainManagerRequest::Synced`]
|
||||||
pub(super) async fn synced(
|
pub(crate) async fn synced(
|
||||||
blockchain_manager: &mut BlockchainManagerHandle,
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let BlockchainManagerResponse::Synced(syncing) = blockchain_manager
|
let BlockchainManagerResponse::Synced(syncing) = blockchain_manager
|
||||||
|
@ -109,7 +116,7 @@ pub(super) async fn synced(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainManagerRequest::Target`]
|
/// [`BlockchainManagerRequest::Target`]
|
||||||
pub(super) async fn target(
|
pub(crate) async fn target(
|
||||||
blockchain_manager: &mut BlockchainManagerHandle,
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
) -> Result<std::time::Duration, Error> {
|
) -> Result<std::time::Duration, Error> {
|
||||||
let BlockchainManagerResponse::Target(target) = blockchain_manager
|
let BlockchainManagerResponse::Target(target) = blockchain_manager
|
||||||
|
@ -125,7 +132,7 @@ pub(super) async fn target(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BlockchainManagerRequest::TargetHeight`]
|
/// [`BlockchainManagerRequest::TargetHeight`]
|
||||||
pub(super) async fn target_height(
|
pub(crate) async fn target_height(
|
||||||
blockchain_manager: &mut BlockchainManagerHandle,
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
) -> Result<u64, Error> {
|
) -> Result<u64, Error> {
|
||||||
let BlockchainManagerResponse::TargetHeight { height } = blockchain_manager
|
let BlockchainManagerResponse::TargetHeight { height } = blockchain_manager
|
||||||
|
@ -139,3 +146,76 @@ pub(super) async fn target_height(
|
||||||
|
|
||||||
Ok(usize_to_u64(height))
|
Ok(usize_to_u64(height))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainManagerRequest::GenerateBlocks`]
|
||||||
|
pub(crate) async fn generate_blocks(
|
||||||
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
amount_of_blocks: u64,
|
||||||
|
prev_block: [u8; 32],
|
||||||
|
starting_nonce: u32,
|
||||||
|
wallet_address: String,
|
||||||
|
) -> Result<(Vec<[u8; 32]>, u64), Error> {
|
||||||
|
let BlockchainManagerResponse::GenerateBlocks { blocks, height } = blockchain_manager
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainManagerRequest::GenerateBlocks {
|
||||||
|
amount_of_blocks,
|
||||||
|
prev_block,
|
||||||
|
starting_nonce,
|
||||||
|
wallet_address,
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((blocks, usize_to_u64(height)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// [`BlockchainManagerRequest::Spans`]
|
||||||
|
pub(crate) async fn spans<Z: NetworkZone>(
|
||||||
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
) -> Result<Vec<Span>, Error> {
|
||||||
|
// let BlockchainManagerResponse::Spans(vec) = blockchain_manager
|
||||||
|
// .ready()
|
||||||
|
// .await?
|
||||||
|
// .call(BlockchainManagerRequest::Spans)
|
||||||
|
// .await?
|
||||||
|
// else {
|
||||||
|
// unreachable!();
|
||||||
|
// };
|
||||||
|
|
||||||
|
let vec: Vec<cuprate_p2p_core::types::Span<Z::Addr>> = todo!();
|
||||||
|
|
||||||
|
// FIXME: impl this map somewhere instead of inline.
|
||||||
|
let vec = vec
|
||||||
|
.into_iter()
|
||||||
|
.map(|span| Span {
|
||||||
|
connection_id: String::from(ConnectionId::DEFAULT_STR),
|
||||||
|
nblocks: span.nblocks,
|
||||||
|
rate: span.rate,
|
||||||
|
remote_address: span.remote_address.to_string(),
|
||||||
|
size: span.size,
|
||||||
|
speed: span.speed,
|
||||||
|
start_block_height: span.start_block_height,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(vec)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainManagerRequest::NextNeededPruningSeed`]
|
||||||
|
pub(crate) async fn next_needed_pruning_seed(
|
||||||
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
) -> Result<PruningSeed, Error> {
|
||||||
|
let BlockchainManagerResponse::NextNeededPruningSeed(seed) = blockchain_manager
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainManagerRequest::NextNeededPruningSeed)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(seed)
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::{anyhow, Error};
|
||||||
use tower::{Service, ServiceExt};
|
use tower::{Service, ServiceExt};
|
||||||
|
|
||||||
use cuprate_helper::cast::usize_to_u64;
|
use cuprate_helper::cast::usize_to_u64;
|
||||||
|
@ -14,15 +14,17 @@ use cuprate_txpool::{
|
||||||
TxEntry,
|
TxEntry,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// FIXME: use `anyhow::Error` over `tower::BoxError` in txpool.
|
||||||
|
|
||||||
/// [`TxpoolReadRequest::Backlog`]
|
/// [`TxpoolReadRequest::Backlog`]
|
||||||
pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result<Vec<TxEntry>, Error> {
|
pub(crate) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result<Vec<TxEntry>, Error> {
|
||||||
let TxpoolReadResponse::Backlog(tx_entries) = txpool_read
|
let TxpoolReadResponse::Backlog(tx_entries) = txpool_read
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
.call(TxpoolReadRequest::Backlog)
|
.call(TxpoolReadRequest::Backlog)
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -31,14 +33,19 @@ pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result<Vec<Tx
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`TxpoolReadRequest::Size`]
|
/// [`TxpoolReadRequest::Size`]
|
||||||
pub(super) async fn size(txpool_read: &mut TxpoolReadHandle) -> Result<u64, Error> {
|
pub(crate) async fn size(
|
||||||
|
txpool_read: &mut TxpoolReadHandle,
|
||||||
|
include_sensitive_txs: bool,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
let TxpoolReadResponse::Size(size) = txpool_read
|
let TxpoolReadResponse::Size(size) = txpool_read
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
.call(TxpoolReadRequest::Size)
|
.call(TxpoolReadRequest::Size {
|
||||||
|
include_sensitive_txs,
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
.expect("TODO")
|
.map_err(|e| anyhow!(e))?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -47,9 +54,17 @@ pub(super) async fn size(txpool_read: &mut TxpoolReadHandle) -> Result<u64, Erro
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TODO
|
/// TODO
|
||||||
#[expect(clippy::needless_pass_by_ref_mut, reason = "TODO: remove after impl")]
|
pub(crate) async fn flush(
|
||||||
pub(super) async fn flush(
|
txpool_manager: &mut Infallible,
|
||||||
txpool_read: &mut TxpoolReadHandle,
|
tx_hashes: Vec<[u8; 32]>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
todo!();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO
|
||||||
|
pub(crate) async fn relay(
|
||||||
|
txpool_manager: &mut Infallible,
|
||||||
tx_hashes: Vec<[u8; 32]>,
|
tx_hashes: Vec<[u8; 32]>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
todo!();
|
todo!();
|
||||||
|
|
|
@ -18,6 +18,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use futures::{channel::oneshot, FutureExt};
|
use futures::{channel::oneshot, FutureExt};
|
||||||
|
use monero_serai::block::Block;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio_util::sync::PollSender;
|
use tokio_util::sync::PollSender;
|
||||||
use tower::Service;
|
use tower::Service;
|
||||||
|
@ -267,6 +268,21 @@ pub enum BlockChainContextRequest {
|
||||||
grace_blocks: u64,
|
grace_blocks: u64,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Calculate proof-of-work for this block.
|
||||||
|
CalculatePow {
|
||||||
|
/// The hardfork of the protocol at this block height.
|
||||||
|
hardfork: HardFork,
|
||||||
|
/// The height of the block.
|
||||||
|
height: usize,
|
||||||
|
/// The block data.
|
||||||
|
///
|
||||||
|
/// This is boxed because [`Block`] causes this enum to be 1200 bytes,
|
||||||
|
/// where the 2nd variant is only 96 bytes.
|
||||||
|
block: Box<Block>,
|
||||||
|
/// The seed hash for the proof-of-work.
|
||||||
|
seed_hash: [u8; 32],
|
||||||
|
},
|
||||||
|
|
||||||
/// Clear the alt chain context caches.
|
/// Clear the alt chain context caches.
|
||||||
ClearAltCache,
|
ClearAltCache,
|
||||||
|
|
||||||
|
@ -364,6 +380,9 @@ pub enum BlockChainContextResponse {
|
||||||
/// Response to [`BlockChainContextRequest::FeeEstimate`]
|
/// Response to [`BlockChainContextRequest::FeeEstimate`]
|
||||||
FeeEstimate(FeeEstimate),
|
FeeEstimate(FeeEstimate),
|
||||||
|
|
||||||
|
/// Response to [`BlockChainContextRequest::CalculatePow`]
|
||||||
|
CalculatePow([u8; 32]),
|
||||||
|
|
||||||
/// Response to [`BlockChainContextRequest::AltChains`]
|
/// Response to [`BlockChainContextRequest::AltChains`]
|
||||||
///
|
///
|
||||||
/// If the inner [`Vec::is_empty`], there were no alternate chains.
|
/// If the inner [`Vec::is_empty`], there were no alternate chains.
|
||||||
|
|
|
@ -324,7 +324,8 @@ impl<D: Database + Clone + Send + 'static> ContextTask<D> {
|
||||||
}
|
}
|
||||||
BlockChainContextRequest::HardForkInfo(_)
|
BlockChainContextRequest::HardForkInfo(_)
|
||||||
| BlockChainContextRequest::FeeEstimate { .. }
|
| BlockChainContextRequest::FeeEstimate { .. }
|
||||||
| BlockChainContextRequest::AltChains => {
|
| BlockChainContextRequest::AltChains
|
||||||
|
| BlockChainContextRequest::CalculatePow { .. } => {
|
||||||
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
// //
|
// //
|
||||||
//============================ SAFETY: DO NOT REMOVE ===========================//
|
//============================ SAFETY: DO NOT REMOVE ===========================//
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Free functions
|
|
||||||
/// Cast [`u64`] to [`usize`].
|
/// Cast [`u64`] to [`usize`].
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn u64_to_usize(u: u64) -> usize {
|
pub const fn u64_to_usize(u: u64) -> usize {
|
||||||
|
|
|
@ -423,7 +423,8 @@ impl<Z: BorshNetworkZone> Service<AddressBookRequest<Z>> for AddressBook<Z> {
|
||||||
AddressBookRequest::PeerlistSize
|
AddressBookRequest::PeerlistSize
|
||||||
| AddressBookRequest::ConnectionCount
|
| AddressBookRequest::ConnectionCount
|
||||||
| AddressBookRequest::SetBan(_)
|
| AddressBookRequest::SetBan(_)
|
||||||
| AddressBookRequest::GetBans => {
|
| AddressBookRequest::GetBans
|
||||||
|
| AddressBookRequest::ConnectionInfo => {
|
||||||
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@ borsh = ["dep:borsh", "cuprate-pruning/borsh"]
|
||||||
cuprate-helper = { workspace = true, features = ["asynch"], default-features = false }
|
cuprate-helper = { workspace = true, features = ["asynch"], default-features = false }
|
||||||
cuprate-wire = { workspace = true, features = ["tracing"] }
|
cuprate-wire = { workspace = true, features = ["tracing"] }
|
||||||
cuprate-pruning = { workspace = true }
|
cuprate-pruning = { workspace = true }
|
||||||
|
cuprate-types = { workspace = true }
|
||||||
|
|
||||||
tokio = { workspace = true, features = ["net", "sync", "macros", "time", "rt", "rt-multi-thread"]}
|
tokio = { workspace = true, features = ["net", "sync", "macros", "time", "rt", "rt-multi-thread"]}
|
||||||
tokio-util = { workspace = true, features = ["codec"] }
|
tokio-util = { workspace = true, features = ["codec"] }
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
//! Data structures related to bans.
|
|
||||||
|
|
||||||
use std::time::{Duration, Instant};
|
|
||||||
|
|
||||||
use crate::NetZoneAddress;
|
|
||||||
|
|
||||||
/// Data within [`crate::services::AddressBookRequest::SetBan`].
|
|
||||||
pub struct SetBan<A: NetZoneAddress> {
|
|
||||||
/// Address of the peer.
|
|
||||||
pub address: A,
|
|
||||||
/// - If [`Some`], how long this peer should be banned for
|
|
||||||
/// - If [`None`], the peer will be unbanned
|
|
||||||
pub ban: Option<Duration>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Data within [`crate::services::AddressBookResponse::GetBans`].
|
|
||||||
pub struct BanState<A: NetZoneAddress> {
|
|
||||||
/// Address of the peer.
|
|
||||||
pub address: A,
|
|
||||||
/// - If [`Some`], the peer is banned until this [`Instant`]
|
|
||||||
/// - If [`None`], the peer is not currently banned
|
|
||||||
pub unban_instant: Option<Instant>,
|
|
||||||
}
|
|
|
@ -111,7 +111,8 @@ impl<N: NetworkZone> Service<AddressBookRequest<N>> for DummyAddressBook {
|
||||||
AddressBookRequest::PeerlistSize
|
AddressBookRequest::PeerlistSize
|
||||||
| AddressBookRequest::ConnectionCount
|
| AddressBookRequest::ConnectionCount
|
||||||
| AddressBookRequest::SetBan(_)
|
| AddressBookRequest::SetBan(_)
|
||||||
| AddressBookRequest::GetBans => {
|
| AddressBookRequest::GetBans
|
||||||
|
| AddressBookRequest::ConnectionInfo => {
|
||||||
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -75,7 +75,6 @@ use cuprate_wire::{
|
||||||
NetworkAddress,
|
NetworkAddress,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod ban;
|
|
||||||
pub mod client;
|
pub mod client;
|
||||||
mod constants;
|
mod constants;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
@ -83,6 +82,7 @@ pub mod handles;
|
||||||
mod network_zones;
|
mod network_zones;
|
||||||
pub mod protocol;
|
pub mod protocol;
|
||||||
pub mod services;
|
pub mod services;
|
||||||
|
pub mod types;
|
||||||
|
|
||||||
pub use error::*;
|
pub use error::*;
|
||||||
pub use network_zones::{ClearNet, ClearNetServerCfg};
|
pub use network_zones::{ClearNet, ClearNetServerCfg};
|
||||||
|
|
|
@ -4,9 +4,9 @@ use cuprate_pruning::{PruningError, PruningSeed};
|
||||||
use cuprate_wire::{CoreSyncData, PeerListEntryBase};
|
use cuprate_wire::{CoreSyncData, PeerListEntryBase};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ban::{BanState, SetBan},
|
|
||||||
client::InternalPeerID,
|
client::InternalPeerID,
|
||||||
handles::ConnectionHandle,
|
handles::ConnectionHandle,
|
||||||
|
types::{BanState, ConnectionInfo, SetBan},
|
||||||
NetZoneAddress, NetworkAddressIncorrectZone, NetworkZone,
|
NetZoneAddress, NetworkAddressIncorrectZone, NetworkZone,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -118,6 +118,9 @@ pub enum AddressBookRequest<Z: NetworkZone> {
|
||||||
/// Get the amount of white & grey peers.
|
/// Get the amount of white & grey peers.
|
||||||
PeerlistSize,
|
PeerlistSize,
|
||||||
|
|
||||||
|
/// Get information on all connections.
|
||||||
|
ConnectionInfo,
|
||||||
|
|
||||||
/// Get the amount of incoming & outgoing connections.
|
/// Get the amount of incoming & outgoing connections.
|
||||||
ConnectionCount,
|
ConnectionCount,
|
||||||
|
|
||||||
|
@ -152,6 +155,9 @@ pub enum AddressBookResponse<Z: NetworkZone> {
|
||||||
/// Response to [`AddressBookRequest::PeerlistSize`].
|
/// Response to [`AddressBookRequest::PeerlistSize`].
|
||||||
PeerlistSize { white: usize, grey: usize },
|
PeerlistSize { white: usize, grey: usize },
|
||||||
|
|
||||||
|
/// Response to [`AddressBookRequest::ConnectionInfo`].
|
||||||
|
ConnectionInfo(Vec<ConnectionInfo<Z::Addr>>),
|
||||||
|
|
||||||
/// Response to [`AddressBookRequest::ConnectionCount`].
|
/// Response to [`AddressBookRequest::ConnectionCount`].
|
||||||
ConnectionCount { incoming: usize, outgoing: usize },
|
ConnectionCount { incoming: usize, outgoing: usize },
|
||||||
|
|
||||||
|
|
96
p2p/p2p-core/src/types.rs
Normal file
96
p2p/p2p-core/src/types.rs
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
//! General data structures.
|
||||||
|
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
use cuprate_pruning::PruningSeed;
|
||||||
|
use cuprate_types::{AddressType, ConnectionState};
|
||||||
|
|
||||||
|
use crate::NetZoneAddress;
|
||||||
|
|
||||||
|
/// Data within [`crate::services::AddressBookRequest::SetBan`].
|
||||||
|
pub struct SetBan<A: NetZoneAddress> {
|
||||||
|
/// Address of the peer.
|
||||||
|
pub address: A,
|
||||||
|
/// - If [`Some`], how long this peer should be banned for
|
||||||
|
/// - If [`None`], the peer will be unbanned
|
||||||
|
pub ban: Option<Duration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Data within [`crate::services::AddressBookResponse::GetBans`].
|
||||||
|
pub struct BanState<A: NetZoneAddress> {
|
||||||
|
/// Address of the peer.
|
||||||
|
pub address: A,
|
||||||
|
/// - If [`Some`], the peer is banned until this [`Instant`]
|
||||||
|
/// - If [`None`], the peer is not currently banned
|
||||||
|
pub unban_instant: Option<Instant>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Data within [`crate::services::AddressBookResponse::ConnectionInfo`].
|
||||||
|
pub struct ConnectionInfo<A: NetZoneAddress> {
|
||||||
|
// The following fields are mostly the same as `monerod`.
|
||||||
|
pub address: A,
|
||||||
|
pub address_type: AddressType,
|
||||||
|
pub avg_download: u64,
|
||||||
|
pub avg_upload: u64,
|
||||||
|
pub current_download: u64,
|
||||||
|
pub current_upload: u64,
|
||||||
|
pub height: u64,
|
||||||
|
/// Either a domain or an IP without the port.
|
||||||
|
pub host: String,
|
||||||
|
pub incoming: bool,
|
||||||
|
pub live_time: u64,
|
||||||
|
pub localhost: bool,
|
||||||
|
pub local_ip: bool,
|
||||||
|
pub peer_id: u64,
|
||||||
|
pub pruning_seed: PruningSeed,
|
||||||
|
pub recv_count: u64,
|
||||||
|
pub recv_idle_time: u64,
|
||||||
|
pub rpc_credits_per_hash: u32,
|
||||||
|
pub rpc_port: u16,
|
||||||
|
pub send_count: u64,
|
||||||
|
pub send_idle_time: u64,
|
||||||
|
pub state: ConnectionState,
|
||||||
|
pub support_flags: u32,
|
||||||
|
|
||||||
|
// The following fields are slightly different than `monerod`.
|
||||||
|
|
||||||
|
//
|
||||||
|
/// [`None`] if Tor/i2p or unknown.
|
||||||
|
pub socket_addr: Option<std::net::SocketAddr>,
|
||||||
|
|
||||||
|
/// This field does not exist for `cuprated`'s RPC, this is just a marker type:
|
||||||
|
/// - <https://github.com/Cuprate/cuprate/pull/320#discussion_r1811335020>
|
||||||
|
/// - <https://github.com/Cuprate/cuprate/pull/320#discussion_r1819826080>
|
||||||
|
///
|
||||||
|
/// [`ConnectionId::DEFAULT_STR`] is used when mapping to the RPC type.
|
||||||
|
pub connection_id: ConnectionId,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Marker type for `monerod`'s connection ID.
|
||||||
|
///
|
||||||
|
/// `connection_id` is a 128-bit `uuid` in `monerod`.
|
||||||
|
/// `cuprated` does not support this field so it returns
|
||||||
|
/// the default value in the RPC interface, an all 0-bit UUID.
|
||||||
|
///
|
||||||
|
/// This default value in string form is [`ConnectionId::DEFAULT_STR`].
|
||||||
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct ConnectionId;
|
||||||
|
|
||||||
|
impl ConnectionId {
|
||||||
|
/// [`str`] representation of a default connection ID.
|
||||||
|
pub const DEFAULT_STR: &str = "00000000000000000000000000000000";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used in RPC's `sync_info`.
|
||||||
|
///
|
||||||
|
// TODO: fix docs after <https://github.com/Cuprate/cuprate/pull/320#discussion_r1811089758>
|
||||||
|
// Data within [`crate::services::AddressBookResponse::Spans`].
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct Span<A: NetZoneAddress> {
|
||||||
|
pub nblocks: u64,
|
||||||
|
pub rate: u32,
|
||||||
|
pub remote_address: A,
|
||||||
|
pub size: u64,
|
||||||
|
pub speed: u32,
|
||||||
|
pub start_block_height: u64,
|
||||||
|
}
|
|
@ -10,13 +10,13 @@ keywords = ["cuprate", "rpc", "types", "monero"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["serde", "epee"]
|
default = ["serde", "epee"]
|
||||||
serde = ["dep:serde", "cuprate-fixed-bytes/serde"]
|
serde = ["dep:serde", "cuprate-fixed-bytes/serde", "cuprate-types/serde"]
|
||||||
epee = ["dep:cuprate-epee-encoding"]
|
epee = ["dep:cuprate-epee-encoding", "cuprate-types/epee"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cuprate-epee-encoding = { workspace = true, optional = true }
|
cuprate-epee-encoding = { workspace = true, optional = true }
|
||||||
cuprate-fixed-bytes = { workspace = true }
|
cuprate-fixed-bytes = { workspace = true }
|
||||||
cuprate-types = { workspace = true, default-features = false, features = ["epee", "serde"] }
|
cuprate-types = { workspace = true, default-features = false }
|
||||||
|
|
||||||
paste = { workspace = true }
|
paste = { workspace = true }
|
||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
|
|
|
@ -58,61 +58,37 @@ pub struct ResponseBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResponseBase {
|
impl ResponseBase {
|
||||||
/// `const` version of [`Default::default`].
|
/// [`Status::Ok`] and trusted [`Self`].
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use cuprate_rpc_types::{misc::*, base::*};
|
|
||||||
///
|
|
||||||
/// let new = ResponseBase::new();
|
|
||||||
/// assert_eq!(new, ResponseBase {
|
|
||||||
/// status: Status::Ok,
|
|
||||||
/// untrusted: false,
|
|
||||||
/// });
|
|
||||||
/// ```
|
|
||||||
pub const fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
status: Status::Ok,
|
|
||||||
untrusted: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns OK and trusted [`Self`].
|
|
||||||
///
|
///
|
||||||
/// This is the most common version of [`Self`].
|
/// This is the most common version of [`Self`].
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use cuprate_rpc_types::{misc::*, base::*};
|
/// use cuprate_rpc_types::{misc::*, base::*};
|
||||||
///
|
///
|
||||||
/// let ok = ResponseBase::ok();
|
/// assert_eq!(ResponseBase::OK, ResponseBase {
|
||||||
/// assert_eq!(ok, ResponseBase {
|
|
||||||
/// status: Status::Ok,
|
/// status: Status::Ok,
|
||||||
/// untrusted: false,
|
/// untrusted: false,
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
pub const fn ok() -> Self {
|
pub const OK: Self = Self {
|
||||||
Self {
|
|
||||||
status: Status::Ok,
|
status: Status::Ok,
|
||||||
untrusted: false,
|
untrusted: false,
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
/// Same as [`Self::ok`] but with [`Self::untrusted`] set to `true`.
|
/// Same as [`Self::OK`] but with [`Self::untrusted`] set to `true`.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use cuprate_rpc_types::{misc::*, base::*};
|
/// use cuprate_rpc_types::{misc::*, base::*};
|
||||||
///
|
///
|
||||||
/// let ok_untrusted = ResponseBase::ok_untrusted();
|
/// assert_eq!(ResponseBase::OK_UNTRUSTED, ResponseBase {
|
||||||
/// assert_eq!(ok_untrusted, ResponseBase {
|
|
||||||
/// status: Status::Ok,
|
/// status: Status::Ok,
|
||||||
/// untrusted: true,
|
/// untrusted: true,
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
pub const fn ok_untrusted() -> Self {
|
pub const OK_UNTRUSTED: Self = Self {
|
||||||
Self {
|
|
||||||
status: Status::Ok,
|
status: Status::Ok,
|
||||||
untrusted: true,
|
untrusted: true,
|
||||||
}
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "epee")]
|
#[cfg(feature = "epee")]
|
||||||
|
@ -148,9 +124,9 @@ impl AccessResponseBase {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use cuprate_rpc_types::{misc::*, base::*};
|
/// use cuprate_rpc_types::{misc::*, base::*};
|
||||||
///
|
///
|
||||||
/// let new = AccessResponseBase::new(ResponseBase::ok());
|
/// let new = AccessResponseBase::new(ResponseBase::OK);
|
||||||
/// assert_eq!(new, AccessResponseBase {
|
/// assert_eq!(new, AccessResponseBase {
|
||||||
/// response_base: ResponseBase::ok(),
|
/// response_base: ResponseBase::OK,
|
||||||
/// credits: 0,
|
/// credits: 0,
|
||||||
/// top_hash: "".into(),
|
/// top_hash: "".into(),
|
||||||
/// });
|
/// });
|
||||||
|
@ -163,47 +139,41 @@ impl AccessResponseBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns OK and trusted [`Self`].
|
/// [`Status::Ok`] and trusted [`Self`].
|
||||||
///
|
///
|
||||||
/// This is the most common version of [`Self`].
|
/// This is the most common version of [`Self`].
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use cuprate_rpc_types::{misc::*, base::*};
|
/// use cuprate_rpc_types::{misc::*, base::*};
|
||||||
///
|
///
|
||||||
/// let ok = AccessResponseBase::ok();
|
/// assert_eq!(AccessResponseBase::OK, AccessResponseBase {
|
||||||
/// assert_eq!(ok, AccessResponseBase {
|
/// response_base: ResponseBase::OK,
|
||||||
/// response_base: ResponseBase::ok(),
|
|
||||||
/// credits: 0,
|
/// credits: 0,
|
||||||
/// top_hash: "".into(),
|
/// top_hash: "".into(),
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
pub const fn ok() -> Self {
|
pub const OK: Self = Self {
|
||||||
Self {
|
response_base: ResponseBase::OK,
|
||||||
response_base: ResponseBase::ok(),
|
|
||||||
credits: 0,
|
credits: 0,
|
||||||
top_hash: String::new(),
|
top_hash: String::new(),
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
/// Same as [`Self::ok`] but with `untrusted` set to `true`.
|
/// Same as [`Self::OK`] but with `untrusted` set to `true`.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use cuprate_rpc_types::{misc::*, base::*};
|
/// use cuprate_rpc_types::{misc::*, base::*};
|
||||||
///
|
///
|
||||||
/// let ok_untrusted = AccessResponseBase::ok_untrusted();
|
/// assert_eq!(AccessResponseBase::OK_UNTRUSTED, AccessResponseBase {
|
||||||
/// assert_eq!(ok_untrusted, AccessResponseBase {
|
/// response_base: ResponseBase::OK_UNTRUSTED,
|
||||||
/// response_base: ResponseBase::ok_untrusted(),
|
|
||||||
/// credits: 0,
|
/// credits: 0,
|
||||||
/// top_hash: "".into(),
|
/// top_hash: "".into(),
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
pub const fn ok_untrusted() -> Self {
|
pub const OK_UNTRUSTED: Self = Self {
|
||||||
Self {
|
response_base: ResponseBase::OK_UNTRUSTED,
|
||||||
response_base: ResponseBase::ok_untrusted(),
|
|
||||||
credits: 0,
|
credits: 0,
|
||||||
top_hash: String::new(),
|
top_hash: String::new(),
|
||||||
}
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "epee")]
|
#[cfg(feature = "epee")]
|
||||||
|
|
|
@ -186,7 +186,7 @@ define_request_and_response! {
|
||||||
// <https://serde.rs/field-attrs.html#flatten>.
|
// <https://serde.rs/field-attrs.html#flatten>.
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_BLOCK_TEMPLATE_RESPONSE => GetBlockTemplateResponse {
|
GET_BLOCK_TEMPLATE_RESPONSE => GetBlockTemplateResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
blockhashing_blob: "1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a00000000e0c20372be23d356347091025c5b5e8f2abf83ab618378565cce2b703491523401".into(),
|
blockhashing_blob: "1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a00000000e0c20372be23d356347091025c5b5e8f2abf83ab618378565cce2b703491523401".into(),
|
||||||
blocktemplate_blob: "1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(),
|
blocktemplate_blob: "1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(),
|
||||||
difficulty_top64: 0,
|
difficulty_top64: 0,
|
||||||
|
@ -242,7 +242,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_BLOCK_COUNT_RESPONSE => GetBlockCountResponse {
|
GET_BLOCK_COUNT_RESPONSE => GetBlockCountResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
count: 3195019,
|
count: 3195019,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
|
@ -334,7 +334,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GENERATE_BLOCKS_RESPONSE => GenerateBlocksResponse {
|
GENERATE_BLOCKS_RESPONSE => GenerateBlocksResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
blocks: vec!["49b712db7760e3728586f8434ee8bc8d7b3d410dac6bb6e98bf5845c83b917e4".into()],
|
blocks: vec!["49b712db7760e3728586f8434ee8bc8d7b3d410dac6bb6e98bf5845c83b917e4".into()],
|
||||||
height: 9783,
|
height: 9783,
|
||||||
}
|
}
|
||||||
|
@ -359,7 +359,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_LAST_BLOCK_HEADER_RESPONSE => GetLastBlockHeaderResponse {
|
GET_LAST_BLOCK_HEADER_RESPONSE => GetLastBlockHeaderResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
block_header: BlockHeader {
|
block_header: BlockHeader {
|
||||||
block_size: 200419,
|
block_size: 200419,
|
||||||
block_weight: 200419,
|
block_weight: 200419,
|
||||||
|
@ -411,7 +411,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_BLOCK_HEADER_BY_HASH_RESPONSE => GetBlockHeaderByHashResponse {
|
GET_BLOCK_HEADER_BY_HASH_RESPONSE => GetBlockHeaderByHashResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
block_headers: vec![],
|
block_headers: vec![],
|
||||||
block_header: BlockHeader {
|
block_header: BlockHeader {
|
||||||
block_size: 210,
|
block_size: 210,
|
||||||
|
@ -466,7 +466,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_BLOCK_HEADER_BY_HEIGHT_RESPONSE => GetBlockHeaderByHeightResponse {
|
GET_BLOCK_HEADER_BY_HEIGHT_RESPONSE => GetBlockHeaderByHeightResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
block_header: BlockHeader {
|
block_header: BlockHeader {
|
||||||
block_size: 210,
|
block_size: 210,
|
||||||
block_weight: 210,
|
block_weight: 210,
|
||||||
|
@ -521,7 +521,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_BLOCK_HEADERS_RANGE_RESPONSE => GetBlockHeadersRangeResponse {
|
GET_BLOCK_HEADERS_RANGE_RESPONSE => GetBlockHeadersRangeResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
headers: vec![
|
headers: vec![
|
||||||
BlockHeader {
|
BlockHeader {
|
||||||
block_size: 301413,
|
block_size: 301413,
|
||||||
|
@ -603,7 +603,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_BLOCK_RESPONSE => GetBlockResponse {
|
GET_BLOCK_RESPONSE => GetBlockResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
blob: "1010c58bab9b06b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7807e07f502cef8a70101ff92f8a7010180e0a596bb1103d7cbf826b665d7a532c316982dc8dbc24f285cbc18bbcc27c7164cd9b3277a85d034019f629d8b36bd16a2bfce3ea80c31dc4d8762c67165aec21845494e32b7582fe00211000000297a787a000000000000000000000000".into(),
|
blob: "1010c58bab9b06b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7807e07f502cef8a70101ff92f8a7010180e0a596bb1103d7cbf826b665d7a532c316982dc8dbc24f285cbc18bbcc27c7164cd9b3277a85d034019f629d8b36bd16a2bfce3ea80c31dc4d8762c67165aec21845494e32b7582fe00211000000297a787a000000000000000000000000".into(),
|
||||||
block_header: BlockHeader {
|
block_header: BlockHeader {
|
||||||
block_size: 106,
|
block_size: 106,
|
||||||
|
@ -656,11 +656,11 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_CONNECTIONS_RESPONSE => GetConnectionsResponse {
|
GET_CONNECTIONS_RESPONSE => GetConnectionsResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
connections: vec![
|
connections: vec![
|
||||||
ConnectionInfo {
|
ConnectionInfo {
|
||||||
address: "3evk3kezfjg44ma6tvesy7rbxwwpgpympj45xar5fo4qajrsmkoaqdqd.onion:18083".into(),
|
address: "3evk3kezfjg44ma6tvesy7rbxwwpgpympj45xar5fo4qajrsmkoaqdqd.onion:18083".into(),
|
||||||
address_type: 4,
|
address_type: cuprate_types::AddressType::Tor,
|
||||||
avg_download: 0,
|
avg_download: 0,
|
||||||
avg_upload: 0,
|
avg_upload: 0,
|
||||||
connection_id: "22ef856d0f1d44cc95e84fecfd065fe2".into(),
|
connection_id: "22ef856d0f1d44cc95e84fecfd065fe2".into(),
|
||||||
|
@ -682,12 +682,12 @@ define_request_and_response! {
|
||||||
rpc_port: 0,
|
rpc_port: 0,
|
||||||
send_count: 3406572,
|
send_count: 3406572,
|
||||||
send_idle_time: 30,
|
send_idle_time: 30,
|
||||||
state: "normal".into(),
|
state: cuprate_types::ConnectionState::Normal,
|
||||||
support_flags: 0
|
support_flags: 0
|
||||||
},
|
},
|
||||||
ConnectionInfo {
|
ConnectionInfo {
|
||||||
address: "4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion:18083".into(),
|
address: "4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion:18083".into(),
|
||||||
address_type: 4,
|
address_type: cuprate_types::AddressType::Tor,
|
||||||
avg_download: 0,
|
avg_download: 0,
|
||||||
avg_upload: 0,
|
avg_upload: 0,
|
||||||
connection_id: "c7734e15936f485a86d2b0534f87e499".into(),
|
connection_id: "c7734e15936f485a86d2b0534f87e499".into(),
|
||||||
|
@ -709,7 +709,7 @@ define_request_and_response! {
|
||||||
rpc_port: 0,
|
rpc_port: 0,
|
||||||
send_count: 3370566,
|
send_count: 3370566,
|
||||||
send_idle_time: 120,
|
send_idle_time: 120,
|
||||||
state: "normal".into(),
|
state: cuprate_types::ConnectionState::Normal,
|
||||||
support_flags: 0
|
support_flags: 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -730,7 +730,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_INFO_RESPONSE => GetInfoResponse {
|
GET_INFO_RESPONSE => GetInfoResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
adjusted_time: 1721245289,
|
adjusted_time: 1721245289,
|
||||||
alt_blocks_count: 16,
|
alt_blocks_count: 16,
|
||||||
block_size_limit: 600000,
|
block_size_limit: 600000,
|
||||||
|
@ -833,7 +833,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
HARD_FORK_INFO_RESPONSE => HardForkInfoResponse {
|
HARD_FORK_INFO_RESPONSE => HardForkInfoResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
earliest_height: 2689608,
|
earliest_height: 2689608,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
state: 0,
|
state: 0,
|
||||||
|
@ -879,7 +879,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
SET_BANS_RESPONSE => SetBansResponse {
|
SET_BANS_RESPONSE => SetBansResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
ResponseBase {}
|
ResponseBase {}
|
||||||
|
@ -894,7 +894,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_BANS_RESPONSE => GetBansResponse {
|
GET_BANS_RESPONSE => GetBansResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
bans: vec![
|
bans: vec![
|
||||||
GetBan {
|
GetBan {
|
||||||
host: "104.248.206.131".into(),
|
host: "104.248.206.131".into(),
|
||||||
|
@ -996,7 +996,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_OUTPUT_HISTOGRAM_RESPONSE => GetOutputHistogramResponse {
|
GET_OUTPUT_HISTOGRAM_RESPONSE => GetOutputHistogramResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
histogram: vec![HistogramEntry {
|
histogram: vec![HistogramEntry {
|
||||||
amount: 20000000000,
|
amount: 20000000000,
|
||||||
recent_instances: 0,
|
recent_instances: 0,
|
||||||
|
@ -1030,7 +1030,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_COINBASE_TX_SUM_RESPONSE => GetCoinbaseTxSumResponse {
|
GET_COINBASE_TX_SUM_RESPONSE => GetCoinbaseTxSumResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
emission_amount: 9387854817320,
|
emission_amount: 9387854817320,
|
||||||
emission_amount_top64: 0,
|
emission_amount_top64: 0,
|
||||||
fee_amount: 83981380000,
|
fee_amount: 83981380000,
|
||||||
|
@ -1059,7 +1059,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_VERSION_RESPONSE => GetVersionResponse {
|
GET_VERSION_RESPONSE => GetVersionResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
current_height: 3195051,
|
current_height: 3195051,
|
||||||
hard_forks: vec![
|
hard_forks: vec![
|
||||||
HardforkEntry {
|
HardforkEntry {
|
||||||
|
@ -1145,12 +1145,16 @@ define_request_and_response! {
|
||||||
get_fee_estimate,
|
get_fee_estimate,
|
||||||
cc73fe71162d564ffda8e549b79a350bca53c454 =>
|
cc73fe71162d564ffda8e549b79a350bca53c454 =>
|
||||||
core_rpc_server_commands_defs.h => 2250..=2277,
|
core_rpc_server_commands_defs.h => 2250..=2277,
|
||||||
GetFeeEstimate (empty),
|
|
||||||
Request {},
|
GetFeeEstimate,
|
||||||
|
|
||||||
|
Request {
|
||||||
|
grace_blocks: u64 = default_zero::<u64>(), "default_zero",
|
||||||
|
},
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_FEE_ESTIMATE_RESPONSE => GetFeeEstimateResponse {
|
GET_FEE_ESTIMATE_RESPONSE => GetFeeEstimateResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
fee: 20000,
|
fee: 20000,
|
||||||
fees: vec![20000,80000,320000,4000000],
|
fees: vec![20000,80000,320000,4000000],
|
||||||
quantization_mask: 10000,
|
quantization_mask: 10000,
|
||||||
|
@ -1172,7 +1176,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_ALTERNATE_CHAINS_RESPONSE => GetAlternateChainsResponse {
|
GET_ALTERNATE_CHAINS_RESPONSE => GetAlternateChainsResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
chains: vec![
|
chains: vec![
|
||||||
ChainInfo {
|
ChainInfo {
|
||||||
block_hash: "4826c7d45d7cf4f02985b5c405b0e5d7f92c8d25e015492ce19aa3b209295dce".into(),
|
block_hash: "4826c7d45d7cf4f02985b5c405b0e5d7f92c8d25e015492ce19aa3b209295dce".into(),
|
||||||
|
@ -1240,7 +1244,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
SYNC_INFO_RESPONSE => SyncInfoResponse {
|
SYNC_INFO_RESPONSE => SyncInfoResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
height: 3195157,
|
height: 3195157,
|
||||||
next_needed_pruning_seed: 0,
|
next_needed_pruning_seed: 0,
|
||||||
overview: "[]".into(),
|
overview: "[]".into(),
|
||||||
|
@ -1249,7 +1253,7 @@ define_request_and_response! {
|
||||||
SyncInfoPeer {
|
SyncInfoPeer {
|
||||||
info: ConnectionInfo {
|
info: ConnectionInfo {
|
||||||
address: "142.93.128.65:44986".into(),
|
address: "142.93.128.65:44986".into(),
|
||||||
address_type: 1,
|
address_type: cuprate_types::AddressType::Ipv4,
|
||||||
avg_download: 1,
|
avg_download: 1,
|
||||||
avg_upload: 1,
|
avg_upload: 1,
|
||||||
connection_id: "a5803c4c2dac49e7b201dccdef54c862".into(),
|
connection_id: "a5803c4c2dac49e7b201dccdef54c862".into(),
|
||||||
|
@ -1271,14 +1275,14 @@ define_request_and_response! {
|
||||||
rpc_port: 18089,
|
rpc_port: 18089,
|
||||||
send_count: 32235,
|
send_count: 32235,
|
||||||
send_idle_time: 6,
|
send_idle_time: 6,
|
||||||
state: "normal".into(),
|
state: cuprate_types::ConnectionState::Normal,
|
||||||
support_flags: 1
|
support_flags: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SyncInfoPeer {
|
SyncInfoPeer {
|
||||||
info: ConnectionInfo {
|
info: ConnectionInfo {
|
||||||
address: "4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion:18083".into(),
|
address: "4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion:18083".into(),
|
||||||
address_type: 4,
|
address_type: cuprate_types::AddressType::Tor,
|
||||||
avg_download: 0,
|
avg_download: 0,
|
||||||
avg_upload: 0,
|
avg_upload: 0,
|
||||||
connection_id: "277f7c821bc546878c8bd29977e780f5".into(),
|
connection_id: "277f7c821bc546878c8bd29977e780f5".into(),
|
||||||
|
@ -1300,7 +1304,7 @@ define_request_and_response! {
|
||||||
rpc_port: 0,
|
rpc_port: 0,
|
||||||
send_count: 99120,
|
send_count: 99120,
|
||||||
send_idle_time: 15,
|
send_idle_time: 15,
|
||||||
state: "normal".into(),
|
state: cuprate_types::ConnectionState::Normal,
|
||||||
support_flags: 0
|
support_flags: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1330,7 +1334,7 @@ define_request_and_response! {
|
||||||
// TODO: enable test after binary string impl.
|
// TODO: enable test after binary string impl.
|
||||||
// #[doc = serde_doc_test!(
|
// #[doc = serde_doc_test!(
|
||||||
// GET_TRANSACTION_POOL_BACKLOG_RESPONSE => GetTransactionPoolBacklogResponse {
|
// GET_TRANSACTION_POOL_BACKLOG_RESPONSE => GetTransactionPoolBacklogResponse {
|
||||||
// base: ResponseBase::ok(),
|
// base: ResponseBase::OK,
|
||||||
// backlog: "...Binary...".into(),
|
// backlog: "...Binary...".into(),
|
||||||
// }
|
// }
|
||||||
// )]
|
// )]
|
||||||
|
@ -1372,7 +1376,7 @@ define_request_and_response! {
|
||||||
// TODO: enable test after binary string impl.
|
// TODO: enable test after binary string impl.
|
||||||
// #[doc = serde_doc_test!(
|
// #[doc = serde_doc_test!(
|
||||||
// GET_OUTPUT_DISTRIBUTION_RESPONSE => GetOutputDistributionResponse {
|
// GET_OUTPUT_DISTRIBUTION_RESPONSE => GetOutputDistributionResponse {
|
||||||
// base: AccessResponseBase::ok(),
|
// base: AccessResponseBase::OK,
|
||||||
// distributions: vec![Distribution::Uncompressed(DistributionUncompressed {
|
// distributions: vec![Distribution::Uncompressed(DistributionUncompressed {
|
||||||
// start_height: 1462078,
|
// start_height: 1462078,
|
||||||
// base: 0,
|
// base: 0,
|
||||||
|
@ -1396,7 +1400,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_MINER_DATA_RESPONSE => GetMinerDataResponse {
|
GET_MINER_DATA_RESPONSE => GetMinerDataResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
already_generated_coins: 18186022843595960691,
|
already_generated_coins: 18186022843595960691,
|
||||||
difficulty: "0x48afae42de".into(),
|
difficulty: "0x48afae42de".into(),
|
||||||
height: 2731375,
|
height: 2731375,
|
||||||
|
@ -1449,7 +1453,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
PRUNE_BLOCKCHAIN_RESPONSE => PruneBlockchainResponse {
|
PRUNE_BLOCKCHAIN_RESPONSE => PruneBlockchainResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
pruned: true,
|
pruned: true,
|
||||||
pruning_seed: 387,
|
pruning_seed: 387,
|
||||||
}
|
}
|
||||||
|
@ -1515,7 +1519,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
FLUSH_CACHE_RESPONSE => FlushCacheResponse {
|
FLUSH_CACHE_RESPONSE => FlushCacheResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
ResponseBase {}
|
ResponseBase {}
|
||||||
|
@ -1544,7 +1548,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
ADD_AUX_POW_RESPONSE => AddAuxPowResponse {
|
ADD_AUX_POW_RESPONSE => AddAuxPowResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
aux_pow: vec![AuxPow {
|
aux_pow: vec![AuxPow {
|
||||||
hash: "7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a".into(),
|
hash: "7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a".into(),
|
||||||
id: "3200b4ea97c3b2081cd4190b58e49572b2319fed00d030ad51809dff06b5d8c8".into(),
|
id: "3200b4ea97c3b2081cd4190b58e49572b2319fed00d030ad51809dff06b5d8c8".into(),
|
||||||
|
|
|
@ -110,7 +110,7 @@ define_struct_and_impl_epee! {
|
||||||
/// Used in [`crate::json::GetConnectionsResponse`].
|
/// Used in [`crate::json::GetConnectionsResponse`].
|
||||||
ConnectionInfo {
|
ConnectionInfo {
|
||||||
address: String,
|
address: String,
|
||||||
address_type: u8,
|
address_type: cuprate_types::AddressType,
|
||||||
avg_download: u64,
|
avg_download: u64,
|
||||||
avg_upload: u64,
|
avg_upload: u64,
|
||||||
connection_id: String,
|
connection_id: String,
|
||||||
|
@ -135,7 +135,7 @@ define_struct_and_impl_epee! {
|
||||||
// Exists in the original definition, but isn't
|
// Exists in the original definition, but isn't
|
||||||
// used or (de)serialized for RPC purposes.
|
// used or (de)serialized for RPC purposes.
|
||||||
// ssl: bool,
|
// ssl: bool,
|
||||||
state: String,
|
state: cuprate_types::ConnectionState,
|
||||||
support_flags: u32,
|
support_flags: u32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_HEIGHT_RESPONSE => GetHeightResponse {
|
GET_HEIGHT_RESPONSE => GetHeightResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
hash: "68bb1a1cff8e2a44c3221e8e1aff80bc6ca45d06fa8eff4d2a3a7ac31d4efe3f".into(),
|
hash: "68bb1a1cff8e2a44c3221e8e1aff80bc6ca45d06fa8eff4d2a3a7ac31d4efe3f".into(),
|
||||||
height: 3195160,
|
height: 3195160,
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_ALT_BLOCKS_HASHES_RESPONSE => GetAltBlocksHashesResponse {
|
GET_ALT_BLOCKS_HASHES_RESPONSE => GetAltBlocksHashesResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
blks_hashes: vec!["8ee10db35b1baf943f201b303890a29e7d45437bd76c2bd4df0d2f2ee34be109".into()],
|
blks_hashes: vec!["8ee10db35b1baf943f201b303890a29e7d45437bd76c2bd4df0d2f2ee34be109".into()],
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
|
@ -189,7 +189,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
IS_KEY_IMAGE_SPENT_RESPONSE => IsKeyImageSpentResponse {
|
IS_KEY_IMAGE_SPENT_RESPONSE => IsKeyImageSpentResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
spent_status: vec![1, 1],
|
spent_status: vec![1, 1],
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
|
@ -285,7 +285,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
START_MINING_RESPONSE => StartMiningResponse {
|
START_MINING_RESPONSE => StartMiningResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
ResponseBase {}
|
ResponseBase {}
|
||||||
|
@ -300,7 +300,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
STOP_MINING_RESPONSE => StopMiningResponse {
|
STOP_MINING_RESPONSE => StopMiningResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
ResponseBase {}
|
ResponseBase {}
|
||||||
|
@ -315,7 +315,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
MINING_STATUS_RESPONSE => MiningStatusResponse {
|
MINING_STATUS_RESPONSE => MiningStatusResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
active: false,
|
active: false,
|
||||||
address: "".into(),
|
address: "".into(),
|
||||||
bg_idle_threshold: 0,
|
bg_idle_threshold: 0,
|
||||||
|
@ -361,7 +361,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
SAVE_BC_RESPONSE => SaveBcResponse {
|
SAVE_BC_RESPONSE => SaveBcResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
ResponseBase {}
|
ResponseBase {}
|
||||||
|
@ -387,7 +387,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_PEER_LIST_RESPONSE => GetPeerListResponse {
|
GET_PEER_LIST_RESPONSE => GetPeerListResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
gray_list: vec![
|
gray_list: vec![
|
||||||
Peer {
|
Peer {
|
||||||
host: "161.97.193.0".into(),
|
host: "161.97.193.0".into(),
|
||||||
|
@ -469,7 +469,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
SET_LOG_HASH_RATE_RESPONSE => SetLogHashRateResponse {
|
SET_LOG_HASH_RATE_RESPONSE => SetLogHashRateResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
ResponseBase {}
|
ResponseBase {}
|
||||||
|
@ -494,7 +494,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
SET_LOG_LEVEL_RESPONSE => SetLogLevelResponse {
|
SET_LOG_LEVEL_RESPONSE => SetLogLevelResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
ResponseBase {}
|
ResponseBase {}
|
||||||
|
@ -518,7 +518,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
SET_LOG_CATEGORIES_RESPONSE => SetLogCategoriesResponse {
|
SET_LOG_CATEGORIES_RESPONSE => SetLogCategoriesResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
categories: "*:INFO".into(),
|
categories: "*:INFO".into(),
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
|
@ -584,7 +584,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_TRANSACTION_POOL_STATS_RESPONSE => GetTransactionPoolStatsResponse {
|
GET_TRANSACTION_POOL_STATS_RESPONSE => GetTransactionPoolStatsResponse {
|
||||||
base: AccessResponseBase::ok(),
|
base: AccessResponseBase::OK,
|
||||||
pool_stats: TxpoolStats {
|
pool_stats: TxpoolStats {
|
||||||
bytes_max: 11843,
|
bytes_max: 11843,
|
||||||
bytes_med: 2219,
|
bytes_med: 2219,
|
||||||
|
@ -646,7 +646,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_LIMIT_RESPONSE => GetLimitResponse {
|
GET_LIMIT_RESPONSE => GetLimitResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
limit_down: 1280000,
|
limit_down: 1280000,
|
||||||
limit_up: 1280000,
|
limit_up: 1280000,
|
||||||
}
|
}
|
||||||
|
@ -678,7 +678,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
SET_LIMIT_RESPONSE => SetLimitResponse {
|
SET_LIMIT_RESPONSE => SetLimitResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
limit_down: 1024,
|
limit_down: 1024,
|
||||||
limit_up: 128,
|
limit_up: 128,
|
||||||
}
|
}
|
||||||
|
@ -709,7 +709,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
OUT_PEERS_RESPONSE => OutPeersResponse {
|
OUT_PEERS_RESPONSE => OutPeersResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
out_peers: 3232235535,
|
out_peers: 3232235535,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
|
@ -742,7 +742,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_NET_STATS_RESPONSE => GetNetStatsResponse {
|
GET_NET_STATS_RESPONSE => GetNetStatsResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
start_time: 1721251858,
|
start_time: 1721251858,
|
||||||
total_bytes_in: 16283817214,
|
total_bytes_in: 16283817214,
|
||||||
total_bytes_out: 34225244079,
|
total_bytes_out: 34225244079,
|
||||||
|
@ -781,7 +781,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_OUTS_RESPONSE => GetOutsResponse {
|
GET_OUTS_RESPONSE => GetOutsResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
outs: vec![
|
outs: vec![
|
||||||
OutKey {
|
OutKey {
|
||||||
height: 51941,
|
height: 51941,
|
||||||
|
@ -825,7 +825,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
UPDATE_RESPONSE => UpdateResponse {
|
UPDATE_RESPONSE => UpdateResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
auto_uri: "".into(),
|
auto_uri: "".into(),
|
||||||
hash: "".into(),
|
hash: "".into(),
|
||||||
path: "".into(),
|
path: "".into(),
|
||||||
|
@ -862,7 +862,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
POP_BLOCKS_RESPONSE => PopBlocksResponse {
|
POP_BLOCKS_RESPONSE => PopBlocksResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
height: 76482,
|
height: 76482,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
|
@ -881,7 +881,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_TRANSACTION_POOL_HASHES_RESPONSE => GetTransactionPoolHashesResponse {
|
GET_TRANSACTION_POOL_HASHES_RESPONSE => GetTransactionPoolHashesResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
tx_hashes: vec![
|
tx_hashes: vec![
|
||||||
"aa928aed888acd6152c60194d50a4df29b0b851be6169acf11b6a8e304dd6c03".into(),
|
"aa928aed888acd6152c60194d50a4df29b0b851be6169acf11b6a8e304dd6c03".into(),
|
||||||
"794345f321a98f3135151f3056c0fdf8188646a8dab27de971428acf3551dd11".into(),
|
"794345f321a98f3135151f3056c0fdf8188646a8dab27de971428acf3551dd11".into(),
|
||||||
|
@ -931,7 +931,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
GET_PUBLIC_NODES_RESPONSE => GetPublicNodesResponse {
|
GET_PUBLIC_NODES_RESPONSE => GetPublicNodesResponse {
|
||||||
base: ResponseBase::ok(),
|
base: ResponseBase::OK,
|
||||||
gray: vec![],
|
gray: vec![],
|
||||||
white: vec![
|
white: vec![
|
||||||
PublicNode {
|
PublicNode {
|
||||||
|
|
|
@ -121,6 +121,8 @@ fn map_request(
|
||||||
R::DatabaseSize => database_size(env),
|
R::DatabaseSize => database_size(env),
|
||||||
R::OutputHistogram(input) => output_histogram(env, input),
|
R::OutputHistogram(input) => output_histogram(env, input),
|
||||||
R::CoinbaseTxSum { height, count } => coinbase_tx_sum(env, height, count),
|
R::CoinbaseTxSum { height, count } => coinbase_tx_sum(env, height, count),
|
||||||
|
R::AltChains => alt_chains(env),
|
||||||
|
R::AltChainCount => alt_chain_count(env),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SOMEDAY: post-request handling, run some code for each request? */
|
/* SOMEDAY: post-request handling, run some code for each request? */
|
||||||
|
@ -648,3 +650,13 @@ fn output_histogram(env: &ConcreteEnv, input: OutputHistogramInput) -> ResponseR
|
||||||
fn coinbase_tx_sum(env: &ConcreteEnv, height: usize, count: u64) -> ResponseResult {
|
fn coinbase_tx_sum(env: &ConcreteEnv, height: usize, count: u64) -> ResponseResult {
|
||||||
Ok(BlockchainResponse::CoinbaseTxSum(todo!()))
|
Ok(BlockchainResponse::CoinbaseTxSum(todo!()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::AltChains`]
|
||||||
|
fn alt_chains(env: &ConcreteEnv) -> ResponseResult {
|
||||||
|
Ok(BlockchainResponse::AltChains(todo!()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::AltChainCount`]
|
||||||
|
fn alt_chain_count(env: &ConcreteEnv) -> ResponseResult {
|
||||||
|
Ok(BlockchainResponse::AltChainCount(todo!()))
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,11 @@ pub enum TxpoolReadRequest {
|
||||||
Backlog,
|
Backlog,
|
||||||
|
|
||||||
/// Get the number of transactions in the pool.
|
/// Get the number of transactions in the pool.
|
||||||
Size,
|
Size {
|
||||||
|
/// If this is [`true`], the size returned will
|
||||||
|
/// include private transactions in the pool.
|
||||||
|
include_sensitive_txs: bool,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxpoolReadResponse
|
//---------------------------------------------------------------------------------------------------- TxpoolReadResponse
|
||||||
|
@ -66,7 +70,7 @@ pub enum TxpoolReadResponse {
|
||||||
|
|
||||||
/// Response to [`TxpoolReadRequest::Backlog`].
|
/// Response to [`TxpoolReadRequest::Backlog`].
|
||||||
///
|
///
|
||||||
/// The inner `Vec` contains information on all
|
/// The inner [`Vec`] contains information on all
|
||||||
/// the transactions currently in the pool.
|
/// the transactions currently in the pool.
|
||||||
Backlog(Vec<TxEntry>),
|
Backlog(Vec<TxEntry>),
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,9 @@ fn map_request(
|
||||||
}
|
}
|
||||||
TxpoolReadRequest::TxsForBlock(txs_needed) => txs_for_block(env, txs_needed),
|
TxpoolReadRequest::TxsForBlock(txs_needed) => txs_for_block(env, txs_needed),
|
||||||
TxpoolReadRequest::Backlog => backlog(env),
|
TxpoolReadRequest::Backlog => backlog(env),
|
||||||
TxpoolReadRequest::Size => size(env),
|
TxpoolReadRequest::Size {
|
||||||
|
include_sensitive_txs,
|
||||||
|
} => size(env, include_sensitive_txs),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +203,6 @@ fn backlog(env: &ConcreteEnv) -> ReadResponseResult {
|
||||||
|
|
||||||
/// [`TxpoolReadRequest::Size`].
|
/// [`TxpoolReadRequest::Size`].
|
||||||
#[inline]
|
#[inline]
|
||||||
fn size(env: &ConcreteEnv) -> ReadResponseResult {
|
fn size(env: &ConcreteEnv, include_sensitive_txs: bool) -> ReadResponseResult {
|
||||||
Ok(TxpoolReadResponse::Size(todo!()))
|
Ok(TxpoolReadResponse::Size(todo!()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
/// Used in [`TxpoolReadResponse::Backlog`](crate::service::interface::TxpoolReadResponse::Backlog).
|
/// Used in [`TxpoolReadResponse::Backlog`](crate::service::interface::TxpoolReadResponse::Backlog).
|
||||||
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||||
pub struct TxEntry {
|
pub struct TxEntry {
|
||||||
|
/// The transaction's ID (hash).
|
||||||
|
pub id: [u8; 32],
|
||||||
/// The transaction's weight.
|
/// The transaction's weight.
|
||||||
pub weight: u64,
|
pub weight: u64,
|
||||||
/// The transaction's fee.
|
/// The transaction's fee.
|
||||||
|
|
147
types/src/address_type.rs
Normal file
147
types/src/address_type.rs
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
//! Types of network addresses; used in P2P.
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "epee")]
|
||||||
|
use cuprate_epee_encoding::{
|
||||||
|
error,
|
||||||
|
macros::bytes::{Buf, BufMut},
|
||||||
|
EpeeValue, Marker,
|
||||||
|
};
|
||||||
|
|
||||||
|
use strum::{
|
||||||
|
AsRefStr, Display, EnumCount, EnumIs, EnumString, FromRepr, IntoStaticStr, VariantArray,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An enumeration of address types.
|
||||||
|
///
|
||||||
|
/// Used in `cuprate_p2p` and `cuprate_types`
|
||||||
|
///
|
||||||
|
/// Original definition:
|
||||||
|
/// - <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/epee/include/net/enums.h/#L49>
|
||||||
|
///
|
||||||
|
/// # Serde
|
||||||
|
/// This type's `serde` implementation (de)serializes from a [`u8`].
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use cuprate_types::AddressType as A;
|
||||||
|
/// use serde_json::{to_string, from_str};
|
||||||
|
///
|
||||||
|
/// assert_eq!(from_str::<A>(&"0").unwrap(), A::Invalid);
|
||||||
|
/// assert_eq!(from_str::<A>(&"1").unwrap(), A::Ipv4);
|
||||||
|
/// assert_eq!(from_str::<A>(&"2").unwrap(), A::Ipv6);
|
||||||
|
/// assert_eq!(from_str::<A>(&"3").unwrap(), A::I2p);
|
||||||
|
/// assert_eq!(from_str::<A>(&"4").unwrap(), A::Tor);
|
||||||
|
///
|
||||||
|
/// assert_eq!(to_string(&A::Invalid).unwrap(), "0");
|
||||||
|
/// assert_eq!(to_string(&A::Ipv4).unwrap(), "1");
|
||||||
|
/// assert_eq!(to_string(&A::Ipv6).unwrap(), "2");
|
||||||
|
/// assert_eq!(to_string(&A::I2p).unwrap(), "3");
|
||||||
|
/// assert_eq!(to_string(&A::Tor).unwrap(), "4");
|
||||||
|
/// ```
|
||||||
|
#[derive(
|
||||||
|
Copy,
|
||||||
|
Clone,
|
||||||
|
Default,
|
||||||
|
Debug,
|
||||||
|
PartialEq,
|
||||||
|
Eq,
|
||||||
|
PartialOrd,
|
||||||
|
Ord,
|
||||||
|
Hash,
|
||||||
|
AsRefStr,
|
||||||
|
Display,
|
||||||
|
EnumCount,
|
||||||
|
EnumIs,
|
||||||
|
EnumString,
|
||||||
|
FromRepr,
|
||||||
|
IntoStaticStr,
|
||||||
|
VariantArray,
|
||||||
|
)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "serde", serde(untagged, try_from = "u8", into = "u8"))]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum AddressType {
|
||||||
|
#[default]
|
||||||
|
Invalid,
|
||||||
|
Ipv4,
|
||||||
|
Ipv6,
|
||||||
|
I2p,
|
||||||
|
Tor,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddressType {
|
||||||
|
/// Convert [`Self`] to a [`u8`].
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use cuprate_types::AddressType as A;
|
||||||
|
///
|
||||||
|
/// assert_eq!(A::Invalid.to_u8(), 0);
|
||||||
|
/// assert_eq!(A::Ipv4.to_u8(), 1);
|
||||||
|
/// assert_eq!(A::Ipv6.to_u8(), 2);
|
||||||
|
/// assert_eq!(A::I2p.to_u8(), 3);
|
||||||
|
/// assert_eq!(A::Tor.to_u8(), 4);
|
||||||
|
/// ```
|
||||||
|
pub const fn to_u8(self) -> u8 {
|
||||||
|
self as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a [`u8`] to a [`Self`].
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// This returns [`None`] if `u > 4`.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use cuprate_types::AddressType as A;
|
||||||
|
///
|
||||||
|
/// assert_eq!(A::from_u8(0), Some(A::Invalid));
|
||||||
|
/// assert_eq!(A::from_u8(1), Some(A::Ipv4));
|
||||||
|
/// assert_eq!(A::from_u8(2), Some(A::Ipv6));
|
||||||
|
/// assert_eq!(A::from_u8(3), Some(A::I2p));
|
||||||
|
/// assert_eq!(A::from_u8(4), Some(A::Tor));
|
||||||
|
/// assert_eq!(A::from_u8(5), None);
|
||||||
|
/// ```
|
||||||
|
pub const fn from_u8(u: u8) -> Option<Self> {
|
||||||
|
Some(match u {
|
||||||
|
0 => Self::Invalid,
|
||||||
|
1 => Self::Ipv4,
|
||||||
|
2 => Self::Ipv6,
|
||||||
|
3 => Self::I2p,
|
||||||
|
4 => Self::Tor,
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AddressType> for u8 {
|
||||||
|
fn from(value: AddressType) -> Self {
|
||||||
|
value.to_u8()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<u8> for AddressType {
|
||||||
|
type Error = u8;
|
||||||
|
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||||
|
match Self::from_u8(value) {
|
||||||
|
Some(s) => Ok(s),
|
||||||
|
None => Err(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "epee")]
|
||||||
|
impl EpeeValue for AddressType {
|
||||||
|
const MARKER: Marker = u8::MARKER;
|
||||||
|
|
||||||
|
fn read<B: Buf>(r: &mut B, marker: &Marker) -> error::Result<Self> {
|
||||||
|
let u = u8::read(r, marker)?;
|
||||||
|
Self::from_u8(u).ok_or(error::Error::Format("u8 was greater than 4"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write<B: BufMut>(self, w: &mut B) -> error::Result<()> {
|
||||||
|
let u = self.to_u8();
|
||||||
|
u8::write(u, w)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,8 @@ use monero_serai::block::Block;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation},
|
types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation},
|
||||||
AltBlockInformation, ChainId, CoinbaseTxSum, OutputHistogramEntry, OutputHistogramInput,
|
AltBlockInformation, ChainId, ChainInfo, CoinbaseTxSum, OutputHistogramEntry,
|
||||||
|
OutputHistogramInput,
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- ReadRequest
|
//---------------------------------------------------------------------------------------------------- ReadRequest
|
||||||
|
@ -128,6 +129,12 @@ pub enum BlockchainReadRequest {
|
||||||
///
|
///
|
||||||
/// TODO: document fields after impl.
|
/// TODO: document fields after impl.
|
||||||
CoinbaseTxSum { height: usize, count: u64 },
|
CoinbaseTxSum { height: usize, count: u64 },
|
||||||
|
|
||||||
|
/// Get information on all alternative chains.
|
||||||
|
AltChains,
|
||||||
|
|
||||||
|
/// Get the amount of alternative chains that exist.
|
||||||
|
AltChainCount,
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- WriteRequest
|
//---------------------------------------------------------------------------------------------------- WriteRequest
|
||||||
|
@ -276,6 +283,12 @@ pub enum BlockchainResponse {
|
||||||
/// Response to [`BlockchainReadRequest::CoinbaseTxSum`].
|
/// Response to [`BlockchainReadRequest::CoinbaseTxSum`].
|
||||||
CoinbaseTxSum(CoinbaseTxSum),
|
CoinbaseTxSum(CoinbaseTxSum),
|
||||||
|
|
||||||
|
/// Response to [`BlockchainReadRequest::AltChains`].
|
||||||
|
AltChains(Vec<ChainInfo>),
|
||||||
|
|
||||||
|
/// Response to [`BlockchainReadRequest::AltChainCount`].
|
||||||
|
AltChainCount(usize),
|
||||||
|
|
||||||
//------------------------------------------------------ Writes
|
//------------------------------------------------------ Writes
|
||||||
/// A generic Ok response to indicate a request was successfully handled.
|
/// A generic Ok response to indicate a request was successfully handled.
|
||||||
///
|
///
|
||||||
|
|
148
types/src/connection_state.rs
Normal file
148
types/src/connection_state.rs
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
//! [`ConnectionState`].
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "epee")]
|
||||||
|
use cuprate_epee_encoding::{
|
||||||
|
error,
|
||||||
|
macros::bytes::{Buf, BufMut},
|
||||||
|
EpeeValue, Marker,
|
||||||
|
};
|
||||||
|
|
||||||
|
use strum::{
|
||||||
|
AsRefStr, Display, EnumCount, EnumIs, EnumString, FromRepr, IntoStaticStr, VariantArray,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An enumeration of P2P connection states.
|
||||||
|
///
|
||||||
|
/// Used in `cuprate_p2p` and `cuprate_rpc_types`.
|
||||||
|
///
|
||||||
|
/// Original definition:
|
||||||
|
/// - <https://github.com/monero-project/monero/blob/893916ad091a92e765ce3241b94e706ad012b62a/src/cryptonote_basic/connection_context.h#L49>
|
||||||
|
///
|
||||||
|
/// # Serde
|
||||||
|
/// This type's `serde` implementation depends on `snake_case`.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use cuprate_types::ConnectionState as C;
|
||||||
|
/// use serde_json::to_string;
|
||||||
|
///
|
||||||
|
/// assert_eq!(to_string(&C::BeforeHandshake).unwrap(), r#""before_handshake""#);
|
||||||
|
/// assert_eq!(to_string(&C::Synchronizing).unwrap(), r#""synchronizing""#);
|
||||||
|
/// assert_eq!(to_string(&C::Standby).unwrap(), r#""standby""#);
|
||||||
|
/// assert_eq!(to_string(&C::Idle).unwrap(), r#""idle""#);
|
||||||
|
/// assert_eq!(to_string(&C::Normal).unwrap(), r#""normal""#);
|
||||||
|
///
|
||||||
|
/// assert_eq!(C::BeforeHandshake.to_string(), "before_handshake");
|
||||||
|
/// assert_eq!(C::Synchronizing.to_string(), "synchronizing");
|
||||||
|
/// assert_eq!(C::Standby.to_string(), "standby");
|
||||||
|
/// assert_eq!(C::Idle.to_string(), "idle");
|
||||||
|
/// assert_eq!(C::Normal.to_string(), "normal");
|
||||||
|
/// ```
|
||||||
|
#[derive(
|
||||||
|
Copy,
|
||||||
|
Clone,
|
||||||
|
Default,
|
||||||
|
Debug,
|
||||||
|
PartialEq,
|
||||||
|
Eq,
|
||||||
|
PartialOrd,
|
||||||
|
Ord,
|
||||||
|
Hash,
|
||||||
|
AsRefStr,
|
||||||
|
Display,
|
||||||
|
EnumCount,
|
||||||
|
EnumIs,
|
||||||
|
EnumString,
|
||||||
|
FromRepr,
|
||||||
|
IntoStaticStr,
|
||||||
|
VariantArray,
|
||||||
|
)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] // cuprate-rpc-types depends on snake_case
|
||||||
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum ConnectionState {
|
||||||
|
BeforeHandshake,
|
||||||
|
Synchronizing,
|
||||||
|
Standby,
|
||||||
|
Idle,
|
||||||
|
#[default]
|
||||||
|
Normal,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConnectionState {
|
||||||
|
/// Convert [`Self`] to a [`u8`].
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use cuprate_types::ConnectionState as C;
|
||||||
|
///
|
||||||
|
/// assert_eq!(C::BeforeHandshake.to_u8(), 0);
|
||||||
|
/// assert_eq!(C::Synchronizing.to_u8(), 1);
|
||||||
|
/// assert_eq!(C::Standby.to_u8(), 2);
|
||||||
|
/// assert_eq!(C::Idle.to_u8(), 3);
|
||||||
|
/// assert_eq!(C::Normal.to_u8(), 4);
|
||||||
|
/// ```
|
||||||
|
pub const fn to_u8(self) -> u8 {
|
||||||
|
self as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a [`u8`] to a [`Self`].
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// This returns [`None`] if `u > 4`.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use cuprate_types::ConnectionState as C;
|
||||||
|
///
|
||||||
|
/// assert_eq!(C::from_u8(0), Some(C::BeforeHandshake));
|
||||||
|
/// assert_eq!(C::from_u8(1), Some(C::Synchronizing));
|
||||||
|
/// assert_eq!(C::from_u8(2), Some(C::Standby));
|
||||||
|
/// assert_eq!(C::from_u8(3), Some(C::Idle));
|
||||||
|
/// assert_eq!(C::from_u8(4), Some(C::Normal));
|
||||||
|
/// assert_eq!(C::from_u8(5), None);
|
||||||
|
/// ```
|
||||||
|
pub const fn from_u8(u: u8) -> Option<Self> {
|
||||||
|
Some(match u {
|
||||||
|
0 => Self::BeforeHandshake,
|
||||||
|
1 => Self::Synchronizing,
|
||||||
|
2 => Self::Standby,
|
||||||
|
3 => Self::Idle,
|
||||||
|
4 => Self::Normal,
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ConnectionState> for u8 {
|
||||||
|
fn from(value: ConnectionState) -> Self {
|
||||||
|
value.to_u8()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<u8> for ConnectionState {
|
||||||
|
type Error = u8;
|
||||||
|
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||||
|
match Self::from_u8(value) {
|
||||||
|
Some(s) => Ok(s),
|
||||||
|
None => Err(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "epee")]
|
||||||
|
impl EpeeValue for ConnectionState {
|
||||||
|
const MARKER: Marker = u8::MARKER;
|
||||||
|
|
||||||
|
fn read<B: Buf>(r: &mut B, marker: &Marker) -> error::Result<Self> {
|
||||||
|
let u = u8::read(r, marker)?;
|
||||||
|
Self::from_u8(u).ok_or(error::Error::Format("u8 was greater than 4"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write<B: BufMut>(self, w: &mut B) -> error::Result<()> {
|
||||||
|
let u = self.to_u8();
|
||||||
|
u8::write(u, w)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,20 +9,25 @@
|
||||||
//
|
//
|
||||||
// Documentation for each module is located in the respective file.
|
// Documentation for each module is located in the respective file.
|
||||||
|
|
||||||
|
mod address_type;
|
||||||
mod block_complete_entry;
|
mod block_complete_entry;
|
||||||
|
mod connection_state;
|
||||||
mod hard_fork;
|
mod hard_fork;
|
||||||
mod transaction_verification_data;
|
mod transaction_verification_data;
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
|
pub use address_type::AddressType;
|
||||||
pub use block_complete_entry::{BlockCompleteEntry, PrunedTxBlobEntry, TransactionBlobs};
|
pub use block_complete_entry::{BlockCompleteEntry, PrunedTxBlobEntry, TransactionBlobs};
|
||||||
|
pub use connection_state::ConnectionState;
|
||||||
pub use hard_fork::{HardFork, HardForkError};
|
pub use hard_fork::{HardFork, HardForkError};
|
||||||
pub use transaction_verification_data::{
|
pub use transaction_verification_data::{
|
||||||
CachedVerificationState, TransactionVerificationData, TxVersion,
|
CachedVerificationState, TransactionVerificationData, TxVersion,
|
||||||
};
|
};
|
||||||
pub use types::{
|
pub use types::{
|
||||||
AltBlockInformation, Chain, ChainId, ChainInfo, CoinbaseTxSum, ExtendedBlockHeader,
|
AddAuxPow, AltBlockInformation, AuxPow, Chain, ChainId, ChainInfo, CoinbaseTxSum,
|
||||||
FeeEstimate, HardForkInfo, MinerData, MinerDataTxBacklogEntry, OutputHistogramEntry,
|
ExtendedBlockHeader, FeeEstimate, HardForkInfo, MinerData, MinerDataTxBacklogEntry,
|
||||||
OutputHistogramInput, OutputOnChain, VerifiedBlockInformation, VerifiedTransactionInformation,
|
OutputHistogramEntry, OutputHistogramInput, OutputOnChain, VerifiedBlockInformation,
|
||||||
|
VerifiedTransactionInformation,
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Feature-gated
|
//---------------------------------------------------------------------------------------------------- Feature-gated
|
||||||
|
|
|
@ -177,8 +177,6 @@ pub struct OutputHistogramEntry {
|
||||||
pub struct CoinbaseTxSum {
|
pub struct CoinbaseTxSum {
|
||||||
pub emission_amount: u128,
|
pub emission_amount: u128,
|
||||||
pub fee_amount: u128,
|
pub fee_amount: u128,
|
||||||
pub wide_emission_amount: u128,
|
|
||||||
pub wide_fee_amount: u128,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Data to create a custom block template.
|
/// Data to create a custom block template.
|
||||||
|
@ -242,7 +240,23 @@ pub struct ChainInfo {
|
||||||
pub height: u64,
|
pub height: u64,
|
||||||
pub length: u64,
|
pub length: u64,
|
||||||
pub main_chain_parent_block: [u8; 32],
|
pub main_chain_parent_block: [u8; 32],
|
||||||
pub wide_difficulty: u128,
|
}
|
||||||
|
|
||||||
|
/// Used in RPC's `add_aux_pow`.
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct AuxPow {
|
||||||
|
pub id: [u8; 32],
|
||||||
|
pub hash: [u8; 32],
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used in RPC's `add_aux_pow`.
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct AddAuxPow {
|
||||||
|
pub blocktemplate_blob: Vec<u8>,
|
||||||
|
pub blockhashing_blob: Vec<u8>,
|
||||||
|
pub merkle_root: [u8; 32],
|
||||||
|
pub merkle_tree_depth: u64,
|
||||||
|
pub aux_pow: Vec<AuxPow>,
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Tests
|
//---------------------------------------------------------------------------------------------------- Tests
|
||||||
|
|
Loading…
Reference in a new issue