move types, fix orphan impl + cyclic dependency

This commit is contained in:
hinto.janai 2024-12-06 19:19:14 -05:00
parent 5b8cacd6b3
commit f2e7af779f
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
39 changed files with 189 additions and 109 deletions

15
Cargo.lock generated
View file

@ -886,6 +886,7 @@ dependencies = [
"bytes", "bytes",
"cuprate-fixed-bytes", "cuprate-fixed-bytes",
"cuprate-helper", "cuprate-helper",
"cuprate-hex",
"hex", "hex",
"paste", "paste",
"ref-cast", "ref-cast",
@ -940,6 +941,15 @@ dependencies = [
"windows", "windows",
] ]
[[package]]
name = "cuprate-hex"
version = "0.0.0"
dependencies = [
"hex",
"serde",
"serde_json",
]
[[package]] [[package]]
name = "cuprate-json-rpc" name = "cuprate-json-rpc"
version = "0.0.0" version = "0.0.0"
@ -1068,6 +1078,7 @@ dependencies = [
"cuprate-epee-encoding", "cuprate-epee-encoding",
"cuprate-fixed-bytes", "cuprate-fixed-bytes",
"cuprate-helper", "cuprate-helper",
"cuprate-hex",
"cuprate-p2p-core", "cuprate-p2p-core",
"cuprate-test-utils", "cuprate-test-utils",
"cuprate-types", "cuprate-types",
@ -1136,8 +1147,8 @@ dependencies = [
"cuprate-epee-encoding", "cuprate-epee-encoding",
"cuprate-fixed-bytes", "cuprate-fixed-bytes",
"cuprate-helper", "cuprate-helper",
"cuprate-hex",
"curve25519-dalek", "curve25519-dalek",
"hex",
"hex-literal", "hex-literal",
"monero-serai", "monero-serai",
"pretty_assertions", "pretty_assertions",
@ -1169,7 +1180,7 @@ name = "cuprate-zmq-types"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"assert-json-diff", "assert-json-diff",
"cuprate-types", "cuprate-hex",
"hex", "hex",
"serde", "serde",
"serde_json", "serde_json",

View file

@ -19,7 +19,6 @@ members = [
# Net # Net
"net/epee-encoding", "net/epee-encoding",
"net/fixed-bytes",
"net/levin", "net/levin",
"net/wire", "net/wire",
@ -28,7 +27,6 @@ members = [
"p2p/p2p-core", "p2p/p2p-core",
"p2p/bucket", "p2p/bucket",
"p2p/dandelion-tower", "p2p/dandelion-tower",
"p2p/async-buffer",
"p2p/address-book", "p2p/address-book",
# Storage # Storage
@ -37,6 +35,12 @@ members = [
"storage/txpool", "storage/txpool",
"storage/database", "storage/database",
# Types
"types/types",
"types/hex",
"types/fixed-bytes",
"types/async-buffer",
# RPC # RPC
"rpc/json-rpc", "rpc/json-rpc",
"rpc/types", "rpc/types",
@ -51,7 +55,6 @@ members = [
"helper", "helper",
"pruning", "pruning",
"test-utils", "test-utils",
"types",
] ]
[profile.release] [profile.release]
@ -85,14 +88,12 @@ cuprate-consensus-context = { path = "consensus/context", default-featur
cuprate-cryptonight = { path = "cryptonight", default-features = false } cuprate-cryptonight = { path = "cryptonight", default-features = false }
cuprate-helper = { path = "helper", default-features = false } cuprate-helper = { path = "helper", default-features = false }
cuprate-epee-encoding = { path = "net/epee-encoding", default-features = false } cuprate-epee-encoding = { path = "net/epee-encoding", default-features = false }
cuprate-fixed-bytes = { path = "net/fixed-bytes", default-features = false }
cuprate-levin = { path = "net/levin", default-features = false } cuprate-levin = { path = "net/levin", default-features = false }
cuprate-wire = { path = "net/wire", default-features = false } cuprate-wire = { path = "net/wire", default-features = false }
cuprate-p2p = { path = "p2p/p2p", default-features = false } cuprate-p2p = { path = "p2p/p2p", default-features = false }
cuprate-p2p-core = { path = "p2p/p2p-core", default-features = false } cuprate-p2p-core = { path = "p2p/p2p-core", default-features = false }
cuprate-p2p-bucket = { path = "p2p/p2p-bucket", default-features = false } cuprate-p2p-bucket = { path = "p2p/p2p-bucket", default-features = false }
cuprate-dandelion-tower = { path = "p2p/dandelion-tower", default-features = false } cuprate-dandelion-tower = { path = "p2p/dandelion-tower", default-features = false }
cuprate-async-buffer = { path = "p2p/async-buffer", default-features = false }
cuprate-address-book = { path = "p2p/address-book", default-features = false } cuprate-address-book = { path = "p2p/address-book", default-features = false }
cuprate-blockchain = { path = "storage/blockchain", default-features = false } cuprate-blockchain = { path = "storage/blockchain", default-features = false }
cuprate-database = { path = "storage/database", default-features = false } cuprate-database = { path = "storage/database", default-features = false }
@ -100,7 +101,10 @@ cuprate-database-service = { path = "storage/service", default-featur
cuprate-txpool = { path = "storage/txpool", default-features = false } cuprate-txpool = { path = "storage/txpool", default-features = false }
cuprate-pruning = { path = "pruning", default-features = false } cuprate-pruning = { path = "pruning", default-features = false }
cuprate-test-utils = { path = "test-utils", default-features = false } cuprate-test-utils = { path = "test-utils", default-features = false }
cuprate-types = { path = "types", default-features = false } cuprate-types = { path = "types/types", default-features = false }
cuprate-hex = { path = "types/hex", default-features = false }
cuprate-fixed-bytes = { path = "types/fixed-bytes", default-features = false }
cuprate-async-buffer = { path = "types/async-buffer", default-features = false }
cuprate-json-rpc = { path = "rpc/json-rpc", default-features = false } cuprate-json-rpc = { path = "rpc/json-rpc", default-features = false }
cuprate-rpc-types = { path = "rpc/types", default-features = false } cuprate-rpc-types = { path = "rpc/types", default-features = false }
cuprate-rpc-interface = { path = "rpc/interface", default-features = false } cuprate-rpc-interface = { path = "rpc/interface", default-features = false }

View file

@ -17,6 +17,7 @@ std = ["dep:thiserror", "bytes/std", "cuprate-fixed-bytes/std"]
[dependencies] [dependencies]
cuprate-helper = { workspace = true, default-features = false, features = ["cast"] } cuprate-helper = { workspace = true, default-features = false, features = ["cast"] }
cuprate-fixed-bytes = { workspace = true, default-features = false } cuprate-fixed-bytes = { workspace = true, default-features = false }
cuprate-hex = { workspace = true, default-features = false }
paste = "1.0.15" paste = "1.0.15"
ref-cast = "1.0.23" ref-cast = "1.0.23"

View file

@ -8,6 +8,7 @@ use bytes::{Buf, BufMut, Bytes, BytesMut};
use cuprate_fixed_bytes::{ByteArray, ByteArrayVec}; use cuprate_fixed_bytes::{ByteArray, ByteArrayVec};
use cuprate_helper::cast::u64_to_usize; use cuprate_helper::cast::u64_to_usize;
use cuprate_hex::Hex;
use crate::{ use crate::{
io::{checked_read_primitive, checked_write_primitive}, io::{checked_read_primitive, checked_write_primitive},
@ -401,6 +402,41 @@ impl<const N: usize> EpeeValue for Vec<[u8; N]> {
} }
} }
impl<const N: usize> EpeeValue for Hex<N> {
const MARKER: Marker = <[u8; N] as EpeeValue>::MARKER;
fn read<B: Buf>(r: &mut B, marker: &Marker) -> Result<Self> {
Ok(Self(<[u8; N] as EpeeValue>::read(r, marker)?))
}
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
<[u8; N] as EpeeValue>::write(self.0, w)
}
}
impl<const N: usize> EpeeValue for Vec<Hex<N>> {
const MARKER: Marker = Vec::<[u8; N]>::MARKER;
fn read<B: Buf>(r: &mut B, marker: &Marker) -> Result<Self> {
Ok(Vec::<[u8; N]>::read(r, marker)?
.into_iter()
.map(Hex)
.collect())
}
fn should_write(&self) -> bool {
!self.is_empty()
}
fn epee_default_value() -> Option<Self> {
Some(Self::new())
}
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
write_iterator(self.into_iter(), w)
}
}
macro_rules! epee_seq { macro_rules! epee_seq {
($val:ty) => { ($val:ty) => {
impl EpeeValue for Vec<$val> { impl EpeeValue for Vec<$val> {

View file

@ -10,7 +10,7 @@ keywords = ["cuprate", "rpc", "types", "monero"]
[features] [features]
default = ["serde", "epee", "from"] default = ["serde", "epee", "from"]
serde = ["dep:serde", "cuprate-fixed-bytes/serde", "cuprate-types/serde"] serde = ["dep:serde", "cuprate-fixed-bytes/serde", "cuprate-types/serde", "cuprate-hex/serde"]
epee = ["dep:cuprate-epee-encoding", "cuprate-types/epee"] epee = ["dep:cuprate-epee-encoding", "cuprate-types/epee"]
from = [ from = [
"dep:cuprate-helper", "dep:cuprate-helper",
@ -22,8 +22,9 @@ from = [
] ]
[dependencies] [dependencies]
cuprate-epee-encoding = { workspace = true, optional = true }
cuprate-fixed-bytes = { workspace = true } cuprate-fixed-bytes = { workspace = true }
cuprate-hex = { workspace = true }
cuprate-epee-encoding = { workspace = true, optional = true }
cuprate-types = { workspace = true, default-features = false } cuprate-types = { workspace = true, default-features = false }
cuprate-helper = { workspace = true, optional = true, default-features = false } cuprate-helper = { workspace = true, optional = true, default-features = false }
cuprate-p2p-core = { workspace = true, optional = true, default-features = false } cuprate-p2p-core = { workspace = true, optional = true, default-features = false }

View file

@ -8,14 +8,12 @@ use std::{
}; };
use cuprate_helper::{fmt::hex_prefix_u128, map::ipv4_from_u32}; use cuprate_helper::{fmt::hex_prefix_u128, map::ipv4_from_u32};
use cuprate_hex::Hex;
use cuprate_p2p_core::{ use cuprate_p2p_core::{
types::{ConnectionId, ConnectionInfo, SetBan, Span}, types::{ConnectionId, ConnectionInfo, SetBan, Span},
NetZoneAddress, NetZoneAddress,
}; };
use cuprate_types::{ use cuprate_types::rpc::{BlockHeader, ChainInfo, HistogramEntry, TxInfo};
hex::Hex,
rpc::{BlockHeader, ChainInfo, HistogramEntry, TxInfo},
};
impl From<BlockHeader> for crate::misc::BlockHeader { impl From<BlockHeader> for crate::misc::BlockHeader {
fn from(x: BlockHeader) -> Self { fn from(x: BlockHeader) -> Self {

View file

@ -6,10 +6,8 @@
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use cuprate_types::{ use cuprate_hex::Hex;
hex::Hex, use cuprate_types::rpc::{AuxPow, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry};
rpc::{AuxPow, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry},
};
use crate::{ use crate::{
base::{AccessResponseBase, ResponseBase}, base::{AccessResponseBase, ResponseBase},

View file

@ -5,7 +5,8 @@
//! the [`crate::misc::ConnectionInfo`] struct defined here. //! the [`crate::misc::ConnectionInfo`] struct defined here.
//---------------------------------------------------------------------------------------------------- Import //---------------------------------------------------------------------------------------------------- Import
use cuprate_types::{hex::Hex, HardFork}; use cuprate_hex::Hex;
use cuprate_types::HardFork;
#[cfg(any(feature = "epee", feature = "serde"))] #[cfg(any(feature = "epee", feature = "serde"))]
use crate::defaults::default_zero; use crate::defaults::default_zero;

View file

@ -39,7 +39,7 @@ define_request_and_response! {
GetTransactions, GetTransactions,
Request { Request {
txs_hashes: Vec<String>, txs_hashes: Vec<String> = default_vec::<String>(), "default_vec",
// 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>
@ -648,19 +648,18 @@ mod test {
use hex_literal::hex; use hex_literal::hex;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde_json::{from_str, from_value, Value};
use cuprate_hex::Hex;
use cuprate_test_utils::rpc::data::other; use cuprate_test_utils::rpc::data::other;
use cuprate_types::HardFork; use cuprate_types::rpc::TxpoolHisto;
use super::*; use super::*;
#[expect(clippy::needless_pass_by_value)]
fn test_json<T: DeserializeOwned + PartialEq + Debug>( fn test_json<T: DeserializeOwned + PartialEq + Debug>(
cuprate_test_utils_example_data: &str, cuprate_test_utils_example_data: &str,
expected_type: Option<T>, expected_type: Option<T>,
) { ) {
let string = from_str::<T>(cuprate_test_utils_example_data).unwrap(); let string = serde_json::from_str::<T>(cuprate_test_utils_example_data).unwrap();
// This is `Option` for structs that have values // This is `Option` for structs that have values
// that are complicated to provide/test, e.g. `GET_TRANSACTIONS_RESPONSE`. // that are complicated to provide/test, e.g. `GET_TRANSACTIONS_RESPONSE`.
@ -802,7 +801,7 @@ mod test {
} }
#[test] #[test]
fn STOP_MINING_RESPONSE() { fn stop_mining_response() {
test_json( test_json(
other::STOP_MINING_RESPONSE, other::STOP_MINING_RESPONSE,
Some(StopMiningResponse { Some(StopMiningResponse {
@ -812,7 +811,7 @@ mod test {
} }
#[test] #[test]
fn MINING_STATUS_RESPONSE() { fn mining_status_response() {
test_json( test_json(
other::MINING_STATUS_RESPONSE, other::MINING_STATUS_RESPONSE,
Some(MiningStatusResponse { Some(MiningStatusResponse {
@ -837,7 +836,7 @@ mod test {
} }
#[test] #[test]
fn SAVE_BC_RESPONSE() { fn save_bc_response() {
test_json( test_json(
other::SAVE_BC_RESPONSE, other::SAVE_BC_RESPONSE,
Some(SaveBcResponse { Some(SaveBcResponse {
@ -847,7 +846,7 @@ mod test {
} }
#[test] #[test]
fn GET_PEER_LIST_REQUEST() { fn get_peer_list_request() {
test_json( test_json(
other::GET_PEER_LIST_REQUEST, other::GET_PEER_LIST_REQUEST,
Some(GetPeerListRequest { Some(GetPeerListRequest {
@ -858,7 +857,7 @@ mod test {
} }
#[test] #[test]
fn GET_PEER_LIST_RESPONSE() { fn get_peer_list_response() {
test_json( test_json(
other::GET_PEER_LIST_RESPONSE, other::GET_PEER_LIST_RESPONSE,
Some(GetPeerListResponse { Some(GetPeerListResponse {
@ -922,7 +921,7 @@ mod test {
} }
#[test] #[test]
fn SET_LOG_HASH_RATE_REQUEST() { fn set_log_hash_rate_request() {
test_json( test_json(
other::SET_LOG_HASH_RATE_REQUEST, other::SET_LOG_HASH_RATE_REQUEST,
Some(SetLogHashRateRequest { visible: true }), Some(SetLogHashRateRequest { visible: true }),
@ -930,7 +929,7 @@ mod test {
} }
#[test] #[test]
fn SET_LOG_HASH_RATE_RESPONSE() { fn set_log_hash_rate_response() {
test_json( test_json(
other::SET_LOG_HASH_RATE_RESPONSE, other::SET_LOG_HASH_RATE_RESPONSE,
Some(SetLogHashRateResponse { Some(SetLogHashRateResponse {
@ -940,7 +939,7 @@ mod test {
} }
#[test] #[test]
fn SET_LOG_LEVEL_REQUEST() { fn set_log_level_request() {
test_json( test_json(
other::SET_LOG_LEVEL_REQUEST, other::SET_LOG_LEVEL_REQUEST,
Some(SetLogLevelRequest { level: 1 }), Some(SetLogLevelRequest { level: 1 }),
@ -948,7 +947,7 @@ mod test {
} }
#[test] #[test]
fn SET_LOG_LEVEL_RESPONSE() { fn set_log_level_response() {
test_json( test_json(
other::SET_LOG_LEVEL_RESPONSE, other::SET_LOG_LEVEL_RESPONSE,
Some(SetLogLevelResponse { Some(SetLogLevelResponse {
@ -958,7 +957,7 @@ mod test {
} }
#[test] #[test]
fn SET_LOG_CATEGORIES_REQUEST() { fn set_log_categories_request() {
test_json( test_json(
other::SET_LOG_CATEGORIES_REQUEST, other::SET_LOG_CATEGORIES_REQUEST,
Some(SetLogCategoriesRequest { Some(SetLogCategoriesRequest {
@ -968,7 +967,7 @@ mod test {
} }
#[test] #[test]
fn SET_LOG_CATEGORIES_RESPONSE() { fn set_log_categories_response() {
test_json( test_json(
other::SET_LOG_CATEGORIES_RESPONSE, other::SET_LOG_CATEGORIES_RESPONSE,
Some(SetLogCategoriesResponse { Some(SetLogCategoriesResponse {
@ -979,7 +978,7 @@ mod test {
} }
#[test] #[test]
fn SET_BOOTSTRAP_DAEMON_REQUEST() { fn set_bootstrap_daemon_request() {
test_json( test_json(
other::SET_BOOTSTRAP_DAEMON_REQUEST, other::SET_BOOTSTRAP_DAEMON_REQUEST,
Some(SetBootstrapDaemonRequest { Some(SetBootstrapDaemonRequest {
@ -992,7 +991,7 @@ mod test {
} }
#[test] #[test]
fn SET_BOOTSTRAP_DAEMON_RESPONSE() { fn set_bootstrap_daemon_response() {
test_json( test_json(
other::SET_BOOTSTRAP_DAEMON_RESPONSE, other::SET_BOOTSTRAP_DAEMON_RESPONSE,
Some(SetBootstrapDaemonResponse { status: Status::Ok }), Some(SetBootstrapDaemonResponse { status: Status::Ok }),
@ -1000,7 +999,7 @@ mod test {
} }
#[test] #[test]
fn GET_TRANSACTION_POOL_STATS_RESPONSE() { fn get_transaction_pool_stats_response() {
test_json( test_json(
other::GET_TRANSACTION_POOL_STATS_RESPONSE, other::GET_TRANSACTION_POOL_STATS_RESPONSE,
Some(GetTransactionPoolStatsResponse { Some(GetTransactionPoolStatsResponse {
@ -1066,7 +1065,7 @@ mod test {
} }
#[test] #[test]
fn STOP_DAEMON_RESPONSE() { fn stop_daemon_response() {
test_json( test_json(
other::STOP_DAEMON_RESPONSE, other::STOP_DAEMON_RESPONSE,
Some(StopDaemonResponse { status: Status::Ok }), Some(StopDaemonResponse { status: Status::Ok }),
@ -1074,7 +1073,7 @@ mod test {
} }
#[test] #[test]
fn GET_LIMIT_RESPONSE() { fn get_limit_response() {
test_json( test_json(
other::GET_LIMIT_RESPONSE, other::GET_LIMIT_RESPONSE,
Some(GetLimitResponse { Some(GetLimitResponse {
@ -1086,7 +1085,7 @@ mod test {
} }
#[test] #[test]
fn SET_LIMIT_REQUEST() { fn set_limit_request() {
test_json( test_json(
other::SET_LIMIT_REQUEST, other::SET_LIMIT_REQUEST,
Some(SetLimitRequest { Some(SetLimitRequest {
@ -1097,7 +1096,7 @@ mod test {
} }
#[test] #[test]
fn SET_LIMIT_RESPONSE() { fn set_limit_response() {
test_json( test_json(
other::SET_LIMIT_RESPONSE, other::SET_LIMIT_RESPONSE,
Some(SetLimitResponse { Some(SetLimitResponse {
@ -1109,7 +1108,7 @@ mod test {
} }
#[test] #[test]
fn OUT_PEERS_REQUEST() { fn out_peers_request() {
test_json( test_json(
other::OUT_PEERS_REQUEST, other::OUT_PEERS_REQUEST,
Some(OutPeersRequest { Some(OutPeersRequest {
@ -1120,7 +1119,7 @@ mod test {
} }
#[test] #[test]
fn OUT_PEERS_RESPONSE() { fn out_peers_response() {
test_json( test_json(
other::OUT_PEERS_RESPONSE, other::OUT_PEERS_RESPONSE,
Some(OutPeersResponse { Some(OutPeersResponse {
@ -1131,7 +1130,7 @@ mod test {
} }
#[test] #[test]
fn GET_NET_STATS_RESPONSE() { fn get_net_stats_response() {
test_json( test_json(
other::GET_NET_STATS_RESPONSE, other::GET_NET_STATS_RESPONSE,
Some(GetNetStatsResponse { Some(GetNetStatsResponse {
@ -1146,7 +1145,7 @@ mod test {
} }
#[test] #[test]
fn GET_OUTS_REQUEST() { fn get_outs_request() {
test_json( test_json(
other::GET_OUTS_REQUEST, other::GET_OUTS_REQUEST,
Some(GetOutsRequest { Some(GetOutsRequest {
@ -1166,7 +1165,7 @@ mod test {
} }
#[test] #[test]
fn GET_OUTS_RESPONSE() { fn get_outs_response() {
test_json( test_json(
other::GET_OUTS_RESPONSE, other::GET_OUTS_RESPONSE,
Some(GetOutsResponse { Some(GetOutsResponse {
@ -1174,22 +1173,28 @@ mod test {
outs: vec![ outs: vec![
OutKey { OutKey {
height: 51941, height: 51941,
key: "08980d939ec297dd597119f498ad69fed9ca55e3a68f29f2782aae887ef0cf8e" key: Hex(hex!(
.into(), "08980d939ec297dd597119f498ad69fed9ca55e3a68f29f2782aae887ef0cf8e"
mask: "1738eb7a677c6149228a2beaa21bea9e3370802d72a3eec790119580e02bd522" )),
.into(), mask: Hex(hex!(
txid: "9d651903b80fb70b9935b72081cd967f543662149aed3839222511acd9100601" "1738eb7a677c6149228a2beaa21bea9e3370802d72a3eec790119580e02bd522"
.into(), )),
txid: Hex(hex!(
"9d651903b80fb70b9935b72081cd967f543662149aed3839222511acd9100601"
)),
unlocked: true, unlocked: true,
}, },
OutKey { OutKey {
height: 51945, height: 51945,
key: "454fe46c405be77625fa7e3389a04d3be392346983f27603561ac3a3a74f4a75" key: Hex(hex!(
.into(), "454fe46c405be77625fa7e3389a04d3be392346983f27603561ac3a3a74f4a75"
mask: "1738eb7a677c6149228a2beaa21bea9e3370802d72a3eec790119580e02bd522" )),
.into(), mask: Hex(hex!(
txid: "230bff732dc5f225df14fff82aadd1bf11b3fb7ad3a03413c396a617e843f7d0" "1738eb7a677c6149228a2beaa21bea9e3370802d72a3eec790119580e02bd522"
.into(), )),
txid: Hex(hex!(
"230bff732dc5f225df14fff82aadd1bf11b3fb7ad3a03413c396a617e843f7d0"
)),
unlocked: true, unlocked: true,
}, },
], ],
@ -1198,7 +1203,7 @@ mod test {
} }
#[test] #[test]
fn UPDATE_REQUEST() { fn update_request() {
test_json( test_json(
other::UPDATE_REQUEST, other::UPDATE_REQUEST,
Some(UpdateRequest { Some(UpdateRequest {
@ -1209,7 +1214,7 @@ mod test {
} }
#[test] #[test]
fn UPDATE_RESPONSE() { fn update_response() {
test_json( test_json(
other::UPDATE_RESPONSE, other::UPDATE_RESPONSE,
Some(UpdateResponse { Some(UpdateResponse {
@ -1225,7 +1230,7 @@ mod test {
} }
#[test] #[test]
fn POP_BLOCKS_REQUEST() { fn pop_blocks_request() {
test_json( test_json(
other::POP_BLOCKS_REQUEST, other::POP_BLOCKS_REQUEST,
Some(PopBlocksRequest { nblocks: 6 }), Some(PopBlocksRequest { nblocks: 6 }),
@ -1233,7 +1238,7 @@ mod test {
} }
#[test] #[test]
fn POP_BLOCKS_RESPONSE() { fn pop_blocks_response() {
test_json( test_json(
other::POP_BLOCKS_RESPONSE, other::POP_BLOCKS_RESPONSE,
Some(PopBlocksResponse { Some(PopBlocksResponse {
@ -1244,7 +1249,7 @@ mod test {
} }
#[test] #[test]
fn GET_TRANSACTION_POOL_HASHES_RESPONSE() { fn get_transaction_pool_hashes_response() {
test_json( test_json(
other::GET_TRANSACTION_POOL_HASHES_RESPONSE, other::GET_TRANSACTION_POOL_HASHES_RESPONSE,
Some(GetTransactionPoolHashesResponse { Some(GetTransactionPoolHashesResponse {
@ -1274,7 +1279,7 @@ mod test {
} }
#[test] #[test]
fn GET_PUBLIC_NODES_REQUEST() { fn get_public_nodes_request() {
test_json( test_json(
other::GET_PUBLIC_NODES_REQUEST, other::GET_PUBLIC_NODES_REQUEST,
Some(GetPublicNodesRequest { Some(GetPublicNodesRequest {
@ -1286,7 +1291,7 @@ mod test {
} }
#[test] #[test]
fn GET_PUBLIC_NODES_RESPONSE() { fn get_publics_nodes_response() {
test_json( test_json(
other::GET_PUBLIC_NODES_RESPONSE, other::GET_PUBLIC_NODES_RESPONSE,
Some(GetPublicNodesResponse { Some(GetPublicNodesResponse {

23
types/hex/Cargo.toml Normal file
View file

@ -0,0 +1,23 @@
[package]
name = "cuprate-hex"
version = "0.0.0"
edition = "2021"
description = "Cuprate's hexadecimal data types"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/types"
keywords = ["cuprate", "hex"]
[features]
default = ["serde"]
serde = ["dep:serde", "hex/serde"]
[dependencies]
hex = { workspace = true, features = ["alloc"] }
serde = { workspace = true, features = ["std", "derive"], optional = true }
[dev-dependencies]
serde_json = { workspace = true, features = ["std"] }
[lints]
workspace = true

7
types/hex/README.md Normal file
View file

@ -0,0 +1,7 @@
# `cuprate-hex`
Cuprate's hexadecimal data types.
# Features flags
| Feature flag | Does what |
|--------------|-----------|
| `serde` | Enables `serde` on types where applicable

View file

@ -3,13 +3,24 @@
//! This module provides transparent wrapper types for //! This module provides transparent wrapper types for
//! arrays that (de)serialize from hexadecimal input/output. //! arrays that (de)serialize from hexadecimal input/output.
#[cfg(feature = "epee")]
use cuprate_epee_encoding::{error, macros::bytes, EpeeValue, Marker};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Wrapper type for a byte array that (de)serializes from/to hexadecimal strings. /// Wrapper type for a byte array that (de)serializes from/to hexadecimal strings.
/// ///
/// ```rust
/// # use cuprate_types::hex::Hex;
/// let hash = [1; 32];
/// let hex_bytes = Hex::<32>(hash);
/// let expected_json = r#""0101010101010101010101010101010101010101010101010101010101010101""#;
///
/// let to_string = serde_json::to_string(&hex_bytes).unwrap();
/// assert_eq!(to_string, expected_json);
///
/// let from_str = serde_json::from_str::<Hex<32>>(expected_json).unwrap();
/// assert_eq!(hex_bytes, from_str);
/// ```
///
/// # Deserialization /// # Deserialization
/// This struct has a custom deserialization that only applies to certain /// This struct has a custom deserialization that only applies to certain
/// `N` lengths because [`hex::FromHex`] does not implement for a generic `N`: /// `N` lengths because [`hex::FromHex`] does not implement for a generic `N`:
@ -36,19 +47,6 @@ where
} }
} }
#[cfg(feature = "epee")]
impl<const N: usize> EpeeValue for Hex<N> {
const MARKER: Marker = <[u8; N] as EpeeValue>::MARKER;
fn read<B: bytes::Buf>(r: &mut B, marker: &Marker) -> error::Result<Self> {
Ok(Self(<[u8; N] as EpeeValue>::read(r, marker)?))
}
fn write<B: bytes::BufMut>(self, w: &mut B) -> error::Result<()> {
<[u8; N] as EpeeValue>::write(self.0, w)
}
}
// Default is not implemented for arrays >32, so we must do it manually. // Default is not implemented for arrays >32, so we must do it manually.
impl<const N: usize> Default for Hex<N> { impl<const N: usize> Default for Hex<N> {
fn default() -> Self { fn default() -> Self {
@ -92,10 +90,10 @@ mod test {
use super::*; use super::*;
#[test] #[test]
fn hex_bytes_32() { fn asdf() {
let hash = [1; 32]; let hash = [0; 32];
let hex_bytes = Hex::<32>(hash); let hex_bytes = Hex::<32>(hash);
let expected_json = r#""0101010101010101010101010101010101010101010101010101010101010101""#; let expected_json = r#""0000000000000000000000000000000000000000000000000000000000000000""#;
let to_string = serde_json::to_string(&hex_bytes).unwrap(); let to_string = serde_json::to_string(&hex_bytes).unwrap();
assert_eq!(to_string, expected_json); assert_eq!(to_string, expected_json);

7
types/hex/src/lib.rs Normal file
View file

@ -0,0 +1,7 @@
#![doc = include_str!("../README.md")]
// Allow some lints when running in debug mode.
#![cfg_attr(debug_assertions, allow(clippy::todo, clippy::multiple_crate_versions))]
mod hex;
pub use hex::Hex;

View file

@ -9,27 +9,24 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/types"
keywords = ["cuprate", "types"] keywords = ["cuprate", "types"]
[features] [features]
default = ["blockchain", "epee", "serde", "json", "hex", "rpc"] default = ["blockchain", "epee", "serde", "json", "rpc"]
blockchain = ["rpc"] blockchain = ["rpc"]
epee = ["dep:cuprate-epee-encoding"] epee = ["dep:cuprate-epee-encoding"]
serde = ["dep:serde", "hex"] serde = ["dep:serde"]
proptest = ["dep:proptest", "dep:proptest-derive"] proptest = ["dep:proptest", "dep:proptest-derive"]
json = ["hex", "dep:cuprate-helper"] json = ["dep:cuprate-hex", "dep:cuprate-helper"]
# We sadly have no choice but to enable serde here as otherwise we will get warnings from the `hex` dep being unused. rpc = ["dep:cuprate-hex", "json"]
# This isn't too bad as `Hex` only makes sense with serde anyway.
hex = ["serde", "dep:hex"]
rpc = ["hex", "json"]
[dependencies] [dependencies]
cuprate-epee-encoding = { workspace = true, optional = true, features = ["std"] } cuprate-epee-encoding = { workspace = true, optional = true, features = ["std"] }
cuprate-helper = { workspace = true, optional = true, features = ["cast"] } cuprate-helper = { workspace = true, optional = true, features = ["cast"] }
cuprate-fixed-bytes = { workspace = true, features = ["std", "serde"] } cuprate-fixed-bytes = { workspace = true, features = ["std", "serde"] }
cuprate-hex = { workspace = true, optional = true, features = ["serde"] }
bytes = { workspace = true } bytes = { workspace = true }
cfg-if = { workspace = true } cfg-if = { workspace = true }
curve25519-dalek = { workspace = true } curve25519-dalek = { workspace = true }
monero-serai = { workspace = true } monero-serai = { workspace = true }
hex = { workspace = true, features = ["serde", "alloc"], optional = true }
serde = { workspace = true, features = ["std", "derive"], optional = true } serde = { workspace = true, features = ["std", "derive"], optional = true }
strum = { workspace = true, features = ["derive"] } strum = { workspace = true, features = ["derive"] }
thiserror = { workspace = true } thiserror = { workspace = true }

View file

@ -11,4 +11,3 @@ This crate is a kitchen-sink for data types that are shared across Cuprate.
| `epee` | Enables `cuprate-epee-encoding` on types where applicable | `epee` | Enables `cuprate-epee-encoding` on types where applicable
| `proptest` | Enables `proptest::arbitrary::Arbitrary` on some types | `proptest` | Enables `proptest::arbitrary::Arbitrary` on some types
| `json` | Enables the `json` module, containing JSON representations of common Monero types | `json` | Enables the `json` module, containing JSON representations of common Monero types
| `hex` | Enables the `hex` module, containing the `HexBytes` type

View file

@ -6,11 +6,9 @@ use serde::{Deserialize, Serialize};
use monero_serai::{block, transaction}; use monero_serai::{block, transaction};
use cuprate_helper::cast::usize_to_u64; use cuprate_helper::cast::usize_to_u64;
use cuprate_hex::Hex;
use crate::{ use crate::json::output::{Output, TaggedKey, Target};
hex::Hex,
json::output::{Output, TaggedKey, Target},
};
/// JSON representation of a block. /// JSON representation of a block.
/// ///

View file

@ -7,7 +7,7 @@
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::hex::Hex; use cuprate_hex::Hex;
/// JSON representation of an output. /// JSON representation of an output.
#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]

View file

@ -16,13 +16,11 @@ use cuprate_epee_encoding::{
}; };
use cuprate_helper::cast::usize_to_u64; use cuprate_helper::cast::usize_to_u64;
use cuprate_hex::Hex;
use monero_serai::{ringct, transaction}; use monero_serai::{ringct, transaction};
use crate::{ use crate::json::output::{Output, TaggedKey, Target};
hex::Hex,
json::output::{Output, TaggedKey, Target},
};
/// JSON representation of a non-miner transaction. /// JSON representation of a non-miner transaction.
/// ///

View file

@ -35,9 +35,6 @@ pub mod blockchain;
#[cfg(feature = "json")] #[cfg(feature = "json")]
pub mod json; pub mod json;
#[cfg(feature = "hex")]
pub mod hex;
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(feature = "rpc")] { if #[cfg(feature = "rpc")] {
pub mod rpc; pub mod rpc;

View file

@ -1,8 +1,9 @@
//! Various types (in)directly used in RPC. //! Various types (in)directly used in RPC.
use cuprate_fixed_bytes::ByteArrayVec; use cuprate_fixed_bytes::ByteArrayVec;
use cuprate_hex::Hex;
use crate::{hex::Hex, AddressType, ConnectionState, HardFork}; use crate::{AddressType, ConnectionState, HardFork};
const fn default_string() -> String { const fn default_string() -> String {
String::new() String::new()

View file

@ -10,7 +10,7 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/zmq/types"
[dependencies] [dependencies]
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
hex = { workspace = true, features = ["std", "serde"] } hex = { workspace = true, features = ["std", "serde"] }
cuprate-types = { workspace = true, features = ["hex"] } cuprate-hex = { workspace = true, features = ["serde"] }
[dev-dependencies] [dev-dependencies]
serde_json = { workspace = true, features = ["std"] } serde_json = { workspace = true, features = ["std"] }

View file

@ -8,7 +8,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use cuprate_types::hex::Hex; use cuprate_hex::Hex;
/// ZMQ `json-full-txpool_add` packets contain an array of `TxPoolAdd`. /// ZMQ `json-full-txpool_add` packets contain an array of `TxPoolAdd`.
/// ///