diff --git a/binaries/cuprated/Cargo.toml b/binaries/cuprated/Cargo.toml index 9f7a699b..e1d0573b 100644 --- a/binaries/cuprated/Cargo.toml +++ b/binaries/cuprated/Cargo.toml @@ -34,7 +34,7 @@ cuprate-test-utils = { workspace = true } cuprate-types = { workspace = true, features = ["json"] } cuprate-json-rpc = { workspace = true } cuprate-rpc-interface = { workspace = true } -cuprate-rpc-types = { workspace = true } +cuprate-rpc-types = { workspace = true, features = ["from"] } # TODO: after v1.0.0, remove unneeded dependencies. diff --git a/binaries/cuprated/src/rpc/helper.rs b/binaries/cuprated/src/rpc/helper.rs index cf5bbc49..98305dfa 100644 --- a/binaries/cuprated/src/rpc/helper.rs +++ b/binaries/cuprated/src/rpc/helper.rs @@ -57,17 +57,17 @@ pub(super) async fn block_header( ) .await?; - let pow_hash = blockchain_context::calculate_pow( - &mut state.blockchain_context, - hardfork, - block, - seed_hash, + Some( + blockchain_context::calculate_pow( + &mut state.blockchain_context, + hardfork, + block, + seed_hash, + ) + .await?, ) - .await?; - - pow_hash } else { - [0; 32] + None }; let block_weight = usize_to_u64(header.block_weight); diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index 7ee16387..998d3519 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -1073,7 +1073,7 @@ fn add_aux_pow_inner( for nonce in 0..=MAX_NONCE { for i in &mut slots { let slot_u32 = get_aux_slot( - &aux_pow[u32_to_usize(*i)].id, + &aux_pow[u32_to_usize(*i)].id.0, nonce, non_zero_len.try_into().unwrap(), ); @@ -1117,8 +1117,8 @@ fn add_aux_pow_inner( return Err(anyhow!("Slot value out of range")); } - aux_pow_id_raw.push(aux_pow.id); - aux_pow_raw.push(aux_pow.hash); + aux_pow_id_raw.push(aux_pow.id.0); + aux_pow_raw.push(aux_pow.hash.0); } assert_eq!( @@ -1139,8 +1139,8 @@ fn add_aux_pow_inner( return Err(anyhow!("Slot value out of range")); } - aux_pow_raw[slot] = aux_pow.hash; - aux_pow_id_raw[slot] = aux_pow.id; + aux_pow_raw[slot] = aux_pow.hash.0; + aux_pow_id_raw[slot] = aux_pow.id.0; } ( @@ -1197,9 +1197,7 @@ fn add_aux_pow_inner( let blocktemplate_blob = hex::encode(blocktemplate_blob); let blockhashing_blob = hex::encode(blockhashing_blob); let merkle_root = hex::encode(merkle_root); - let aux_pow = IntoIterator::into_iter(aux_pow) // must be explicit due to `boxed_slice_into_iter` - .map(Into::into) - .collect::>(); + let aux_pow = aux_pow.into_vec(); Ok(AddAuxPowResponse { base: ResponseBase::OK, diff --git a/helper/Cargo.toml b/helper/Cargo.toml index 716beb34..7ebbf8a0 100644 --- a/helper/Cargo.toml +++ b/helper/Cargo.toml @@ -23,6 +23,7 @@ map = ["cast", "dep:monero-serai", "dep:cuprate-constants"] time = ["dep:chrono", "std"] thread = ["std", "dep:target_os_lib"] tx = ["dep:monero-serai"] +fmt = ["map"] [dependencies] cuprate-constants = { workspace = true, optional = true, features = ["block"] } diff --git a/helper/src/fmt.rs b/helper/src/fmt.rs new file mode 100644 index 00000000..d5c043e3 --- /dev/null +++ b/helper/src/fmt.rs @@ -0,0 +1,19 @@ +//! Formatting. + +use crate::map::combine_low_high_bits_to_u128; + +/// Format two [`u64`]'s as a [`u128`] as a lower-case hexadecimal string prefixed with `0x`. +/// +/// ```rust +/// # use cuprate_helper::fmt::hex_prefix_u128; +/// assert_eq!(hex_prefix_u128(0, 0), "0x0"); +/// assert_eq!(hex_prefix_u128(0, u64::MAX), "0xffffffffffffffff0000000000000000"); +/// assert_eq!(hex_prefix_u128(u64::MAX, 0), "0xffffffffffffffff"); +/// assert_eq!(hex_prefix_u128(u64::MAX, u64::MAX), "0xffffffffffffffffffffffffffffffff"); +/// ``` +pub fn hex_prefix_u128(low_bits: u64, high_bits: u64) -> String { + format!("{:#x}", combine_low_high_bits_to_u128(low_bits, high_bits)) +} + +#[cfg(test)] +mod tests {} diff --git a/helper/src/lib.rs b/helper/src/lib.rs index 9bd64fa1..7142bd90 100644 --- a/helper/src/lib.rs +++ b/helper/src/lib.rs @@ -33,6 +33,6 @@ pub mod tx; #[cfg(feature = "crypto")] pub mod crypto; -//---------------------------------------------------------------------------------------------------- Private Usage -//---------------------------------------------------------------------------------------------------- +#[cfg(feature = "fmt")] +pub mod fmt; diff --git a/helper/src/map.rs b/helper/src/map.rs index b719f8fb..8f72e50e 100644 --- a/helper/src/map.rs +++ b/helper/src/map.rs @@ -5,6 +5,8 @@ //! `#[no_std]` compatible. //---------------------------------------------------------------------------------------------------- Use +use core::net::Ipv4Addr; + use monero_serai::transaction::Timelock; use cuprate_constants::block::MAX_BLOCK_HEIGHT; @@ -28,6 +30,7 @@ use crate::cast::{u64_to_usize, usize_to_u64}; /// let high = u64::MAX; /// /// assert_eq!(split_u128_into_low_high_bits(value), (low, high)); +/// assert_eq!(split_u128_into_low_high_bits(0), (0, 0)); /// ``` #[inline] pub const fn split_u128_into_low_high_bits(value: u128) -> (u64, u64) { @@ -52,6 +55,7 @@ pub const fn split_u128_into_low_high_bits(value: u128) -> (u64, u64) { /// let high = u64::MAX; /// /// assert_eq!(combine_low_high_bits_to_u128(low, high), value); +/// assert_eq!(combine_low_high_bits_to_u128(0, 0), 0); /// ``` #[inline] pub const fn combine_low_high_bits_to_u128(low_bits: u64, high_bits: u64) -> u128 { @@ -59,6 +63,24 @@ pub const fn combine_low_high_bits_to_u128(low_bits: u64, high_bits: u64) -> u12 res | (low_bits as u128) } +//---------------------------------------------------------------------------------------------------- IPv4 +/// Convert an [`Ipv4Addr`] to a [`u32`]. +/// +/// For why this exists, see: . +#[inline] +pub const fn ipv4_from_u32(ip: u32) -> Ipv4Addr { + let [a, b, c, d] = ip.to_le_bytes(); + Ipv4Addr::new(a, b, c, d) +} + +/// Convert a [`u32`] to an [`Ipv4Addr`]. +/// +/// For why this exists, see: . +#[inline] +pub const fn u32_from_ipv4(ip: Ipv4Addr) -> u32 { + u32::from_le_bytes(ip.octets()) +} + //---------------------------------------------------------------------------------------------------- Timelock /// Map a [`u64`] to a [`Timelock`]. /// diff --git a/rpc/types/Cargo.toml b/rpc/types/Cargo.toml index 1f4e62bc..55fac9cd 100644 --- a/rpc/types/Cargo.toml +++ b/rpc/types/Cargo.toml @@ -12,7 +12,13 @@ keywords = ["cuprate", "rpc", "types", "monero"] default = ["serde", "epee", "from"] serde = ["dep:serde", "cuprate-fixed-bytes/serde", "cuprate-types/serde"] epee = ["dep:cuprate-epee-encoding", "cuprate-types/epee"] -from = ["dep:cuprate-helper", "cuprate-helper/map", "dep:cuprate-p2p-core", "dep:hex"] +from = [ + "dep:cuprate-helper", + "cuprate-helper/map", + "cuprate-helper/fmt", + "dep:cuprate-p2p-core", + "dep:hex" +] [dependencies] cuprate-epee-encoding = { workspace = true, optional = true } diff --git a/rpc/types/src/from.rs b/rpc/types/src/from.rs index 6d8ceec5..6d374dfc 100644 --- a/rpc/types/src/from.rs +++ b/rpc/types/src/from.rs @@ -2,39 +2,24 @@ //! //! Only non-crate types are imported, all crate types use `crate::`. -#![allow(unused_variables, unreachable_code, reason = "TODO")] - use std::{ net::{Ipv4Addr, SocketAddr, SocketAddrV4}, time::Duration, }; -use cuprate_helper::map::combine_low_high_bits_to_u128; +use cuprate_helper::{ + fmt::hex_prefix_u128, + map::{combine_low_high_bits_to_u128, ipv4_from_u32}, +}; use cuprate_p2p_core::{ - types::{BanState, ConnectionId, ConnectionInfo, SetBan, Span}, - ClearNet, NetZoneAddress, NetworkZone, + types::{ConnectionId, ConnectionInfo, SetBan, Span}, + NetZoneAddress, }; use cuprate_types::{ hex::Hex, - rpc::{ - AuxPow, BlockHeader, BlockOutputIndices, ChainInfo, GetBan, GetMinerDataTxBacklogEntry, - GetOutputsOut, HardforkEntry, HistogramEntry, OutKey, OutKeyBin, OutputDistributionData, - Peer, PublicNode, SpentKeyImageInfo, TxBacklogEntry, TxInfo, TxOutputIndices, TxpoolHisto, - TxpoolStats, - }, + rpc::{BlockHeader, ChainInfo, HistogramEntry, TxInfo}, }; -/// -const fn ipv4_from_u32(ip: u32) -> Ipv4Addr { - let [a, b, c, d] = ip.to_le_bytes(); - Ipv4Addr::new(a, b, c, d) -} - -/// Format two [`u64`]'s as a [`u128`] as a hexadecimal string prefixed with `0x`. -fn hex_prefix_u128(low: u64, high: u64) -> String { - format!("{:#x}", combine_low_high_bits_to_u128(low, high)) -} - impl From for crate::misc::BlockHeader { fn from(x: BlockHeader) -> Self { Self { @@ -54,7 +39,7 @@ impl From for crate::misc::BlockHeader { nonce: x.nonce, num_txes: x.num_txes, orphan_status: x.orphan_status, - pow_hash: Hex(x.pow_hash), + pow_hash: x.pow_hash.map_or_else(String::new, hex::encode), prev_hash: Hex(x.prev_hash), reward: x.reward, timestamp: x.timestamp, @@ -206,25 +191,3 @@ impl From for crate::misc::TxInfo { } } } - -impl From for crate::misc::AuxPow { - fn from(x: AuxPow) -> Self { - Self { - id: Hex(x.id), - hash: Hex(x.hash), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn hex() { - assert_eq!(hex_prefix_u128(0, 0), "0x0"); - assert_eq!(hex_prefix_u128(0, u64::MAX), "0x0"); - assert_eq!(hex_prefix_u128(u64::MAX, 0), "0x0"); - assert_eq!(hex_prefix_u128(u64::MAX, u64::MAX), "0x0"); - } -} diff --git a/rpc/types/src/json.rs b/rpc/types/src/json.rs index 8f687268..4d51252a 100644 --- a/rpc/types/src/json.rs +++ b/rpc/types/src/json.rs @@ -6,14 +6,14 @@ #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use cuprate_types::rpc::{GetMinerDataTxBacklogEntry, HardforkEntry, TxBacklogEntry}; +use cuprate_types::rpc::{AuxPow, GetMinerDataTxBacklogEntry, HardforkEntry, TxBacklogEntry}; use crate::{ base::{AccessResponseBase, ResponseBase}, macros::define_request_and_response, misc::{ - AuxPow, BlockHeader, ChainInfo, ConnectionInfo, Distribution, GetBan, HistogramEntry, - SetBan, Span, Status, SyncInfoPeer, + BlockHeader, ChainInfo, ConnectionInfo, Distribution, GetBan, HistogramEntry, SetBan, Span, + Status, SyncInfoPeer, }, rpc_call::RpcCallValue, }; diff --git a/rpc/types/src/misc/mod.rs b/rpc/types/src/misc/mod.rs index 0d616210..b81bf9c8 100644 --- a/rpc/types/src/misc/mod.rs +++ b/rpc/types/src/misc/mod.rs @@ -27,6 +27,6 @@ pub use requested_info::RequestedInfo; pub use status::Status; pub use tx_entry::TxEntry; pub use types::{ - AuxPow, BlockHeader, ChainInfo, ConnectionInfo, GetBan, GetOutputsOut, HistogramEntry, - OutKeyBin, SetBan, Span, SpentKeyImageInfo, SyncInfoPeer, TxInfo, + BlockHeader, ChainInfo, ConnectionInfo, GetBan, GetOutputsOut, HistogramEntry, OutKeyBin, + SetBan, Span, SpentKeyImageInfo, SyncInfoPeer, TxInfo, }; diff --git a/rpc/types/src/misc/types.rs b/rpc/types/src/misc/types.rs index 49bd8517..82227121 100644 --- a/rpc/types/src/misc/types.rs +++ b/rpc/types/src/misc/types.rs @@ -90,7 +90,8 @@ define_struct_and_impl_epee! { nonce: u32, num_txes: u64, orphan_status: bool, - pow_hash: Hex<32>, + /// This is an empty string if the `fill_pow_hash` param is `false`. + pow_hash: String, prev_hash: Hex<32>, reward: u64, timestamp: u64, @@ -309,18 +310,6 @@ define_struct_and_impl_epee! { } } -define_struct_and_impl_epee! { - #[doc = monero_definition_link!( - "cc73fe71162d564ffda8e549b79a350bca53c454", - "rpc/core_rpc_server_commands_defs.h", - 1070..=1079 - )] - AuxPow { - id: Hex<32>, - hash: Hex<32>, - } -} - //---------------------------------------------------------------------------------------------------- Tests #[cfg(test)] mod test {} diff --git a/types/src/rpc/types.rs b/types/src/rpc/types.rs index a9ac06fc..2939b355 100644 --- a/types/src/rpc/types.rs +++ b/types/src/rpc/types.rs @@ -103,7 +103,8 @@ define_struct_and_impl_epee! { nonce: u32, num_txes: u64, orphan_status: bool, - pow_hash: [u8; 32], + /// This is [`None`] if the `fill_pow_hash` param is `false`. + pow_hash: Option<[u8; 32]>, prev_hash: [u8; 32], reward: u64, timestamp: u64, @@ -273,8 +274,8 @@ define_struct_and_impl_epee! { 1070..=1079 )] AuxPow { - id: [u8; 32], - hash: [u8; 32], + id: Hex<32>, + hash: Hex<32>, } #[doc = monero_definition_link!(