Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cuprated: RPC handlers (json-rpc) #308

Draft
wants to merge 52 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
d170b46
import diffs
hinto-janai Oct 10, 2024
02e950b
small fixes, hardfork changes
hinto-janai Oct 10, 2024
c18ba6e
lints
hinto-janai Oct 10, 2024
93be3be
hard_fork
hinto-janai Oct 11, 2024
c590bbb
apply diffs
hinto-janai Oct 11, 2024
cec746b
review fixes
hinto-janai Oct 11, 2024
e57c887
Merge branch 'hf' into json
hinto-janai Oct 11, 2024
ac6360a
Merge branch 'main' into json
hinto-janai Oct 11, 2024
2522bb8
binaries/cuprated/src/rpc/request: `pub(super)` -> `pub(crate)`
hinto-janai Oct 11, 2024
fd136b2
add `BlockChainContextService`, `on_get_block_hash`
hinto-janai Oct 11, 2024
9459d59
Merge branch 'main' into json
hinto-janai Oct 12, 2024
b82ff27
map `tower::BoxError` to `anyhow::Error`
hinto-janai Oct 12, 2024
8a3229b
get_block
hinto-janai Oct 12, 2024
9422c07
connection_info
hinto-janai Oct 14, 2024
50bd576
hard_fork_info
hinto-janai Oct 14, 2024
f677b1a
set_bans
hinto-janai Oct 14, 2024
37bcbb5
get_bans
hinto-janai Oct 14, 2024
c7ae795
banned
hinto-janai Oct 14, 2024
6af977f
flush_transaction_pool
hinto-janai Oct 14, 2024
1a76934
get_output_histogram
hinto-janai Oct 14, 2024
1d435cc
get_coinbase_tx_sum
hinto-janai Oct 15, 2024
d7fef15
get_version
hinto-janai Oct 15, 2024
1e0ab56
get_fee_estimate
hinto-janai Oct 15, 2024
294df3f
get_alternate_chains
hinto-janai Oct 15, 2024
08b5ff2
relay_tx
hinto-janai Oct 15, 2024
2daf255
response_base: `fn` -> `const`
hinto-janai Oct 15, 2024
a10ed59
get_transaction_pool_backlog
hinto-janai Oct 15, 2024
d7d8b35
prune
hinto-janai Oct 15, 2024
5926f24
calc_pow
hinto-janai Oct 15, 2024
7148ba1
add_aux_pow
hinto-janai Oct 15, 2024
d56477c
get_tx_ids_loose
hinto-janai Oct 15, 2024
548639b
generate_blocks
hinto-janai Oct 16, 2024
e2f25bd
get_info
hinto-janai Oct 16, 2024
4b1d7bc
sync_info
hinto-janai Oct 16, 2024
bd3a844
get_miner_data
hinto-janai Oct 16, 2024
bf07f2c
`BlockchainManagerRequest` docs
hinto-janai Oct 17, 2024
98dfaa4
docs, `ConnectionInfo`, `AddressType`
hinto-janai Oct 17, 2024
13eedc6
sig docs, remove `HardForks` request
hinto-janai Oct 17, 2024
79b03e3
Merge branch 'main' into json
hinto-janai Nov 2, 2024
544287d
Merge branch 'main' into json
hinto-janai Nov 13, 2024
0cb6a76
clean imports
hinto-janai Nov 13, 2024
e30eeb8
fix `on_get_block_hash`, `generate_blocks`, `get_block_headers_range`
hinto-janai Nov 13, 2024
228a718
fix `get_info`, `banned`
hinto-janai Nov 13, 2024
9374d08
fix `sync_info`
hinto-janai Nov 13, 2024
fd84940
fix `get_miner_data`
hinto-janai Nov 13, 2024
46bf198
initial `add_aux_pow` impl
hinto-janai Nov 14, 2024
1f3b5ed
fix `calculate_pow`
hinto-janai Nov 14, 2024
e975c42
add_aux_pow
hinto-janai Nov 15, 2024
d634bea
`get_output_distribution`
hinto-janai Nov 15, 2024
854b175
checkup
hinto-janai Nov 16, 2024
2d2d493
`find_nonce()` + `add_aux_pow` async wrapper
hinto-janai Nov 16, 2024
86f2dd1
fixes
hinto-janai Nov 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
313 changes: 155 additions & 158 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion binaries/cuprated/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ cuprate-consensus = { workspace = true }
cuprate-fast-sync = { workspace = true }
cuprate-consensus-context = { workspace = true }
cuprate-consensus-rules = { workspace = true }
cuprate-constants = { workspace = true }
cuprate-constants = { workspace = true, features = ["build", "rpc"] }
cuprate-cryptonight = { workspace = true }
cuprate-helper = { workspace = true }
cuprate-epee-encoding = { workspace = true }
Expand Down Expand Up @@ -66,6 +66,7 @@ rayon = { workspace = true }
serde_bytes = { workspace = true }
serde_json = { workspace = true }
serde = { workspace = true }
strum = { workspace = true }
thiserror = { workspace = true }
thread_local = { workspace = true }
tokio-util = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions binaries/cuprated/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
mod bin;
mod constants;
mod handler;
mod helper;
mod json;
mod other;
mod request;
Expand Down
2 changes: 2 additions & 0 deletions binaries/cuprated/src/rpc/bin.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! RPC request handler functions (binary endpoints).

use anyhow::Error;

use cuprate_rpc_types::{
Expand Down
15 changes: 8 additions & 7 deletions binaries/cuprated/src/rpc/handler.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Dummy implementation of [`RpcHandler`].
//! `cuprated`'s implementation of [`RpcHandler`].

use std::task::{Context, Poll};

Expand All @@ -7,7 +7,7 @@ use futures::future::BoxFuture;
use monero_serai::block::Block;
use tower::Service;

use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle};
use cuprate_blockchain::service::BlockchainReadHandle;
use cuprate_consensus::BlockChainContextService;
use cuprate_pruning::PruningSeed;
use cuprate_rpc_interface::RpcHandler;
Expand All @@ -16,14 +16,12 @@ use cuprate_rpc_types::{
json::{JsonRpcRequest, JsonRpcResponse},
other::{OtherRequest, OtherResponse},
};
use cuprate_txpool::service::{TxpoolReadHandle, TxpoolWriteHandle};
use cuprate_types::{AddAuxPow, AuxPow, HardFork};
use cuprate_txpool::service::TxpoolReadHandle;

use crate::rpc::{bin, json, other};

/// TODO: use real type when public.
#[derive(Clone)]
#[expect(clippy::large_enum_variant)]
pub enum BlockchainManagerRequest {
/// Pop blocks off the top of the blockchain.
///
Expand All @@ -37,7 +35,10 @@ pub enum BlockchainManagerRequest {
Pruned,

/// Relay a block to the network.
RelayBlock(Block),
RelayBlock(
/// This is [`Box`]ed due to `clippy::large_enum_variant`.
Box<Block>,
),

/// Is the blockchain in the middle of syncing?
///
Expand Down Expand Up @@ -182,7 +183,7 @@ impl CupratedRpcHandler {
}

impl RpcHandler for CupratedRpcHandler {
fn restricted(&self) -> bool {
fn is_restricted(&self) -> bool {
self.restricted
}
}
Expand Down
161 changes: 161 additions & 0 deletions binaries/cuprated/src/rpc/helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
//! These are internal helper functions used by the actual RPC handlers.
//!
//! Many of the handlers have bodies with only small differences,
//! the identical code is extracted and reused here in these functions.
//!
//! These build on-top of [`crate::rpc::request`] functions.

use anyhow::{anyhow, Error};
use monero_serai::block::Block;

use cuprate_consensus::{BlockChainContext, BlockChainContextService};
use cuprate_helper::{cast::usize_to_u64, map::split_u128_into_low_high_bits};
use cuprate_rpc_types::misc::{BlockHeader, KeyImageSpentStatus};
use cuprate_types::ExtendedBlockHeader;

use crate::{
rpc::request::{blockchain, blockchain_context},
rpc::CupratedRpcHandler,
};

pub(super) fn into_block_header(
height: u64,
top_height: u64,
fill_pow_hash: bool,
block: Block,
header: ExtendedBlockHeader,
) -> BlockHeader {
let block_weight = usize_to_u64(header.block_weight);
let depth = top_height.saturating_sub(height);
let (cumulative_difficulty_top64, cumulative_difficulty) =
split_u128_into_low_high_bits(header.cumulative_difficulty);

BlockHeader {
block_size: block_weight,
block_weight,
cumulative_difficulty_top64,
cumulative_difficulty,
depth,
difficulty_top64: todo!(),
difficulty: todo!(),
hash: hex::encode(block.hash()),
height,
long_term_weight: usize_to_u64(header.long_term_weight),
major_version: header.version.as_u8(),
miner_tx_hash: hex::encode(block.miner_transaction.hash()),
minor_version: header.vote,
nonce: block.header.nonce,
num_txes: usize_to_u64(block.transactions.len()),
orphan_status: todo!(),
pow_hash: if fill_pow_hash {
todo!()
} else {
String::new()
},
prev_hash: hex::encode(block.header.previous),
reward: todo!(),
timestamp: block.header.timestamp,
wide_cumulative_difficulty: hex::encode(u128::to_le_bytes(header.cumulative_difficulty)),
wide_difficulty: todo!(),
}
}

/// Get a [`VerifiedBlockInformation`] and map it to a [`BlockHeader`].
pub(super) async fn block_header(
state: &mut CupratedRpcHandler,
height: u64,
fill_pow_hash: bool,
) -> Result<BlockHeader, Error> {
let (top_height, _) = top_height(state).await?;
let block = blockchain::block(&mut state.blockchain_read, height).await?;
let header = blockchain::block_extended_header(&mut state.blockchain_read, height).await?;

let block_header = into_block_header(height, top_height, fill_pow_hash, block, header);

Ok(block_header)
}

/// Same as [`block_header`] but with the block's hash.
pub(super) async fn block_header_by_hash(
state: &mut CupratedRpcHandler,
hash: [u8; 32],
fill_pow_hash: bool,
) -> Result<BlockHeader, Error> {
let (top_height, _) = top_height(state).await?;
let block = blockchain::block_by_hash(&mut state.blockchain_read, hash).await?;
let header: ExtendedBlockHeader = todo!(); //blockchain::block_extended_header_by_hash(state.blockchain_read, hash).await?;

let block_header = into_block_header(todo!(), top_height, fill_pow_hash, block, header);

Ok(block_header)
}

/// TODO
pub(super) async fn top_block_header(
state: &mut CupratedRpcHandler,
fill_pow_hash: bool,
) -> Result<BlockHeader, Error> {
let block: Block = todo!();
let header: ExtendedBlockHeader = todo!();

let block_header = into_block_header(todo!(), todo!(), fill_pow_hash, block, header);

Ok(block_header)
}

/// Check if `height` is greater than the [`top_height`].
///
/// # Errors
/// This returns the [`top_height`] on [`Ok`] and
/// returns [`Error`] if `height` is greater than [`top_height`].
pub(super) async fn check_height(
state: &mut CupratedRpcHandler,
height: u64,
) -> Result<u64, Error> {
let (top_height, _) = top_height(state).await?;

if height > top_height {
return Err(anyhow!(
"Requested block height: {height} greater than current top block height: {top_height}",
));
}

Ok(top_height)
}

/// Parse a hexadecimal [`String`] as a 32-byte hash.
pub(super) fn hex_to_hash(hex: String) -> Result<[u8; 32], Error> {
let error = || anyhow!("Failed to parse hex representation of hash. Hex = {hex}.");

let Ok(bytes) = hex::decode(&hex) else {
return Err(error());
};

let Ok(hash) = bytes.try_into() else {
return Err(error());
};

Ok(hash)
}

/// [`BlockchainResponse::ChainHeight`] minus 1.
pub(super) async fn top_height(state: &mut CupratedRpcHandler) -> Result<(u64, [u8; 32]), Error> {
let (chain_height, hash) = blockchain::chain_height(&mut state.blockchain_read).await?;
let height = chain_height.saturating_sub(1);
Ok((height, hash))
}

/// TODO
pub(super) async fn key_image_spent(
state: &mut CupratedRpcHandler,
key_image: [u8; 32],
) -> Result<KeyImageSpentStatus, Error> {
todo!("impl key image vec check responding KeyImageSpentStatus")
// if blockchain::key_image_spent(state, key_image).await? {
// Ok(KeyImageSpentStatus::SpentInBlockchain)
// } else if todo!("key image is spent in tx pool") {
// Ok(KeyImageSpentStatus::SpentInPool)
// } else {
// Ok(KeyImageSpentStatus::Unspent)
// }
}
Loading
Loading