mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-23 12:09:57 +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",
|
"bytes",
|
||||||
"cuprate-fixed-bytes",
|
"cuprate-fixed-bytes",
|
||||||
"cuprate-helper",
|
"cuprate-helper",
|
||||||
"cuprate-hex",
|
|
||||||
"hex",
|
"hex",
|
||||||
"paste",
|
"paste",
|
||||||
"ref-cast",
|
"ref-cast",
|
||||||
|
@ -941,15 +940,6 @@ 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"
|
||||||
|
@ -1078,7 +1068,6 @@ 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",
|
||||||
|
@ -1147,8 +1136,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",
|
||||||
|
@ -1180,7 +1169,7 @@ name = "cuprate-zmq-types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert-json-diff",
|
"assert-json-diff",
|
||||||
"cuprate-hex",
|
"cuprate-types",
|
||||||
"hex",
|
"hex",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -1217,7 +1206,6 @@ dependencies = [
|
||||||
"cuprate-fast-sync",
|
"cuprate-fast-sync",
|
||||||
"cuprate-fixed-bytes",
|
"cuprate-fixed-bytes",
|
||||||
"cuprate-helper",
|
"cuprate-helper",
|
||||||
"cuprate-hex",
|
|
||||||
"cuprate-json-rpc",
|
"cuprate-json-rpc",
|
||||||
"cuprate-levin",
|
"cuprate-levin",
|
||||||
"cuprate-p2p",
|
"cuprate-p2p",
|
||||||
|
|
16
Cargo.toml
16
Cargo.toml
|
@ -19,6 +19,7 @@ members = [
|
||||||
|
|
||||||
# Net
|
# Net
|
||||||
"net/epee-encoding",
|
"net/epee-encoding",
|
||||||
|
"net/fixed-bytes",
|
||||||
"net/levin",
|
"net/levin",
|
||||||
"net/wire",
|
"net/wire",
|
||||||
|
|
||||||
|
@ -27,8 +28,8 @@ members = [
|
||||||
"p2p/p2p-core",
|
"p2p/p2p-core",
|
||||||
"p2p/bucket",
|
"p2p/bucket",
|
||||||
"p2p/dandelion-tower",
|
"p2p/dandelion-tower",
|
||||||
"p2p/address-book",
|
|
||||||
"p2p/async-buffer",
|
"p2p/async-buffer",
|
||||||
|
"p2p/address-book",
|
||||||
|
|
||||||
# Storage
|
# Storage
|
||||||
"storage/blockchain",
|
"storage/blockchain",
|
||||||
|
@ -36,11 +37,6 @@ members = [
|
||||||
"storage/txpool",
|
"storage/txpool",
|
||||||
"storage/database",
|
"storage/database",
|
||||||
|
|
||||||
# Types
|
|
||||||
"types/types",
|
|
||||||
"types/hex",
|
|
||||||
"types/fixed-bytes",
|
|
||||||
|
|
||||||
# RPC
|
# RPC
|
||||||
"rpc/json-rpc",
|
"rpc/json-rpc",
|
||||||
"rpc/types",
|
"rpc/types",
|
||||||
|
@ -55,6 +51,7 @@ members = [
|
||||||
"helper",
|
"helper",
|
||||||
"pruning",
|
"pruning",
|
||||||
"test-utils",
|
"test-utils",
|
||||||
|
"types",
|
||||||
]
|
]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
@ -88,13 +85,14 @@ 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-async-buffer = { path = "p2p/async-buffer", 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 }
|
||||||
|
@ -102,9 +100,7 @@ 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/types", default-features = false }
|
cuprate-types = { path = "types", default-features = false }
|
||||||
cuprate-hex = { path = "types/hex", default-features = false }
|
|
||||||
cuprate-fixed-bytes = { path = "types/fixed-bytes", 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 }
|
||||||
|
|
|
@ -32,7 +32,6 @@ cuprate-database = { workspace = true, features = ["serde"] }
|
||||||
cuprate-pruning = { workspace = true }
|
cuprate-pruning = { workspace = true }
|
||||||
cuprate-test-utils = { workspace = true }
|
cuprate-test-utils = { workspace = true }
|
||||||
cuprate-types = { workspace = true, features = ["json"] }
|
cuprate-types = { workspace = true, features = ["json"] }
|
||||||
cuprate-hex = { workspace = true }
|
|
||||||
cuprate-json-rpc = { workspace = true }
|
cuprate-json-rpc = { workspace = true }
|
||||||
cuprate-rpc-interface = { workspace = true }
|
cuprate-rpc-interface = { workspace = true }
|
||||||
cuprate-rpc-types = { workspace = true, features = ["from"] }
|
cuprate-rpc-types = { workspace = true, features = ["from"] }
|
||||||
|
|
|
@ -66,7 +66,7 @@ pub enum BlockchainManagerRequest {
|
||||||
/// Number of the blocks to be generated.
|
/// Number of the blocks to be generated.
|
||||||
amount_of_blocks: u64,
|
amount_of_blocks: u64,
|
||||||
/// The previous block's hash.
|
/// The previous block's hash.
|
||||||
prev_block: Option<[u8; 32]>,
|
prev_block: [u8; 32],
|
||||||
/// The starting value for the nonce.
|
/// The starting value for the nonce.
|
||||||
starting_nonce: u32,
|
starting_nonce: u32,
|
||||||
/// The address that will receive the coinbase reward.
|
/// 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},
|
cast::{u32_to_usize, u64_to_usize, usize_to_u64},
|
||||||
map::split_u128_into_low_high_bits,
|
map::split_u128_into_low_high_bits,
|
||||||
};
|
};
|
||||||
use cuprate_hex::Hex;
|
|
||||||
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::{
|
||||||
|
@ -52,6 +51,7 @@ use cuprate_rpc_types::{
|
||||||
CORE_RPC_VERSION,
|
CORE_RPC_VERSION,
|
||||||
};
|
};
|
||||||
use cuprate_types::{
|
use cuprate_types::{
|
||||||
|
hex::Hex,
|
||||||
rpc::{AuxPow, CoinbaseTxSum, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry},
|
rpc::{AuxPow, CoinbaseTxSum, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry},
|
||||||
HardFork,
|
HardFork,
|
||||||
};
|
};
|
||||||
|
@ -260,7 +260,7 @@ async fn submit_block(
|
||||||
let [blob] = request.block_blob;
|
let [blob] = request.block_blob;
|
||||||
let bytes = hex::decode(blob)?;
|
let bytes = hex::decode(blob)?;
|
||||||
let block = Block::read(&mut bytes.as_slice())?;
|
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.
|
// Attempt to relay the block.
|
||||||
blockchain_manager::relay_block(&mut state.blockchain_manager, Box::new(block)).await?;
|
blockchain_manager::relay_block(&mut state.blockchain_manager, Box::new(block)).await?;
|
||||||
|
@ -283,11 +283,7 @@ async fn generate_blocks(
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// is this field only used as a local variable in the handler in `monerod`?
|
// is this field only used as a local variable in the handler in `monerod`?
|
||||||
// It may not be needed in the request type.
|
// It may not be needed in the request type.
|
||||||
let prev_block = if request.prev_block.is_empty() {
|
let prev_block = helper::hex_to_hash(request.prev_block)?;
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(helper::hex_to_hash(request.prev_block)?)
|
|
||||||
};
|
|
||||||
|
|
||||||
let (blocks, height) = blockchain_manager::generate_blocks(
|
let (blocks, height) = blockchain_manager::generate_blocks(
|
||||||
&mut state.blockchain_manager,
|
&mut state.blockchain_manager,
|
||||||
|
@ -298,7 +294,7 @@ async fn generate_blocks(
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let blocks = blocks.into_iter().map(Hex).collect();
|
let blocks = blocks.into_iter().map(hex::encode).collect();
|
||||||
|
|
||||||
Ok(GenerateBlocksResponse {
|
Ok(GenerateBlocksResponse {
|
||||||
base: ResponseBase::OK,
|
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.
|
// 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::hex_to_hash(hash)?;
|
||||||
|
let hash = get(&mut state, hash, request.fill_pow_hash).await?;
|
||||||
block_headers.push(hash);
|
block_headers.push(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,8 +444,8 @@ async fn get_block(
|
||||||
};
|
};
|
||||||
|
|
||||||
let blob = hex::encode(block.serialize());
|
let blob = hex::encode(block.serialize());
|
||||||
let miner_tx_hash = Hex(block.miner_transaction.hash());
|
let miner_tx_hash = hex::encode(block.miner_transaction.hash());
|
||||||
let tx_hashes = block.transactions.iter().map(|a| Hex(*a)).collect();
|
let tx_hashes = block.transactions.iter().map(hex::encode).collect();
|
||||||
let json = {
|
let json = {
|
||||||
let block = cuprate_types::json::block::Block::from(block);
|
let block = cuprate_types::json::block::Block::from(block);
|
||||||
serde_json::to_string_pretty(&block)?
|
serde_json::to_string_pretty(&block)?
|
||||||
|
@ -548,7 +545,7 @@ async fn get_info(
|
||||||
let target = blockchain_manager::target(&mut state.blockchain_manager)
|
let target = blockchain_manager::target(&mut state.blockchain_manager)
|
||||||
.await?
|
.await?
|
||||||
.as_secs();
|
.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_count = blockchain::total_tx_count(&mut state.blockchain_read).await?;
|
||||||
let tx_pool_size = txpool::size(&mut state.txpool_read, !restricted).await?;
|
let tx_pool_size = txpool::size(&mut state.txpool_read, !restricted).await?;
|
||||||
let update_available = if restricted {
|
let update_available = if restricted {
|
||||||
|
@ -757,8 +754,8 @@ async fn flush_transaction_pool(
|
||||||
let tx_hashes = request
|
let tx_hashes = request
|
||||||
.txids
|
.txids
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|h| h.0)
|
.map(helper::hex_to_hash)
|
||||||
.collect::<Vec<[u8; 32]>>();
|
.collect::<Result<Vec<[u8; 32]>, _>>()?;
|
||||||
|
|
||||||
txpool::flush(&mut state.txpool_manager, tx_hashes).await?;
|
txpool::flush(&mut state.txpool_manager, tx_hashes).await?;
|
||||||
|
|
||||||
|
@ -899,8 +896,8 @@ async fn relay_tx(
|
||||||
let tx_hashes = request
|
let tx_hashes = request
|
||||||
.txids
|
.txids
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|h| h.0)
|
.map(helper::hex_to_hash)
|
||||||
.collect::<Vec<[u8; 32]>>();
|
.collect::<Result<Vec<[u8; 32]>, _>>()?;
|
||||||
|
|
||||||
txpool::relay(&mut state.txpool_manager, tx_hashes).await?;
|
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 major_version = c.current_hf.as_u8();
|
||||||
let height = usize_to_u64(c.chain_height);
|
let height = usize_to_u64(c.chain_height);
|
||||||
let prev_id = Hex(c.top_hash);
|
let prev_id = hex::encode(c.top_hash);
|
||||||
let seed_hash = Hex(c.top_hash);
|
let seed_hash = hex::encode(c.top_hash);
|
||||||
let difficulty = format!("{:#x}", c.next_difficulty);
|
let difficulty = format!("{:#x}", c.next_difficulty);
|
||||||
let median_weight = usize_to_u64(c.median_weight_for_block_reward);
|
let median_weight = usize_to_u64(c.median_weight_for_block_reward);
|
||||||
let already_generated_coins = c.already_generated_coins;
|
let already_generated_coins = c.already_generated_coins;
|
||||||
|
@ -1021,7 +1018,7 @@ async fn get_miner_data(
|
||||||
.await?
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|entry| GetMinerDataTxBacklogEntry {
|
.map(|entry| GetMinerDataTxBacklogEntry {
|
||||||
id: Hex(entry.id),
|
id: hex::encode(entry.id),
|
||||||
weight: entry.weight,
|
weight: entry.weight,
|
||||||
fee: entry.fee,
|
fee: entry.fee,
|
||||||
})
|
})
|
||||||
|
@ -1065,7 +1062,7 @@ async fn calc_pow(
|
||||||
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_blob: Vec<u8> = hex::decode(request.block_blob)?;
|
||||||
let block = Block::read(&mut block_blob.as_slice())?;
|
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!();
|
// let block_weight = todo!();
|
||||||
|
|
||||||
|
@ -1090,9 +1087,9 @@ async fn calc_pow(
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(CalcPowResponse {
|
let pow_hash = hex::encode(pow_hash);
|
||||||
pow_hash: Hex(pow_hash),
|
|
||||||
})
|
Ok(CalcPowResponse { pow_hash })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L3542-L3551>
|
/// <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(
|
pub(crate) async fn generate_blocks(
|
||||||
blockchain_manager: &mut BlockchainManagerHandle,
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
amount_of_blocks: u64,
|
amount_of_blocks: u64,
|
||||||
prev_block: Option<[u8; 32]>,
|
prev_block: [u8; 32],
|
||||||
starting_nonce: u32,
|
starting_nonce: u32,
|
||||||
wallet_address: String,
|
wallet_address: String,
|
||||||
) -> Result<(Vec<[u8; 32]>, u64), Error> {
|
) -> Result<(Vec<[u8; 32]>, u64), Error> {
|
||||||
|
|
|
@ -24,6 +24,7 @@ cargo doc --open --package cuprate-blockchain
|
||||||
| Crate | In-tree path | Purpose |
|
| 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-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-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
|
| [`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-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`
|
| [`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
|
## RPC
|
||||||
| Crate | In-tree path | Purpose |
|
| 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-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-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-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
|
## Benchmarks
|
||||||
| Crate | In-tree path | Purpose |
|
| Crate | In-tree path | Purpose |
|
||||||
|
|
|
@ -17,7 +17,6 @@ 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"
|
||||||
|
|
|
@ -8,7 +8,6 @@ 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},
|
||||||
|
@ -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 {
|
macro_rules! epee_seq {
|
||||||
($val:ty) => {
|
($val:ty) => {
|
||||||
impl EpeeValue for Vec<$val> {
|
impl EpeeValue for Vec<$val> {
|
||||||
|
|
|
@ -22,9 +22,8 @@ from = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cuprate-fixed-bytes = { workspace = true }
|
|
||||||
cuprate-hex = { workspace = true }
|
|
||||||
cuprate-epee-encoding = { workspace = true, optional = true }
|
cuprate-epee-encoding = { workspace = true, optional = true }
|
||||||
|
cuprate-fixed-bytes = { workspace = 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 }
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
//! `height`, it will use [`default_height`] to fill that in.
|
//! `height`, it will use [`default_height`] to fill that in.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
|
// use cuprate_types::hex::Hex;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TODO
|
//---------------------------------------------------------------------------------------------------- TODO
|
||||||
/// Default [`bool`] type used in request/response types, `false`.
|
/// Default [`bool`] type used in request/response types, `false`.
|
||||||
|
@ -28,6 +29,12 @@ pub(crate) const fn default_string() -> String {
|
||||||
String::new()
|
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.
|
/// Default block height used in request/response types.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) const fn default_height() -> u64 {
|
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_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::rpc::{BlockHeader, ChainInfo, HistogramEntry, TxInfo};
|
use cuprate_types::{
|
||||||
|
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 {
|
||||||
|
@ -126,7 +128,7 @@ impl From<ChainInfo> for crate::misc::ChainInfo {
|
||||||
fn from(x: ChainInfo) -> Self {
|
fn from(x: ChainInfo) -> Self {
|
||||||
Self {
|
Self {
|
||||||
block_hash: Hex(x.block_hash),
|
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_top64: x.difficulty_top64,
|
||||||
difficulty: x.difficulty,
|
difficulty: x.difficulty,
|
||||||
height: x.height,
|
height: x.height,
|
||||||
|
|
|
@ -6,8 +6,10 @@
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use cuprate_hex::Hex;
|
use cuprate_types::{
|
||||||
use cuprate_types::rpc::{AuxPow, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry};
|
hex::Hex,
|
||||||
|
rpc::{AuxPow, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
base::{AccessResponseBase, ResponseBase},
|
base::{AccessResponseBase, ResponseBase},
|
||||||
|
@ -55,6 +57,11 @@ define_request_and_response! {
|
||||||
|
|
||||||
// The request type.
|
// 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)
|
// If there are any additional attributes (`/// docs` or `#[derive]`s)
|
||||||
// for the struct, they go here.
|
// for the struct, they go here.
|
||||||
Request {
|
Request {
|
||||||
|
@ -140,6 +147,9 @@ define_request_and_response! {
|
||||||
core_rpc_server_commands_defs.h => 919..=933,
|
core_rpc_server_commands_defs.h => 919..=933,
|
||||||
GetBlockCount (empty),
|
GetBlockCount (empty),
|
||||||
|
|
||||||
|
// There are no request fields specified,
|
||||||
|
// this will cause the macro to generate a
|
||||||
|
// type alias to `()` instead of a `struct`.
|
||||||
Request {},
|
Request {},
|
||||||
|
|
||||||
ResponseBase {
|
ResponseBase {
|
||||||
|
@ -158,8 +168,8 @@ define_request_and_response! {
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Copy)]
|
#[derive(Copy)]
|
||||||
Request {
|
Request {
|
||||||
/// This is `std::vector<u64>` in `monerod` but
|
// This is `std::vector<u64>` 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_height: [u64; 1],
|
block_height: [u64; 1],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -187,7 +197,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
// FIXME: `cuprate_test_utils` only has an `error` response for this.
|
// FIXME: `cuprate_test_utils` only has an `error` response for this.
|
||||||
ResponseBase {
|
ResponseBase {
|
||||||
block_id: Hex<32>,
|
block_id: String,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +216,7 @@ define_request_and_response! {
|
||||||
},
|
},
|
||||||
|
|
||||||
ResponseBase {
|
ResponseBase {
|
||||||
blocks: Vec<Hex<32>>,
|
blocks: Vec<String>,
|
||||||
height: u64,
|
height: u64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +246,7 @@ define_request_and_response! {
|
||||||
|
|
||||||
Request {
|
Request {
|
||||||
hash: Hex<32>,
|
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",
|
fill_pow_hash: bool = default_false(), "default_false",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -301,11 +311,11 @@ define_request_and_response! {
|
||||||
AccessResponseBase {
|
AccessResponseBase {
|
||||||
blob: String,
|
blob: String,
|
||||||
block_header: BlockHeader,
|
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.
|
/// to create this JSON string in a type-safe manner.
|
||||||
json: String,
|
json: String,
|
||||||
miner_tx_hash: Hex<32>,
|
miner_tx_hash: String,
|
||||||
tx_hashes: Vec<Hex<32>> = default_vec::<Hex<32>>(), "default_vec",
|
tx_hashes: Vec<String> = default_vec::<String>(), "default_vec",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +372,7 @@ define_request_and_response! {
|
||||||
target_height: u64,
|
target_height: u64,
|
||||||
target: u64,
|
target: u64,
|
||||||
testnet: bool,
|
testnet: bool,
|
||||||
top_block_hash: Hex<32>,
|
top_block_hash: String,
|
||||||
tx_count: u64,
|
tx_count: u64,
|
||||||
tx_pool_size: u64,
|
tx_pool_size: u64,
|
||||||
update_available: bool,
|
update_available: bool,
|
||||||
|
@ -449,7 +459,7 @@ define_request_and_response! {
|
||||||
FlushTransactionPool (restricted),
|
FlushTransactionPool (restricted),
|
||||||
|
|
||||||
Request {
|
Request {
|
||||||
txids: Vec<Hex<32>> = default_vec::<Hex<32>>(), "default_vec",
|
txids: Vec<String> = default_vec::<String>(), "default_vec",
|
||||||
},
|
},
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -554,7 +564,7 @@ define_request_and_response! {
|
||||||
RelayTx (restricted),
|
RelayTx (restricted),
|
||||||
|
|
||||||
Request {
|
Request {
|
||||||
txids: Vec<Hex<32>>,
|
txids: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -631,8 +641,8 @@ define_request_and_response! {
|
||||||
ResponseBase {
|
ResponseBase {
|
||||||
major_version: u8,
|
major_version: u8,
|
||||||
height: u64,
|
height: u64,
|
||||||
prev_id: Hex<32>,
|
prev_id: String,
|
||||||
seed_hash: Hex<32>,
|
seed_hash: String,
|
||||||
difficulty: String,
|
difficulty: String,
|
||||||
median_weight: u64,
|
median_weight: u64,
|
||||||
already_generated_coins: u64,
|
already_generated_coins: u64,
|
||||||
|
@ -669,13 +679,13 @@ define_request_and_response! {
|
||||||
major_version: u8,
|
major_version: u8,
|
||||||
height: u64,
|
height: u64,
|
||||||
block_blob: String,
|
block_blob: String,
|
||||||
seed_hash: Hex<32>,
|
seed_hash: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
Response {
|
Response {
|
||||||
pow_hash: Hex<32>,
|
pow_hash: String,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1045,9 +1055,9 @@ mod test {
|
||||||
json::GENERATE_BLOCKS_RESPONSE,
|
json::GENERATE_BLOCKS_RESPONSE,
|
||||||
GenerateBlocksResponse {
|
GenerateBlocksResponse {
|
||||||
base: ResponseBase::OK,
|
base: ResponseBase::OK,
|
||||||
blocks: vec![Hex(hex!(
|
blocks: vec![
|
||||||
"49b712db7760e3728586f8434ee8bc8d7b3d410dac6bb6e98bf5845c83b917e4"
|
"49b712db7760e3728586f8434ee8bc8d7b3d410dac6bb6e98bf5845c83b917e4".into(),
|
||||||
))],
|
],
|
||||||
height: 9783,
|
height: 9783,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1289,7 +1299,7 @@ mod test {
|
||||||
json::GET_BLOCK_REQUEST,
|
json::GET_BLOCK_REQUEST,
|
||||||
GetBlockRequest {
|
GetBlockRequest {
|
||||||
height: 2751506,
|
height: 2751506,
|
||||||
hash: String::new(),
|
hash: String::default(),
|
||||||
fill_pow_hash: false,
|
fill_pow_hash: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1325,7 +1335,7 @@ mod test {
|
||||||
wide_difficulty: "0x490be69168".into()
|
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(),
|
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![],
|
tx_hashes: vec![],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1438,9 +1448,8 @@ mod test {
|
||||||
target: 120,
|
target: 120,
|
||||||
target_height: 0,
|
target_height: 0,
|
||||||
testnet: false,
|
testnet: false,
|
||||||
top_block_hash: Hex(hex!(
|
top_block_hash: "bdf06d18ed1931a8ee62654e9b6478cc459bc7072628b8e36f4524d339552946"
|
||||||
"bdf06d18ed1931a8ee62654e9b6478cc459bc7072628b8e36f4524d339552946"
|
.into(),
|
||||||
)),
|
|
||||||
tx_count: 43205750,
|
tx_count: 43205750,
|
||||||
tx_pool_size: 12,
|
tx_pool_size: 12,
|
||||||
update_available: false,
|
update_available: false,
|
||||||
|
@ -1553,9 +1562,9 @@ mod test {
|
||||||
test_json_request(
|
test_json_request(
|
||||||
json::FLUSH_TRANSACTION_POOL_REQUEST,
|
json::FLUSH_TRANSACTION_POOL_REQUEST,
|
||||||
FlushTransactionPoolRequest {
|
FlushTransactionPoolRequest {
|
||||||
txids: vec![Hex(hex!(
|
txids: vec![
|
||||||
"dc16fa8eaffe1484ca9014ea050e13131d3acf23b419f33bb4cc0b32b6c49308"
|
"dc16fa8eaffe1484ca9014ea050e13131d3acf23b419f33bb4cc0b32b6c49308".into(),
|
||||||
))],
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1684,9 +1693,10 @@ mod test {
|
||||||
block_hash: Hex(hex!(
|
block_hash: Hex(hex!(
|
||||||
"4826c7d45d7cf4f02985b5c405b0e5d7f92c8d25e015492ce19aa3b209295dce"
|
"4826c7d45d7cf4f02985b5c405b0e5d7f92c8d25e015492ce19aa3b209295dce"
|
||||||
)),
|
)),
|
||||||
block_hashes: vec![Hex(hex!(
|
block_hashes: vec![
|
||||||
"4826c7d45d7cf4f02985b5c405b0e5d7f92c8d25e015492ce19aa3b209295dce"
|
"4826c7d45d7cf4f02985b5c405b0e5d7f92c8d25e015492ce19aa3b209295dce"
|
||||||
))],
|
.into(),
|
||||||
|
],
|
||||||
difficulty: 357404825113208373,
|
difficulty: 357404825113208373,
|
||||||
difficulty_top64: 0,
|
difficulty_top64: 0,
|
||||||
height: 3167471,
|
height: 3167471,
|
||||||
|
@ -1700,9 +1710,10 @@ mod test {
|
||||||
block_hash: Hex(hex!(
|
block_hash: Hex(hex!(
|
||||||
"33ee476f5a1c5b9d889274cbbe171f5e0112df7ed69021918042525485deb401"
|
"33ee476f5a1c5b9d889274cbbe171f5e0112df7ed69021918042525485deb401"
|
||||||
)),
|
)),
|
||||||
block_hashes: vec![Hex(hex!(
|
block_hashes: vec![
|
||||||
"33ee476f5a1c5b9d889274cbbe171f5e0112df7ed69021918042525485deb401"
|
"33ee476f5a1c5b9d889274cbbe171f5e0112df7ed69021918042525485deb401"
|
||||||
))],
|
.into(),
|
||||||
|
],
|
||||||
difficulty: 354736121711617293,
|
difficulty: 354736121711617293,
|
||||||
difficulty_top64: 0,
|
difficulty_top64: 0,
|
||||||
height: 3157465,
|
height: 3157465,
|
||||||
|
@ -1722,9 +1733,9 @@ mod test {
|
||||||
test_json_request(
|
test_json_request(
|
||||||
json::RELAY_TX_REQUEST,
|
json::RELAY_TX_REQUEST,
|
||||||
RelayTxRequest {
|
RelayTxRequest {
|
||||||
txids: vec![Hex(hex!(
|
txids: vec![
|
||||||
"9fd75c429cbe52da9a52f2ffc5fbd107fe7fd2099c0d8de274dc8a67e0c98613"
|
"9fd75c429cbe52da9a52f2ffc5fbd107fe7fd2099c0d8de274dc8a67e0c98613".into(),
|
||||||
))],
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1859,25 +1870,20 @@ mod test {
|
||||||
height: 2731375,
|
height: 2731375,
|
||||||
major_version: 16,
|
major_version: 16,
|
||||||
median_weight: 300000,
|
median_weight: 300000,
|
||||||
prev_id: Hex(hex!(
|
prev_id: "78d50c5894d187c4946d54410990ca59a75017628174a9e8c7055fa4ca5c7c6d".into(),
|
||||||
"78d50c5894d187c4946d54410990ca59a75017628174a9e8c7055fa4ca5c7c6d"
|
seed_hash: "a6b869d50eca3a43ec26fe4c369859cf36ae37ce6ecb76457d31ffeb8a6ca8a6"
|
||||||
)),
|
.into(),
|
||||||
seed_hash: Hex(hex!(
|
|
||||||
"a6b869d50eca3a43ec26fe4c369859cf36ae37ce6ecb76457d31ffeb8a6ca8a6"
|
|
||||||
)),
|
|
||||||
tx_backlog: vec![
|
tx_backlog: vec![
|
||||||
GetMinerDataTxBacklogEntry {
|
GetMinerDataTxBacklogEntry {
|
||||||
fee: 30700000,
|
fee: 30700000,
|
||||||
id: Hex(hex!(
|
id: "9868490d6bb9207fdd9cf17ca1f6c791b92ca97de0365855ea5c089f67c22208"
|
||||||
"9868490d6bb9207fdd9cf17ca1f6c791b92ca97de0365855ea5c089f67c22208"
|
.into(),
|
||||||
)),
|
|
||||||
weight: 1535,
|
weight: 1535,
|
||||||
},
|
},
|
||||||
GetMinerDataTxBacklogEntry {
|
GetMinerDataTxBacklogEntry {
|
||||||
fee: 44280000,
|
fee: 44280000,
|
||||||
id: Hex(hex!(
|
id: "b6000b02bbec71e18ad704bcae09fb6e5ae86d897ced14a718753e76e86c0a0a"
|
||||||
"b6000b02bbec71e18ad704bcae09fb6e5ae86d897ced14a718753e76e86c0a0a"
|
.into(),
|
||||||
)),
|
|
||||||
weight: 2214,
|
weight: 2214,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -1911,7 +1917,7 @@ mod test {
|
||||||
major_version: 14,
|
major_version: 14,
|
||||||
height: 2286447,
|
height: 2286447,
|
||||||
block_blob: "0e0ed286da8006ecdc1aab3033cf1716c52f13f9d8ae0051615a2453643de94643b550d543becd0000000002abc78b0101ffefc68b0101fcfcf0d4b422025014bb4a1eade6622fd781cb1063381cad396efa69719b41aa28b4fce8c7ad4b5f019ce1dc670456b24a5e03c2d9058a2df10fec779e2579753b1847b74ee644f16b023c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051399a1bc46a846474f5b33db24eae173a26393b976054ee14f9feefe99925233802867097564c9db7a36af5bb5ed33ab46e63092bd8d32cef121608c3258edd55562812e21cc7e3ac73045745a72f7d74581d9a0849d6f30e8b2923171253e864f4e9ddea3acb5bc755f1c4a878130a70c26297540bc0b7a57affb6b35c1f03d8dbd54ece8457531f8cba15bb74516779c01193e212050423020e45aa2c15dcb".into(),
|
block_blob: "0e0ed286da8006ecdc1aab3033cf1716c52f13f9d8ae0051615a2453643de94643b550d543becd0000000002abc78b0101ffefc68b0101fcfcf0d4b422025014bb4a1eade6622fd781cb1063381cad396efa69719b41aa28b4fce8c7ad4b5f019ce1dc670456b24a5e03c2d9058a2df10fec779e2579753b1847b74ee644f16b023c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051399a1bc46a846474f5b33db24eae173a26393b976054ee14f9feefe99925233802867097564c9db7a36af5bb5ed33ab46e63092bd8d32cef121608c3258edd55562812e21cc7e3ac73045745a72f7d74581d9a0849d6f30e8b2923171253e864f4e9ddea3acb5bc755f1c4a878130a70c26297540bc0b7a57affb6b35c1f03d8dbd54ece8457531f8cba15bb74516779c01193e212050423020e45aa2c15dcb".into(),
|
||||||
seed_hash: Hex(hex!("d432f499205150873b2572b5f033c9c6e4b7c6f3394bd2dd93822cd7085e7307")),
|
seed_hash: "d432f499205150873b2572b5f033c9c6e4b7c6f3394bd2dd93822cd7085e7307".into(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1920,9 +1926,7 @@ mod test {
|
||||||
test_json_response(
|
test_json_response(
|
||||||
json::CALC_POW_RESPONSE,
|
json::CALC_POW_RESPONSE,
|
||||||
CalcPowResponse {
|
CalcPowResponse {
|
||||||
pow_hash: Hex(hex!(
|
pow_hash: "d0402d6834e26fb94a9ce38c6424d27d2069896a9b8b1ce685d79936bca6e0a8".into(),
|
||||||
"d0402d6834e26fb94a9ce38c6424d27d2069896a9b8b1ce685d79936bca6e0a8"
|
|
||||||
)),
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
//! the [`crate::misc::ConnectionInfo`] struct defined here.
|
//! the [`crate::misc::ConnectionInfo`] struct defined here.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use cuprate_hex::Hex;
|
use cuprate_types::{hex::Hex, HardFork};
|
||||||
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;
|
||||||
|
@ -196,7 +195,7 @@ define_struct_and_impl_epee! {
|
||||||
/// Used in [`crate::json::GetAlternateChainsResponse`].
|
/// Used in [`crate::json::GetAlternateChainsResponse`].
|
||||||
ChainInfo {
|
ChainInfo {
|
||||||
block_hash: Hex<32>,
|
block_hash: Hex<32>,
|
||||||
block_hashes: Vec<Hex<32>>,
|
block_hashes: Vec<String>, // TODO: Vec<Hex<32>> when it has epee
|
||||||
difficulty: u64,
|
difficulty: u64,
|
||||||
difficulty_top64: u64,
|
difficulty_top64: u64,
|
||||||
height: u64,
|
height: u64,
|
||||||
|
@ -307,7 +306,7 @@ define_struct_and_impl_epee! {
|
||||||
/// Used in [`crate::other::GetTransactionPoolResponse`].
|
/// Used in [`crate::other::GetTransactionPoolResponse`].
|
||||||
SpentKeyImageInfo {
|
SpentKeyImageInfo {
|
||||||
id_hash: Hex<32>,
|
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"]
|
keywords = ["cuprate", "types"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["blockchain", "epee", "serde", "json", "rpc"]
|
default = ["blockchain", "epee", "serde", "json", "hex", "rpc"]
|
||||||
blockchain = ["rpc"]
|
blockchain = ["rpc"]
|
||||||
epee = ["dep:cuprate-epee-encoding"]
|
epee = ["dep:cuprate-epee-encoding"]
|
||||||
serde = ["dep:serde"]
|
serde = ["dep:serde", "hex"]
|
||||||
proptest = ["dep:proptest", "dep:proptest-derive"]
|
proptest = ["dep:proptest", "dep:proptest-derive"]
|
||||||
json = ["dep:cuprate-hex", "dep:cuprate-helper"]
|
json = ["hex", "dep:cuprate-helper"]
|
||||||
rpc = ["dep:cuprate-hex", "json"]
|
# 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]
|
[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 }
|
|
||||||
|
|
||||||
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 }
|
|
@ -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
|
| `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
|
|
@ -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
|
//! This module provides transparent wrapper types for
|
||||||
//! arrays that (de)serialize from hexadecimal input/output.
|
//! arrays that (de)serialize from hexadecimal input/output.
|
||||||
|
|
||||||
use hex::{FromHex, FromHexError};
|
#[cfg(feature = "epee")]
|
||||||
use serde::{Deserialize, Deserializer, Serialize};
|
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.
|
/// 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 [`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>
|
/// <https://docs.rs/hex/0.4.3/src/hex/lib.rs.html#220-230>
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[serde(transparent)]
|
#[cfg_attr(feature = "serde", derive(Serialize))]
|
||||||
|
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||||
#[repr(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>
|
impl<'de, const N: usize> Deserialize<'de> for Hex<N>
|
||||||
where
|
where
|
||||||
[u8; N]: FromHex,
|
[u8; N]: hex::FromHex,
|
||||||
<[u8; N] as FromHex>::Error: std::fmt::Display,
|
<[u8; N] as hex::FromHex>::Error: std::fmt::Display,
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
Ok(Self(hex::serde::deserialize(deserializer)?))
|
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.
|
// 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 {
|
||||||
|
@ -63,18 +69,18 @@ impl<const N: usize> From<[u8; N]> for Hex<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> TryFrom<String> 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> {
|
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||||
let vec = hex::decode(value)?;
|
let vec = hex::decode(value)?;
|
||||||
match <[u8; N]>::try_from(vec) {
|
match <[u8; N]>::try_from(vec) {
|
||||||
Ok(s) => Ok(Self(s)),
|
Ok(s) => Ok(Self(s)),
|
||||||
Err(_) => Err(FromHexError::InvalidStringLength),
|
Err(_) => Err(hex::FromHexError::InvalidStringLength),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> TryFrom<&str> for Hex<N> {
|
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> {
|
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||||
let mut bytes = [0; N];
|
let mut bytes = [0; N];
|
||||||
hex::decode_to_slice(value, &mut bytes).map(|()| Self(bytes))
|
hex::decode_to_slice(value, &mut bytes).map(|()| Self(bytes))
|
||||||
|
@ -86,10 +92,10 @@ mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn asdf() {
|
fn hex_bytes_32() {
|
||||||
let hash = [0; 32];
|
let hash = [1; 32];
|
||||||
let hex_bytes = Hex::<32>(hash);
|
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();
|
let to_string = serde_json::to_string(&hex_bytes).unwrap();
|
||||||
assert_eq!(to_string, expected_json);
|
assert_eq!(to_string, expected_json);
|
|
@ -6,9 +6,11 @@ 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::json::output::{Output, TaggedKey, Target};
|
use crate::{
|
||||||
|
hex::Hex,
|
||||||
|
json::output::{Output, TaggedKey, Target},
|
||||||
|
};
|
||||||
|
|
||||||
/// JSON representation of a block.
|
/// 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");
|
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 {
|
Self {
|
||||||
major_version: b.header.hardfork_version,
|
major_version: b.header.hardfork_version,
|
||||||
minor_version: b.header.hardfork_signal,
|
minor_version: b.header.hardfork_signal,
|
||||||
timestamp: b.header.timestamp,
|
timestamp: b.header.timestamp,
|
||||||
prev_id: Hex(b.header.previous),
|
prev_id: Hex::<32>(b.header.previous),
|
||||||
nonce: b.header.nonce,
|
nonce: b.header.nonce,
|
||||||
miner_tx,
|
miner_tx,
|
||||||
tx_hashes,
|
tx_hashes,
|
||||||
|
@ -99,13 +101,15 @@ impl TryFrom<transaction::Transaction> for MinerTransaction {
|
||||||
let target = match o.view_tag {
|
let target = match o.view_tag {
|
||||||
Some(view_tag) => {
|
Some(view_tag) => {
|
||||||
let tagged_key = TaggedKey {
|
let tagged_key = TaggedKey {
|
||||||
key: Hex(o.key.0),
|
key: Hex::<32>(o.key.0),
|
||||||
view_tag: Hex([view_tag]),
|
view_tag: Hex::<1>([view_tag]),
|
||||||
};
|
};
|
||||||
|
|
||||||
Target::TaggedKey { tagged_key }
|
Target::TaggedKey { tagged_key }
|
||||||
}
|
}
|
||||||
None => Target::Key { key: Hex(o.key.0) },
|
None => Target::Key {
|
||||||
|
key: Hex::<32>(o.key.0),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Output { amount, target }
|
Output { amount, target }
|
||||||
|
@ -218,7 +222,7 @@ mod test {
|
||||||
major_version: 1,
|
major_version: 1,
|
||||||
minor_version: 0,
|
minor_version: 0,
|
||||||
timestamp: 1415690591,
|
timestamp: 1415690591,
|
||||||
prev_id: Hex(hex!(
|
prev_id: Hex::<32>(hex!(
|
||||||
"e97a0ab6307de9b9f9a9872263ef3e957976fb227eb9422c6854e989e5d5d34c"
|
"e97a0ab6307de9b9f9a9872263ef3e957976fb227eb9422c6854e989e5d5d34c"
|
||||||
)),
|
)),
|
||||||
nonce: 2147484616,
|
nonce: 2147484616,
|
||||||
|
@ -233,25 +237,25 @@ mod test {
|
||||||
Output {
|
Output {
|
||||||
amount: 47019296802,
|
amount: 47019296802,
|
||||||
target: Target::Key {
|
target: Target::Key {
|
||||||
key: Hex(hex!("3c1dcbf5b485987ecef4596bb700e32cbc7bd05964e3888ffc05f8a46bf5fc33")),
|
key: Hex::<32>(hex!("3c1dcbf5b485987ecef4596bb700e32cbc7bd05964e3888ffc05f8a46bf5fc33")),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Output {
|
Output {
|
||||||
amount: 200000000000,
|
amount: 200000000000,
|
||||||
target: Target::Key {
|
target: Target::Key {
|
||||||
key: Hex(hex!("5810afc7a1b01a1c913eb6aab15d4a851cbc4a8cf0adf90bb80ac1a7ca9928aa")),
|
key: Hex::<32>(hex!("5810afc7a1b01a1c913eb6aab15d4a851cbc4a8cf0adf90bb80ac1a7ca9928aa")),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Output {
|
Output {
|
||||||
amount: 3000000000000,
|
amount: 3000000000000,
|
||||||
target: Target::Key {
|
target: Target::Key {
|
||||||
key: Hex(hex!("520f49c5f2ce8456dc1a565f35ed3a5ccfff3a1210b340870a57d2749a81a2df")),
|
key: Hex::<32>(hex!("520f49c5f2ce8456dc1a565f35ed3a5ccfff3a1210b340870a57d2749a81a2df")),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Output {
|
Output {
|
||||||
amount: 10000000000000,
|
amount: 10000000000000,
|
||||||
target: Target::Key {
|
target: Target::Key {
|
||||||
key: Hex(hex!("44d7705e62c76c2e349a474df6724aa1d9932092002b03a94f9c19d9d12b9427")),
|
key: Hex::<32>(hex!("44d7705e62c76c2e349a474df6724aa1d9932092002b03a94f9c19d9d12b9427")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -277,7 +281,7 @@ mod test {
|
||||||
major_version: 16,
|
major_version: 16,
|
||||||
minor_version: 16,
|
minor_version: 16,
|
||||||
timestamp: 1727293028,
|
timestamp: 1727293028,
|
||||||
prev_id: Hex(hex!(
|
prev_id: Hex::<32>(hex!(
|
||||||
"41b56c273d69def3294e56179de71c61808042d54c1e085078d21dbe99e81b6f"
|
"41b56c273d69def3294e56179de71c61808042d54c1e085078d21dbe99e81b6f"
|
||||||
)),
|
)),
|
||||||
nonce: 311,
|
nonce: 311,
|
||||||
|
@ -292,10 +296,10 @@ mod test {
|
||||||
amount: 601012280000,
|
amount: 601012280000,
|
||||||
target: Target::TaggedKey {
|
target: Target::TaggedKey {
|
||||||
tagged_key: TaggedKey {
|
tagged_key: TaggedKey {
|
||||||
key: Hex(hex!(
|
key: Hex::<32>(hex!(
|
||||||
"8c0b16c6df02b9944b49f375d96a958a0fc5431c048879bb5bf25f64a1163b9e"
|
"8c0b16c6df02b9944b49f375d96a958a0fc5431c048879bb5bf25f64a1163b9e"
|
||||||
)),
|
)),
|
||||||
view_tag: Hex(hex!("88")),
|
view_tag: Hex::<1>(hex!("88")),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
|
@ -308,43 +312,43 @@ mod test {
|
||||||
rct_signatures: MinerTransactionRctSignatures { r#type: 0 },
|
rct_signatures: MinerTransactionRctSignatures { r#type: 0 },
|
||||||
},
|
},
|
||||||
tx_hashes: vec![
|
tx_hashes: vec![
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"eab76986a0cbcae690d8499f0f616f783fd2c89c6f611417f18011950dbdab2e"
|
"eab76986a0cbcae690d8499f0f616f783fd2c89c6f611417f18011950dbdab2e"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"57b19aa8c2cdbb6836cf13dd1e321a67860965c12e4418f3c30f58c8899a851e"
|
"57b19aa8c2cdbb6836cf13dd1e321a67860965c12e4418f3c30f58c8899a851e"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"5340185432ab6b74fb21379f7e8d8f0e37f0882b2a7121fd7c08736f079e2edc"
|
"5340185432ab6b74fb21379f7e8d8f0e37f0882b2a7121fd7c08736f079e2edc"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"01dc6d31db56d68116f5294c1b4f80b33b048b5cdfefcd904f23e6c0de3daff5"
|
"01dc6d31db56d68116f5294c1b4f80b33b048b5cdfefcd904f23e6c0de3daff5"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"c9fb6a2730678203948fef2a49fa155b63f35a3649f3d32ed405a6806f3bbd56"
|
"c9fb6a2730678203948fef2a49fa155b63f35a3649f3d32ed405a6806f3bbd56"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"af965cdd2a2315baf1d4a3d242f44fe07b1fd606d5f4853c9ff546ca6c12a5af"
|
"af965cdd2a2315baf1d4a3d242f44fe07b1fd606d5f4853c9ff546ca6c12a5af"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"97bc9e047d25fae8c14ce6ec882224e7b722f5e79b62a2602a6bacebdac8547b"
|
"97bc9e047d25fae8c14ce6ec882224e7b722f5e79b62a2602a6bacebdac8547b"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"28c46992eaf10dc0cceb313c30572d023432b7bd26e85e679bc8fe419533a7bf"
|
"28c46992eaf10dc0cceb313c30572d023432b7bd26e85e679bc8fe419533a7bf"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"c32e3acde2ff2885c9cc87253b40d6827d167dfcc3022c72f27084fd98788062"
|
"c32e3acde2ff2885c9cc87253b40d6827d167dfcc3022c72f27084fd98788062"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"19e66a47f075c7cccde8a7b52803119e089e33e3a4847cace0bd1d17b0d22bab"
|
"19e66a47f075c7cccde8a7b52803119e089e33e3a4847cace0bd1d17b0d22bab"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"8e8ac560e77a1ee72e82a5eb6887adbe5979a10cd29cb2c2a3720ce87db43a70"
|
"8e8ac560e77a1ee72e82a5eb6887adbe5979a10cd29cb2c2a3720ce87db43a70"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"b7ff5141524b5cca24de6780a5dbfdf71e7de1e062fd85f557fb3b43b8e285dc"
|
"b7ff5141524b5cca24de6780a5dbfdf71e7de1e062fd85f557fb3b43b8e285dc"
|
||||||
)),
|
)),
|
||||||
Hex(hex!(
|
Hex::<32>(hex!(
|
||||||
"f09df0f113763ef9b9a2752ac293b478102f7cab03ef803a3d9db7585aea8912"
|
"f09df0f113763ef9b9a2752ac293b478102f7cab03ef803a3d9db7585aea8912"
|
||||||
)),
|
)),
|
||||||
],
|
],
|
|
@ -7,7 +7,7 @@
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use cuprate_hex::Hex;
|
use crate::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)]
|
File diff suppressed because it is too large
Load diff
|
@ -35,6 +35,9 @@ 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;
|
|
@ -1,9 +1,8 @@
|
||||||
//! 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::{AddressType, ConnectionState, HardFork};
|
use crate::{hex::Hex, AddressType, ConnectionState, HardFork};
|
||||||
|
|
||||||
const fn default_string() -> String {
|
const fn default_string() -> String {
|
||||||
String::new()
|
String::new()
|
||||||
|
@ -22,7 +21,7 @@ macro_rules! monero_definition_link {
|
||||||
) => {
|
) => {
|
||||||
concat!(
|
concat!(
|
||||||
"[Definition](https://github.com/monero-project/monero/blob/",
|
"[Definition](https://github.com/monero-project/monero/blob/",
|
||||||
$commit,
|
stringify!($commit),
|
||||||
"/src/",
|
"/src/",
|
||||||
$file_path,
|
$file_path,
|
||||||
"#L",
|
"#L",
|
||||||
|
@ -264,7 +263,7 @@ define_struct_and_impl_epee! {
|
||||||
1016..=1027
|
1016..=1027
|
||||||
)]
|
)]
|
||||||
GetMinerDataTxBacklogEntry {
|
GetMinerDataTxBacklogEntry {
|
||||||
id: Hex<32>,
|
id: String,
|
||||||
weight: u64,
|
weight: u64,
|
||||||
fee: u64,
|
fee: u64,
|
||||||
}
|
}
|
|
@ -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-hex = { workspace = true }
|
cuprate-types = { workspace = true, features = ["hex"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = { workspace = true, features = ["std"] }
|
serde_json = { workspace = true, features = ["std"] }
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use cuprate_hex::Hex;
|
use cuprate_types::hex::Hex;
|
||||||
|
|
||||||
/// ZMQ `json-full-txpool_add` packets contain an array of `TxPoolAdd`.
|
/// ZMQ `json-full-txpool_add` packets contain an array of `TxPoolAdd`.
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in a new issue