mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-22 19:49:33 +00:00
Compare commits
6 commits
afab072816
...
604ecc8393
Author | SHA1 | Date | |
---|---|---|---|
|
604ecc8393 | ||
|
82583263fe | ||
|
21c14d8d43 | ||
|
58a91c4e65 | ||
|
9482753304 | ||
|
b0751c417c |
19 changed files with 256 additions and 331 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -834,6 +834,7 @@ dependencies = [
|
|||
"cuprate-helper",
|
||||
"cuprate-pruning",
|
||||
"cuprate-test-utils",
|
||||
"cuprate-types",
|
||||
"cuprate-wire",
|
||||
"futures",
|
||||
"hex",
|
||||
|
|
|
@ -23,6 +23,7 @@ use crate::rpc::{bin, json, other};
|
|||
|
||||
/// TODO: use real type when public.
|
||||
#[derive(Clone)]
|
||||
#[expect(clippy::large_enum_variant)]
|
||||
pub enum BlockchainManagerRequest {
|
||||
/// Pop blocks off the top of the blockchain.
|
||||
///
|
||||
|
@ -57,33 +58,6 @@ pub enum BlockchainManagerRequest {
|
|||
/// The height of the next block in the chain.
|
||||
TargetHeight,
|
||||
|
||||
/// 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.
|
||||
block: Block,
|
||||
/// The seed hash for the proof-of-work.
|
||||
seed_hash: [u8; 32],
|
||||
},
|
||||
|
||||
/// Add auxirilly proof-of-work to a block.
|
||||
///
|
||||
/// From the RPC `add_aux_pow` usecase's documentation:
|
||||
/// ````
|
||||
/// This enables merge mining with Monero without requiring
|
||||
/// software that manually alters the extra field in the coinbase
|
||||
/// tx to include the merkle root of the aux blocks.
|
||||
/// ````
|
||||
AddAuxPow {
|
||||
/// The block template to add to.
|
||||
block_template: Block,
|
||||
/// The auxirilly proof-of-work to add.
|
||||
aux_pow: Vec<AuxPow>,
|
||||
},
|
||||
|
||||
/// Generate new blocks.
|
||||
///
|
||||
/// This request is only for regtest, see RPC's `generateblocks`.
|
||||
|
@ -97,6 +71,18 @@ pub enum BlockchainManagerRequest {
|
|||
/// 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.
|
||||
|
@ -130,12 +116,6 @@ pub enum BlockchainManagerResponse {
|
|||
/// Response to [`BlockchainManagerRequest::TargetHeight`]
|
||||
TargetHeight { height: usize },
|
||||
|
||||
/// Response to [`BlockchainManagerRequest::CalculatePow`]
|
||||
CalculatePow([u8; 32]),
|
||||
|
||||
/// Response to [`BlockchainManagerRequest::AddAuxPow`]
|
||||
AddAuxPow(AddAuxPow),
|
||||
|
||||
/// Response to [`BlockchainManagerRequest::GenerateBlocks`]
|
||||
GenerateBlocks {
|
||||
/// Hashes of the blocks generated.
|
||||
|
@ -143,6 +123,11 @@ pub enum BlockchainManagerResponse {
|
|||
/// 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.
|
||||
|
|
|
@ -55,17 +55,6 @@ pub(crate) async fn connection_info<Z: NetworkZone>(
|
|||
let vec = vec
|
||||
.into_iter()
|
||||
.map(|info| {
|
||||
/// Message to use when casting between enums with `u8` fails.
|
||||
/// This should never happen.
|
||||
const EXPECT: &str = "u8 repr between these types should be 1-1";
|
||||
|
||||
let address_type =
|
||||
cuprate_rpc_types::misc::AddressType::from_u8(info.address_type.to_u8())
|
||||
.expect(EXPECT);
|
||||
|
||||
let state = cuprate_rpc_types::misc::ConnectionState::from_u8(info.state.to_u8())
|
||||
.expect(EXPECT);
|
||||
|
||||
let (ip, port) = match info.socket_addr {
|
||||
Some(socket) => (socket.ip().to_string(), socket.port().to_string()),
|
||||
None => (String::new(), String::new()),
|
||||
|
@ -73,7 +62,7 @@ pub(crate) async fn connection_info<Z: NetworkZone>(
|
|||
|
||||
ConnectionInfo {
|
||||
address: info.address.to_string(),
|
||||
address_type,
|
||||
address_type: info.address_type,
|
||||
avg_download: info.avg_download,
|
||||
avg_upload: info.avg_upload,
|
||||
connection_id: String::from(FIELD_NOT_SUPPORTED),
|
||||
|
@ -95,7 +84,7 @@ pub(crate) async fn connection_info<Z: NetworkZone>(
|
|||
rpc_port: info.rpc_port,
|
||||
send_count: info.send_count,
|
||||
send_idle_time: info.send_idle_time,
|
||||
state,
|
||||
state: info.state,
|
||||
support_flags: info.support_flags,
|
||||
}
|
||||
})
|
||||
|
@ -177,53 +166,3 @@ pub(crate) async fn get_bans<Z: NetworkZone>(
|
|||
|
||||
Ok(bans)
|
||||
}
|
||||
|
||||
/// [`AddressBookRequest::Spans`]
|
||||
pub(crate) async fn spans<Z: NetworkZone>(
|
||||
address_book: &mut impl AddressBook<Z>,
|
||||
) -> Result<Vec<Span>, Error> {
|
||||
let AddressBookResponse::Spans(vec) = address_book
|
||||
.ready()
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))?
|
||||
.call(AddressBookRequest::Spans)
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))?
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
// FIXME: impl this map somewhere instead of inline.
|
||||
let vec = vec
|
||||
.into_iter()
|
||||
.map(|span| Span {
|
||||
connection_id: String::from(FIELD_NOT_SUPPORTED),
|
||||
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)
|
||||
}
|
||||
|
||||
/// [`AddressBookRequest::NextNeededPruningSeed`]
|
||||
pub(crate) async fn next_needed_pruning_seed<Z: NetworkZone>(
|
||||
address_book: &mut impl AddressBook<Z>,
|
||||
) -> Result<PruningSeed, Error> {
|
||||
let AddressBookResponse::NextNeededPruningSeed(seed) = address_book
|
||||
.ready()
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))?
|
||||
.call(AddressBookRequest::NextNeededPruningSeed)
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))?
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
Ok(seed)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
use std::convert::Infallible;
|
||||
|
||||
use anyhow::{anyhow, Error};
|
||||
use cuprate_helper::cast::u64_to_usize;
|
||||
use monero_serai::block::Block;
|
||||
use tower::{Service, ServiceExt};
|
||||
|
||||
use cuprate_consensus_context::{
|
||||
|
@ -68,3 +70,30 @@ pub(crate) async fn fee_estimate(
|
|||
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
//! Functions for [`BlockchainManagerRequest`] & [`BlockchainManagerResponse`].
|
||||
|
||||
use anyhow::Error;
|
||||
use cuprate_p2p_core::NetworkZone;
|
||||
use cuprate_rpc_types::misc::Span;
|
||||
use monero_serai::block::Block;
|
||||
use tower::{Service, ServiceExt};
|
||||
|
||||
|
@ -8,8 +10,9 @@ use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
|
|||
use cuprate_pruning::PruningSeed;
|
||||
use cuprate_types::{AddAuxPow, AuxPow, HardFork};
|
||||
|
||||
use crate::rpc::handler::{
|
||||
BlockchainManagerHandle, BlockchainManagerRequest, BlockchainManagerResponse,
|
||||
use crate::rpc::{
|
||||
constants::FIELD_NOT_SUPPORTED,
|
||||
handler::{BlockchainManagerHandle, BlockchainManagerRequest, BlockchainManagerResponse},
|
||||
};
|
||||
|
||||
/// [`BlockchainManagerRequest::PopBlocks`]
|
||||
|
@ -144,52 +147,6 @@ pub(crate) async fn target_height(
|
|||
Ok(usize_to_u64(height))
|
||||
}
|
||||
|
||||
/// [`BlockchainManagerRequest::CalculatePow`]
|
||||
pub(crate) async fn calculate_pow(
|
||||
blockchain_manager: &mut BlockchainManagerHandle,
|
||||
hardfork: HardFork,
|
||||
height: u64,
|
||||
block: Block,
|
||||
seed_hash: [u8; 32],
|
||||
) -> Result<[u8; 32], Error> {
|
||||
let BlockchainManagerResponse::CalculatePow(hash) = blockchain_manager
|
||||
.ready()
|
||||
.await?
|
||||
.call(BlockchainManagerRequest::CalculatePow {
|
||||
hardfork,
|
||||
height: u64_to_usize(height),
|
||||
block,
|
||||
seed_hash,
|
||||
})
|
||||
.await?
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
Ok(hash)
|
||||
}
|
||||
|
||||
/// [`BlockchainManagerRequest::AddAuxPow`]
|
||||
pub(crate) async fn add_aux_pow(
|
||||
blockchain_manager: &mut BlockchainManagerHandle,
|
||||
block_template: Block,
|
||||
aux_pow: Vec<AuxPow>,
|
||||
) -> Result<AddAuxPow, Error> {
|
||||
let BlockchainManagerResponse::AddAuxPow(response) = blockchain_manager
|
||||
.ready()
|
||||
.await?
|
||||
.call(BlockchainManagerRequest::AddAuxPow {
|
||||
block_template,
|
||||
aux_pow,
|
||||
})
|
||||
.await?
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
/// [`BlockchainManagerRequest::GenerateBlocks`]
|
||||
pub(crate) async fn generate_blocks(
|
||||
blockchain_manager: &mut BlockchainManagerHandle,
|
||||
|
@ -214,3 +171,51 @@ pub(crate) async fn generate_blocks(
|
|||
|
||||
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(FIELD_NOT_SUPPORTED),
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use std::{
|
|||
};
|
||||
|
||||
use futures::{channel::oneshot, FutureExt};
|
||||
use monero_serai::block::Block;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio_util::sync::PollSender;
|
||||
use tower::Service;
|
||||
|
@ -263,6 +264,21 @@ pub enum BlockChainContextRequest {
|
|||
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.
|
||||
ClearAltCache,
|
||||
|
||||
|
@ -360,6 +376,9 @@ pub enum BlockChainContextResponse {
|
|||
/// Response to [`BlockChainContextRequest::FeeEstimate`]
|
||||
FeeEstimate(FeeEstimate),
|
||||
|
||||
/// Response to [`BlockChainContextRequest::CalculatePow`]
|
||||
CalculatePow([u8; 32]),
|
||||
|
||||
/// Response to [`BlockChainContextRequest::AltChains`]
|
||||
///
|
||||
/// 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::FeeEstimate { .. }
|
||||
| BlockChainContextRequest::AltChains => {
|
||||
| BlockChainContextRequest::AltChains
|
||||
| BlockChainContextRequest::CalculatePow { .. } => {
|
||||
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
||||
}
|
||||
})
|
||||
|
|
|
@ -424,9 +424,7 @@ impl<Z: BorshNetworkZone> Service<AddressBookRequest<Z>> for AddressBook<Z> {
|
|||
| AddressBookRequest::ConnectionCount
|
||||
| AddressBookRequest::SetBan(_)
|
||||
| AddressBookRequest::GetBans
|
||||
| AddressBookRequest::ConnectionInfo
|
||||
| AddressBookRequest::NextNeededPruningSeed
|
||||
| AddressBookRequest::Spans => {
|
||||
| AddressBookRequest::ConnectionInfo => {
|
||||
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
||||
}
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@ borsh = ["dep:borsh", "cuprate-pruning/borsh"]
|
|||
cuprate-helper = { path = "../../helper", features = ["asynch"], default-features = false }
|
||||
cuprate-wire = { path = "../../net/wire", features = ["tracing"] }
|
||||
cuprate-pruning = { path = "../../pruning" }
|
||||
cuprate-types = { path = "../../types" }
|
||||
|
||||
tokio = { workspace = true, features = ["net", "sync", "macros", "time", "rt", "rt-multi-thread"]}
|
||||
tokio-util = { workspace = true, features = ["codec"] }
|
||||
|
|
|
@ -112,9 +112,7 @@ impl<N: NetworkZone> Service<AddressBookRequest<N>> for DummyAddressBook {
|
|||
| AddressBookRequest::ConnectionCount
|
||||
| AddressBookRequest::SetBan(_)
|
||||
| AddressBookRequest::GetBans
|
||||
| AddressBookRequest::ConnectionInfo
|
||||
| AddressBookRequest::NextNeededPruningSeed
|
||||
| AddressBookRequest::Spans => {
|
||||
| AddressBookRequest::ConnectionInfo => {
|
||||
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
||||
}
|
||||
}))
|
||||
|
|
|
@ -6,7 +6,7 @@ use cuprate_wire::{CoreSyncData, PeerListEntryBase};
|
|||
use crate::{
|
||||
client::InternalPeerID,
|
||||
handles::ConnectionHandle,
|
||||
types::{BanState, ConnectionInfo, SetBan, Span},
|
||||
types::{BanState, ConnectionInfo, SetBan},
|
||||
NetZoneAddress, NetworkAddressIncorrectZone, NetworkZone,
|
||||
};
|
||||
|
||||
|
@ -132,15 +132,6 @@ pub enum AddressBookRequest<Z: NetworkZone> {
|
|||
|
||||
/// Get the state of all bans.
|
||||
GetBans,
|
||||
|
||||
/// 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,
|
||||
}
|
||||
|
||||
/// A response from the address book service.
|
||||
|
@ -178,10 +169,4 @@ pub enum AddressBookResponse<Z: NetworkZone> {
|
|||
|
||||
/// Response to [`AddressBookRequest::GetBans`].
|
||||
GetBans(Vec<BanState<Z::Addr>>),
|
||||
|
||||
/// Response to [`AddressBookRequest::Spans`].
|
||||
Spans(Vec<Span<Z::Addr>>),
|
||||
|
||||
/// Response to [`AddressBookRequest::NextNeededPruningSeed`].
|
||||
NextNeededPruningSeed(PruningSeed),
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use std::time::{Duration, Instant};
|
||||
|
||||
use cuprate_pruning::PruningSeed;
|
||||
use cuprate_types::{AddressType, ConnectionState};
|
||||
|
||||
use crate::NetZoneAddress;
|
||||
|
||||
|
@ -24,125 +25,6 @@ pub struct BanState<A: NetZoneAddress> {
|
|||
pub unban_instant: Option<Instant>,
|
||||
}
|
||||
|
||||
/// An enumeration of address types.
|
||||
///
|
||||
/// Used [`ConnectionInfo::address_type`].
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[repr(u8)]
|
||||
pub enum AddressType {
|
||||
#[default]
|
||||
Invalid,
|
||||
Ipv4,
|
||||
Ipv6,
|
||||
I2p,
|
||||
Tor,
|
||||
}
|
||||
|
||||
impl AddressType {
|
||||
/// Convert [`Self`] to a [`u8`].
|
||||
///
|
||||
/// ```rust
|
||||
/// use cuprate_p2p_core::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_p2p_core::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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// An enumeration of P2P connection states.
|
||||
///
|
||||
/// Used [`ConnectionInfo::state`].
|
||||
///
|
||||
/// Original definition:
|
||||
/// - <https://github.com/monero-project/monero/blob/893916ad091a92e765ce3241b94e706ad012b62a/src/cryptonote_basic/connection_context.h#L49>
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[repr(u8)]
|
||||
pub enum ConnectionState {
|
||||
BeforeHandshake,
|
||||
Synchronizing,
|
||||
Standby,
|
||||
Idle,
|
||||
#[default]
|
||||
Normal,
|
||||
}
|
||||
|
||||
impl ConnectionState {
|
||||
/// Convert [`Self`] to a [`u8`].
|
||||
///
|
||||
/// ```rust
|
||||
/// use cuprate_p2p_core::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_p2p_core::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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: reduce fields and map to RPC type.
|
||||
//
|
||||
/// Data within [`crate::services::AddressBookResponse::ConnectionInfo`].
|
||||
pub struct ConnectionInfo<A: NetZoneAddress> {
|
||||
// The following fields are mostly the same as `monerod`.
|
||||
|
@ -181,7 +63,8 @@ pub struct ConnectionInfo<A: NetZoneAddress> {
|
|||
|
||||
/// Used in RPC's `sync_info`.
|
||||
///
|
||||
/// Data within [`crate::services::AddressBookResponse::Spans`].
|
||||
// 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,
|
||||
|
|
|
@ -10,16 +10,16 @@ keywords = ["cuprate", "rpc", "types", "monero"]
|
|||
|
||||
[features]
|
||||
default = ["serde", "epee"]
|
||||
serde = ["dep:serde", "cuprate-fixed-bytes/serde"]
|
||||
epee = ["dep:cuprate-epee-encoding"]
|
||||
serde = ["dep:serde", "cuprate-fixed-bytes/serde", "cuprate-types/serde"]
|
||||
epee = ["dep:cuprate-epee-encoding", "cuprate-types/epee"]
|
||||
|
||||
[dependencies]
|
||||
cuprate-epee-encoding = { path = "../../net/epee-encoding", optional = true }
|
||||
cuprate-fixed-bytes = { path = "../../net/fixed-bytes" }
|
||||
cuprate-types = { path = "../../types", default-features = false, features = ["epee", "serde"] }
|
||||
cuprate-types = { path = "../../types", default-features = false }
|
||||
|
||||
paste = { workspace = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
paste = { workspace = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
cuprate-test-utils = { path = "../../test-utils" }
|
||||
|
|
|
@ -658,7 +658,7 @@ define_request_and_response! {
|
|||
connections: vec![
|
||||
ConnectionInfo {
|
||||
address: "3evk3kezfjg44ma6tvesy7rbxwwpgpympj45xar5fo4qajrsmkoaqdqd.onion:18083".into(),
|
||||
address_type: cuprate_rpc_types::misc::AddressType::Tor,
|
||||
address_type: cuprate_types::AddressType::Tor,
|
||||
avg_download: 0,
|
||||
avg_upload: 0,
|
||||
connection_id: "22ef856d0f1d44cc95e84fecfd065fe2".into(),
|
||||
|
@ -680,12 +680,12 @@ define_request_and_response! {
|
|||
rpc_port: 0,
|
||||
send_count: 3406572,
|
||||
send_idle_time: 30,
|
||||
state: "normal".into(),
|
||||
state: cuprate_types::ConnectionState::Normal,
|
||||
support_flags: 0
|
||||
},
|
||||
ConnectionInfo {
|
||||
address: "4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion:18083".into(),
|
||||
address_type: cuprate_rpc_types::misc::AddressType::Tor,
|
||||
address_type: cuprate_types::AddressType::Tor,
|
||||
avg_download: 0,
|
||||
avg_upload: 0,
|
||||
connection_id: "c7734e15936f485a86d2b0534f87e499".into(),
|
||||
|
@ -707,7 +707,7 @@ define_request_and_response! {
|
|||
rpc_port: 0,
|
||||
send_count: 3370566,
|
||||
send_idle_time: 120,
|
||||
state: "normal".into(),
|
||||
state: cuprate_types::ConnectionState::Normal,
|
||||
support_flags: 0
|
||||
}
|
||||
],
|
||||
|
@ -1251,7 +1251,7 @@ define_request_and_response! {
|
|||
SyncInfoPeer {
|
||||
info: ConnectionInfo {
|
||||
address: "142.93.128.65:44986".into(),
|
||||
address_type: AddressType::Ipv4,
|
||||
address_type: cuprate_types::AddressType::Ipv4,
|
||||
avg_download: 1,
|
||||
avg_upload: 1,
|
||||
connection_id: "a5803c4c2dac49e7b201dccdef54c862".into(),
|
||||
|
@ -1273,14 +1273,14 @@ define_request_and_response! {
|
|||
rpc_port: 18089,
|
||||
send_count: 32235,
|
||||
send_idle_time: 6,
|
||||
state: "normal".into(),
|
||||
state: cuprate_types::ConnectionState::Normal,
|
||||
support_flags: 1
|
||||
}
|
||||
},
|
||||
SyncInfoPeer {
|
||||
info: ConnectionInfo {
|
||||
address: "4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion:18083".into(),
|
||||
address_type: AddressType::Tor,
|
||||
address_type: cuprate_types::AddressType::Tor,
|
||||
avg_download: 0,
|
||||
avg_upload: 0,
|
||||
connection_id: "277f7c821bc546878c8bd29977e780f5".into(),
|
||||
|
@ -1302,7 +1302,7 @@ define_request_and_response! {
|
|||
rpc_port: 0,
|
||||
send_count: 99120,
|
||||
send_idle_time: 15,
|
||||
state: "normal".into(),
|
||||
state: cuprate_types::ConnectionState::Normal,
|
||||
support_flags: 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ define_struct_and_impl_epee! {
|
|||
/// Used in [`crate::json::GetConnectionsResponse`].
|
||||
ConnectionInfo {
|
||||
address: String,
|
||||
address_type: crate::misc::AddressType,
|
||||
address_type: cuprate_types::AddressType,
|
||||
avg_download: u64,
|
||||
avg_upload: u64,
|
||||
connection_id: String,
|
||||
|
@ -135,7 +135,7 @@ define_struct_and_impl_epee! {
|
|||
// Exists in the original definition, but isn't
|
||||
// used or (de)serialized for RPC purposes.
|
||||
// ssl: bool,
|
||||
state: crate::misc::ConnectionState,
|
||||
state: cuprate_types::ConnectionState,
|
||||
support_flags: u32,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,7 @@
|
|||
)]
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Mod
|
||||
mod address_type;
|
||||
mod binary_string;
|
||||
mod connection_state;
|
||||
mod distribution;
|
||||
mod key_image_spent_status;
|
||||
#[expect(clippy::module_inception)]
|
||||
|
@ -23,9 +21,7 @@ mod pool_info_extent;
|
|||
mod status;
|
||||
mod tx_entry;
|
||||
|
||||
pub use address_type::AddressType;
|
||||
pub use binary_string::BinaryString;
|
||||
pub use connection_state::ConnectionState;
|
||||
pub use distribution::{Distribution, DistributionCompressedBinary, DistributionUncompressed};
|
||||
pub use key_image_spent_status::KeyImageSpentStatus;
|
||||
pub use misc::{
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
//! Types of network addresses; used in P2P.
|
||||
|
||||
use cuprate_epee_encoding::Marker;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -9,16 +7,58 @@ use serde::{Deserialize, Serialize};
|
|||
use cuprate_epee_encoding::{
|
||||
error,
|
||||
macros::bytes::{Buf, BufMut},
|
||||
EpeeValue,
|
||||
EpeeValue, Marker,
|
||||
};
|
||||
|
||||
/// Used in [`crate::misc::ConnectionInfo::address_type`].
|
||||
#[doc = crate::macros::monero_definition_link!(
|
||||
cc73fe71162d564ffda8e549b79a350bca53c454,
|
||||
"epee/include/net/enums.h",
|
||||
39..=47
|
||||
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,
|
||||
)]
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(untagged, try_from = "u8", into = "u8"))]
|
||||
#[repr(u8)]
|
||||
|
@ -35,7 +75,7 @@ impl AddressType {
|
|||
/// Convert [`Self`] to a [`u8`].
|
||||
///
|
||||
/// ```rust
|
||||
/// use cuprate_rpc_types::misc::AddressType as A;
|
||||
/// use cuprate_types::AddressType as A;
|
||||
///
|
||||
/// assert_eq!(A::Invalid.to_u8(), 0);
|
||||
/// assert_eq!(A::Ipv4.to_u8(), 1);
|
||||
|
@ -53,7 +93,7 @@ impl AddressType {
|
|||
/// This returns [`None`] if `u > 4`.
|
||||
///
|
||||
/// ```rust
|
||||
/// use cuprate_rpc_types::misc::AddressType as A;
|
||||
/// use cuprate_types::AddressType as A;
|
||||
///
|
||||
/// assert_eq!(A::from_u8(0), Some(A::Invalid));
|
||||
/// assert_eq!(A::from_u8(1), Some(A::Ipv4));
|
|
@ -1,6 +1,4 @@
|
|||
//! Types of network addresses; used in P2P.
|
||||
|
||||
use cuprate_epee_encoding::Marker;
|
||||
//! [`ConnectionState`].
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -9,18 +7,61 @@ use serde::{Deserialize, Serialize};
|
|||
use cuprate_epee_encoding::{
|
||||
error,
|
||||
macros::bytes::{Buf, BufMut},
|
||||
EpeeValue,
|
||||
EpeeValue, Marker,
|
||||
};
|
||||
|
||||
/// Used in [`crate::misc::ConnectionInfo::address_type`].
|
||||
#[doc = crate::macros::monero_definition_link!(
|
||||
cc73fe71162d564ffda8e549b79a350bca53c454,
|
||||
"cryptonote_basic/connection_context.h",
|
||||
49..=56
|
||||
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,
|
||||
)]
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(untagged, try_from = "u8", into = "u8"))]
|
||||
#[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,
|
||||
|
@ -35,7 +76,7 @@ impl ConnectionState {
|
|||
/// Convert [`Self`] to a [`u8`].
|
||||
///
|
||||
/// ```rust
|
||||
/// use cuprate_p2p_core::types::ConnectionState as C;
|
||||
/// use cuprate_types::ConnectionState as C;
|
||||
///
|
||||
/// assert_eq!(C::BeforeHandshake.to_u8(), 0);
|
||||
/// assert_eq!(C::Synchronizing.to_u8(), 1);
|
||||
|
@ -53,9 +94,9 @@ impl ConnectionState {
|
|||
/// This returns [`None`] if `u > 4`.
|
||||
///
|
||||
/// ```rust
|
||||
/// use cuprate_p2p_core::types::ConnectionState as C;
|
||||
/// use cuprate_types::ConnectionState as C;
|
||||
///
|
||||
/// assert_eq!(C::from_u8(0), Some(C::BeforeHandShake));
|
||||
/// 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));
|
|
@ -9,12 +9,16 @@
|
|||
//
|
||||
// Documentation for each module is located in the respective file.
|
||||
|
||||
mod address_type;
|
||||
mod block_complete_entry;
|
||||
mod connection_state;
|
||||
mod hard_fork;
|
||||
mod transaction_verification_data;
|
||||
mod types;
|
||||
|
||||
pub use address_type::AddressType;
|
||||
pub use block_complete_entry::{BlockCompleteEntry, PrunedTxBlobEntry, TransactionBlobs};
|
||||
pub use connection_state::ConnectionState;
|
||||
pub use hard_fork::{HardFork, HardForkError};
|
||||
pub use transaction_verification_data::{
|
||||
CachedVerificationState, TransactionVerificationData, TxVersion,
|
||||
|
|
Loading…
Reference in a new issue