return defaults, hex test
Some checks failed
Deny / audit (push) Has been cancelled

This commit is contained in:
hinto.janai 2024-12-10 20:49:39 -05:00
parent 3a799219b8
commit 1719d7db84
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
6 changed files with 75 additions and 67 deletions

View file

@ -27,8 +27,8 @@ members = [
"p2p/p2p-core", "p2p/p2p-core",
"p2p/bucket", "p2p/bucket",
"p2p/dandelion-tower", "p2p/dandelion-tower",
"p2p/address-book",
"p2p/async-buffer", "p2p/async-buffer",
"p2p/address-book",
# Storage # Storage
"storage/blockchain", "storage/blockchain",

View file

@ -5,7 +5,7 @@
//! has a [`crate::json::GetBlockRequest::height`] //! has a [`crate::json::GetBlockRequest::height`]
//! field and a [`crate::json::GetBlockRequest::hash`] //! field and a [`crate::json::GetBlockRequest::hash`]
//! field, when the RPC interface reads JSON without //! field, when the RPC interface reads JSON without
//! `height`, it will use [`default_height`] to fill that in. //! `height`, it will use [`default`] to fill that in.
//---------------------------------------------------------------------------------------------------- Import //---------------------------------------------------------------------------------------------------- Import
@ -16,12 +16,6 @@ pub(crate) const fn default_true() -> bool {
true true
} }
/// Default `0` value used in request/response types.
#[inline]
pub(crate) fn default_zero<T: From<u8>>() -> T {
T::from(0)
}
/// Default `1` value used in request/response types. /// Default `1` value used in request/response types.
#[inline] #[inline]
pub(crate) fn default_one<T: From<u8>>() -> T { pub(crate) fn default_one<T: From<u8>>() -> T {
@ -36,16 +30,4 @@ pub(crate) fn default<T: Default>() -> T {
//---------------------------------------------------------------------------------------------------- Tests //---------------------------------------------------------------------------------------------------- Tests
#[cfg(test)] #[cfg(test)]
mod test { mod test {}
use super::*;
/// Tests that [`default_zero`] returns `0` on all unsigned numbers.
#[test]
fn zero() {
assert_eq!(default_zero::<usize>(), 0);
assert_eq!(default_zero::<u64>(), 0);
assert_eq!(default_zero::<u32>(), 0);
assert_eq!(default_zero::<u16>(), 0);
assert_eq!(default_zero::<u8>(), 0);
}
}

View file

@ -78,15 +78,15 @@ define_request_and_response! {
// //
// This is a HACK since `serde`'s default attribute only takes in // This is a HACK since `serde`'s default attribute only takes in
// string literals and macros (stringify) within attributes do not work. // string literals and macros (stringify) within attributes do not work.
extra_nonce: String, extra_nonce: String = default::<String>(), "default",
prev_block: String, prev_block: String = default::<String>(), "default",
// Another optional expression: // Another optional expression:
// This indicates to the macro to (de)serialize // This indicates to the macro to (de)serialize
// this field as another type in epee. // this field as another type in epee.
// //
// See `cuprate_epee_encoding::epee_object` for info. // See `cuprate_epee_encoding::epee_object` for info.
reserve_size: u64, reserve_size: u64 /* as Type */,
wallet_address: String, wallet_address: String,
}, },
@ -197,7 +197,7 @@ define_request_and_response! {
Request { Request {
amount_of_blocks: u64, amount_of_blocks: u64,
prev_block: String, prev_block: String = default::<String>(), "default",
starting_nonce: u32, starting_nonce: u32,
wallet_address: String, wallet_address: String,
}, },
@ -217,7 +217,7 @@ define_request_and_response! {
#[derive(Copy)] #[derive(Copy)]
Request { Request {
fill_pow_hash: bool, fill_pow_hash: bool = default::<bool>(), "default",
}, },
AccessResponseBase { AccessResponseBase {
@ -232,9 +232,9 @@ define_request_and_response! {
GetBlockHeaderByHash, GetBlockHeaderByHash,
Request { Request {
hash: Hex<32>, hash: Hex<32> = default::<Hex<32>>(), "default",
hashes: Vec<Hex<32>>, hashes: Vec<Hex<32>> = default::<Vec<Hex<32>>>(), "default",
fill_pow_hash: bool, fill_pow_hash: bool = default::<bool>(), "default",
}, },
AccessResponseBase { AccessResponseBase {
@ -253,7 +253,7 @@ define_request_and_response! {
#[derive(Copy)] #[derive(Copy)]
Request { Request {
height: u64, height: u64,
fill_pow_hash: bool, fill_pow_hash: bool = default::<bool>(), "default",
}, },
AccessResponseBase { AccessResponseBase {
@ -272,7 +272,7 @@ define_request_and_response! {
Request { Request {
start_height: u64, start_height: u64,
end_height: u64, end_height: u64,
fill_pow_hash: bool, fill_pow_hash: bool = default::<bool>(), "default",
}, },
AccessResponseBase { AccessResponseBase {
@ -290,9 +290,9 @@ define_request_and_response! {
// `monerod` has both `hash` and `height` fields. // `monerod` has both `hash` and `height` fields.
// In the RPC handler, if `hash.is_empty()`, it will use it, else, it uses `height`. // In the RPC handler, if `hash.is_empty()`, it will use it, else, it uses `height`.
// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L2674> // <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L2674>
hash: String, hash: String = default::<String>(), "default",
height: u64, height: u64 = default::<u64>(), "default",
fill_pow_hash: bool, fill_pow_hash: bool = default::<bool>(), "default",
}, },
AccessResponseBase { AccessResponseBase {
@ -445,7 +445,7 @@ define_request_and_response! {
FlushTransactionPool (restricted), FlushTransactionPool (restricted),
Request { Request {
txids: Vec<Hex<32>>, txids: Vec<Hex<32>> = default::<Vec<Hex<32>>>(), "default",
}, },
#[repr(transparent)] #[repr(transparent)]
@ -461,11 +461,11 @@ define_request_and_response! {
GetOutputHistogram, GetOutputHistogram,
Request { Request {
amounts: Vec<u64>, amounts: Vec<u64> = default::<Vec<u64>>(), "default",
min_count: u64, min_count: u64 = default::<u64>(), "default",
max_count: u64, max_count: u64 = default::<u64>(), "default",
unlocked: bool, unlocked: bool = default::<bool>(), "default",
recent_cutoff: u64, recent_cutoff: u64 = default::<u64>(), "default",
}, },
AccessResponseBase { AccessResponseBase {
@ -520,7 +520,7 @@ define_request_and_response! {
GetFeeEstimate, GetFeeEstimate,
Request { Request {
grace_blocks: u64, grace_blocks: u64 = default::<u64>(), "default",
}, },
AccessResponseBase { AccessResponseBase {
@ -550,7 +550,7 @@ define_request_and_response! {
RelayTx (restricted), RelayTx (restricted),
Request { Request {
txids: Vec<Hex<32>>, txids: Vec<Hex<32>> = default::<Vec<Hex<32>>>(), "default",
}, },
#[repr(transparent)] #[repr(transparent)]
@ -604,10 +604,10 @@ define_request_and_response! {
Request { Request {
amounts: Vec<u64>, amounts: Vec<u64>,
binary: bool = default_true(), "default_true", binary: bool = default_true(), "default_true",
compress: bool, compress: bool = default::<bool>(), "default",
cumulative: bool, cumulative: bool = default::<bool>(), "default",
from_height: u64, from_height: u64 = default::<u64>(), "default",
to_height: u64, to_height: u64 = default::<u64>(), "default",
}, },
AccessResponseBase { AccessResponseBase {
@ -643,7 +643,7 @@ define_request_and_response! {
#[derive(Copy)] #[derive(Copy)]
Request { Request {
check: bool, check: bool = default::<bool>(), "default",
}, },
ResponseBase { ResponseBase {

View file

@ -238,7 +238,6 @@ macro_rules! define_request {
) => { ) => {
#[allow(dead_code, missing_docs, reason = "inside a macro")] #[allow(dead_code, missing_docs, reason = "inside a macro")]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(default))] // TODO: link epee field not serializing oddity
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
$( #[$attr] )* $( #[$attr] )*
pub struct $t { pub struct $t {
@ -292,6 +291,7 @@ macro_rules! define_response {
} }
) => { ) => {
$( #[$attr] )* $( #[$attr] )*
#[cfg_attr(feature = "serde", serde(default))] // TODO: link epee field not serializing oddity
pub struct $t { pub struct $t {
$( $(
$( #[$field_attr] )* $( #[$field_attr] )*
@ -329,6 +329,7 @@ macro_rules! define_response {
} }
) => { ) => {
$( #[$attr] )* $( #[$attr] )*
#[cfg_attr(feature = "serde", serde(default))] // TODO: link epee field not serializing oddity
pub struct $t { pub struct $t {
#[cfg_attr(feature = "serde", serde(flatten))] #[cfg_attr(feature = "serde", serde(flatten))]
pub base: $base, pub base: $base,

View file

@ -12,12 +12,12 @@ use cuprate_types::rpc::{OutKey, Peer, PublicNode, TxpoolStats};
use crate::{ use crate::{
base::{AccessResponseBase, ResponseBase}, base::{AccessResponseBase, ResponseBase},
macros::define_request_and_response, macros::define_request_and_response,
misc::{GetOutputsOut, KeyImageSpentStatus, SpentKeyImageInfo, Status, TxEntry, TxInfo}, misc::{GetOutputsOut, SpentKeyImageInfo, Status, TxEntry, TxInfo},
RpcCallValue, RpcCallValue,
}; };
#[cfg(any(feature = "serde", feature = "epee"))] #[cfg(any(feature = "serde", feature = "epee"))]
use crate::defaults::default_true; use crate::defaults::{default, default_true};
//---------------------------------------------------------------------------------------------------- Definitions //---------------------------------------------------------------------------------------------------- Definitions
define_request_and_response! { define_request_and_response! {
@ -44,9 +44,9 @@ define_request_and_response! {
// FIXME: this is documented as optional but it isn't serialized as an optional // FIXME: this is documented as optional but it isn't serialized as an optional
// but it is set _somewhere_ to false in `monerod` // but it is set _somewhere_ to false in `monerod`
// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L382> // <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L382>
decode_as_json: bool, decode_as_json: bool = default::<bool>(), "default",
prune: bool, prune: bool = default::<bool>(), "default",
split: bool, split: bool = default::<bool>(), "default",
}, },
AccessResponseBase { AccessResponseBase {
@ -83,7 +83,8 @@ define_request_and_response! {
}, },
AccessResponseBase { AccessResponseBase {
spent_status: Vec<KeyImageSpentStatus>, /// These [`u8`]s are [`crate::misc::KeyImageSpentStatus`].
spent_status: Vec<u8>,
} }
} }
@ -96,7 +97,7 @@ define_request_and_response! {
Request { Request {
tx_as_hex: String, tx_as_hex: String,
do_not_relay: bool, do_not_relay: bool = default::<bool>(), "default",
do_sanity_checks: bool = default_true(), "default_true", do_sanity_checks: bool = default_true(), "default_true",
}, },
@ -189,7 +190,7 @@ define_request_and_response! {
Request { Request {
public_only: bool = default_true(), "default_true", public_only: bool = default_true(), "default_true",
include_blocked: bool, include_blocked: bool = default::<bool>(), "default",
}, },
ResponseBase { ResponseBase {
@ -236,7 +237,7 @@ define_request_and_response! {
SetLogCategories (restricted), SetLogCategories (restricted),
Request { Request {
categories: String, categories: String = default::<String>(), "default",
}, },
ResponseBase { ResponseBase {
@ -253,9 +254,9 @@ define_request_and_response! {
Request { Request {
address: String, address: String,
username: String, username: String = default::<String>(), "default",
password: String, password: String = default::<String>(), "default",
proxy: String, proxy: String = default::<String>(), "default",
}, },
Response { Response {
@ -325,8 +326,8 @@ define_request_and_response! {
SetLimit (restricted), SetLimit (restricted),
Request { Request {
limit_down: i64, limit_down: i64 = default::<i64>(), "default",
limit_up: i64, limit_up: i64 = default::<i64>(), "default",
}, },
ResponseBase { ResponseBase {
@ -408,7 +409,7 @@ define_request_and_response! {
Request { Request {
command: String, command: String,
path: String, path: String = default::<String>(), "default",
}, },
ResponseBase { ResponseBase {
auto_uri: String, auto_uri: String,
@ -458,9 +459,9 @@ define_request_and_response! {
GetPublicNodes (restricted), GetPublicNodes (restricted),
Request { Request {
gray: bool, gray: bool = default::<bool>(), "default",
white: bool = default_true(), "default_true", white: bool = default_true(), "default_true",
include_blocked: bool, include_blocked: bool = default::<bool>(), "default",
}, },
ResponseBase { ResponseBase {
@ -698,7 +699,7 @@ mod test {
#[test] #[test]
fn get_transactions_response() { fn get_transactions_response() {
test_json::<GetTransactionsRequest>(other::GET_TRANSACTIONS_RESPONSE, None); test_json::<GetTransactionsResponse>(other::GET_TRANSACTIONS_RESPONSE, None);
} }
#[test] #[test]
@ -737,7 +738,7 @@ mod test {
other::IS_KEY_IMAGE_SPENT_RESPONSE, other::IS_KEY_IMAGE_SPENT_RESPONSE,
Some(IsKeyImageSpentResponse { Some(IsKeyImageSpentResponse {
base: AccessResponseBase::OK, base: AccessResponseBase::OK,
spent_status: vec![KeyImageSpentStatus::SpentInBlockchain; 2], spent_status: vec![1, 1],
}), }),
); );
} }

View file

@ -19,6 +19,17 @@ use serde::{Deserialize, Deserializer, Serialize};
/// ///
/// let from_str = serde_json::from_str::<Hex<32>>(expected_json).unwrap(); /// let from_str = serde_json::from_str::<Hex<32>>(expected_json).unwrap();
/// assert_eq!(hex_bytes, from_str); /// assert_eq!(hex_bytes, from_str);
///
/// //------
///
/// let vec = vec![hex_bytes; 2];
/// let expected_json = r#"["0101010101010101010101010101010101010101010101010101010101010101","0101010101010101010101010101010101010101010101010101010101010101"]"#;
///
/// let to_string = serde_json::to_string(&vec).unwrap();
/// assert_eq!(to_string, expected_json);
///
/// let from_str = serde_json::from_str::<Vec<Hex<32>>>(expected_json).unwrap();
/// assert_eq!(vec, from_str);
/// ``` /// ```
/// ///
/// # Deserialization /// # Deserialization
@ -30,6 +41,19 @@ use serde::{Deserialize, Deserializer, Serialize};
#[repr(transparent)] #[repr(transparent)]
pub struct Hex<const N: usize>(#[serde(with = "hex::serde")] pub [u8; N]); pub struct Hex<const N: usize>(#[serde(with = "hex::serde")] pub [u8; N]);
impl<const N: usize> Hex<N> {
/// Returns `true` if the inner array is zeroed.
///
/// ```rust
/// # use cuprate_hex::Hex;
/// assert!(Hex([0; 32]).is_zeroed());
/// assert!(!Hex([1; 32]).is_zeroed());
/// ```
pub fn is_zeroed(&self) -> bool {
*self == Self([0; N])
}
}
impl<'de, const N: usize> Deserialize<'de> for Hex<N> impl<'de, const N: usize> Deserialize<'de> for Hex<N>
where where
[u8; N]: FromHex, [u8; N]: FromHex,