mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-23 03:59:37 +00:00
Compare commits
No commits in common. "bf5e863f1817776a2b70d6fb3833294d6b8c8848" and "d1c1025238abdf23abccbdab5559a332d862ed42" have entirely different histories.
bf5e863f18
...
d1c1025238
42 changed files with 928 additions and 1183 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -886,7 +886,6 @@ dependencies = [
|
|||
"bytes",
|
||||
"cuprate-fixed-bytes",
|
||||
"cuprate-helper",
|
||||
"cuprate-hex",
|
||||
"hex",
|
||||
"paste",
|
||||
"ref-cast",
|
||||
|
@ -941,15 +940,6 @@ dependencies = [
|
|||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cuprate-hex"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cuprate-json-rpc"
|
||||
version = "0.0.0"
|
||||
|
@ -1078,7 +1068,6 @@ dependencies = [
|
|||
"cuprate-epee-encoding",
|
||||
"cuprate-fixed-bytes",
|
||||
"cuprate-helper",
|
||||
"cuprate-hex",
|
||||
"cuprate-p2p-core",
|
||||
"cuprate-test-utils",
|
||||
"cuprate-types",
|
||||
|
@ -1147,8 +1136,8 @@ dependencies = [
|
|||
"cuprate-epee-encoding",
|
||||
"cuprate-fixed-bytes",
|
||||
"cuprate-helper",
|
||||
"cuprate-hex",
|
||||
"curve25519-dalek",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
"monero-serai",
|
||||
"pretty_assertions",
|
||||
|
@ -1180,7 +1169,7 @@ name = "cuprate-zmq-types"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"assert-json-diff",
|
||||
"cuprate-hex",
|
||||
"cuprate-types",
|
||||
"hex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -1217,7 +1206,6 @@ dependencies = [
|
|||
"cuprate-fast-sync",
|
||||
"cuprate-fixed-bytes",
|
||||
"cuprate-helper",
|
||||
"cuprate-hex",
|
||||
"cuprate-json-rpc",
|
||||
"cuprate-levin",
|
||||
"cuprate-p2p",
|
||||
|
|
18
Cargo.toml
18
Cargo.toml
|
@ -19,6 +19,7 @@ members = [
|
|||
|
||||
# Net
|
||||
"net/epee-encoding",
|
||||
"net/fixed-bytes",
|
||||
"net/levin",
|
||||
"net/wire",
|
||||
|
||||
|
@ -27,8 +28,8 @@ members = [
|
|||
"p2p/p2p-core",
|
||||
"p2p/bucket",
|
||||
"p2p/dandelion-tower",
|
||||
"p2p/address-book",
|
||||
"p2p/async-buffer",
|
||||
"p2p/address-book",
|
||||
|
||||
# Storage
|
||||
"storage/blockchain",
|
||||
|
@ -36,11 +37,6 @@ members = [
|
|||
"storage/txpool",
|
||||
"storage/database",
|
||||
|
||||
# Types
|
||||
"types/types",
|
||||
"types/hex",
|
||||
"types/fixed-bytes",
|
||||
|
||||
# RPC
|
||||
"rpc/json-rpc",
|
||||
"rpc/types",
|
||||
|
@ -55,10 +51,11 @@ members = [
|
|||
"helper",
|
||||
"pruning",
|
||||
"test-utils",
|
||||
"types",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
panic = "abort"
|
||||
lto = true # Build with LTO
|
||||
strip = "none" # Keep panic stack traces
|
||||
codegen-units = 1 # Optimize for binary speed over compile times
|
||||
|
@ -88,13 +85,14 @@ cuprate-consensus-context = { path = "consensus/context", default-featur
|
|||
cuprate-cryptonight = { path = "cryptonight", default-features = false }
|
||||
cuprate-helper = { path = "helper", 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-wire = { path = "net/wire", default-features = false }
|
||||
cuprate-async-buffer = { path = "p2p/async-buffer", default-features = false }
|
||||
cuprate-p2p = { path = "p2p/p2p", default-features = false }
|
||||
cuprate-p2p-core = { path = "p2p/p2p-core", default-features = false }
|
||||
cuprate-p2p-bucket = { path = "p2p/p2p-bucket", 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-blockchain = { path = "storage/blockchain", default-features = false }
|
||||
cuprate-database = { path = "storage/database", default-features = false }
|
||||
|
@ -102,9 +100,7 @@ cuprate-database-service = { path = "storage/service", default-featur
|
|||
cuprate-txpool = { path = "storage/txpool", default-features = false }
|
||||
cuprate-pruning = { path = "pruning", default-features = false }
|
||||
cuprate-test-utils = { path = "test-utils", 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-types = { path = "types", default-features = false }
|
||||
cuprate-json-rpc = { path = "rpc/json-rpc", default-features = false }
|
||||
cuprate-rpc-types = { path = "rpc/types", default-features = false }
|
||||
cuprate-rpc-interface = { path = "rpc/interface", default-features = false }
|
||||
|
|
|
@ -32,7 +32,6 @@ cuprate-database = { workspace = true, features = ["serde"] }
|
|||
cuprate-pruning = { workspace = true }
|
||||
cuprate-test-utils = { workspace = true }
|
||||
cuprate-types = { workspace = true, features = ["json"] }
|
||||
cuprate-hex = { workspace = true }
|
||||
cuprate-json-rpc = { workspace = true }
|
||||
cuprate-rpc-interface = { workspace = true }
|
||||
cuprate-rpc-types = { workspace = true, features = ["from"] }
|
||||
|
|
|
@ -66,7 +66,7 @@ pub enum BlockchainManagerRequest {
|
|||
/// Number of the blocks to be generated.
|
||||
amount_of_blocks: u64,
|
||||
/// The previous block's hash.
|
||||
prev_block: Option<[u8; 32]>,
|
||||
prev_block: [u8; 32],
|
||||
/// The starting value for the nonce.
|
||||
starting_nonce: u32,
|
||||
/// The address that will receive the coinbase reward.
|
||||
|
|
|
@ -22,7 +22,6 @@ use cuprate_helper::{
|
|||
cast::{u32_to_usize, u64_to_usize, usize_to_u64},
|
||||
map::split_u128_into_low_high_bits,
|
||||
};
|
||||
use cuprate_hex::Hex;
|
||||
use cuprate_p2p_core::{client::handshaker::builder::DummyAddressBook, ClearNet, Network};
|
||||
use cuprate_rpc_interface::RpcHandler;
|
||||
use cuprate_rpc_types::{
|
||||
|
@ -52,6 +51,7 @@ use cuprate_rpc_types::{
|
|||
CORE_RPC_VERSION,
|
||||
};
|
||||
use cuprate_types::{
|
||||
hex::Hex,
|
||||
rpc::{AuxPow, CoinbaseTxSum, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry},
|
||||
HardFork,
|
||||
};
|
||||
|
@ -260,7 +260,7 @@ async fn submit_block(
|
|||
let [blob] = request.block_blob;
|
||||
let bytes = hex::decode(blob)?;
|
||||
let block = Block::read(&mut bytes.as_slice())?;
|
||||
let block_id = Hex(block.hash());
|
||||
let block_id = hex::encode(block.hash());
|
||||
|
||||
// Attempt to relay the block.
|
||||
blockchain_manager::relay_block(&mut state.blockchain_manager, Box::new(block)).await?;
|
||||
|
@ -283,11 +283,7 @@ async fn generate_blocks(
|
|||
// FIXME:
|
||||
// is this field only used as a local variable in the handler in `monerod`?
|
||||
// It may not be needed in the request type.
|
||||
let prev_block = if request.prev_block.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(helper::hex_to_hash(request.prev_block)?)
|
||||
};
|
||||
let prev_block = helper::hex_to_hash(request.prev_block)?;
|
||||
|
||||
let (blocks, height) = blockchain_manager::generate_blocks(
|
||||
&mut state.blockchain_manager,
|
||||
|
@ -298,7 +294,7 @@ async fn generate_blocks(
|
|||
)
|
||||
.await?;
|
||||
|
||||
let blocks = blocks.into_iter().map(Hex).collect();
|
||||
let blocks = blocks.into_iter().map(hex::encode).collect();
|
||||
|
||||
Ok(GenerateBlocksResponse {
|
||||
base: ResponseBase::OK,
|
||||
|
@ -346,7 +342,8 @@ async fn get_block_header_by_hash(
|
|||
// FIXME PERF: could make a `Vec` on await on all tasks at the same time.
|
||||
let mut block_headers = Vec::with_capacity(request.hashes.len());
|
||||
for hash in request.hashes {
|
||||
let hash = get(&mut state, hash.0, request.fill_pow_hash).await?;
|
||||
let hash = helper::hex_to_hash(hash)?;
|
||||
let hash = get(&mut state, hash, request.fill_pow_hash).await?;
|
||||
block_headers.push(hash);
|
||||
}
|
||||
|
||||
|
@ -447,8 +444,8 @@ async fn get_block(
|
|||
};
|
||||
|
||||
let blob = hex::encode(block.serialize());
|
||||
let miner_tx_hash = Hex(block.miner_transaction.hash());
|
||||
let tx_hashes = block.transactions.iter().map(|a| Hex(*a)).collect();
|
||||
let miner_tx_hash = hex::encode(block.miner_transaction.hash());
|
||||
let tx_hashes = block.transactions.iter().map(hex::encode).collect();
|
||||
let json = {
|
||||
let block = cuprate_types::json::block::Block::from(block);
|
||||
serde_json::to_string_pretty(&block)?
|
||||
|
@ -548,7 +545,7 @@ async fn get_info(
|
|||
let target = blockchain_manager::target(&mut state.blockchain_manager)
|
||||
.await?
|
||||
.as_secs();
|
||||
let top_block_hash = Hex(c.top_hash);
|
||||
let top_block_hash = hex::encode(c.top_hash);
|
||||
let tx_count = blockchain::total_tx_count(&mut state.blockchain_read).await?;
|
||||
let tx_pool_size = txpool::size(&mut state.txpool_read, !restricted).await?;
|
||||
let update_available = if restricted {
|
||||
|
@ -757,8 +754,8 @@ async fn flush_transaction_pool(
|
|||
let tx_hashes = request
|
||||
.txids
|
||||
.into_iter()
|
||||
.map(|h| h.0)
|
||||
.collect::<Vec<[u8; 32]>>();
|
||||
.map(helper::hex_to_hash)
|
||||
.collect::<Result<Vec<[u8; 32]>, _>>()?;
|
||||
|
||||
txpool::flush(&mut state.txpool_manager, tx_hashes).await?;
|
||||
|
||||
|
@ -899,8 +896,8 @@ async fn relay_tx(
|
|||
let tx_hashes = request
|
||||
.txids
|
||||
.into_iter()
|
||||
.map(|h| h.0)
|
||||
.collect::<Vec<[u8; 32]>>();
|
||||
.map(helper::hex_to_hash)
|
||||
.collect::<Result<Vec<[u8; 32]>, _>>()?;
|
||||
|
||||
txpool::relay(&mut state.txpool_manager, tx_hashes).await?;
|
||||
|
||||
|
@ -1012,8 +1009,8 @@ async fn get_miner_data(
|
|||
|
||||
let major_version = c.current_hf.as_u8();
|
||||
let height = usize_to_u64(c.chain_height);
|
||||
let prev_id = Hex(c.top_hash);
|
||||
let seed_hash = Hex(c.top_hash);
|
||||
let prev_id = hex::encode(c.top_hash);
|
||||
let seed_hash = hex::encode(c.top_hash);
|
||||
let difficulty = format!("{:#x}", c.next_difficulty);
|
||||
let median_weight = usize_to_u64(c.median_weight_for_block_reward);
|
||||
let already_generated_coins = c.already_generated_coins;
|
||||
|
@ -1021,7 +1018,7 @@ async fn get_miner_data(
|
|||
.await?
|
||||
.into_iter()
|
||||
.map(|entry| GetMinerDataTxBacklogEntry {
|
||||
id: Hex(entry.id),
|
||||
id: hex::encode(entry.id),
|
||||
weight: entry.weight,
|
||||
fee: entry.fee,
|
||||
})
|
||||
|
@ -1065,7 +1062,7 @@ async fn calc_pow(
|
|||
let hardfork = HardFork::from_version(request.major_version)?;
|
||||
let block_blob: Vec<u8> = hex::decode(request.block_blob)?;
|
||||
let block = Block::read(&mut block_blob.as_slice())?;
|
||||
let seed_hash = request.seed_hash.0;
|
||||
let seed_hash = helper::hex_to_hash(request.seed_hash)?;
|
||||
|
||||
// let block_weight = todo!();
|
||||
|
||||
|
@ -1090,9 +1087,9 @@ async fn calc_pow(
|
|||
)
|
||||
.await?;
|
||||
|
||||
Ok(CalcPowResponse {
|
||||
pow_hash: Hex(pow_hash),
|
||||
})
|
||||
let pow_hash = hex::encode(pow_hash);
|
||||
|
||||
Ok(CalcPowResponse { pow_hash })
|
||||
}
|
||||
|
||||
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L3542-L3551>
|
||||
|
|
|
@ -149,7 +149,7 @@ pub(crate) async fn target_height(
|
|||
pub(crate) async fn generate_blocks(
|
||||
blockchain_manager: &mut BlockchainManagerHandle,
|
||||
amount_of_blocks: u64,
|
||||
prev_block: Option<[u8; 32]>,
|
||||
prev_block: [u8; 32],
|
||||
starting_nonce: u32,
|
||||
wallet_address: String,
|
||||
) -> Result<(Vec<[u8; 32]>, u64), Error> {
|
||||
|
|
|
@ -24,6 +24,7 @@ cargo doc --open --package cuprate-blockchain
|
|||
| Crate | In-tree path | Purpose |
|
||||
|-------|--------------|---------|
|
||||
| [`cuprate-epee-encoding`](https://doc.cuprate.org/cuprate_epee_encoding) | [`net/epee-encoding/`](https://github.com/Cuprate/cuprate/tree/main/net/epee-encoding) | Epee (de)serialization
|
||||
| [`cuprate-fixed-bytes`](https://doc.cuprate.org/cuprate_fixed_bytes) | [`net/fixed-bytes/`](https://github.com/Cuprate/cuprate/tree/main/net/fixed-bytes) | Fixed byte containers backed by `byte::Byte`
|
||||
| [`cuprate-levin`](https://doc.cuprate.org/cuprate_levin) | [`net/levin/`](https://github.com/Cuprate/cuprate/tree/main/net/levin) | Levin bucket protocol implementation
|
||||
| [`cuprate-wire`](https://doc.cuprate.org/cuprate_wire) | [`net/wire/`](https://github.com/Cuprate/cuprate/tree/main/net/wire) | TODO
|
||||
|
||||
|
@ -45,13 +46,6 @@ cargo doc --open --package cuprate-blockchain
|
|||
| [`cuprate-database-service`](https://doc.cuprate.org/cuprate_database_service) | [`storage/database-service/`](https://github.com/Cuprate/cuprate/tree/main/storage/database-service) | `tower::Service` + thread-pool abstraction built on-top of `cuprate-database`
|
||||
| [`cuprate-txpool`](https://doc.cuprate.org/cuprate_txpool) | [`storage/txpool/`](https://github.com/Cuprate/cuprate/tree/main/storage/txpool) | Transaction pool database built on-top of `cuprate-database` & `cuprate-database-service`
|
||||
|
||||
## Types
|
||||
| Crate | In-tree path | Purpose |
|
||||
|-------|--------------|---------|
|
||||
| [`cuprate-types`](https://doc.cuprate.org/cuprate_types) | [`types/types/`](https://github.com/Cuprate/cuprate/tree/main/types/types) | General types used throughout Cuprate |
|
||||
| [`cuprate-hex`](https://doc.cuprate.org/cuprate_hex) | [`types/hex/`](https://github.com/Cuprate/cuprate/tree/main/types/hex) | Hexadecimal data types |
|
||||
| [`cuprate-fixed-bytes`](https://doc.cuprate.org/cuprate_fixed_bytes) | [`types/fixed-bytes/`](https://github.com/Cuprate/cuprate/tree/main/net/fixed-bytes) | Fixed byte containers backed by `byte::Byte`
|
||||
|
||||
## RPC
|
||||
| Crate | In-tree path | Purpose |
|
||||
|-------|--------------|---------|
|
||||
|
@ -73,6 +67,7 @@ cargo doc --open --package cuprate-blockchain
|
|||
| [`cuprate-pruning`](https://doc.cuprate.org/cuprate_pruning) | [`pruning/`](https://github.com/Cuprate/cuprate/tree/main/pruning) | Monero pruning logic/types
|
||||
| [`cuprate-helper`](https://doc.cuprate.org/cuprate_helper) | [`helper/`](https://github.com/Cuprate/cuprate/tree/main/helper) | Kitchen-sink helper crate for Cuprate
|
||||
| [`cuprate-test-utils`](https://doc.cuprate.org/cuprate_test_utils) | [`test-utils/`](https://github.com/Cuprate/cuprate/tree/main/test-utils) | Testing utilities for Cuprate
|
||||
| [`cuprate-types`](https://doc.cuprate.org/cuprate_types) | [`types/`](https://github.com/Cuprate/cuprate/tree/main/types) | Shared types across Cuprate
|
||||
|
||||
## Benchmarks
|
||||
| Crate | In-tree path | Purpose |
|
||||
|
|
|
@ -17,7 +17,6 @@ std = ["dep:thiserror", "bytes/std", "cuprate-fixed-bytes/std"]
|
|||
[dependencies]
|
||||
cuprate-helper = { workspace = true, default-features = false, features = ["cast"] }
|
||||
cuprate-fixed-bytes = { workspace = true, default-features = false }
|
||||
cuprate-hex = { workspace = true, default-features = false }
|
||||
|
||||
paste = "1.0.15"
|
||||
ref-cast = "1.0.23"
|
||||
|
|
|
@ -8,7 +8,6 @@ use bytes::{Buf, BufMut, Bytes, BytesMut};
|
|||
|
||||
use cuprate_fixed_bytes::{ByteArray, ByteArrayVec};
|
||||
use cuprate_helper::cast::u64_to_usize;
|
||||
use cuprate_hex::Hex;
|
||||
|
||||
use crate::{
|
||||
io::{checked_read_primitive, checked_write_primitive},
|
||||
|
@ -402,41 +401,6 @@ 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 {
|
||||
($val:ty) => {
|
||||
impl EpeeValue for Vec<$val> {
|
||||
|
|
|
@ -22,16 +22,15 @@ from = [
|
|||
]
|
||||
|
||||
[dependencies]
|
||||
cuprate-fixed-bytes = { workspace = true }
|
||||
cuprate-hex = { workspace = true }
|
||||
cuprate-epee-encoding = { workspace = true, optional = true }
|
||||
cuprate-fixed-bytes = { workspace = true }
|
||||
cuprate-types = { workspace = true, default-features = false }
|
||||
cuprate-helper = { workspace = true, optional = true, default-features = false }
|
||||
cuprate-p2p-core = { workspace = true, optional = true, default-features = false }
|
||||
|
||||
paste = { workspace = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
hex = { workspace = true, optional = true }
|
||||
paste = { workspace = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
hex = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
cuprate-test-utils = { workspace = true }
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
//! `height`, it will use [`default_height`] to fill that in.
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
// use cuprate_types::hex::Hex;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- TODO
|
||||
/// Default [`bool`] type used in request/response types, `false`.
|
||||
|
@ -28,6 +29,12 @@ pub(crate) const fn default_string() -> String {
|
|||
String::new()
|
||||
}
|
||||
|
||||
// /// Default [`Hex`] type used in request/response types.
|
||||
// #[inline]
|
||||
// pub(crate) const fn default_hex<const N: usize>() -> Hex<N> {
|
||||
// Hex([0; N])
|
||||
// }
|
||||
|
||||
/// Default block height used in request/response types.
|
||||
#[inline]
|
||||
pub(crate) const fn default_height() -> u64 {
|
||||
|
|
|
@ -8,12 +8,14 @@ use std::{
|
|||
};
|
||||
|
||||
use cuprate_helper::{fmt::hex_prefix_u128, map::ipv4_from_u32};
|
||||
use cuprate_hex::Hex;
|
||||
use cuprate_p2p_core::{
|
||||
types::{ConnectionId, ConnectionInfo, SetBan, Span},
|
||||
NetZoneAddress,
|
||||
};
|
||||
use cuprate_types::rpc::{BlockHeader, ChainInfo, HistogramEntry, TxInfo};
|
||||
use cuprate_types::{
|
||||
hex::Hex,
|
||||
rpc::{BlockHeader, ChainInfo, HistogramEntry, TxInfo},
|
||||
};
|
||||
|
||||
impl From<BlockHeader> for crate::misc::BlockHeader {
|
||||
fn from(x: BlockHeader) -> Self {
|
||||
|
@ -126,7 +128,7 @@ impl From<ChainInfo> for crate::misc::ChainInfo {
|
|||
fn from(x: ChainInfo) -> Self {
|
||||
Self {
|
||||
block_hash: Hex(x.block_hash),
|
||||
block_hashes: x.block_hashes.into_iter().map(Hex).collect(),
|
||||
block_hashes: x.block_hashes.into_iter().map(hex::encode).collect(),
|
||||
difficulty_top64: x.difficulty_top64,
|
||||
difficulty: x.difficulty,
|
||||
height: x.height,
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use cuprate_hex::Hex;
|
||||
use cuprate_types::rpc::{AuxPow, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry};
|
||||
use cuprate_types::{
|
||||
hex::Hex,
|
||||
rpc::{AuxPow, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
base::{AccessResponseBase, ResponseBase},
|
||||
|
@ -55,6 +57,11 @@ define_request_and_response! {
|
|||
|
||||
// The request type.
|
||||
//
|
||||
// If `Request {/* fields */}` is provided, a struct is generate as-is.
|
||||
//
|
||||
// If `Request {}` is specified here, it will create a `pub type YOUR_REQUEST_TYPE = ()`
|
||||
// instead of a `struct`, see below in other macro definitions for an example.
|
||||
//
|
||||
// If there are any additional attributes (`/// docs` or `#[derive]`s)
|
||||
// for the struct, they go here.
|
||||
Request {
|
||||
|
@ -140,6 +147,9 @@ define_request_and_response! {
|
|||
core_rpc_server_commands_defs.h => 919..=933,
|
||||
GetBlockCount (empty),
|
||||
|
||||
// There are no request fields specified,
|
||||
// this will cause the macro to generate a
|
||||
// type alias to `()` instead of a `struct`.
|
||||
Request {},
|
||||
|
||||
ResponseBase {
|
||||
|
@ -158,8 +168,8 @@ define_request_and_response! {
|
|||
#[repr(transparent)]
|
||||
#[derive(Copy)]
|
||||
Request {
|
||||
/// This is `std::vector<u64>` in `monerod` but
|
||||
/// it must be a 1 length array or else it will error.
|
||||
// This is `std::vector<u64>` in `monerod` but
|
||||
// it must be a 1 length array or else it will error.
|
||||
block_height: [u64; 1],
|
||||
},
|
||||
|
||||
|
@ -187,7 +197,7 @@ define_request_and_response! {
|
|||
|
||||
// FIXME: `cuprate_test_utils` only has an `error` response for this.
|
||||
ResponseBase {
|
||||
block_id: Hex<32>,
|
||||
block_id: String,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,7 +216,7 @@ define_request_and_response! {
|
|||
},
|
||||
|
||||
ResponseBase {
|
||||
blocks: Vec<Hex<32>>,
|
||||
blocks: Vec<String>,
|
||||
height: u64,
|
||||
}
|
||||
}
|
||||
|
@ -236,7 +246,7 @@ define_request_and_response! {
|
|||
|
||||
Request {
|
||||
hash: Hex<32>,
|
||||
hashes: Vec<Hex<32>> = default_vec::<Hex<32>>(), "default_vec",
|
||||
hashes: Vec<String> = default_vec::<String>(), "default_vec",
|
||||
fill_pow_hash: bool = default_false(), "default_false",
|
||||
},
|
||||
|
||||
|
@ -301,11 +311,11 @@ define_request_and_response! {
|
|||
AccessResponseBase {
|
||||
blob: String,
|
||||
block_header: BlockHeader,
|
||||
/// `cuprate_types::json::block::Block` should be used
|
||||
/// `cuprate_rpc_types::json::block::Block` should be used
|
||||
/// to create this JSON string in a type-safe manner.
|
||||
json: String,
|
||||
miner_tx_hash: Hex<32>,
|
||||
tx_hashes: Vec<Hex<32>> = default_vec::<Hex<32>>(), "default_vec",
|
||||
miner_tx_hash: String,
|
||||
tx_hashes: Vec<String> = default_vec::<String>(), "default_vec",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,7 +372,7 @@ define_request_and_response! {
|
|||
target_height: u64,
|
||||
target: u64,
|
||||
testnet: bool,
|
||||
top_block_hash: Hex<32>,
|
||||
top_block_hash: String,
|
||||
tx_count: u64,
|
||||
tx_pool_size: u64,
|
||||
update_available: bool,
|
||||
|
@ -449,7 +459,7 @@ define_request_and_response! {
|
|||
FlushTransactionPool (restricted),
|
||||
|
||||
Request {
|
||||
txids: Vec<Hex<32>> = default_vec::<Hex<32>>(), "default_vec",
|
||||
txids: Vec<String> = default_vec::<String>(), "default_vec",
|
||||
},
|
||||
|
||||
#[repr(transparent)]
|
||||
|
@ -554,7 +564,7 @@ define_request_and_response! {
|
|||
RelayTx (restricted),
|
||||
|
||||
Request {
|
||||
txids: Vec<Hex<32>>,
|
||||
txids: Vec<String>,
|
||||
},
|
||||
|
||||
#[repr(transparent)]
|
||||
|
@ -631,8 +641,8 @@ define_request_and_response! {
|
|||
ResponseBase {
|
||||
major_version: u8,
|
||||
height: u64,
|
||||
prev_id: Hex<32>,
|
||||
seed_hash: Hex<32>,
|
||||
prev_id: String,
|
||||
seed_hash: String,
|
||||
difficulty: String,
|
||||
median_weight: u64,
|
||||
already_generated_coins: u64,
|
||||
|
@ -669,13 +679,13 @@ define_request_and_response! {
|
|||
major_version: u8,
|
||||
height: u64,
|
||||
block_blob: String,
|
||||
seed_hash: Hex<32>,
|
||||
seed_hash: String,
|
||||
},
|
||||
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[repr(transparent)]
|
||||
Response {
|
||||
pow_hash: Hex<32>,
|
||||
pow_hash: String,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1045,9 +1055,9 @@ mod test {
|
|||
json::GENERATE_BLOCKS_RESPONSE,
|
||||
GenerateBlocksResponse {
|
||||
base: ResponseBase::OK,
|
||||
blocks: vec![Hex(hex!(
|
||||
"49b712db7760e3728586f8434ee8bc8d7b3d410dac6bb6e98bf5845c83b917e4"
|
||||
))],
|
||||
blocks: vec![
|
||||
"49b712db7760e3728586f8434ee8bc8d7b3d410dac6bb6e98bf5845c83b917e4".into(),
|
||||
],
|
||||
height: 9783,
|
||||
},
|
||||
);
|
||||
|
@ -1289,7 +1299,7 @@ mod test {
|
|||
json::GET_BLOCK_REQUEST,
|
||||
GetBlockRequest {
|
||||
height: 2751506,
|
||||
hash: String::new(),
|
||||
hash: String::default(),
|
||||
fill_pow_hash: false,
|
||||
},
|
||||
);
|
||||
|
@ -1325,7 +1335,7 @@ mod test {
|
|||
wide_difficulty: "0x490be69168".into()
|
||||
},
|
||||
json: "{\n \"major_version\": 16, \n \"minor_version\": 16, \n \"timestamp\": 1667941829, \n \"prev_id\": \"b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7\", \n \"nonce\": 4110909056, \n \"miner_tx\": {\n \"version\": 2, \n \"unlock_time\": 2751566, \n \"vin\": [ {\n \"gen\": {\n \"height\": 2751506\n }\n }\n ], \n \"vout\": [ {\n \"amount\": 600000000000, \n \"target\": {\n \"tagged_key\": {\n \"key\": \"d7cbf826b665d7a532c316982dc8dbc24f285cbc18bbcc27c7164cd9b3277a85\", \n \"view_tag\": \"d0\"\n }\n }\n }\n ], \n \"extra\": [ 1, 159, 98, 157, 139, 54, 189, 22, 162, 191, 206, 62, 168, 12, 49, 220, 77, 135, 98, 198, 113, 101, 174, 194, 24, 69, 73, 78, 50, 183, 88, 47, 224, 2, 17, 0, 0, 0, 41, 122, 120, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n ], \n \"rct_signatures\": {\n \"type\": 0\n }\n }, \n \"tx_hashes\": [ ]\n}".into(),
|
||||
miner_tx_hash: Hex(hex!("e49b854c5f339d7410a77f2a137281d8042a0ffc7ef9ab24cd670b67139b24cd")),
|
||||
miner_tx_hash: "e49b854c5f339d7410a77f2a137281d8042a0ffc7ef9ab24cd670b67139b24cd".into(),
|
||||
tx_hashes: vec![],
|
||||
});
|
||||
}
|
||||
|
@ -1438,9 +1448,8 @@ mod test {
|
|||
target: 120,
|
||||
target_height: 0,
|
||||
testnet: false,
|
||||
top_block_hash: Hex(hex!(
|
||||
"bdf06d18ed1931a8ee62654e9b6478cc459bc7072628b8e36f4524d339552946"
|
||||
)),
|
||||
top_block_hash: "bdf06d18ed1931a8ee62654e9b6478cc459bc7072628b8e36f4524d339552946"
|
||||
.into(),
|
||||
tx_count: 43205750,
|
||||
tx_pool_size: 12,
|
||||
update_available: false,
|
||||
|
@ -1553,9 +1562,9 @@ mod test {
|
|||
test_json_request(
|
||||
json::FLUSH_TRANSACTION_POOL_REQUEST,
|
||||
FlushTransactionPoolRequest {
|
||||
txids: vec![Hex(hex!(
|
||||
"dc16fa8eaffe1484ca9014ea050e13131d3acf23b419f33bb4cc0b32b6c49308"
|
||||
))],
|
||||
txids: vec![
|
||||
"dc16fa8eaffe1484ca9014ea050e13131d3acf23b419f33bb4cc0b32b6c49308".into(),
|
||||
],
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1684,9 +1693,10 @@ mod test {
|
|||
block_hash: Hex(hex!(
|
||||
"4826c7d45d7cf4f02985b5c405b0e5d7f92c8d25e015492ce19aa3b209295dce"
|
||||
)),
|
||||
block_hashes: vec![Hex(hex!(
|
||||
block_hashes: vec![
|
||||
"4826c7d45d7cf4f02985b5c405b0e5d7f92c8d25e015492ce19aa3b209295dce"
|
||||
))],
|
||||
.into(),
|
||||
],
|
||||
difficulty: 357404825113208373,
|
||||
difficulty_top64: 0,
|
||||
height: 3167471,
|
||||
|
@ -1700,9 +1710,10 @@ mod test {
|
|||
block_hash: Hex(hex!(
|
||||
"33ee476f5a1c5b9d889274cbbe171f5e0112df7ed69021918042525485deb401"
|
||||
)),
|
||||
block_hashes: vec![Hex(hex!(
|
||||
block_hashes: vec![
|
||||
"33ee476f5a1c5b9d889274cbbe171f5e0112df7ed69021918042525485deb401"
|
||||
))],
|
||||
.into(),
|
||||
],
|
||||
difficulty: 354736121711617293,
|
||||
difficulty_top64: 0,
|
||||
height: 3157465,
|
||||
|
@ -1722,9 +1733,9 @@ mod test {
|
|||
test_json_request(
|
||||
json::RELAY_TX_REQUEST,
|
||||
RelayTxRequest {
|
||||
txids: vec![Hex(hex!(
|
||||
"9fd75c429cbe52da9a52f2ffc5fbd107fe7fd2099c0d8de274dc8a67e0c98613"
|
||||
))],
|
||||
txids: vec![
|
||||
"9fd75c429cbe52da9a52f2ffc5fbd107fe7fd2099c0d8de274dc8a67e0c98613".into(),
|
||||
],
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1859,25 +1870,20 @@ mod test {
|
|||
height: 2731375,
|
||||
major_version: 16,
|
||||
median_weight: 300000,
|
||||
prev_id: Hex(hex!(
|
||||
"78d50c5894d187c4946d54410990ca59a75017628174a9e8c7055fa4ca5c7c6d"
|
||||
)),
|
||||
seed_hash: Hex(hex!(
|
||||
"a6b869d50eca3a43ec26fe4c369859cf36ae37ce6ecb76457d31ffeb8a6ca8a6"
|
||||
)),
|
||||
prev_id: "78d50c5894d187c4946d54410990ca59a75017628174a9e8c7055fa4ca5c7c6d".into(),
|
||||
seed_hash: "a6b869d50eca3a43ec26fe4c369859cf36ae37ce6ecb76457d31ffeb8a6ca8a6"
|
||||
.into(),
|
||||
tx_backlog: vec![
|
||||
GetMinerDataTxBacklogEntry {
|
||||
fee: 30700000,
|
||||
id: Hex(hex!(
|
||||
"9868490d6bb9207fdd9cf17ca1f6c791b92ca97de0365855ea5c089f67c22208"
|
||||
)),
|
||||
id: "9868490d6bb9207fdd9cf17ca1f6c791b92ca97de0365855ea5c089f67c22208"
|
||||
.into(),
|
||||
weight: 1535,
|
||||
},
|
||||
GetMinerDataTxBacklogEntry {
|
||||
fee: 44280000,
|
||||
id: Hex(hex!(
|
||||
"b6000b02bbec71e18ad704bcae09fb6e5ae86d897ced14a718753e76e86c0a0a"
|
||||
)),
|
||||
id: "b6000b02bbec71e18ad704bcae09fb6e5ae86d897ced14a718753e76e86c0a0a"
|
||||
.into(),
|
||||
weight: 2214,
|
||||
},
|
||||
],
|
||||
|
@ -1911,7 +1917,7 @@ mod test {
|
|||
major_version: 14,
|
||||
height: 2286447,
|
||||
block_blob: "0e0ed286da8006ecdc1aab3033cf1716c52f13f9d8ae0051615a2453643de94643b550d543becd0000000002abc78b0101ffefc68b0101fcfcf0d4b422025014bb4a1eade6622fd781cb1063381cad396efa69719b41aa28b4fce8c7ad4b5f019ce1dc670456b24a5e03c2d9058a2df10fec779e2579753b1847b74ee644f16b023c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051399a1bc46a846474f5b33db24eae173a26393b976054ee14f9feefe99925233802867097564c9db7a36af5bb5ed33ab46e63092bd8d32cef121608c3258edd55562812e21cc7e3ac73045745a72f7d74581d9a0849d6f30e8b2923171253e864f4e9ddea3acb5bc755f1c4a878130a70c26297540bc0b7a57affb6b35c1f03d8dbd54ece8457531f8cba15bb74516779c01193e212050423020e45aa2c15dcb".into(),
|
||||
seed_hash: Hex(hex!("d432f499205150873b2572b5f033c9c6e4b7c6f3394bd2dd93822cd7085e7307")),
|
||||
seed_hash: "d432f499205150873b2572b5f033c9c6e4b7c6f3394bd2dd93822cd7085e7307".into(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1920,9 +1926,7 @@ mod test {
|
|||
test_json_response(
|
||||
json::CALC_POW_RESPONSE,
|
||||
CalcPowResponse {
|
||||
pow_hash: Hex(hex!(
|
||||
"d0402d6834e26fb94a9ce38c6424d27d2069896a9b8b1ce685d79936bca6e0a8"
|
||||
)),
|
||||
pow_hash: "d0402d6834e26fb94a9ce38c6424d27d2069896a9b8b1ce685d79936bca6e0a8".into(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
//! the [`crate::misc::ConnectionInfo`] struct defined here.
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use cuprate_hex::Hex;
|
||||
use cuprate_types::HardFork;
|
||||
use cuprate_types::{hex::Hex, HardFork};
|
||||
|
||||
#[cfg(any(feature = "epee", feature = "serde"))]
|
||||
use crate::defaults::default_zero;
|
||||
|
@ -196,7 +195,7 @@ define_struct_and_impl_epee! {
|
|||
/// Used in [`crate::json::GetAlternateChainsResponse`].
|
||||
ChainInfo {
|
||||
block_hash: Hex<32>,
|
||||
block_hashes: Vec<Hex<32>>,
|
||||
block_hashes: Vec<String>, // TODO: Vec<Hex<32>> when it has epee
|
||||
difficulty: u64,
|
||||
difficulty_top64: u64,
|
||||
height: u64,
|
||||
|
@ -307,7 +306,7 @@ define_struct_and_impl_epee! {
|
|||
/// Used in [`crate::other::GetTransactionPoolResponse`].
|
||||
SpentKeyImageInfo {
|
||||
id_hash: Hex<32>,
|
||||
txs_hashes: Vec<Hex<32>>,
|
||||
txs_hashes: Vec<String>, // TODO: Vec<Hex<32>> when it has epee
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9,24 +9,27 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/types"
|
|||
keywords = ["cuprate", "types"]
|
||||
|
||||
[features]
|
||||
default = ["blockchain", "epee", "serde", "json", "rpc"]
|
||||
default = ["blockchain", "epee", "serde", "json", "hex", "rpc"]
|
||||
blockchain = ["rpc"]
|
||||
epee = ["dep:cuprate-epee-encoding"]
|
||||
serde = ["dep:serde"]
|
||||
serde = ["dep:serde", "hex"]
|
||||
proptest = ["dep:proptest", "dep:proptest-derive"]
|
||||
json = ["dep:cuprate-hex", "dep:cuprate-helper"]
|
||||
rpc = ["dep:cuprate-hex", "json"]
|
||||
json = ["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.
|
||||
# This isn't too bad as `Hex` only makes sense with serde anyway.
|
||||
hex = ["serde", "dep:hex"]
|
||||
rpc = ["hex", "json"]
|
||||
|
||||
[dependencies]
|
||||
cuprate-epee-encoding = { workspace = true, optional = true, features = ["std"] }
|
||||
cuprate-helper = { workspace = true, optional = true, features = ["cast"] }
|
||||
cuprate-fixed-bytes = { workspace = true, features = ["std", "serde"] }
|
||||
cuprate-hex = { workspace = true, optional = true }
|
||||
|
||||
bytes = { workspace = true }
|
||||
cfg-if = { workspace = true }
|
||||
curve25519-dalek = { workspace = true }
|
||||
monero-serai = { workspace = true }
|
||||
hex = { workspace = true, features = ["serde", "alloc"], optional = true }
|
||||
serde = { workspace = true, features = ["std", "derive"], optional = true }
|
||||
strum = { workspace = true, features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
|
@ -11,3 +11,4 @@ This crate is a kitchen-sink for data types that are shared across Cuprate.
|
|||
| `epee` | Enables `cuprate-epee-encoding` on types where applicable
|
||||
| `proptest` | Enables `proptest::arbitrary::Arbitrary` on some types
|
||||
| `json` | Enables the `json` module, containing JSON representations of common Monero types
|
||||
| `hex` | Enables the `hex` module, containing the `HexBytes` type
|
|
@ -1,22 +0,0 @@
|
|||
[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 = []
|
||||
|
||||
[dependencies]
|
||||
hex = { workspace = true, features = ["alloc", "serde"] }
|
||||
serde = { workspace = true, features = ["std", "derive"] }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = { workspace = true, features = ["std"] }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
|
@ -1,7 +0,0 @@
|
|||
# `cuprate-hex`
|
||||
Cuprate's hexadecimal data types.
|
||||
|
||||
# Features flags
|
||||
| Feature flag | Does what |
|
||||
|--------------|-----------|
|
||||
| `serde` | Enables `serde` on types where applicable
|
|
@ -1,7 +0,0 @@
|
|||
#![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;
|
|
@ -3,46 +3,52 @@
|
|||
//! This module provides transparent wrapper types for
|
||||
//! arrays that (de)serialize from hexadecimal input/output.
|
||||
|
||||
use hex::{FromHex, FromHexError};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
#[cfg(feature = "epee")]
|
||||
use cuprate_epee_encoding::{error, macros::bytes, EpeeValue, Marker};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// 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
|
||||
/// This struct has a custom deserialization that only applies to certain
|
||||
/// `N` lengths because [`FromHex`] does not implement for a generic `N`:
|
||||
/// `N` lengths because [`hex::FromHex`] does not implement for a generic `N`:
|
||||
/// <https://docs.rs/hex/0.4.3/src/hex/lib.rs.html#220-230>
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
|
||||
#[serde(transparent)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[repr(transparent)]
|
||||
pub struct Hex<const N: usize>(#[serde(with = "hex::serde")] pub [u8; N]);
|
||||
pub struct Hex<const N: usize>(
|
||||
#[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; N],
|
||||
);
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, const N: usize> Deserialize<'de> for Hex<N>
|
||||
where
|
||||
[u8; N]: FromHex,
|
||||
<[u8; N] as FromHex>::Error: std::fmt::Display,
|
||||
[u8; N]: hex::FromHex,
|
||||
<[u8; N] as hex::FromHex>::Error: std::fmt::Display,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
Ok(Self(hex::serde::deserialize(deserializer)?))
|
||||
}
|
||||
}
|
||||
|
||||
#[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.
|
||||
impl<const N: usize> Default for Hex<N> {
|
||||
fn default() -> Self {
|
||||
|
@ -63,18 +69,18 @@ impl<const N: usize> From<[u8; N]> for Hex<N> {
|
|||
}
|
||||
|
||||
impl<const N: usize> TryFrom<String> for Hex<N> {
|
||||
type Error = FromHexError;
|
||||
type Error = hex::FromHexError;
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
let vec = hex::decode(value)?;
|
||||
match <[u8; N]>::try_from(vec) {
|
||||
Ok(s) => Ok(Self(s)),
|
||||
Err(_) => Err(FromHexError::InvalidStringLength),
|
||||
Err(_) => Err(hex::FromHexError::InvalidStringLength),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> TryFrom<&str> for Hex<N> {
|
||||
type Error = FromHexError;
|
||||
type Error = hex::FromHexError;
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let mut bytes = [0; N];
|
||||
hex::decode_to_slice(value, &mut bytes).map(|()| Self(bytes))
|
||||
|
@ -86,10 +92,10 @@ mod test {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn asdf() {
|
||||
let hash = [0; 32];
|
||||
fn hex_bytes_32() {
|
||||
let hash = [1; 32];
|
||||
let hex_bytes = Hex::<32>(hash);
|
||||
let expected_json = r#""0000000000000000000000000000000000000000000000000000000000000000""#;
|
||||
let expected_json = r#""0101010101010101010101010101010101010101010101010101010101010101""#;
|
||||
|
||||
let to_string = serde_json::to_string(&hex_bytes).unwrap();
|
||||
assert_eq!(to_string, expected_json);
|
|
@ -6,9 +6,11 @@ use serde::{Deserialize, Serialize};
|
|||
use monero_serai::{block, transaction};
|
||||
|
||||
use cuprate_helper::cast::usize_to_u64;
|
||||
use cuprate_hex::Hex;
|
||||
|
||||
use crate::json::output::{Output, TaggedKey, Target};
|
||||
use crate::{
|
||||
hex::Hex,
|
||||
json::output::{Output, TaggedKey, Target},
|
||||
};
|
||||
|
||||
/// JSON representation of a block.
|
||||
///
|
||||
|
@ -32,13 +34,13 @@ impl From<block::Block> for Block {
|
|||
unreachable!("input is a miner tx, this should never fail");
|
||||
};
|
||||
|
||||
let tx_hashes = b.transactions.into_iter().map(Hex).collect();
|
||||
let tx_hashes = b.transactions.into_iter().map(Hex::<32>).collect();
|
||||
|
||||
Self {
|
||||
major_version: b.header.hardfork_version,
|
||||
minor_version: b.header.hardfork_signal,
|
||||
timestamp: b.header.timestamp,
|
||||
prev_id: Hex(b.header.previous),
|
||||
prev_id: Hex::<32>(b.header.previous),
|
||||
nonce: b.header.nonce,
|
||||
miner_tx,
|
||||
tx_hashes,
|
||||
|
@ -99,13 +101,15 @@ impl TryFrom<transaction::Transaction> for MinerTransaction {
|
|||
let target = match o.view_tag {
|
||||
Some(view_tag) => {
|
||||
let tagged_key = TaggedKey {
|
||||
key: Hex(o.key.0),
|
||||
view_tag: Hex([view_tag]),
|
||||
key: Hex::<32>(o.key.0),
|
||||
view_tag: Hex::<1>([view_tag]),
|
||||
};
|
||||
|
||||
Target::TaggedKey { tagged_key }
|
||||
}
|
||||
None => Target::Key { key: Hex(o.key.0) },
|
||||
None => Target::Key {
|
||||
key: Hex::<32>(o.key.0),
|
||||
},
|
||||
};
|
||||
|
||||
Output { amount, target }
|
||||
|
@ -218,7 +222,7 @@ mod test {
|
|||
major_version: 1,
|
||||
minor_version: 0,
|
||||
timestamp: 1415690591,
|
||||
prev_id: Hex(hex!(
|
||||
prev_id: Hex::<32>(hex!(
|
||||
"e97a0ab6307de9b9f9a9872263ef3e957976fb227eb9422c6854e989e5d5d34c"
|
||||
)),
|
||||
nonce: 2147484616,
|
||||
|
@ -233,25 +237,25 @@ mod test {
|
|||
Output {
|
||||
amount: 47019296802,
|
||||
target: Target::Key {
|
||||
key: Hex(hex!("3c1dcbf5b485987ecef4596bb700e32cbc7bd05964e3888ffc05f8a46bf5fc33")),
|
||||
key: Hex::<32>(hex!("3c1dcbf5b485987ecef4596bb700e32cbc7bd05964e3888ffc05f8a46bf5fc33")),
|
||||
}
|
||||
},
|
||||
Output {
|
||||
amount: 200000000000,
|
||||
target: Target::Key {
|
||||
key: Hex(hex!("5810afc7a1b01a1c913eb6aab15d4a851cbc4a8cf0adf90bb80ac1a7ca9928aa")),
|
||||
key: Hex::<32>(hex!("5810afc7a1b01a1c913eb6aab15d4a851cbc4a8cf0adf90bb80ac1a7ca9928aa")),
|
||||
}
|
||||
},
|
||||
Output {
|
||||
amount: 3000000000000,
|
||||
target: Target::Key {
|
||||
key: Hex(hex!("520f49c5f2ce8456dc1a565f35ed3a5ccfff3a1210b340870a57d2749a81a2df")),
|
||||
key: Hex::<32>(hex!("520f49c5f2ce8456dc1a565f35ed3a5ccfff3a1210b340870a57d2749a81a2df")),
|
||||
}
|
||||
},
|
||||
Output {
|
||||
amount: 10000000000000,
|
||||
target: Target::Key {
|
||||
key: Hex(hex!("44d7705e62c76c2e349a474df6724aa1d9932092002b03a94f9c19d9d12b9427")),
|
||||
key: Hex::<32>(hex!("44d7705e62c76c2e349a474df6724aa1d9932092002b03a94f9c19d9d12b9427")),
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -277,7 +281,7 @@ mod test {
|
|||
major_version: 16,
|
||||
minor_version: 16,
|
||||
timestamp: 1727293028,
|
||||
prev_id: Hex(hex!(
|
||||
prev_id: Hex::<32>(hex!(
|
||||
"41b56c273d69def3294e56179de71c61808042d54c1e085078d21dbe99e81b6f"
|
||||
)),
|
||||
nonce: 311,
|
||||
|
@ -292,10 +296,10 @@ mod test {
|
|||
amount: 601012280000,
|
||||
target: Target::TaggedKey {
|
||||
tagged_key: TaggedKey {
|
||||
key: Hex(hex!(
|
||||
key: Hex::<32>(hex!(
|
||||
"8c0b16c6df02b9944b49f375d96a958a0fc5431c048879bb5bf25f64a1163b9e"
|
||||
)),
|
||||
view_tag: Hex(hex!("88")),
|
||||
view_tag: Hex::<1>(hex!("88")),
|
||||
},
|
||||
},
|
||||
}],
|
||||
|
@ -308,43 +312,43 @@ mod test {
|
|||
rct_signatures: MinerTransactionRctSignatures { r#type: 0 },
|
||||
},
|
||||
tx_hashes: vec![
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"eab76986a0cbcae690d8499f0f616f783fd2c89c6f611417f18011950dbdab2e"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"57b19aa8c2cdbb6836cf13dd1e321a67860965c12e4418f3c30f58c8899a851e"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"5340185432ab6b74fb21379f7e8d8f0e37f0882b2a7121fd7c08736f079e2edc"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"01dc6d31db56d68116f5294c1b4f80b33b048b5cdfefcd904f23e6c0de3daff5"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"c9fb6a2730678203948fef2a49fa155b63f35a3649f3d32ed405a6806f3bbd56"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"af965cdd2a2315baf1d4a3d242f44fe07b1fd606d5f4853c9ff546ca6c12a5af"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"97bc9e047d25fae8c14ce6ec882224e7b722f5e79b62a2602a6bacebdac8547b"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"28c46992eaf10dc0cceb313c30572d023432b7bd26e85e679bc8fe419533a7bf"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"c32e3acde2ff2885c9cc87253b40d6827d167dfcc3022c72f27084fd98788062"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"19e66a47f075c7cccde8a7b52803119e089e33e3a4847cace0bd1d17b0d22bab"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"8e8ac560e77a1ee72e82a5eb6887adbe5979a10cd29cb2c2a3720ce87db43a70"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"b7ff5141524b5cca24de6780a5dbfdf71e7de1e062fd85f557fb3b43b8e285dc"
|
||||
)),
|
||||
Hex(hex!(
|
||||
Hex::<32>(hex!(
|
||||
"f09df0f113763ef9b9a2752ac293b478102f7cab03ef803a3d9db7585aea8912"
|
||||
)),
|
||||
],
|
|
@ -7,7 +7,7 @@
|
|||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use cuprate_hex::Hex;
|
||||
use crate::hex::Hex;
|
||||
|
||||
/// JSON representation of an output.
|
||||
#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
File diff suppressed because it is too large
Load diff
|
@ -35,6 +35,9 @@ pub mod blockchain;
|
|||
#[cfg(feature = "json")]
|
||||
pub mod json;
|
||||
|
||||
#[cfg(feature = "hex")]
|
||||
pub mod hex;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "rpc")] {
|
||||
pub mod rpc;
|
|
@ -1,9 +1,8 @@
|
|||
//! Various types (in)directly used in RPC.
|
||||
|
||||
use cuprate_fixed_bytes::ByteArrayVec;
|
||||
use cuprate_hex::Hex;
|
||||
|
||||
use crate::{AddressType, ConnectionState, HardFork};
|
||||
use crate::{hex::Hex, AddressType, ConnectionState, HardFork};
|
||||
|
||||
const fn default_string() -> String {
|
||||
String::new()
|
||||
|
@ -22,7 +21,7 @@ macro_rules! monero_definition_link {
|
|||
) => {
|
||||
concat!(
|
||||
"[Definition](https://github.com/monero-project/monero/blob/",
|
||||
$commit,
|
||||
stringify!($commit),
|
||||
"/src/",
|
||||
$file_path,
|
||||
"#L",
|
||||
|
@ -264,7 +263,7 @@ define_struct_and_impl_epee! {
|
|||
1016..=1027
|
||||
)]
|
||||
GetMinerDataTxBacklogEntry {
|
||||
id: Hex<32>,
|
||||
id: String,
|
||||
weight: u64,
|
||||
fee: u64,
|
||||
}
|
|
@ -10,7 +10,7 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/zmq/types"
|
|||
[dependencies]
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
hex = { workspace = true, features = ["std", "serde"] }
|
||||
cuprate-hex = { workspace = true }
|
||||
cuprate-types = { workspace = true, features = ["hex"] }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = { workspace = true, features = ["std"] }
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use cuprate_hex::Hex;
|
||||
use cuprate_types::hex::Hex;
|
||||
|
||||
/// ZMQ `json-full-txpool_add` packets contain an array of `TxPoolAdd`.
|
||||
///
|
||||
|
|
Loading…
Reference in a new issue