mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-22 11:39:30 +00:00
HexVec
This commit is contained in:
parent
ed8de29504
commit
cb6fdb76e4
11 changed files with 245 additions and 103 deletions
|
@ -23,7 +23,7 @@ use cuprate_helper::{
|
||||||
fmt::HexPrefix,
|
fmt::HexPrefix,
|
||||||
map::split_u128_into_low_high_bits,
|
map::split_u128_into_low_high_bits,
|
||||||
};
|
};
|
||||||
use cuprate_hex::Hex;
|
use cuprate_hex::{Hex, HexVec};
|
||||||
use cuprate_p2p_core::{client::handshaker::builder::DummyAddressBook, ClearNet, Network};
|
use cuprate_p2p_core::{client::handshaker::builder::DummyAddressBook, ClearNet, Network};
|
||||||
use cuprate_rpc_interface::RpcHandler;
|
use cuprate_rpc_interface::RpcHandler;
|
||||||
use cuprate_rpc_types::{
|
use cuprate_rpc_types::{
|
||||||
|
@ -162,7 +162,7 @@ async fn get_block_template(
|
||||||
}
|
}
|
||||||
|
|
||||||
let blob_reserve = hex::decode(request.extra_nonce)?;
|
let blob_reserve = hex::decode(request.extra_nonce)?;
|
||||||
let prev_block = helper::hex_to_hash(request.prev_block)?;
|
let prev_block: [u8; 32] = request.prev_block.try_into()?;
|
||||||
let extra_nonce = hex::decode(request.extra_nonce)?;
|
let extra_nonce = hex::decode(request.extra_nonce)?;
|
||||||
|
|
||||||
let BlockTemplate {
|
let BlockTemplate {
|
||||||
|
@ -182,11 +182,11 @@ async fn get_block_template(
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let blockhashing_blob = hex::encode(block.serialize_pow_hash());
|
let blockhashing_blob = HexVec(block.serialize_pow_hash());
|
||||||
let blocktemplate_blob = hex::encode(block.serialize());
|
let blocktemplate_blob = HexVec(block.serialize());
|
||||||
let (difficulty, difficulty_top64) = split_u128_into_low_high_bits(difficulty);
|
let (difficulty, difficulty_top64) = split_u128_into_low_high_bits(difficulty);
|
||||||
// let next_seed_hash = Hex(next_seed_hash);
|
// let next_seed_hash = Hex(next_seed_hash);
|
||||||
let next_seed_hash = hex::encode(next_seed_hash);
|
let next_seed_hash = HexVec::empty_if_zeroed(next_seed_hash);
|
||||||
let prev_hash = Hex(block.header.previous);
|
let prev_hash = Hex(block.header.previous);
|
||||||
let seed_hash = Hex(seed_hash);
|
let seed_hash = Hex(seed_hash);
|
||||||
let wide_difficulty = (difficulty, difficulty_top64).hex_prefix();
|
let wide_difficulty = (difficulty, difficulty_top64).hex_prefix();
|
||||||
|
@ -215,7 +215,10 @@ async fn get_block_count(
|
||||||
) -> Result<GetBlockCountResponse, Error> {
|
) -> Result<GetBlockCountResponse, Error> {
|
||||||
Ok(GetBlockCountResponse {
|
Ok(GetBlockCountResponse {
|
||||||
base: helper::response_base(false),
|
base: helper::response_base(false),
|
||||||
count: helper::top_height(&mut state).await?.0,
|
// Block count starts at 1
|
||||||
|
count: blockchain::chain_height(&mut state.blockchain_read)
|
||||||
|
.await?
|
||||||
|
.0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,8 +247,7 @@ async fn submit_block(
|
||||||
) -> Result<SubmitBlockResponse, Error> {
|
) -> Result<SubmitBlockResponse, Error> {
|
||||||
// Parse hex into block.
|
// Parse hex into block.
|
||||||
let [blob] = request.block_blob;
|
let [blob] = request.block_blob;
|
||||||
let bytes = hex::decode(blob)?;
|
let block = Block::read(&mut blob.0.as_slice())?;
|
||||||
let block = Block::read(&mut bytes.as_slice())?;
|
|
||||||
let block_id = Hex(block.hash());
|
let block_id = Hex(block.hash());
|
||||||
|
|
||||||
// Attempt to relay the block.
|
// Attempt to relay the block.
|
||||||
|
@ -272,7 +274,7 @@ async fn generate_blocks(
|
||||||
let prev_block = if request.prev_block.is_empty() {
|
let prev_block = if request.prev_block.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(helper::hex_to_hash(request.prev_block)?)
|
Some(request.prev_block.try_into()?)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (blocks, height) = blockchain_manager::generate_blocks(
|
let (blocks, height) = blockchain_manager::generate_blocks(
|
||||||
|
@ -318,21 +320,13 @@ async fn get_block_header_by_hash(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get(
|
let block_header =
|
||||||
state: &mut CupratedRpcHandler,
|
helper::block_header_by_hash(&mut state, request.hash.0, request.fill_pow_hash).await?;
|
||||||
hash: [u8; 32],
|
|
||||||
fill_pow_hash: bool,
|
|
||||||
) -> Result<BlockHeader, Error> {
|
|
||||||
let block_header = helper::block_header_by_hash(state, hash, fill_pow_hash).await?;
|
|
||||||
Ok(block_header)
|
|
||||||
}
|
|
||||||
|
|
||||||
let block_header = get(&mut state, request.hash.0, request.fill_pow_hash).await?;
|
|
||||||
|
|
||||||
// FIXME PERF: could make a `Vec` on await on all tasks at the same time.
|
// 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());
|
let mut block_headers = Vec::with_capacity(request.hashes.len());
|
||||||
for hash in request.hashes {
|
for hash in request.hashes {
|
||||||
let hash = get(&mut state, hash.0, request.fill_pow_hash).await?;
|
let hash = helper::block_header_by_hash(&mut state, hash.0, request.fill_pow_hash).await?;
|
||||||
block_headers.push(hash);
|
block_headers.push(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,14 +419,14 @@ async fn get_block(
|
||||||
helper::block_header(&mut state, request.height, request.fill_pow_hash).await?;
|
helper::block_header(&mut state, request.height, request.fill_pow_hash).await?;
|
||||||
(block, block_header)
|
(block, block_header)
|
||||||
} else {
|
} else {
|
||||||
let hash = helper::hex_to_hash(request.hash)?;
|
let hash: [u8; 32] = request.hash.try_into()?;
|
||||||
let block = blockchain::block_by_hash(&mut state.blockchain_read, hash).await?;
|
let block = blockchain::block_by_hash(&mut state.blockchain_read, hash).await?;
|
||||||
let block_header =
|
let block_header =
|
||||||
helper::block_header_by_hash(&mut state, hash, request.fill_pow_hash).await?;
|
helper::block_header_by_hash(&mut state, hash, request.fill_pow_hash).await?;
|
||||||
(block, block_header)
|
(block, block_header)
|
||||||
};
|
};
|
||||||
|
|
||||||
let blob = hex::encode(block.serialize());
|
let blob = HexVec(block.serialize());
|
||||||
let miner_tx_hash = Hex(block.miner_transaction.hash());
|
let miner_tx_hash = Hex(block.miner_transaction.hash());
|
||||||
let tx_hashes = block.transactions.iter().map(|a| Hex(*a)).collect();
|
let tx_hashes = block.transactions.iter().map(|a| Hex(*a)).collect();
|
||||||
let json = {
|
let json = {
|
||||||
|
@ -1024,8 +1018,7 @@ async fn calc_pow(
|
||||||
request: CalcPowRequest,
|
request: CalcPowRequest,
|
||||||
) -> Result<CalcPowResponse, Error> {
|
) -> Result<CalcPowResponse, Error> {
|
||||||
let hardfork = HardFork::from_version(request.major_version)?;
|
let hardfork = HardFork::from_version(request.major_version)?;
|
||||||
let block_blob: Vec<u8> = hex::decode(request.block_blob)?;
|
let block = Block::read(&mut request.block_blob.0.as_slice())?;
|
||||||
let block = Block::read(&mut block_blob.as_slice())?;
|
|
||||||
let seed_hash = request.seed_hash.0;
|
let seed_hash = request.seed_hash.0;
|
||||||
|
|
||||||
// let block_weight = todo!();
|
// let block_weight = todo!();
|
||||||
|
@ -1222,10 +1215,7 @@ fn add_aux_pow_inner(
|
||||||
let merkle_root = tree_hash(aux_pow_raw.as_ref());
|
let merkle_root = tree_hash(aux_pow_raw.as_ref());
|
||||||
let merkle_tree_depth = encode_mm_depth(len, nonce);
|
let merkle_tree_depth = encode_mm_depth(len, nonce);
|
||||||
|
|
||||||
let block_template = {
|
let block_template = Block::read(&mut request.blocktemplate_blob.0.as_slice())?;
|
||||||
let hex = hex::decode(request.blocktemplate_blob)?;
|
|
||||||
Block::read(&mut hex.as_slice())?
|
|
||||||
};
|
|
||||||
|
|
||||||
fn remove_field_from_tx_extra() -> Result<(), ()> {
|
fn remove_field_from_tx_extra() -> Result<(), ()> {
|
||||||
todo!("https://github.com/monero-project/monero/blob/master/src/cryptonote_basic/cryptonote_format_utils.cpp#L767")
|
todo!("https://github.com/monero-project/monero/blob/master/src/cryptonote_basic/cryptonote_format_utils.cpp#L767")
|
||||||
|
@ -1256,8 +1246,8 @@ fn add_aux_pow_inner(
|
||||||
let blocktemplate_blob = block_template.serialize();
|
let blocktemplate_blob = block_template.serialize();
|
||||||
let blockhashing_blob = block_template.serialize_pow_hash();
|
let blockhashing_blob = block_template.serialize_pow_hash();
|
||||||
|
|
||||||
let blocktemplate_blob = hex::encode(blocktemplate_blob);
|
let blocktemplate_blob = HexVec(blocktemplate_blob);
|
||||||
let blockhashing_blob = hex::encode(blockhashing_blob);
|
let blockhashing_blob = HexVec(blockhashing_blob);
|
||||||
let merkle_root = Hex(merkle_root);
|
let merkle_root = Hex(merkle_root);
|
||||||
let aux_pow = aux_pow.into_vec();
|
let aux_pow = aux_pow.into_vec();
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use cuprate_constants::rpc::{
|
||||||
RESTRICTED_TRANSACTIONS_COUNT,
|
RESTRICTED_TRANSACTIONS_COUNT,
|
||||||
};
|
};
|
||||||
use cuprate_helper::cast::usize_to_u64;
|
use cuprate_helper::cast::usize_to_u64;
|
||||||
use cuprate_hex::Hex;
|
use cuprate_hex::{Hex, HexVec};
|
||||||
use cuprate_p2p_core::{client::handshaker::builder::DummyAddressBook, ClearNet};
|
use cuprate_p2p_core::{client::handshaker::builder::DummyAddressBook, ClearNet};
|
||||||
use cuprate_rpc_interface::RpcHandler;
|
use cuprate_rpc_interface::RpcHandler;
|
||||||
use cuprate_rpc_types::{
|
use cuprate_rpc_types::{
|
||||||
|
@ -157,23 +157,23 @@ async fn get_transactions(
|
||||||
let prunable_hash = Hex(tx.prunable_hash);
|
let prunable_hash = Hex(tx.prunable_hash);
|
||||||
|
|
||||||
let (pruned_as_hex, prunable_as_hex) = if tx.pruned_blob.is_empty() {
|
let (pruned_as_hex, prunable_as_hex) = if tx.pruned_blob.is_empty() {
|
||||||
(String::new(), String::new())
|
(HexVec::new(), HexVec::new())
|
||||||
} else {
|
} else {
|
||||||
(hex::encode(tx.pruned_blob), hex::encode(tx.prunable_blob))
|
(HexVec(tx.pruned_blob), HexVec(tx.prunable_blob))
|
||||||
};
|
};
|
||||||
|
|
||||||
let as_hex = if pruned_as_hex.is_empty() {
|
let as_hex = if pruned_as_hex.is_empty() {
|
||||||
// `monerod` will insert a `""` into the `txs_as_hex` array for pruned transactions.
|
// `monerod` will insert a `""` into the `txs_as_hex` array for pruned transactions.
|
||||||
// curl http://127.0.0.1:18081/get_transactions -d '{"txs_hashes":["4c8b98753d1577d225a497a50f453827cff3aa023a4add60ec4ce4f923f75de8"]}' -H 'Content-Type: application/json'
|
// curl http://127.0.0.1:18081/get_transactions -d '{"txs_hashes":["4c8b98753d1577d225a497a50f453827cff3aa023a4add60ec4ce4f923f75de8"]}' -H 'Content-Type: application/json'
|
||||||
String::new()
|
HexVec::new()
|
||||||
} else {
|
} else {
|
||||||
hex::encode(&tx.tx_blob)
|
HexVec(tx.tx_blob)
|
||||||
};
|
};
|
||||||
|
|
||||||
txs_as_hex.push(as_hex.clone());
|
txs_as_hex.push(as_hex.clone());
|
||||||
|
|
||||||
let as_json = if request.decode_as_json {
|
let as_json = if request.decode_as_json {
|
||||||
let tx = Transaction::read(&mut tx.tx_blob.as_slice())?;
|
let tx = Transaction::read(&mut as_hex.0.as_slice())?;
|
||||||
let json_type = cuprate_types::json::tx::Transaction::from(tx);
|
let json_type = cuprate_types::json::tx::Transaction::from(tx);
|
||||||
let json = serde_json::to_string(&json_type).unwrap();
|
let json = serde_json::to_string(&json_type).unwrap();
|
||||||
txs_as_json.push(json.clone());
|
txs_as_json.push(json.clone());
|
||||||
|
@ -217,11 +217,11 @@ async fn get_transactions(
|
||||||
let tx_hash = Hex(tx_hash);
|
let tx_hash = Hex(tx_hash);
|
||||||
let tx = Transaction::read(&mut tx_blob.as_slice())?;
|
let tx = Transaction::read(&mut tx_blob.as_slice())?;
|
||||||
|
|
||||||
let pruned_as_hex = String::new();
|
let pruned_as_hex = HexVec::new();
|
||||||
let prunable_as_hex = String::new();
|
let prunable_as_hex = HexVec::new();
|
||||||
let prunable_hash = Hex([0; 32]);
|
let prunable_hash = Hex([0; 32]);
|
||||||
|
|
||||||
let as_hex = hex::encode(tx_blob);
|
let as_hex = HexVec(tx_blob);
|
||||||
txs_as_hex.push(as_hex.clone());
|
txs_as_hex.push(as_hex.clone());
|
||||||
|
|
||||||
let as_json = if request.decode_as_json {
|
let as_json = if request.decode_as_json {
|
||||||
|
@ -351,10 +351,7 @@ async fn send_raw_transaction(
|
||||||
tx_extra_too_big: false,
|
tx_extra_too_big: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let tx = {
|
let tx = Transaction::read(&mut request.tx_as_hex.0.as_slice())?;
|
||||||
let blob = hex::decode(request.tx_as_hex)?;
|
|
||||||
Transaction::read(&mut blob.as_slice())?
|
|
||||||
};
|
|
||||||
|
|
||||||
if request.do_sanity_checks {
|
if request.do_sanity_checks {
|
||||||
/// FIXME: these checks could be defined elsewhere.
|
/// FIXME: these checks could be defined elsewhere.
|
||||||
|
|
|
@ -8,7 +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 cuprate_hex::{Hex, HexVec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
io::{checked_read_primitive, checked_write_primitive},
|
io::{checked_read_primitive, checked_write_primitive},
|
||||||
|
@ -437,6 +437,18 @@ impl<const N: usize> EpeeValue for Vec<Hex<N>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EpeeValue for HexVec {
|
||||||
|
const MARKER: Marker = <Vec<u8> as EpeeValue>::MARKER;
|
||||||
|
|
||||||
|
fn read<B: Buf>(r: &mut B, marker: &Marker) -> Result<Self> {
|
||||||
|
Ok(Self(<Vec<u8> as EpeeValue>::read(r, marker)?))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
|
||||||
|
<Vec<u8> as EpeeValue>::write(self.0, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! epee_seq {
|
macro_rules! epee_seq {
|
||||||
($val:ty) => {
|
($val:ty) => {
|
||||||
impl EpeeValue for Vec<$val> {
|
impl EpeeValue for Vec<$val> {
|
||||||
|
@ -503,6 +515,7 @@ epee_seq!(u16);
|
||||||
epee_seq!(f64);
|
epee_seq!(f64);
|
||||||
epee_seq!(bool);
|
epee_seq!(bool);
|
||||||
epee_seq!(Vec<u8>);
|
epee_seq!(Vec<u8>);
|
||||||
|
epee_seq!(HexVec);
|
||||||
epee_seq!(String);
|
epee_seq!(String);
|
||||||
epee_seq!(Bytes);
|
epee_seq!(Bytes);
|
||||||
epee_seq!(BytesMut);
|
epee_seq!(BytesMut);
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use cuprate_helper::{fmt::HexPrefix, map::ipv4_from_u32};
|
use cuprate_helper::{fmt::HexPrefix, map::ipv4_from_u32};
|
||||||
use cuprate_hex::Hex;
|
use cuprate_hex::{Hex, HexVec};
|
||||||
use cuprate_p2p_core::{
|
use cuprate_p2p_core::{
|
||||||
types::{ConnectionId, ConnectionInfo, SetBan, Span},
|
types::{ConnectionId, ConnectionInfo, SetBan, Span},
|
||||||
NetZoneAddress,
|
NetZoneAddress,
|
||||||
|
@ -34,7 +34,7 @@ impl From<BlockHeader> for crate::misc::BlockHeader {
|
||||||
nonce: x.nonce,
|
nonce: x.nonce,
|
||||||
num_txes: x.num_txes,
|
num_txes: x.num_txes,
|
||||||
orphan_status: x.orphan_status,
|
orphan_status: x.orphan_status,
|
||||||
pow_hash: x.pow_hash.map_or_else(String::new, hex::encode),
|
pow_hash: x.pow_hash.map_or_else(HexVec::new, |a| HexVec(a.into())),
|
||||||
prev_hash: Hex(x.prev_hash),
|
prev_hash: Hex(x.prev_hash),
|
||||||
reward: x.reward,
|
reward: x.reward,
|
||||||
timestamp: x.timestamp,
|
timestamp: x.timestamp,
|
||||||
|
@ -178,7 +178,7 @@ impl From<TxInfo> for crate::misc::TxInfo {
|
||||||
max_used_block_id_hash: Hex(x.max_used_block_id_hash),
|
max_used_block_id_hash: Hex(x.max_used_block_id_hash),
|
||||||
receive_time: x.receive_time,
|
receive_time: x.receive_time,
|
||||||
relayed: x.relayed,
|
relayed: x.relayed,
|
||||||
tx_blob: hex::encode(x.tx_blob),
|
tx_blob: HexVec(x.tx_blob),
|
||||||
tx_json: x.tx_json,
|
tx_json: x.tx_json,
|
||||||
weight: x.weight,
|
weight: x.weight,
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,11 @@ impl From<crate::misc::OutKeyBin> for crate::misc::OutKey {
|
||||||
mask: Hex(x.mask),
|
mask: Hex(x.mask),
|
||||||
unlocked: x.unlocked,
|
unlocked: x.unlocked,
|
||||||
height: x.height,
|
height: x.height,
|
||||||
txid: hex::encode(x.txid),
|
txid: if x.txid == [0; 32] {
|
||||||
|
HexVec::new()
|
||||||
|
} else {
|
||||||
|
HexVec::from(x.txid)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use cuprate_hex::Hex;
|
use cuprate_hex::{Hex, HexVec};
|
||||||
use cuprate_types::rpc::{AuxPow, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry};
|
use cuprate_types::rpc::{AuxPow, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -79,7 +79,7 @@ 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 = default::<String>(), "default",
|
extra_nonce: String = default::<String>(), "default",
|
||||||
prev_block: String = default::<String>(), "default",
|
prev_block: HexVec = default::<HexVec>(), "default",
|
||||||
|
|
||||||
// Another optional expression:
|
// Another optional expression:
|
||||||
// This indicates to the macro to (de)serialize
|
// This indicates to the macro to (de)serialize
|
||||||
|
@ -116,13 +116,14 @@ define_request_and_response! {
|
||||||
// status: crate::Status,
|
// status: crate::Status,
|
||||||
// untrusted: bool,
|
// untrusted: bool,
|
||||||
// ```
|
// ```
|
||||||
blockhashing_blob: String,
|
blockhashing_blob: HexVec,
|
||||||
blocktemplate_blob: String,
|
blocktemplate_blob: HexVec,
|
||||||
difficulty_top64: u64,
|
difficulty_top64: u64,
|
||||||
difficulty: u64,
|
difficulty: u64,
|
||||||
expected_reward: u64,
|
expected_reward: u64,
|
||||||
height: u64,
|
height: u64,
|
||||||
next_seed_hash: String,
|
/// This is a [`Hex<32>`] that is sometimes empty.
|
||||||
|
next_seed_hash: HexVec,
|
||||||
prev_hash: Hex<32>,
|
prev_hash: Hex<32>,
|
||||||
reserved_offset: u64,
|
reserved_offset: u64,
|
||||||
seed_hash: Hex<32>,
|
seed_hash: Hex<32>,
|
||||||
|
@ -179,7 +180,7 @@ define_request_and_response! {
|
||||||
Request {
|
Request {
|
||||||
// This is `std::vector<std::string>` in `monerod` but
|
// This is `std::vector<std::string>` in `monerod` but
|
||||||
// it must be a 1 length array or else it will error.
|
// it must be a 1 length array or else it will error.
|
||||||
block_blob: [String; 1],
|
block_blob: [HexVec; 1],
|
||||||
},
|
},
|
||||||
|
|
||||||
// FIXME: `cuprate_test_utils` only has an `error` response for this.
|
// FIXME: `cuprate_test_utils` only has an `error` response for this.
|
||||||
|
@ -197,7 +198,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
Request {
|
Request {
|
||||||
amount_of_blocks: u64,
|
amount_of_blocks: u64,
|
||||||
prev_block: String = default::<String>(), "default",
|
prev_block: HexVec = default::<HexVec>(), "default",
|
||||||
starting_nonce: u32,
|
starting_nonce: u32,
|
||||||
wallet_address: String,
|
wallet_address: String,
|
||||||
},
|
},
|
||||||
|
@ -290,13 +291,15 @@ 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 = default::<String>(), "default",
|
|
||||||
|
/// This is a [`Hex<32>`] that is sometimes empty.
|
||||||
|
hash: HexVec = default::<HexVec>(), "default",
|
||||||
height: u64 = default::<u64>(), "default",
|
height: u64 = default::<u64>(), "default",
|
||||||
fill_pow_hash: bool = default::<bool>(), "default",
|
fill_pow_hash: bool = default::<bool>(), "default",
|
||||||
},
|
},
|
||||||
|
|
||||||
AccessResponseBase {
|
AccessResponseBase {
|
||||||
blob: String,
|
blob: HexVec,
|
||||||
block_header: BlockHeader,
|
block_header: BlockHeader,
|
||||||
/// `cuprate_types::json::block::Block` should be used
|
/// `cuprate_types::json::block::Block` should be used
|
||||||
/// to create this JSON string in a type-safe manner.
|
/// to create this JSON string in a type-safe manner.
|
||||||
|
@ -662,7 +665,7 @@ define_request_and_response! {
|
||||||
Request {
|
Request {
|
||||||
major_version: u8,
|
major_version: u8,
|
||||||
height: u64,
|
height: u64,
|
||||||
block_blob: String,
|
block_blob: HexVec,
|
||||||
seed_hash: Hex<32>,
|
seed_hash: Hex<32>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -697,13 +700,13 @@ define_request_and_response! {
|
||||||
AddAuxPow,
|
AddAuxPow,
|
||||||
|
|
||||||
Request {
|
Request {
|
||||||
blocktemplate_blob: String,
|
blocktemplate_blob: HexVec,
|
||||||
aux_pow: Vec<AuxPow>,
|
aux_pow: Vec<AuxPow>,
|
||||||
},
|
},
|
||||||
|
|
||||||
ResponseBase {
|
ResponseBase {
|
||||||
blocktemplate_blob: String,
|
blocktemplate_blob: HexVec,
|
||||||
blockhashing_blob: String,
|
blockhashing_blob: HexVec,
|
||||||
merkle_root: Hex<32>,
|
merkle_root: Hex<32>,
|
||||||
merkle_tree_depth: u64,
|
merkle_tree_depth: u64,
|
||||||
aux_pow: Vec<AuxPow>,
|
aux_pow: Vec<AuxPow>,
|
||||||
|
@ -722,7 +725,7 @@ define_request_and_response! {
|
||||||
num_matching_bits: u32,
|
num_matching_bits: u32,
|
||||||
},
|
},
|
||||||
ResponseBase {
|
ResponseBase {
|
||||||
txids: Vec<String>,
|
txids: Vec<Hex<32>>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,7 +962,7 @@ mod test {
|
||||||
test_json_request(json::GET_BLOCK_TEMPLATE_REQUEST, GetBlockTemplateRequest {
|
test_json_request(json::GET_BLOCK_TEMPLATE_REQUEST, GetBlockTemplateRequest {
|
||||||
reserve_size: 60,
|
reserve_size: 60,
|
||||||
extra_nonce: String::default(),
|
extra_nonce: String::default(),
|
||||||
prev_block: String::default(),
|
prev_block: HexVec::default(),
|
||||||
wallet_address: "44GBHzv6ZyQdJkjqZje6KLZ3xSyN1hBSFAnLP6EAqJtCRVzMzZmeXTC2AHKDS9aEDTRKmo6a6o9r9j86pYfhCWDkKjbtcns".into(),
|
wallet_address: "44GBHzv6ZyQdJkjqZje6KLZ3xSyN1hBSFAnLP6EAqJtCRVzMzZmeXTC2AHKDS9aEDTRKmo6a6o9r9j86pYfhCWDkKjbtcns".into(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -968,13 +971,13 @@ mod test {
|
||||||
fn get_block_template_response() {
|
fn get_block_template_response() {
|
||||||
test_json_response(json::GET_BLOCK_TEMPLATE_RESPONSE, GetBlockTemplateResponse {
|
test_json_response(json::GET_BLOCK_TEMPLATE_RESPONSE, GetBlockTemplateResponse {
|
||||||
base: ResponseBase::OK,
|
base: ResponseBase::OK,
|
||||||
blockhashing_blob: "1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a00000000e0c20372be23d356347091025c5b5e8f2abf83ab618378565cce2b703491523401".into(),
|
blockhashing_blob: HexVec(hex!("1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a00000000e0c20372be23d356347091025c5b5e8f2abf83ab618378565cce2b703491523401").into()),
|
||||||
blocktemplate_blob: "1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(),
|
blocktemplate_blob: HexVec(hex!("1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()),
|
||||||
difficulty_top64: 0,
|
difficulty_top64: 0,
|
||||||
difficulty: 283305047039,
|
difficulty: 283305047039,
|
||||||
expected_reward: 600000000000,
|
expected_reward: 600000000000,
|
||||||
height: 3195018,
|
height: 3195018,
|
||||||
next_seed_hash: String::new(),
|
next_seed_hash: HexVec::new(),
|
||||||
prev_hash: Hex(hex!("9d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a")),
|
prev_hash: Hex(hex!("9d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a")),
|
||||||
reserved_offset: 131,
|
reserved_offset: 131,
|
||||||
seed_hash: Hex(hex!("e2aa0b7b55042cd48b02e395d78fa66a29815ccc1584e38db2d1f0e8485cd44f")),
|
seed_hash: Hex(hex!("e2aa0b7b55042cd48b02e395d78fa66a29815ccc1584e38db2d1f0e8485cd44f")),
|
||||||
|
@ -1019,7 +1022,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn submit_block_request() {
|
fn submit_block_request() {
|
||||||
test_json_request(json::SUBMIT_BLOCK_REQUEST, SubmitBlockRequest {
|
test_json_request(json::SUBMIT_BLOCK_REQUEST, SubmitBlockRequest {
|
||||||
block_blob: ["0707e6bdfedc053771512f1bc27c62731ae9e8f2443db64ce742f4e57f5cf8d393de28551e441a0000000002fb830a01ffbf830a018cfe88bee283060274c0aae2ef5730e680308d9c00b6da59187ad0352efe3c71d36eeeb28782f29f2501bd56b952c3ddc3e350c2631d3a5086cac172c56893831228b17de296ff4669de020200000000".into()],
|
block_blob: [HexVec(hex!("0707e6bdfedc053771512f1bc27c62731ae9e8f2443db64ce742f4e57f5cf8d393de28551e441a0000000002fb830a01ffbf830a018cfe88bee283060274c0aae2ef5730e680308d9c00b6da59187ad0352efe3c71d36eeeb28782f29f2501bd56b952c3ddc3e350c2631d3a5086cac172c56893831228b17de296ff4669de020200000000").into())],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1027,7 +1030,7 @@ mod test {
|
||||||
fn generate_blocks_request() {
|
fn generate_blocks_request() {
|
||||||
test_json_request(json::GENERATE_BLOCKS_REQUEST, GenerateBlocksRequest {
|
test_json_request(json::GENERATE_BLOCKS_REQUEST, GenerateBlocksRequest {
|
||||||
amount_of_blocks: 1,
|
amount_of_blocks: 1,
|
||||||
prev_block: String::default(),
|
prev_block: HexVec::default(),
|
||||||
wallet_address: "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A".into(),
|
wallet_address: "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A".into(),
|
||||||
starting_nonce: 0
|
starting_nonce: 0
|
||||||
});
|
});
|
||||||
|
@ -1074,7 +1077,7 @@ mod test {
|
||||||
nonce: 1885649739,
|
nonce: 1885649739,
|
||||||
num_txes: 37,
|
num_txes: 37,
|
||||||
orphan_status: false,
|
orphan_status: false,
|
||||||
pow_hash: String::new(),
|
pow_hash: HexVec::new(),
|
||||||
prev_hash: Hex(hex!(
|
prev_hash: Hex(hex!(
|
||||||
"22c72248ae9c5a2863c94735d710a3525c499f70707d1c2f395169bc5c8a0da3"
|
"22c72248ae9c5a2863c94735d710a3525c499f70707d1c2f395169bc5c8a0da3"
|
||||||
)),
|
)),
|
||||||
|
@ -1129,7 +1132,7 @@ mod test {
|
||||||
nonce: 1646,
|
nonce: 1646,
|
||||||
num_txes: 0,
|
num_txes: 0,
|
||||||
orphan_status: false,
|
orphan_status: false,
|
||||||
pow_hash: String::new(),
|
pow_hash: HexVec::new(),
|
||||||
prev_hash: Hex(hex!(
|
prev_hash: Hex(hex!(
|
||||||
"b61c58b2e0be53fad5ef9d9731a55e8a81d972b8d90ed07c04fd37ca6403ff78"
|
"b61c58b2e0be53fad5ef9d9731a55e8a81d972b8d90ed07c04fd37ca6403ff78"
|
||||||
)),
|
)),
|
||||||
|
@ -1180,7 +1183,7 @@ mod test {
|
||||||
nonce: 1646,
|
nonce: 1646,
|
||||||
num_txes: 0,
|
num_txes: 0,
|
||||||
orphan_status: false,
|
orphan_status: false,
|
||||||
pow_hash: String::new(),
|
pow_hash: HexVec::new(),
|
||||||
prev_hash: Hex(hex!(
|
prev_hash: Hex(hex!(
|
||||||
"b61c58b2e0be53fad5ef9d9731a55e8a81d972b8d90ed07c04fd37ca6403ff78"
|
"b61c58b2e0be53fad5ef9d9731a55e8a81d972b8d90ed07c04fd37ca6403ff78"
|
||||||
)),
|
)),
|
||||||
|
@ -1233,7 +1236,7 @@ mod test {
|
||||||
nonce: 3246403956,
|
nonce: 3246403956,
|
||||||
num_txes: 20,
|
num_txes: 20,
|
||||||
orphan_status: false,
|
orphan_status: false,
|
||||||
pow_hash: String::new(),
|
pow_hash: HexVec::new(),
|
||||||
prev_hash: Hex(hex!(
|
prev_hash: Hex(hex!(
|
||||||
"0ef6e948f77b8f8806621003f5de24b1bcbea150bc0e376835aea099674a5db5"
|
"0ef6e948f77b8f8806621003f5de24b1bcbea150bc0e376835aea099674a5db5"
|
||||||
)),
|
)),
|
||||||
|
@ -1263,7 +1266,7 @@ mod test {
|
||||||
nonce: 3737164176,
|
nonce: 3737164176,
|
||||||
num_txes: 1,
|
num_txes: 1,
|
||||||
orphan_status: false,
|
orphan_status: false,
|
||||||
pow_hash: String::new(),
|
pow_hash: HexVec::new(),
|
||||||
prev_hash: Hex(hex!(
|
prev_hash: Hex(hex!(
|
||||||
"86d1d20a40cefcf3dd410ff6967e0491613b77bf73ea8f1bf2e335cf9cf7d57a"
|
"86d1d20a40cefcf3dd410ff6967e0491613b77bf73ea8f1bf2e335cf9cf7d57a"
|
||||||
)),
|
)),
|
||||||
|
@ -1283,7 +1286,7 @@ mod test {
|
||||||
json::GET_BLOCK_REQUEST,
|
json::GET_BLOCK_REQUEST,
|
||||||
GetBlockRequest {
|
GetBlockRequest {
|
||||||
height: 2751506,
|
height: 2751506,
|
||||||
hash: String::new(),
|
hash: HexVec::new(),
|
||||||
fill_pow_hash: false,
|
fill_pow_hash: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1293,7 +1296,7 @@ mod test {
|
||||||
fn get_block_response() {
|
fn get_block_response() {
|
||||||
test_json_response(json::GET_BLOCK_RESPONSE, GetBlockResponse {
|
test_json_response(json::GET_BLOCK_RESPONSE, GetBlockResponse {
|
||||||
base: AccessResponseBase::OK,
|
base: AccessResponseBase::OK,
|
||||||
blob: "1010c58bab9b06b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7807e07f502cef8a70101ff92f8a7010180e0a596bb1103d7cbf826b665d7a532c316982dc8dbc24f285cbc18bbcc27c7164cd9b3277a85d034019f629d8b36bd16a2bfce3ea80c31dc4d8762c67165aec21845494e32b7582fe00211000000297a787a000000000000000000000000".into(),
|
blob: HexVec(hex!("1010c58bab9b06b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7807e07f502cef8a70101ff92f8a7010180e0a596bb1103d7cbf826b665d7a532c316982dc8dbc24f285cbc18bbcc27c7164cd9b3277a85d034019f629d8b36bd16a2bfce3ea80c31dc4d8762c67165aec21845494e32b7582fe00211000000297a787a000000000000000000000000").into()),
|
||||||
block_header: BlockHeader {
|
block_header: BlockHeader {
|
||||||
block_size: 106,
|
block_size: 106,
|
||||||
block_weight: 106,
|
block_weight: 106,
|
||||||
|
@ -1311,7 +1314,7 @@ mod test {
|
||||||
nonce: 4110909056,
|
nonce: 4110909056,
|
||||||
num_txes: 0,
|
num_txes: 0,
|
||||||
orphan_status: false,
|
orphan_status: false,
|
||||||
pow_hash: String::new(),
|
pow_hash: HexVec::new(),
|
||||||
prev_hash: Hex(hex!("b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7")),
|
prev_hash: Hex(hex!("b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7")),
|
||||||
reward: 600000000000,
|
reward: 600000000000,
|
||||||
timestamp: 1667941829,
|
timestamp: 1667941829,
|
||||||
|
@ -1904,7 +1907,7 @@ mod test {
|
||||||
test_json_request(json::CALC_POW_REQUEST, CalcPowRequest {
|
test_json_request(json::CALC_POW_REQUEST, CalcPowRequest {
|
||||||
major_version: 14,
|
major_version: 14,
|
||||||
height: 2286447,
|
height: 2286447,
|
||||||
block_blob: "0e0ed286da8006ecdc1aab3033cf1716c52f13f9d8ae0051615a2453643de94643b550d543becd0000000002abc78b0101ffefc68b0101fcfcf0d4b422025014bb4a1eade6622fd781cb1063381cad396efa69719b41aa28b4fce8c7ad4b5f019ce1dc670456b24a5e03c2d9058a2df10fec779e2579753b1847b74ee644f16b023c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051399a1bc46a846474f5b33db24eae173a26393b976054ee14f9feefe99925233802867097564c9db7a36af5bb5ed33ab46e63092bd8d32cef121608c3258edd55562812e21cc7e3ac73045745a72f7d74581d9a0849d6f30e8b2923171253e864f4e9ddea3acb5bc755f1c4a878130a70c26297540bc0b7a57affb6b35c1f03d8dbd54ece8457531f8cba15bb74516779c01193e212050423020e45aa2c15dcb".into(),
|
block_blob: HexVec(hex!("0e0ed286da8006ecdc1aab3033cf1716c52f13f9d8ae0051615a2453643de94643b550d543becd0000000002abc78b0101ffefc68b0101fcfcf0d4b422025014bb4a1eade6622fd781cb1063381cad396efa69719b41aa28b4fce8c7ad4b5f019ce1dc670456b24a5e03c2d9058a2df10fec779e2579753b1847b74ee644f16b023c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051399a1bc46a846474f5b33db24eae173a26393b976054ee14f9feefe99925233802867097564c9db7a36af5bb5ed33ab46e63092bd8d32cef121608c3258edd55562812e21cc7e3ac73045745a72f7d74581d9a0849d6f30e8b2923171253e864f4e9ddea3acb5bc755f1c4a878130a70c26297540bc0b7a57affb6b35c1f03d8dbd54ece8457531f8cba15bb74516779c01193e212050423020e45aa2c15dcb").into()),
|
||||||
seed_hash: Hex(hex!("d432f499205150873b2572b5f033c9c6e4b7c6f3394bd2dd93822cd7085e7307")),
|
seed_hash: Hex(hex!("d432f499205150873b2572b5f033c9c6e4b7c6f3394bd2dd93822cd7085e7307")),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1945,7 +1948,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn add_aux_pow_request() {
|
fn add_aux_pow_request() {
|
||||||
test_json_request(json::ADD_AUX_POW_REQUEST, AddAuxPowRequest {
|
test_json_request(json::ADD_AUX_POW_REQUEST, AddAuxPowRequest {
|
||||||
blocktemplate_blob: "1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(),
|
blocktemplate_blob: HexVec(hex!("1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()),
|
||||||
aux_pow: vec![AuxPow {
|
aux_pow: vec![AuxPow {
|
||||||
id: Hex(hex!("3200b4ea97c3b2081cd4190b58e49572b2319fed00d030ad51809dff06b5d8c8")),
|
id: Hex(hex!("3200b4ea97c3b2081cd4190b58e49572b2319fed00d030ad51809dff06b5d8c8")),
|
||||||
hash: Hex(hex!("7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a"))
|
hash: Hex(hex!("7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a"))
|
||||||
|
@ -1961,8 +1964,8 @@ mod test {
|
||||||
hash: Hex(hex!("7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a")),
|
hash: Hex(hex!("7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a")),
|
||||||
id: Hex(hex!("3200b4ea97c3b2081cd4190b58e49572b2319fed00d030ad51809dff06b5d8c8")),
|
id: Hex(hex!("3200b4ea97c3b2081cd4190b58e49572b2319fed00d030ad51809dff06b5d8c8")),
|
||||||
}],
|
}],
|
||||||
blockhashing_blob: "1010ee97e2a106e9f8ebe8887e5b609949ac8ea6143e560ed13552b110cb009b21f0cfca1eaccf00000000b2685c1283a646bc9020c758daa443be145b7370ce5a6efacb3e614117032e2c22".into(),
|
blockhashing_blob: HexVec(hex!("1010ee97e2a106e9f8ebe8887e5b609949ac8ea6143e560ed13552b110cb009b21f0cfca1eaccf00000000b2685c1283a646bc9020c758daa443be145b7370ce5a6efacb3e614117032e2c22").into()),
|
||||||
blocktemplate_blob: "1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into(),
|
blocktemplate_blob: HexVec(hex!("1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()),
|
||||||
merkle_root: Hex(hex!("7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a")),
|
merkle_root: Hex(hex!("7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a")),
|
||||||
merkle_tree_depth: 0,
|
merkle_tree_depth: 0,
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,7 @@ use cuprate_epee_encoding::{
|
||||||
EpeeObject, EpeeObjectBuilder,
|
EpeeObject, EpeeObjectBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
use cuprate_hex::Hex;
|
use cuprate_hex::{Hex, HexVec};
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use crate::serde::{serde_false, serde_true};
|
use crate::serde::{serde_false, serde_true};
|
||||||
|
@ -37,12 +37,12 @@ pub struct TxEntry {
|
||||||
/// to create this JSON string in a type-safe manner.
|
/// to create this JSON string in a type-safe manner.
|
||||||
pub as_json: String,
|
pub as_json: String,
|
||||||
|
|
||||||
pub as_hex: String,
|
pub as_hex: HexVec,
|
||||||
pub double_spend_seen: bool,
|
pub double_spend_seen: bool,
|
||||||
pub tx_hash: Hex<32>,
|
pub tx_hash: Hex<32>,
|
||||||
pub prunable_as_hex: String,
|
pub prunable_as_hex: HexVec,
|
||||||
pub prunable_hash: Hex<32>,
|
pub prunable_hash: Hex<32>,
|
||||||
pub pruned_as_hex: String,
|
pub pruned_as_hex: HexVec,
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||||
pub tx_entry_type: TxEntryType,
|
pub tx_entry_type: TxEntryType,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//! the [`crate::misc::ConnectionInfo`] struct defined here.
|
//! the [`crate::misc::ConnectionInfo`] struct defined here.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use cuprate_hex::Hex;
|
use cuprate_hex::{Hex, HexVec};
|
||||||
use cuprate_types::HardFork;
|
use cuprate_types::HardFork;
|
||||||
|
|
||||||
#[cfg(any(feature = "epee", feature = "serde"))]
|
#[cfg(any(feature = "epee", feature = "serde"))]
|
||||||
|
@ -92,8 +92,8 @@ define_struct_and_impl_epee! {
|
||||||
nonce: u32,
|
nonce: u32,
|
||||||
num_txes: u64,
|
num_txes: u64,
|
||||||
orphan_status: bool,
|
orphan_status: bool,
|
||||||
/// This is an empty string if the `fill_pow_hash` param is `false`.
|
/// This is a [`Hex<32>`] that is sometimes empty.
|
||||||
pow_hash: String,
|
pow_hash: HexVec,
|
||||||
prev_hash: Hex<32>,
|
prev_hash: Hex<32>,
|
||||||
reward: u64,
|
reward: u64,
|
||||||
timestamp: u64,
|
timestamp: u64,
|
||||||
|
@ -264,8 +264,8 @@ define_struct_and_impl_epee! {
|
||||||
mask: Hex<32>,
|
mask: Hex<32>,
|
||||||
unlocked: bool,
|
unlocked: bool,
|
||||||
height: u64,
|
height: u64,
|
||||||
/// Optionally empty with `/get_outs`'s `"get_txid": false`.
|
/// This is a [`Hex<32>`] that is sometimes empty.
|
||||||
txid: String,
|
txid: HexVec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ define_struct_and_impl_epee! {
|
||||||
max_used_block_id_hash: Hex<32>,
|
max_used_block_id_hash: Hex<32>,
|
||||||
receive_time: u64,
|
receive_time: u64,
|
||||||
relayed: bool,
|
relayed: bool,
|
||||||
tx_blob: String,
|
tx_blob: HexVec,
|
||||||
tx_json: cuprate_types::json::tx::Transaction,
|
tx_json: cuprate_types::json::tx::Transaction,
|
||||||
weight: u64 = default::<u64>(),
|
weight: u64 = default::<u64>(),
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -2,6 +2,8 @@
|
||||||
// Allow some lints when running in debug mode.
|
// Allow some lints when running in debug mode.
|
||||||
#![cfg_attr(debug_assertions, allow(clippy::todo, clippy::multiple_crate_versions))]
|
#![cfg_attr(debug_assertions, allow(clippy::todo, clippy::multiple_crate_versions))]
|
||||||
|
|
||||||
mod hex;
|
mod array;
|
||||||
|
mod vec;
|
||||||
|
|
||||||
pub use hex::Hex;
|
pub use array::Hex;
|
||||||
|
pub use vec::HexVec;
|
||||||
|
|
124
types/hex/src/vec.rs
Normal file
124
types/hex/src/vec.rs
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
//! Hexadecimal serde wrappers for [`Vec<u8>`].
|
||||||
|
//!
|
||||||
|
//! This module provides transparent wrapper types for
|
||||||
|
//! arrays that (de)serialize from hexadecimal input/output.
|
||||||
|
|
||||||
|
use hex::FromHexError;
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
|
|
||||||
|
/// Wrapper type for a byte [`Vec`] that (de)serializes from/to hexadecimal strings.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use cuprate_hex::HexVec;
|
||||||
|
/// let hash = [1; 32];
|
||||||
|
/// let hex_bytes = HexVec(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::<HexVec>(expected_json).unwrap();
|
||||||
|
/// 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<HexVec>>(expected_json).unwrap();
|
||||||
|
/// assert_eq!(vec, from_str);
|
||||||
|
/// ```
|
||||||
|
#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct HexVec(#[serde(with = "hex::serde")] pub Vec<u8>);
|
||||||
|
|
||||||
|
impl HexVec {
|
||||||
|
/// [`Vec::new`].
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Self(Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`Vec::is_empty`].
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO
|
||||||
|
pub fn empty_if_zeroed<const N: usize>(array: [u8; N]) -> Self {
|
||||||
|
if array == [0; N] {
|
||||||
|
Self(Vec::new())
|
||||||
|
} else {
|
||||||
|
Self(array.to_vec())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for HexVec {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Ok(Self(hex::serde::deserialize(deserializer)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<HexVec> for Vec<u8> {
|
||||||
|
fn from(hex: HexVec) -> Self {
|
||||||
|
hex.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<u8>> for HexVec {
|
||||||
|
fn from(value: Vec<u8>) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> From<[u8; N]> for HexVec {
|
||||||
|
fn from(value: [u8; N]) -> Self {
|
||||||
|
Self(value.to_vec())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<String> for HexVec {
|
||||||
|
type Error = FromHexError;
|
||||||
|
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||||
|
hex::decode(value).map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&str> for HexVec {
|
||||||
|
type Error = FromHexError;
|
||||||
|
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||||
|
hex::decode(value).map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> TryFrom<HexVec> for [u8; N] {
|
||||||
|
type Error = FromHexError;
|
||||||
|
fn try_from(value: HexVec) -> Result<Self, Self::Error> {
|
||||||
|
Self::try_from(value.0).map_err(|_| FromHexError::InvalidStringLength)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn asdf() {
|
||||||
|
let hash = vec![0; 32];
|
||||||
|
let hex_bytes = HexVec(hash);
|
||||||
|
let expected_json = r#""0000000000000000000000000000000000000000000000000000000000000000""#;
|
||||||
|
|
||||||
|
let to_string = serde_json::to_string(&hex_bytes).unwrap();
|
||||||
|
assert_eq!(to_string, expected_json);
|
||||||
|
|
||||||
|
let from_str = serde_json::from_str::<HexVec>(expected_json).unwrap();
|
||||||
|
assert_eq!(hex_bytes, from_str);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue