mirror of
https://github.com/hinto-janai/cuprate.git
synced 2025-01-22 02:34:29 +00:00
Merge branch 'main' into cuprated-txpool
This commit is contained in:
commit
e199b8c26d
43 changed files with 1474 additions and 190 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -934,6 +934,7 @@ dependencies = [
|
||||||
"proptest-derive",
|
"proptest-derive",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"strum",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2675,6 +2676,28 @@ dependencies = [
|
||||||
"spin",
|
"spin",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.26.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
||||||
|
dependencies = [
|
||||||
|
"strum_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.26.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn 2.0.77",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
|
|
|
@ -79,6 +79,7 @@ serde_bytes = { version = "0.11.15", default-features = false }
|
||||||
serde_json = { version = "1.0.128", default-features = false }
|
serde_json = { version = "1.0.128", default-features = false }
|
||||||
serde = { version = "1.0.210", default-features = false }
|
serde = { version = "1.0.210", default-features = false }
|
||||||
sha3 = { version = "0.10.8", default-features = false }
|
sha3 = { version = "0.10.8", default-features = false }
|
||||||
|
strum = { version = "0.26.3", default-features = false }
|
||||||
thiserror = { version = "1.0.63", default-features = false }
|
thiserror = { version = "1.0.63", default-features = false }
|
||||||
thread_local = { version = "1.1.8", default-features = false }
|
thread_local = { version = "1.1.8", default-features = false }
|
||||||
tokio-util = { version = "0.7.12", default-features = false }
|
tokio-util = { version = "0.7.12", default-features = false }
|
||||||
|
|
|
@ -71,7 +71,7 @@ pub async fn init_blockchain_manager(
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
||||||
.call(BlockChainContextRequest::GetContext)
|
.call(BlockChainContextRequest::Context)
|
||||||
.await
|
.await
|
||||||
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -479,7 +479,7 @@ impl super::BlockchainManager {
|
||||||
.ready()
|
.ready()
|
||||||
.await
|
.await
|
||||||
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
||||||
.call(BlockChainContextRequest::GetContext)
|
.call(BlockChainContextRequest::Context)
|
||||||
.await
|
.await
|
||||||
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -62,7 +62,7 @@ where
|
||||||
let BlockChainContextResponse::Context(mut blockchain_ctx) = context_svc
|
let BlockChainContextResponse::Context(mut blockchain_ctx) = context_svc
|
||||||
.ready()
|
.ready()
|
||||||
.await?
|
.await?
|
||||||
.call(BlockChainContextRequest::GetContext)
|
.call(BlockChainContextRequest::Context)
|
||||||
.await?
|
.await?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
|
@ -131,7 +131,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
let BlockChainContextResponse::Context(ctx) = context_svc
|
let BlockChainContextResponse::Context(ctx) = context_svc
|
||||||
.oneshot(BlockChainContextRequest::GetContext)
|
.oneshot(BlockChainContextRequest::Context)
|
||||||
.await?
|
.await?
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#![allow(
|
#![allow(
|
||||||
unused_imports,
|
unused_imports,
|
||||||
unreachable_pub,
|
unreachable_pub,
|
||||||
|
unreachable_code,
|
||||||
unused_crate_dependencies,
|
unused_crate_dependencies,
|
||||||
dead_code,
|
dead_code,
|
||||||
unused_variables,
|
unused_variables,
|
||||||
|
|
|
@ -6,5 +6,6 @@ mod bin;
|
||||||
mod handler;
|
mod handler;
|
||||||
mod json;
|
mod json;
|
||||||
mod other;
|
mod other;
|
||||||
|
mod request;
|
||||||
|
|
||||||
pub use handler::{CupratedRpcHandler, CupratedRpcHandlerState};
|
pub use handler::CupratedRpcHandler;
|
||||||
|
|
|
@ -10,11 +10,11 @@ use cuprate_rpc_types::{
|
||||||
json::{GetOutputDistributionRequest, GetOutputDistributionResponse},
|
json::{GetOutputDistributionRequest, GetOutputDistributionResponse},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::rpc::CupratedRpcHandlerState;
|
use crate::rpc::CupratedRpcHandler;
|
||||||
|
|
||||||
/// Map a [`BinRequest`] to the function that will lead to a [`BinResponse`].
|
/// Map a [`BinRequest`] to the function that will lead to a [`BinResponse`].
|
||||||
pub(super) async fn map_request(
|
pub(super) async fn map_request(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: BinRequest,
|
request: BinRequest,
|
||||||
) -> Result<BinResponse, Error> {
|
) -> Result<BinResponse, Error> {
|
||||||
use BinRequest as Req;
|
use BinRequest as Req;
|
||||||
|
@ -36,49 +36,49 @@ pub(super) async fn map_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_blocks(
|
async fn get_blocks(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetBlocksRequest,
|
request: GetBlocksRequest,
|
||||||
) -> Result<GetBlocksResponse, Error> {
|
) -> Result<GetBlocksResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_blocks_by_height(
|
async fn get_blocks_by_height(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetBlocksByHeightRequest,
|
request: GetBlocksByHeightRequest,
|
||||||
) -> Result<GetBlocksByHeightResponse, Error> {
|
) -> Result<GetBlocksByHeightResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_hashes(
|
async fn get_hashes(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetHashesRequest,
|
request: GetHashesRequest,
|
||||||
) -> Result<GetHashesResponse, Error> {
|
) -> Result<GetHashesResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_output_indexes(
|
async fn get_output_indexes(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetOutputIndexesRequest,
|
request: GetOutputIndexesRequest,
|
||||||
) -> Result<GetOutputIndexesResponse, Error> {
|
) -> Result<GetOutputIndexesResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_outs(
|
async fn get_outs(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetOutsRequest,
|
request: GetOutsRequest,
|
||||||
) -> Result<GetOutsResponse, Error> {
|
) -> Result<GetOutsResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_transaction_pool_hashes(
|
async fn get_transaction_pool_hashes(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetTransactionPoolHashesRequest,
|
request: GetTransactionPoolHashesRequest,
|
||||||
) -> Result<GetTransactionPoolHashesResponse, Error> {
|
) -> Result<GetTransactionPoolHashesResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_output_distribution(
|
async fn get_output_distribution(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetOutputDistributionRequest,
|
request: GetOutputDistributionRequest,
|
||||||
) -> Result<GetOutputDistributionResponse, Error> {
|
) -> Result<GetOutputDistributionResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
|
|
|
@ -3,51 +3,131 @@
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use futures::{channel::oneshot::channel, future::BoxFuture};
|
use futures::future::BoxFuture;
|
||||||
use serde::{Deserialize, Serialize};
|
use monero_serai::block::Block;
|
||||||
use tower::Service;
|
use tower::Service;
|
||||||
|
|
||||||
use cuprate_blockchain::service::BlockchainReadHandle;
|
use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle};
|
||||||
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
|
||||||
use cuprate_json_rpc::Id;
|
|
||||||
use cuprate_rpc_interface::RpcHandler;
|
use cuprate_rpc_interface::RpcHandler;
|
||||||
use cuprate_rpc_types::{
|
use cuprate_rpc_types::{
|
||||||
bin::{BinRequest, BinResponse},
|
bin::{BinRequest, BinResponse},
|
||||||
json::{JsonRpcRequest, JsonRpcResponse},
|
json::{JsonRpcRequest, JsonRpcResponse},
|
||||||
other::{OtherRequest, OtherResponse},
|
other::{OtherRequest, OtherResponse},
|
||||||
};
|
};
|
||||||
use cuprate_txpool::service::TxpoolReadHandle;
|
use cuprate_txpool::service::{TxpoolReadHandle, TxpoolWriteHandle};
|
||||||
|
|
||||||
use crate::rpc::{bin, json, other};
|
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.
|
||||||
|
///
|
||||||
|
/// Input is the amount of blocks to pop.
|
||||||
|
PopBlocks { amount: usize },
|
||||||
|
|
||||||
|
/// Start pruning the blockchain.
|
||||||
|
Prune,
|
||||||
|
|
||||||
|
/// Is the blockchain pruned?
|
||||||
|
Pruned,
|
||||||
|
|
||||||
|
/// Relay a block to the network.
|
||||||
|
RelayBlock(Block),
|
||||||
|
|
||||||
|
/// Is the blockchain in the middle of syncing?
|
||||||
|
///
|
||||||
|
/// This returning `false` does not necessarily
|
||||||
|
/// mean [`BlockchainManagerRequest::Synced`] will
|
||||||
|
/// return `true`, for example, if the network has been
|
||||||
|
/// cut off and we have no peers, this will return `false`,
|
||||||
|
/// however, [`BlockchainManagerRequest::Synced`] may return
|
||||||
|
/// `true` if the latest known chain tip is equal to our height.
|
||||||
|
Syncing,
|
||||||
|
|
||||||
|
/// Is the blockchain fully synced?
|
||||||
|
Synced,
|
||||||
|
|
||||||
|
/// Current target block time.
|
||||||
|
Target,
|
||||||
|
|
||||||
|
/// The height of the next block in the chain.
|
||||||
|
TargetHeight,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO: use real type when public.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum BlockchainManagerResponse {
|
||||||
|
/// General OK response.
|
||||||
|
///
|
||||||
|
/// Response to:
|
||||||
|
/// - [`BlockchainManagerRequest::Prune`]
|
||||||
|
/// - [`BlockchainManagerRequest::RelayBlock`]
|
||||||
|
Ok,
|
||||||
|
|
||||||
|
/// Response to [`BlockchainManagerRequest::PopBlocks`]
|
||||||
|
PopBlocks { new_height: usize },
|
||||||
|
|
||||||
|
/// Response to [`BlockchainManagerRequest::Pruned`]
|
||||||
|
Pruned(bool),
|
||||||
|
|
||||||
|
/// Response to [`BlockchainManagerRequest::Syncing`]
|
||||||
|
Syncing(bool),
|
||||||
|
|
||||||
|
/// Response to [`BlockchainManagerRequest::Synced`]
|
||||||
|
Synced(bool),
|
||||||
|
|
||||||
|
/// Response to [`BlockchainManagerRequest::Target`]
|
||||||
|
Target(std::time::Duration),
|
||||||
|
|
||||||
|
/// Response to [`BlockchainManagerRequest::TargetHeight`]
|
||||||
|
TargetHeight { height: usize },
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO: use real type when public.
|
||||||
|
pub type BlockchainManagerHandle = cuprate_database_service::DatabaseReadService<
|
||||||
|
BlockchainManagerRequest,
|
||||||
|
BlockchainManagerResponse,
|
||||||
|
>;
|
||||||
|
|
||||||
/// TODO
|
/// TODO
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CupratedRpcHandler {
|
pub struct CupratedRpcHandler {
|
||||||
/// Should this RPC server be [restricted](RpcHandler::restricted)?
|
/// Should this RPC server be [restricted](RpcHandler::restricted)?
|
||||||
//
|
///
|
||||||
// INVARIANT:
|
/// This is not `pub` on purpose, as it should not be mutated after [`Self::new`].
|
||||||
// We don't need to include this in `state` and check for
|
restricted: bool,
|
||||||
// `self.is_restricted()` because `cuprate-rpc-interface` handles that.
|
|
||||||
pub restricted: bool,
|
|
||||||
|
|
||||||
/// State needed for request -> response mapping.
|
|
||||||
pub state: CupratedRpcHandlerState,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// TODO
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct CupratedRpcHandlerState {
|
|
||||||
/// Read handle to the blockchain database.
|
/// Read handle to the blockchain database.
|
||||||
pub blockchain: BlockchainReadHandle,
|
pub blockchain_read: BlockchainReadHandle,
|
||||||
|
|
||||||
|
/// Handle to the blockchain manager.
|
||||||
|
pub blockchain_manager: BlockchainManagerHandle,
|
||||||
|
|
||||||
/// Read handle to the transaction pool database.
|
/// Read handle to the transaction pool database.
|
||||||
pub txpool: TxpoolReadHandle,
|
pub txpool_read: TxpoolReadHandle,
|
||||||
|
|
||||||
|
/// TODO: handle to txpool service.
|
||||||
|
pub txpool_manager: std::convert::Infallible,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CupratedRpcHandler {
|
impl CupratedRpcHandler {
|
||||||
/// TODO
|
/// Create a new [`Self`].
|
||||||
pub fn init() {
|
pub const fn new(
|
||||||
todo!()
|
restricted: bool,
|
||||||
|
blockchain_read: BlockchainReadHandle,
|
||||||
|
blockchain_manager: BlockchainManagerHandle,
|
||||||
|
txpool_read: TxpoolReadHandle,
|
||||||
|
txpool_manager: std::convert::Infallible,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
restricted,
|
||||||
|
blockchain_read,
|
||||||
|
blockchain_manager,
|
||||||
|
txpool_read,
|
||||||
|
txpool_manager,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +147,7 @@ impl Service<JsonRpcRequest> for CupratedRpcHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, request: JsonRpcRequest) -> Self::Future {
|
fn call(&mut self, request: JsonRpcRequest) -> Self::Future {
|
||||||
let state = CupratedRpcHandlerState::clone(&self.state);
|
let state = self.clone();
|
||||||
Box::pin(json::map_request(state, request))
|
Box::pin(json::map_request(state, request))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +162,7 @@ impl Service<BinRequest> for CupratedRpcHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, request: BinRequest) -> Self::Future {
|
fn call(&mut self, request: BinRequest) -> Self::Future {
|
||||||
let state = CupratedRpcHandlerState::clone(&self.state);
|
let state = self.clone();
|
||||||
Box::pin(bin::map_request(state, request))
|
Box::pin(bin::map_request(state, request))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +177,7 @@ impl Service<OtherRequest> for CupratedRpcHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, request: OtherRequest) -> Self::Future {
|
fn call(&mut self, request: OtherRequest) -> Self::Future {
|
||||||
let state = CupratedRpcHandlerState::clone(&self.state);
|
let state = self.clone();
|
||||||
Box::pin(other::map_request(state, request))
|
Box::pin(other::map_request(state, request))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,11 @@ use cuprate_rpc_types::json::{
|
||||||
SyncInfoRequest, SyncInfoResponse,
|
SyncInfoRequest, SyncInfoResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::rpc::CupratedRpcHandlerState;
|
use crate::rpc::CupratedRpcHandler;
|
||||||
|
|
||||||
/// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`].
|
/// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`].
|
||||||
pub(super) async fn map_request(
|
pub(super) async fn map_request(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: JsonRpcRequest,
|
request: JsonRpcRequest,
|
||||||
) -> Result<JsonRpcResponse, Error> {
|
) -> Result<JsonRpcResponse, Error> {
|
||||||
use JsonRpcRequest as Req;
|
use JsonRpcRequest as Req;
|
||||||
|
@ -84,210 +84,210 @@ pub(super) async fn map_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_block_count(
|
async fn get_block_count(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetBlockCountRequest,
|
request: GetBlockCountRequest,
|
||||||
) -> Result<GetBlockCountResponse, Error> {
|
) -> Result<GetBlockCountResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn on_get_block_hash(
|
async fn on_get_block_hash(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: OnGetBlockHashRequest,
|
request: OnGetBlockHashRequest,
|
||||||
) -> Result<OnGetBlockHashResponse, Error> {
|
) -> Result<OnGetBlockHashResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn submit_block(
|
async fn submit_block(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: SubmitBlockRequest,
|
request: SubmitBlockRequest,
|
||||||
) -> Result<SubmitBlockResponse, Error> {
|
) -> Result<SubmitBlockResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn generate_blocks(
|
async fn generate_blocks(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GenerateBlocksRequest,
|
request: GenerateBlocksRequest,
|
||||||
) -> Result<GenerateBlocksResponse, Error> {
|
) -> Result<GenerateBlocksResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_last_block_header(
|
async fn get_last_block_header(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetLastBlockHeaderRequest,
|
request: GetLastBlockHeaderRequest,
|
||||||
) -> Result<GetLastBlockHeaderResponse, Error> {
|
) -> Result<GetLastBlockHeaderResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_block_header_by_hash(
|
async fn get_block_header_by_hash(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetBlockHeaderByHashRequest,
|
request: GetBlockHeaderByHashRequest,
|
||||||
) -> Result<GetBlockHeaderByHashResponse, Error> {
|
) -> Result<GetBlockHeaderByHashResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_block_header_by_height(
|
async fn get_block_header_by_height(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetBlockHeaderByHeightRequest,
|
request: GetBlockHeaderByHeightRequest,
|
||||||
) -> Result<GetBlockHeaderByHeightResponse, Error> {
|
) -> Result<GetBlockHeaderByHeightResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_block_headers_range(
|
async fn get_block_headers_range(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetBlockHeadersRangeRequest,
|
request: GetBlockHeadersRangeRequest,
|
||||||
) -> Result<GetBlockHeadersRangeResponse, Error> {
|
) -> Result<GetBlockHeadersRangeResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_block(
|
async fn get_block(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetBlockRequest,
|
request: GetBlockRequest,
|
||||||
) -> Result<GetBlockResponse, Error> {
|
) -> Result<GetBlockResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_connections(
|
async fn get_connections(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetConnectionsRequest,
|
request: GetConnectionsRequest,
|
||||||
) -> Result<GetConnectionsResponse, Error> {
|
) -> Result<GetConnectionsResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_info(
|
async fn get_info(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetInfoRequest,
|
request: GetInfoRequest,
|
||||||
) -> Result<GetInfoResponse, Error> {
|
) -> Result<GetInfoResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn hard_fork_info(
|
async fn hard_fork_info(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: HardForkInfoRequest,
|
request: HardForkInfoRequest,
|
||||||
) -> Result<HardForkInfoResponse, Error> {
|
) -> Result<HardForkInfoResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_bans(
|
async fn set_bans(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: SetBansRequest,
|
request: SetBansRequest,
|
||||||
) -> Result<SetBansResponse, Error> {
|
) -> Result<SetBansResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_bans(
|
async fn get_bans(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetBansRequest,
|
request: GetBansRequest,
|
||||||
) -> Result<GetBansResponse, Error> {
|
) -> Result<GetBansResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn banned(
|
async fn banned(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: BannedRequest,
|
request: BannedRequest,
|
||||||
) -> Result<BannedResponse, Error> {
|
) -> Result<BannedResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn flush_transaction_pool(
|
async fn flush_transaction_pool(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: FlushTransactionPoolRequest,
|
request: FlushTransactionPoolRequest,
|
||||||
) -> Result<FlushTransactionPoolResponse, Error> {
|
) -> Result<FlushTransactionPoolResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_output_histogram(
|
async fn get_output_histogram(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetOutputHistogramRequest,
|
request: GetOutputHistogramRequest,
|
||||||
) -> Result<GetOutputHistogramResponse, Error> {
|
) -> Result<GetOutputHistogramResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_coinbase_tx_sum(
|
async fn get_coinbase_tx_sum(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetCoinbaseTxSumRequest,
|
request: GetCoinbaseTxSumRequest,
|
||||||
) -> Result<GetCoinbaseTxSumResponse, Error> {
|
) -> Result<GetCoinbaseTxSumResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_version(
|
async fn get_version(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetVersionRequest,
|
request: GetVersionRequest,
|
||||||
) -> Result<GetVersionResponse, Error> {
|
) -> Result<GetVersionResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_fee_estimate(
|
async fn get_fee_estimate(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetFeeEstimateRequest,
|
request: GetFeeEstimateRequest,
|
||||||
) -> Result<GetFeeEstimateResponse, Error> {
|
) -> Result<GetFeeEstimateResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_alternate_chains(
|
async fn get_alternate_chains(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetAlternateChainsRequest,
|
request: GetAlternateChainsRequest,
|
||||||
) -> Result<GetAlternateChainsResponse, Error> {
|
) -> Result<GetAlternateChainsResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn relay_tx(
|
async fn relay_tx(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: RelayTxRequest,
|
request: RelayTxRequest,
|
||||||
) -> Result<RelayTxResponse, Error> {
|
) -> Result<RelayTxResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn sync_info(
|
async fn sync_info(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: SyncInfoRequest,
|
request: SyncInfoRequest,
|
||||||
) -> Result<SyncInfoResponse, Error> {
|
) -> Result<SyncInfoResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_transaction_pool_backlog(
|
async fn get_transaction_pool_backlog(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetTransactionPoolBacklogRequest,
|
request: GetTransactionPoolBacklogRequest,
|
||||||
) -> Result<GetTransactionPoolBacklogResponse, Error> {
|
) -> Result<GetTransactionPoolBacklogResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_miner_data(
|
async fn get_miner_data(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetMinerDataRequest,
|
request: GetMinerDataRequest,
|
||||||
) -> Result<GetMinerDataResponse, Error> {
|
) -> Result<GetMinerDataResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn prune_blockchain(
|
async fn prune_blockchain(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: PruneBlockchainRequest,
|
request: PruneBlockchainRequest,
|
||||||
) -> Result<PruneBlockchainResponse, Error> {
|
) -> Result<PruneBlockchainResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn calc_pow(
|
async fn calc_pow(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: CalcPowRequest,
|
request: CalcPowRequest,
|
||||||
) -> Result<CalcPowResponse, Error> {
|
) -> Result<CalcPowResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn flush_cache(
|
async fn flush_cache(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: FlushCacheRequest,
|
request: FlushCacheRequest,
|
||||||
) -> Result<FlushCacheResponse, Error> {
|
) -> Result<FlushCacheResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_aux_pow(
|
async fn add_aux_pow(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: AddAuxPowRequest,
|
request: AddAuxPowRequest,
|
||||||
) -> Result<AddAuxPowResponse, Error> {
|
) -> Result<AddAuxPowResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_tx_ids_loose(
|
async fn get_tx_ids_loose(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetTxIdsLooseRequest,
|
request: GetTxIdsLooseRequest,
|
||||||
) -> Result<GetTxIdsLooseResponse, Error> {
|
) -> Result<GetTxIdsLooseResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
|
|
|
@ -17,11 +17,11 @@ use cuprate_rpc_types::other::{
|
||||||
StopDaemonResponse, StopMiningRequest, StopMiningResponse, UpdateRequest, UpdateResponse,
|
StopDaemonResponse, StopMiningRequest, StopMiningResponse, UpdateRequest, UpdateResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::rpc::CupratedRpcHandlerState;
|
use crate::rpc::CupratedRpcHandler;
|
||||||
|
|
||||||
/// Map a [`OtherRequest`] to the function that will lead to a [`OtherResponse`].
|
/// Map a [`OtherRequest`] to the function that will lead to a [`OtherResponse`].
|
||||||
pub(super) async fn map_request(
|
pub(super) async fn map_request(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: OtherRequest,
|
request: OtherRequest,
|
||||||
) -> Result<OtherResponse, Error> {
|
) -> Result<OtherResponse, Error> {
|
||||||
use OtherRequest as Req;
|
use OtherRequest as Req;
|
||||||
|
@ -71,189 +71,189 @@ pub(super) async fn map_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_height(
|
async fn get_height(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetHeightRequest,
|
request: GetHeightRequest,
|
||||||
) -> Result<GetHeightResponse, Error> {
|
) -> Result<GetHeightResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_transactions(
|
async fn get_transactions(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetTransactionsRequest,
|
request: GetTransactionsRequest,
|
||||||
) -> Result<GetTransactionsResponse, Error> {
|
) -> Result<GetTransactionsResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_alt_blocks_hashes(
|
async fn get_alt_blocks_hashes(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetAltBlocksHashesRequest,
|
request: GetAltBlocksHashesRequest,
|
||||||
) -> Result<GetAltBlocksHashesResponse, Error> {
|
) -> Result<GetAltBlocksHashesResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_key_image_spent(
|
async fn is_key_image_spent(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: IsKeyImageSpentRequest,
|
request: IsKeyImageSpentRequest,
|
||||||
) -> Result<IsKeyImageSpentResponse, Error> {
|
) -> Result<IsKeyImageSpentResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_raw_transaction(
|
async fn send_raw_transaction(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: SendRawTransactionRequest,
|
request: SendRawTransactionRequest,
|
||||||
) -> Result<SendRawTransactionResponse, Error> {
|
) -> Result<SendRawTransactionResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn start_mining(
|
async fn start_mining(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: StartMiningRequest,
|
request: StartMiningRequest,
|
||||||
) -> Result<StartMiningResponse, Error> {
|
) -> Result<StartMiningResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn stop_mining(
|
async fn stop_mining(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: StopMiningRequest,
|
request: StopMiningRequest,
|
||||||
) -> Result<StopMiningResponse, Error> {
|
) -> Result<StopMiningResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn mining_status(
|
async fn mining_status(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: MiningStatusRequest,
|
request: MiningStatusRequest,
|
||||||
) -> Result<MiningStatusResponse, Error> {
|
) -> Result<MiningStatusResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn save_bc(
|
async fn save_bc(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: SaveBcRequest,
|
request: SaveBcRequest,
|
||||||
) -> Result<SaveBcResponse, Error> {
|
) -> Result<SaveBcResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_peer_list(
|
async fn get_peer_list(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetPeerListRequest,
|
request: GetPeerListRequest,
|
||||||
) -> Result<GetPeerListResponse, Error> {
|
) -> Result<GetPeerListResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_log_hash_rate(
|
async fn set_log_hash_rate(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: SetLogHashRateRequest,
|
request: SetLogHashRateRequest,
|
||||||
) -> Result<SetLogHashRateResponse, Error> {
|
) -> Result<SetLogHashRateResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_log_level(
|
async fn set_log_level(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: SetLogLevelRequest,
|
request: SetLogLevelRequest,
|
||||||
) -> Result<SetLogLevelResponse, Error> {
|
) -> Result<SetLogLevelResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_log_categories(
|
async fn set_log_categories(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: SetLogCategoriesRequest,
|
request: SetLogCategoriesRequest,
|
||||||
) -> Result<SetLogCategoriesResponse, Error> {
|
) -> Result<SetLogCategoriesResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_bootstrap_daemon(
|
async fn set_bootstrap_daemon(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: SetBootstrapDaemonRequest,
|
request: SetBootstrapDaemonRequest,
|
||||||
) -> Result<SetBootstrapDaemonResponse, Error> {
|
) -> Result<SetBootstrapDaemonResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_transaction_pool(
|
async fn get_transaction_pool(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetTransactionPoolRequest,
|
request: GetTransactionPoolRequest,
|
||||||
) -> Result<GetTransactionPoolResponse, Error> {
|
) -> Result<GetTransactionPoolResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_transaction_pool_stats(
|
async fn get_transaction_pool_stats(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetTransactionPoolStatsRequest,
|
request: GetTransactionPoolStatsRequest,
|
||||||
) -> Result<GetTransactionPoolStatsResponse, Error> {
|
) -> Result<GetTransactionPoolStatsResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn stop_daemon(
|
async fn stop_daemon(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: StopDaemonRequest,
|
request: StopDaemonRequest,
|
||||||
) -> Result<StopDaemonResponse, Error> {
|
) -> Result<StopDaemonResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_limit(
|
async fn get_limit(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetLimitRequest,
|
request: GetLimitRequest,
|
||||||
) -> Result<GetLimitResponse, Error> {
|
) -> Result<GetLimitResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_limit(
|
async fn set_limit(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: SetLimitRequest,
|
request: SetLimitRequest,
|
||||||
) -> Result<SetLimitResponse, Error> {
|
) -> Result<SetLimitResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn out_peers(
|
async fn out_peers(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: OutPeersRequest,
|
request: OutPeersRequest,
|
||||||
) -> Result<OutPeersResponse, Error> {
|
) -> Result<OutPeersResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn in_peers(
|
async fn in_peers(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: InPeersRequest,
|
request: InPeersRequest,
|
||||||
) -> Result<InPeersResponse, Error> {
|
) -> Result<InPeersResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_net_stats(
|
async fn get_net_stats(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetNetStatsRequest,
|
request: GetNetStatsRequest,
|
||||||
) -> Result<GetNetStatsResponse, Error> {
|
) -> Result<GetNetStatsResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_outs(
|
async fn get_outs(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetOutsRequest,
|
request: GetOutsRequest,
|
||||||
) -> Result<GetOutsResponse, Error> {
|
) -> Result<GetOutsResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update(
|
async fn update(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: UpdateRequest,
|
request: UpdateRequest,
|
||||||
) -> Result<UpdateResponse, Error> {
|
) -> Result<UpdateResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn pop_blocks(
|
async fn pop_blocks(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: PopBlocksRequest,
|
request: PopBlocksRequest,
|
||||||
) -> Result<PopBlocksResponse, Error> {
|
) -> Result<PopBlocksResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_transaction_pool_hashes(
|
async fn get_transaction_pool_hashes(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetTransactionPoolHashesRequest,
|
request: GetTransactionPoolHashesRequest,
|
||||||
) -> Result<GetTransactionPoolHashesResponse, Error> {
|
) -> Result<GetTransactionPoolHashesResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_public_nodes(
|
async fn get_public_nodes(
|
||||||
state: CupratedRpcHandlerState,
|
state: CupratedRpcHandler,
|
||||||
request: GetPublicNodesRequest,
|
request: GetPublicNodesRequest,
|
||||||
) -> Result<GetPublicNodesResponse, Error> {
|
) -> Result<GetPublicNodesResponse, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
|
|
19
binaries/cuprated/src/rpc/request.rs
Normal file
19
binaries/cuprated/src/rpc/request.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//! Convenience functions for requests/responses.
|
||||||
|
//!
|
||||||
|
//! This module implements many methods for
|
||||||
|
//! [`CupratedRpcHandler`](crate::rpc::CupratedRpcHandler)
|
||||||
|
//! that are simple wrappers around the request/response API provided
|
||||||
|
//! by the multiple [`tower::Service`]s.
|
||||||
|
//!
|
||||||
|
//! These exist to prevent noise like `unreachable!()`
|
||||||
|
//! from being everywhere in the actual handler functions.
|
||||||
|
//!
|
||||||
|
//! Each module implements methods for a specific API, e.g.
|
||||||
|
//! the [`blockchain`] modules contains methods for the
|
||||||
|
//! blockchain database [`tower::Service`] API.
|
||||||
|
|
||||||
|
mod address_book;
|
||||||
|
mod blockchain;
|
||||||
|
mod blockchain_context;
|
||||||
|
mod blockchain_manager;
|
||||||
|
mod txpool;
|
104
binaries/cuprated/src/rpc/request/address_book.rs
Normal file
104
binaries/cuprated/src/rpc/request/address_book.rs
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
//! Functions for TODO: doc enum message.
|
||||||
|
|
||||||
|
use std::convert::Infallible;
|
||||||
|
|
||||||
|
use anyhow::Error;
|
||||||
|
use tower::ServiceExt;
|
||||||
|
|
||||||
|
use cuprate_helper::cast::usize_to_u64;
|
||||||
|
use cuprate_p2p_core::{
|
||||||
|
services::{AddressBookRequest, AddressBookResponse},
|
||||||
|
AddressBook, NetworkZone,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// [`AddressBookRequest::PeerlistSize`]
|
||||||
|
pub(super) async fn peerlist_size<Z: NetworkZone>(
|
||||||
|
address_book: &mut impl AddressBook<Z>,
|
||||||
|
) -> Result<(u64, u64), Error> {
|
||||||
|
let AddressBookResponse::PeerlistSize { white, grey } = address_book
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
.call(AddressBookRequest::PeerlistSize)
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((usize_to_u64(white), usize_to_u64(grey)))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`AddressBookRequest::ConnectionCount`]
|
||||||
|
pub(super) async fn connection_count<Z: NetworkZone>(
|
||||||
|
address_book: &mut impl AddressBook<Z>,
|
||||||
|
) -> Result<(u64, u64), Error> {
|
||||||
|
let AddressBookResponse::ConnectionCount { incoming, outgoing } = address_book
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
.call(AddressBookRequest::ConnectionCount)
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((usize_to_u64(incoming), usize_to_u64(outgoing)))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`AddressBookRequest::SetBan`]
|
||||||
|
pub(super) async fn set_ban<Z: NetworkZone>(
|
||||||
|
address_book: &mut impl AddressBook<Z>,
|
||||||
|
peer: cuprate_p2p_core::ban::SetBan<Z::Addr>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let AddressBookResponse::Ok = address_book
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
.call(AddressBookRequest::SetBan(peer))
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`AddressBookRequest::GetBan`]
|
||||||
|
pub(super) async fn get_ban<Z: NetworkZone>(
|
||||||
|
address_book: &mut impl AddressBook<Z>,
|
||||||
|
peer: Z::Addr,
|
||||||
|
) -> Result<Option<std::time::Instant>, Error> {
|
||||||
|
let AddressBookResponse::GetBan { unban_instant } = address_book
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
.call(AddressBookRequest::GetBan(peer))
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(unban_instant)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`AddressBookRequest::GetBans`]
|
||||||
|
pub(super) async fn get_bans<Z: NetworkZone>(
|
||||||
|
address_book: &mut impl AddressBook<Z>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let AddressBookResponse::GetBans(bans) = address_book
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
.call(AddressBookRequest::GetBans)
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(todo!())
|
||||||
|
}
|
308
binaries/cuprated/src/rpc/request/blockchain.rs
Normal file
308
binaries/cuprated/src/rpc/request/blockchain.rs
Normal file
|
@ -0,0 +1,308 @@
|
||||||
|
//! Functions for [`BlockchainReadRequest`].
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
ops::Range,
|
||||||
|
};
|
||||||
|
|
||||||
|
use anyhow::Error;
|
||||||
|
use cuprate_blockchain::service::BlockchainReadHandle;
|
||||||
|
use tower::{Service, ServiceExt};
|
||||||
|
|
||||||
|
use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
|
||||||
|
use cuprate_types::{
|
||||||
|
blockchain::{BlockchainReadRequest, BlockchainResponse},
|
||||||
|
Chain, CoinbaseTxSum, ExtendedBlockHeader, MinerData, OutputHistogramEntry,
|
||||||
|
OutputHistogramInput, OutputOnChain,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::BlockExtendedHeader`].
|
||||||
|
pub(super) async fn block_extended_header(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
height: u64,
|
||||||
|
) -> Result<ExtendedBlockHeader, Error> {
|
||||||
|
let BlockchainResponse::BlockExtendedHeader(header) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::BlockExtendedHeader(u64_to_usize(
|
||||||
|
height,
|
||||||
|
)))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(header)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::BlockHash`].
|
||||||
|
pub(super) async fn block_hash(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
height: u64,
|
||||||
|
chain: Chain,
|
||||||
|
) -> Result<[u8; 32], Error> {
|
||||||
|
let BlockchainResponse::BlockHash(hash) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::BlockHash(
|
||||||
|
u64_to_usize(height),
|
||||||
|
chain,
|
||||||
|
))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::FindBlock`].
|
||||||
|
pub(super) async fn find_block(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
block_hash: [u8; 32],
|
||||||
|
) -> Result<Option<(Chain, usize)>, Error> {
|
||||||
|
let BlockchainResponse::FindBlock(option) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::FindBlock(block_hash))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(option)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::FilterUnknownHashes`].
|
||||||
|
pub(super) async fn filter_unknown_hashes(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
block_hashes: HashSet<[u8; 32]>,
|
||||||
|
) -> Result<HashSet<[u8; 32]>, Error> {
|
||||||
|
let BlockchainResponse::FilterUnknownHashes(output) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::FilterUnknownHashes(block_hashes))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::BlockExtendedHeaderInRange`]
|
||||||
|
pub(super) async fn block_extended_header_in_range(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
range: Range<usize>,
|
||||||
|
chain: Chain,
|
||||||
|
) -> Result<Vec<ExtendedBlockHeader>, Error> {
|
||||||
|
let BlockchainResponse::BlockExtendedHeaderInRange(output) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::BlockExtendedHeaderInRange(
|
||||||
|
range, chain,
|
||||||
|
))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::ChainHeight`].
|
||||||
|
pub(super) async fn chain_height(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
) -> Result<(u64, [u8; 32]), Error> {
|
||||||
|
let BlockchainResponse::ChainHeight(height, hash) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::ChainHeight)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((usize_to_u64(height), hash))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::GeneratedCoins`].
|
||||||
|
pub(super) async fn generated_coins(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
block_height: u64,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
let BlockchainResponse::GeneratedCoins(generated_coins) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::GeneratedCoins(u64_to_usize(
|
||||||
|
block_height,
|
||||||
|
)))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(generated_coins)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::Outputs`]
|
||||||
|
pub(super) async fn outputs(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
outputs: HashMap<u64, HashSet<u64>>,
|
||||||
|
) -> Result<HashMap<u64, HashMap<u64, OutputOnChain>>, Error> {
|
||||||
|
let BlockchainResponse::Outputs(outputs) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::Outputs(outputs))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(outputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::NumberOutputsWithAmount`]
|
||||||
|
pub(super) async fn number_outputs_with_amount(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
output_amounts: Vec<u64>,
|
||||||
|
) -> Result<HashMap<u64, usize>, Error> {
|
||||||
|
let BlockchainResponse::NumberOutputsWithAmount(map) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::NumberOutputsWithAmount(
|
||||||
|
output_amounts,
|
||||||
|
))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(map)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::KeyImagesSpent`]
|
||||||
|
pub(super) async fn key_images_spent(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
key_images: HashSet<[u8; 32]>,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
let BlockchainResponse::KeyImagesSpent(is_spent) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::KeyImagesSpent(key_images))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(is_spent)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::CompactChainHistory`]
|
||||||
|
pub(super) async fn compact_chain_history(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
) -> Result<(Vec<[u8; 32]>, u128), Error> {
|
||||||
|
let BlockchainResponse::CompactChainHistory {
|
||||||
|
block_ids,
|
||||||
|
cumulative_difficulty,
|
||||||
|
} = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::CompactChainHistory)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((block_ids, cumulative_difficulty))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::FindFirstUnknown`]
|
||||||
|
pub(super) async fn find_first_unknown(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
hashes: Vec<[u8; 32]>,
|
||||||
|
) -> Result<Option<(usize, u64)>, Error> {
|
||||||
|
let BlockchainResponse::FindFirstUnknown(resp) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::FindFirstUnknown(hashes))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(resp.map(|(index, height)| (index, usize_to_u64(height))))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::TotalTxCount`]
|
||||||
|
pub(super) async fn total_tx_count(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
let BlockchainResponse::TotalTxCount(tx_count) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::TotalTxCount)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(usize_to_u64(tx_count))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::DatabaseSize`]
|
||||||
|
pub(super) async fn database_size(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
) -> Result<(u64, u64), Error> {
|
||||||
|
let BlockchainResponse::DatabaseSize {
|
||||||
|
database_size,
|
||||||
|
free_space,
|
||||||
|
} = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::DatabaseSize)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((database_size, free_space))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::OutputHistogram`]
|
||||||
|
pub(super) async fn output_histogram(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
input: OutputHistogramInput,
|
||||||
|
) -> Result<Vec<OutputHistogramEntry>, Error> {
|
||||||
|
let BlockchainResponse::OutputHistogram(histogram) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::OutputHistogram(input))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(histogram)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::CoinbaseTxSum`]
|
||||||
|
pub(super) async fn coinbase_tx_sum(
|
||||||
|
mut blockchain_read: BlockchainReadHandle,
|
||||||
|
height: u64,
|
||||||
|
count: u64,
|
||||||
|
) -> Result<CoinbaseTxSum, Error> {
|
||||||
|
let BlockchainResponse::CoinbaseTxSum(sum) = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::CoinbaseTxSum {
|
||||||
|
height: u64_to_usize(height),
|
||||||
|
count,
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(sum)
|
||||||
|
}
|
69
binaries/cuprated/src/rpc/request/blockchain_context.rs
Normal file
69
binaries/cuprated/src/rpc/request/blockchain_context.rs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
//! Functions for [`BlockChainContextRequest`] and [`BlockChainContextResponse`].
|
||||||
|
|
||||||
|
use std::convert::Infallible;
|
||||||
|
|
||||||
|
use anyhow::Error;
|
||||||
|
use tower::{Service, ServiceExt};
|
||||||
|
|
||||||
|
use cuprate_consensus::context::{
|
||||||
|
BlockChainContext, BlockChainContextRequest, BlockChainContextResponse,
|
||||||
|
BlockChainContextService,
|
||||||
|
};
|
||||||
|
use cuprate_types::{FeeEstimate, HardFork, HardForkInfo};
|
||||||
|
|
||||||
|
/// [`BlockChainContextRequest::Context`].
|
||||||
|
pub(super) async fn context(
|
||||||
|
service: &mut BlockChainContextService,
|
||||||
|
height: u64,
|
||||||
|
) -> Result<BlockChainContext, Error> {
|
||||||
|
let BlockChainContextResponse::Context(context) = service
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
.call(BlockChainContextRequest::Context)
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockChainContextRequest::HardForkInfo`].
|
||||||
|
pub(super) async fn hard_fork_info(
|
||||||
|
service: &mut BlockChainContextService,
|
||||||
|
hard_fork: HardFork,
|
||||||
|
) -> Result<HardForkInfo, Error> {
|
||||||
|
let BlockChainContextResponse::HardForkInfo(hf_info) = service
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
.call(BlockChainContextRequest::HardForkInfo(hard_fork))
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(hf_info)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockChainContextRequest::FeeEstimate`].
|
||||||
|
pub(super) async fn fee_estimate(
|
||||||
|
service: &mut BlockChainContextService,
|
||||||
|
grace_blocks: u64,
|
||||||
|
) -> Result<FeeEstimate, Error> {
|
||||||
|
let BlockChainContextResponse::FeeEstimate(fee) = service
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
.call(BlockChainContextRequest::FeeEstimate { grace_blocks })
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(fee)
|
||||||
|
}
|
141
binaries/cuprated/src/rpc/request/blockchain_manager.rs
Normal file
141
binaries/cuprated/src/rpc/request/blockchain_manager.rs
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
//! Functions for [`BlockchainManagerRequest`] & [`BlockchainManagerResponse`].
|
||||||
|
|
||||||
|
use anyhow::Error;
|
||||||
|
use monero_serai::block::Block;
|
||||||
|
use tower::{Service, ServiceExt};
|
||||||
|
|
||||||
|
use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
|
||||||
|
|
||||||
|
use crate::rpc::handler::{
|
||||||
|
BlockchainManagerHandle, BlockchainManagerRequest, BlockchainManagerResponse,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// [`BlockchainManagerRequest::PopBlocks`]
|
||||||
|
pub(super) async fn pop_blocks(
|
||||||
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
amount: u64,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
let BlockchainManagerResponse::PopBlocks { new_height } = blockchain_manager
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainManagerRequest::PopBlocks {
|
||||||
|
amount: u64_to_usize(amount),
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(usize_to_u64(new_height))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainManagerRequest::Prune`]
|
||||||
|
pub(super) async fn prune(blockchain_manager: &mut BlockchainManagerHandle) -> Result<(), Error> {
|
||||||
|
let BlockchainManagerResponse::Ok = blockchain_manager
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainManagerRequest::Prune)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainManagerRequest::Pruned`]
|
||||||
|
pub(super) async fn pruned(
|
||||||
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
let BlockchainManagerResponse::Pruned(pruned) = blockchain_manager
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainManagerRequest::Pruned)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(pruned)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainManagerRequest::RelayBlock`]
|
||||||
|
pub(super) async fn relay_block(
|
||||||
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
block: Block,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let BlockchainManagerResponse::Ok = blockchain_manager
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainManagerRequest::RelayBlock(block))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainManagerRequest::Syncing`]
|
||||||
|
pub(super) async fn syncing(
|
||||||
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
let BlockchainManagerResponse::Syncing(syncing) = blockchain_manager
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainManagerRequest::Syncing)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(syncing)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainManagerRequest::Synced`]
|
||||||
|
pub(super) async fn synced(
|
||||||
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
let BlockchainManagerResponse::Synced(syncing) = blockchain_manager
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainManagerRequest::Synced)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(syncing)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainManagerRequest::Target`]
|
||||||
|
pub(super) async fn target(
|
||||||
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
) -> Result<std::time::Duration, Error> {
|
||||||
|
let BlockchainManagerResponse::Target(target) = blockchain_manager
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainManagerRequest::Target)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainManagerRequest::TargetHeight`]
|
||||||
|
pub(super) async fn target_height(
|
||||||
|
blockchain_manager: &mut BlockchainManagerHandle,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
let BlockchainManagerResponse::TargetHeight { height } = blockchain_manager
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainManagerRequest::TargetHeight)
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(usize_to_u64(height))
|
||||||
|
}
|
57
binaries/cuprated/src/rpc/request/txpool.rs
Normal file
57
binaries/cuprated/src/rpc/request/txpool.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
//! Functions for [`TxpoolReadRequest`].
|
||||||
|
|
||||||
|
use std::convert::Infallible;
|
||||||
|
|
||||||
|
use anyhow::Error;
|
||||||
|
use tower::{Service, ServiceExt};
|
||||||
|
|
||||||
|
use cuprate_helper::cast::usize_to_u64;
|
||||||
|
use cuprate_txpool::{
|
||||||
|
service::{
|
||||||
|
interface::{TxpoolReadRequest, TxpoolReadResponse},
|
||||||
|
TxpoolReadHandle,
|
||||||
|
},
|
||||||
|
TxEntry,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// [`TxpoolReadRequest::Backlog`]
|
||||||
|
pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result<Vec<TxEntry>, Error> {
|
||||||
|
let TxpoolReadResponse::Backlog(tx_entries) = txpool_read
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
.call(TxpoolReadRequest::Backlog)
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(tx_entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`TxpoolReadRequest::Size`]
|
||||||
|
pub(super) async fn size(txpool_read: &mut TxpoolReadHandle) -> Result<u64, Error> {
|
||||||
|
let TxpoolReadResponse::Size(size) = txpool_read
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
.call(TxpoolReadRequest::Size)
|
||||||
|
.await
|
||||||
|
.expect("TODO")
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(usize_to_u64(size))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO
|
||||||
|
#[expect(clippy::needless_pass_by_ref_mut, reason = "TODO: remove after impl")]
|
||||||
|
pub(super) async fn flush(
|
||||||
|
txpool_read: &mut TxpoolReadHandle,
|
||||||
|
tx_hashes: Vec<[u8; 32]>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
todo!();
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -230,7 +230,7 @@ where
|
||||||
let BlockChainContextResponse::Context(checked_context) = context_svc
|
let BlockChainContextResponse::Context(checked_context) = context_svc
|
||||||
.ready()
|
.ready()
|
||||||
.await?
|
.await?
|
||||||
.call(BlockChainContextRequest::GetContext)
|
.call(BlockChainContextRequest::Context)
|
||||||
.await?
|
.await?
|
||||||
else {
|
else {
|
||||||
panic!("Context service returned wrong response!");
|
panic!("Context service returned wrong response!");
|
||||||
|
|
|
@ -351,7 +351,7 @@ where
|
||||||
let BlockChainContextResponse::Context(checked_context) = context_svc
|
let BlockChainContextResponse::Context(checked_context) = context_svc
|
||||||
.ready()
|
.ready()
|
||||||
.await?
|
.await?
|
||||||
.call(BlockChainContextRequest::GetContext)
|
.call(BlockChainContextRequest::Context)
|
||||||
.await?
|
.await?
|
||||||
else {
|
else {
|
||||||
panic!("Context service returned wrong response!");
|
panic!("Context service returned wrong response!");
|
||||||
|
@ -374,7 +374,7 @@ where
|
||||||
let BlockChainContextResponse::RxVms(rx_vms) = context_svc
|
let BlockChainContextResponse::RxVms(rx_vms) = context_svc
|
||||||
.ready()
|
.ready()
|
||||||
.await?
|
.await?
|
||||||
.call(BlockChainContextRequest::GetCurrentRxVm)
|
.call(BlockChainContextRequest::CurrentRxVms)
|
||||||
.await?
|
.await?
|
||||||
else {
|
else {
|
||||||
panic!("Blockchain context service returned wrong response!");
|
panic!("Blockchain context service returned wrong response!");
|
||||||
|
@ -433,7 +433,7 @@ where
|
||||||
context
|
context
|
||||||
} else {
|
} else {
|
||||||
let BlockChainContextResponse::Context(checked_context) = context_svc
|
let BlockChainContextResponse::Context(checked_context) = context_svc
|
||||||
.oneshot(BlockChainContextRequest::GetContext)
|
.oneshot(BlockChainContextRequest::Context)
|
||||||
.await?
|
.await?
|
||||||
else {
|
else {
|
||||||
panic!("Context service returned wrong response!");
|
panic!("Context service returned wrong response!");
|
||||||
|
|
|
@ -93,7 +93,7 @@ where
|
||||||
let BlockChainContextResponse::Context(checked_context) = context_svc
|
let BlockChainContextResponse::Context(checked_context) = context_svc
|
||||||
.ready()
|
.ready()
|
||||||
.await?
|
.await?
|
||||||
.call(BlockChainContextRequest::GetContext)
|
.call(BlockChainContextRequest::Context)
|
||||||
.await?
|
.await?
|
||||||
else {
|
else {
|
||||||
panic!("Context service returned wrong response!");
|
panic!("Context service returned wrong response!");
|
||||||
|
@ -136,7 +136,7 @@ where
|
||||||
let BlockChainContextResponse::RxVms(rx_vms) = context_svc
|
let BlockChainContextResponse::RxVms(rx_vms) = context_svc
|
||||||
.ready()
|
.ready()
|
||||||
.await?
|
.await?
|
||||||
.call(BlockChainContextRequest::GetCurrentRxVm)
|
.call(BlockChainContextRequest::CurrentRxVms)
|
||||||
.await?
|
.await?
|
||||||
else {
|
else {
|
||||||
panic!("Blockchain context service returned wrong response!");
|
panic!("Blockchain context service returned wrong response!");
|
||||||
|
|
|
@ -31,7 +31,7 @@ mod alt_chains;
|
||||||
mod task;
|
mod task;
|
||||||
mod tokens;
|
mod tokens;
|
||||||
|
|
||||||
use cuprate_types::Chain;
|
use cuprate_types::{Chain, ChainInfo, FeeEstimate, HardForkInfo};
|
||||||
use difficulty::DifficultyCache;
|
use difficulty::DifficultyCache;
|
||||||
use rx_vms::RandomXVm;
|
use rx_vms::RandomXVm;
|
||||||
use weight::BlockWeightsCache;
|
use weight::BlockWeightsCache;
|
||||||
|
@ -221,15 +221,18 @@ pub struct NewBlockData {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum BlockChainContextRequest {
|
pub enum BlockChainContextRequest {
|
||||||
/// Get the current blockchain context.
|
/// Get the current blockchain context.
|
||||||
GetContext,
|
Context,
|
||||||
/// Gets the current `RandomX` VM.
|
|
||||||
GetCurrentRxVm,
|
/// Gets all the current `RandomX` VMs.
|
||||||
|
CurrentRxVms,
|
||||||
|
|
||||||
/// Get the next difficulties for these blocks.
|
/// Get the next difficulties for these blocks.
|
||||||
///
|
///
|
||||||
/// Inputs: a list of block timestamps and hfs
|
/// Inputs: a list of block timestamps and hfs
|
||||||
///
|
///
|
||||||
/// The number of difficulties returned will be one more than the number of timestamps/ hfs.
|
/// The number of difficulties returned will be one more than the number of timestamps/ hfs.
|
||||||
BatchGetDifficulties(Vec<(u64, HardFork)>),
|
BatchGetDifficulties(Vec<(u64, HardFork)>),
|
||||||
|
|
||||||
/// Add a VM that has been created outside of the blockchain context service to the blockchain context.
|
/// Add a VM that has been created outside of the blockchain context service to the blockchain context.
|
||||||
/// This is useful when batch calculating POW as you may need to create a new VM if you batch a lot of blocks together,
|
/// This is useful when batch calculating POW as you may need to create a new VM if you batch a lot of blocks together,
|
||||||
/// it would be wasteful to then not give this VM to the context service to then use when it needs to init a VM with the same
|
/// it would be wasteful to then not give this VM to the context service to then use when it needs to init a VM with the same
|
||||||
|
@ -237,8 +240,10 @@ pub enum BlockChainContextRequest {
|
||||||
///
|
///
|
||||||
/// This should include the seed used to init this VM and the VM.
|
/// This should include the seed used to init this VM and the VM.
|
||||||
NewRXVM(([u8; 32], Arc<RandomXVm>)),
|
NewRXVM(([u8; 32], Arc<RandomXVm>)),
|
||||||
|
|
||||||
/// A request to add a new block to the cache.
|
/// A request to add a new block to the cache.
|
||||||
Update(NewBlockData),
|
Update(NewBlockData),
|
||||||
|
|
||||||
/// Pop blocks from the cache to the specified height.
|
/// Pop blocks from the cache to the specified height.
|
||||||
PopBlocks {
|
PopBlocks {
|
||||||
/// The number of blocks to pop from the top of the chain.
|
/// The number of blocks to pop from the top of the chain.
|
||||||
|
@ -248,8 +253,22 @@ pub enum BlockChainContextRequest {
|
||||||
/// This will panic if the number of blocks will pop the genesis block.
|
/// This will panic if the number of blocks will pop the genesis block.
|
||||||
numb_blocks: usize,
|
numb_blocks: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Get information on a certain hardfork.
|
||||||
|
HardForkInfo(HardFork),
|
||||||
|
|
||||||
|
/// Get the current fee estimate.
|
||||||
|
FeeEstimate {
|
||||||
|
/// TODO
|
||||||
|
grace_blocks: u64,
|
||||||
|
},
|
||||||
|
|
||||||
/// Clear the alt chain context caches.
|
/// Clear the alt chain context caches.
|
||||||
ClearAltCache,
|
ClearAltCache,
|
||||||
|
|
||||||
|
/// Get information on all the current alternate chains.
|
||||||
|
AltChains,
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------- AltChainRequests
|
//----------------------------------------------------------------------------------------------------------- AltChainRequests
|
||||||
/// A request for an alt chain context cache.
|
/// A request for an alt chain context cache.
|
||||||
///
|
///
|
||||||
|
@ -261,6 +280,7 @@ pub enum BlockChainContextRequest {
|
||||||
/// An internal token to prevent external crates calling this request.
|
/// An internal token to prevent external crates calling this request.
|
||||||
_token: AltChainRequestToken,
|
_token: AltChainRequestToken,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A request for a difficulty cache of an alternative chin.
|
/// A request for a difficulty cache of an alternative chin.
|
||||||
///
|
///
|
||||||
/// This variant is private and is not callable from outside this crate, the block verifier service will
|
/// This variant is private and is not callable from outside this crate, the block verifier service will
|
||||||
|
@ -271,6 +291,7 @@ pub enum BlockChainContextRequest {
|
||||||
/// An internal token to prevent external crates calling this request.
|
/// An internal token to prevent external crates calling this request.
|
||||||
_token: AltChainRequestToken,
|
_token: AltChainRequestToken,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A request for a block weight cache of an alternative chin.
|
/// A request for a block weight cache of an alternative chin.
|
||||||
///
|
///
|
||||||
/// This variant is private and is not callable from outside this crate, the block verifier service will
|
/// This variant is private and is not callable from outside this crate, the block verifier service will
|
||||||
|
@ -281,6 +302,7 @@ pub enum BlockChainContextRequest {
|
||||||
/// An internal token to prevent external crates calling this request.
|
/// An internal token to prevent external crates calling this request.
|
||||||
_token: AltChainRequestToken,
|
_token: AltChainRequestToken,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A request for a RX VM for an alternative chin.
|
/// A request for a RX VM for an alternative chin.
|
||||||
///
|
///
|
||||||
/// Response variant: [`BlockChainContextResponse::AltChainRxVM`].
|
/// Response variant: [`BlockChainContextResponse::AltChainRxVM`].
|
||||||
|
@ -295,6 +317,7 @@ pub enum BlockChainContextRequest {
|
||||||
/// An internal token to prevent external crates calling this request.
|
/// An internal token to prevent external crates calling this request.
|
||||||
_token: AltChainRequestToken,
|
_token: AltChainRequestToken,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A request to add an alt chain context cache to the context cache.
|
/// A request to add an alt chain context cache to the context cache.
|
||||||
///
|
///
|
||||||
/// This variant is private and is not callable from outside this crate, the block verifier service will
|
/// This variant is private and is not callable from outside this crate, the block verifier service will
|
||||||
|
@ -310,22 +333,49 @@ pub enum BlockChainContextRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum BlockChainContextResponse {
|
pub enum BlockChainContextResponse {
|
||||||
/// Blockchain context response.
|
/// A generic Ok response.
|
||||||
|
///
|
||||||
|
/// Response to:
|
||||||
|
/// - [`BlockChainContextRequest::NewRXVM`]
|
||||||
|
/// - [`BlockChainContextRequest::Update`]
|
||||||
|
/// - [`BlockChainContextRequest::PopBlocks`]
|
||||||
|
/// - [`BlockChainContextRequest::ClearAltCache`]
|
||||||
|
/// - [`BlockChainContextRequest::AddAltChainContextCache`]
|
||||||
|
Ok,
|
||||||
|
|
||||||
|
/// Response to [`BlockChainContextRequest::Context`]
|
||||||
Context(BlockChainContext),
|
Context(BlockChainContext),
|
||||||
|
|
||||||
|
/// Response to [`BlockChainContextRequest::CurrentRxVms`]
|
||||||
|
///
|
||||||
/// A map of seed height to `RandomX` VMs.
|
/// A map of seed height to `RandomX` VMs.
|
||||||
RxVms(HashMap<usize, Arc<RandomXVm>>),
|
RxVms(HashMap<usize, Arc<RandomXVm>>),
|
||||||
|
|
||||||
/// A list of difficulties.
|
/// A list of difficulties.
|
||||||
BatchDifficulties(Vec<u128>),
|
BatchDifficulties(Vec<u128>),
|
||||||
|
|
||||||
|
/// Response to [`BlockChainContextRequest::HardForkInfo`]
|
||||||
|
HardForkInfo(HardForkInfo),
|
||||||
|
|
||||||
|
/// Response to [`BlockChainContextRequest::FeeEstimate`]
|
||||||
|
FeeEstimate(FeeEstimate),
|
||||||
|
|
||||||
|
/// Response to [`BlockChainContextRequest::AltChains`]
|
||||||
|
///
|
||||||
|
/// If the inner [`Vec::is_empty`], there were no alternate chains.
|
||||||
|
AltChains(Vec<ChainInfo>),
|
||||||
|
|
||||||
/// An alt chain context cache.
|
/// An alt chain context cache.
|
||||||
AltChainContextCache(Box<AltChainContextCache>),
|
AltChainContextCache(Box<AltChainContextCache>),
|
||||||
|
|
||||||
/// A difficulty cache for an alt chain.
|
/// A difficulty cache for an alt chain.
|
||||||
AltChainDifficultyCache(DifficultyCache),
|
AltChainDifficultyCache(DifficultyCache),
|
||||||
|
|
||||||
/// A randomX VM for an alt chain.
|
/// A randomX VM for an alt chain.
|
||||||
AltChainRxVM(Arc<RandomXVm>),
|
AltChainRxVM(Arc<RandomXVm>),
|
||||||
|
|
||||||
/// A weight cache for an alt chain
|
/// A weight cache for an alt chain
|
||||||
AltChainWeightCache(BlockWeightsCache),
|
AltChainWeightCache(BlockWeightsCache),
|
||||||
/// A generic Ok response.
|
|
||||||
Ok,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The blockchain context service.
|
/// The blockchain context service.
|
||||||
|
|
|
@ -153,7 +153,7 @@ impl<D: Database + Clone + Send + 'static> ContextTask<D> {
|
||||||
req: BlockChainContextRequest,
|
req: BlockChainContextRequest,
|
||||||
) -> Result<BlockChainContextResponse, tower::BoxError> {
|
) -> Result<BlockChainContextResponse, tower::BoxError> {
|
||||||
Ok(match req {
|
Ok(match req {
|
||||||
BlockChainContextRequest::GetContext => {
|
BlockChainContextRequest::Context => {
|
||||||
tracing::debug!("Getting blockchain context");
|
tracing::debug!("Getting blockchain context");
|
||||||
|
|
||||||
let current_hf = self.hardfork_state.current_hardfork();
|
let current_hf = self.hardfork_state.current_hardfork();
|
||||||
|
@ -183,7 +183,7 @@ impl<D: Database + Clone + Send + 'static> ContextTask<D> {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
BlockChainContextRequest::GetCurrentRxVm => {
|
BlockChainContextRequest::CurrentRxVms => {
|
||||||
BlockChainContextResponse::RxVms(self.rx_vm_cache.get_vms().await)
|
BlockChainContextResponse::RxVms(self.rx_vm_cache.get_vms().await)
|
||||||
}
|
}
|
||||||
BlockChainContextRequest::BatchGetDifficulties(blocks) => {
|
BlockChainContextRequest::BatchGetDifficulties(blocks) => {
|
||||||
|
@ -325,6 +325,11 @@ impl<D: Database + Clone + Send + 'static> ContextTask<D> {
|
||||||
self.alt_chain_cache_map.add_alt_cache(prev_id, cache);
|
self.alt_chain_cache_map.add_alt_cache(prev_id, cache);
|
||||||
BlockChainContextResponse::Ok
|
BlockChainContextResponse::Ok
|
||||||
}
|
}
|
||||||
|
BlockChainContextRequest::HardForkInfo(_)
|
||||||
|
| BlockChainContextRequest::FeeEstimate { .. }
|
||||||
|
| BlockChainContextRequest::AltChains => {
|
||||||
|
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ async fn context_invalidated_on_new_block() -> Result<(), tower::BoxError> {
|
||||||
|
|
||||||
let BlockChainContextResponse::Context(context) = ctx_svc
|
let BlockChainContextResponse::Context(context) = ctx_svc
|
||||||
.clone()
|
.clone()
|
||||||
.oneshot(BlockChainContextRequest::GetContext)
|
.oneshot(BlockChainContextRequest::Context)
|
||||||
.await?
|
.await?
|
||||||
else {
|
else {
|
||||||
panic!("Context service returned wrong response!");
|
panic!("Context service returned wrong response!");
|
||||||
|
@ -81,9 +81,8 @@ async fn context_height_correct() -> Result<(), tower::BoxError> {
|
||||||
|
|
||||||
let ctx_svc = initialize_blockchain_context(TEST_CONTEXT_CONFIG, db).await?;
|
let ctx_svc = initialize_blockchain_context(TEST_CONTEXT_CONFIG, db).await?;
|
||||||
|
|
||||||
let BlockChainContextResponse::Context(context) = ctx_svc
|
let BlockChainContextResponse::Context(context) =
|
||||||
.oneshot(BlockChainContextRequest::GetContext)
|
ctx_svc.oneshot(BlockChainContextRequest::Context).await?
|
||||||
.await?
|
|
||||||
else {
|
else {
|
||||||
panic!("context service returned incorrect response!")
|
panic!("context service returned incorrect response!")
|
||||||
};
|
};
|
||||||
|
|
|
@ -229,6 +229,15 @@ impl<Z: BorshNetworkZone> AddressBook<Z> {
|
||||||
self.banned_peers.contains_key(&peer.ban_id())
|
self.banned_peers.contains_key(&peer.ban_id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks when a peer will be unbanned.
|
||||||
|
///
|
||||||
|
/// - If the peer is banned, this returns [`Some`] containing
|
||||||
|
/// the [`Instant`] the peer will be unbanned
|
||||||
|
/// - If the peer is not banned, this returns [`None`]
|
||||||
|
fn peer_unban_instant(&self, peer: &Z::Addr) -> Option<Instant> {
|
||||||
|
self.banned_peers.get(&peer.ban_id()).copied()
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_incoming_peer_list(
|
fn handle_incoming_peer_list(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut peer_list: Vec<ZoneSpecificPeerListEntryBase<Z::Addr>>,
|
mut peer_list: Vec<ZoneSpecificPeerListEntryBase<Z::Addr>>,
|
||||||
|
@ -408,9 +417,15 @@ impl<Z: BorshNetworkZone> Service<AddressBookRequest<Z>> for AddressBook<Z> {
|
||||||
AddressBookRequest::GetWhitePeers(len) => {
|
AddressBookRequest::GetWhitePeers(len) => {
|
||||||
Ok(AddressBookResponse::Peers(self.get_white_peers(len)))
|
Ok(AddressBookResponse::Peers(self.get_white_peers(len)))
|
||||||
}
|
}
|
||||||
AddressBookRequest::IsPeerBanned(addr) => Ok(AddressBookResponse::IsPeerBanned(
|
AddressBookRequest::GetBan(addr) => Ok(AddressBookResponse::GetBan {
|
||||||
self.is_peer_banned(&addr),
|
unban_instant: self.peer_unban_instant(&addr).map(Instant::into_std),
|
||||||
)),
|
}),
|
||||||
|
AddressBookRequest::PeerlistSize
|
||||||
|
| AddressBookRequest::ConnectionCount
|
||||||
|
| AddressBookRequest::SetBan(_)
|
||||||
|
| AddressBookRequest::GetBans => {
|
||||||
|
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ready(response)
|
ready(response)
|
||||||
|
|
23
p2p/p2p-core/src/ban.rs
Normal file
23
p2p/p2p-core/src/ban.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
//! Data structures related to bans.
|
||||||
|
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
use crate::NetZoneAddress;
|
||||||
|
|
||||||
|
/// Data within [`crate::services::AddressBookRequest::SetBan`].
|
||||||
|
pub struct SetBan<A: NetZoneAddress> {
|
||||||
|
/// Address of the peer.
|
||||||
|
pub address: A,
|
||||||
|
/// - If [`Some`], how long this peer should be banned for
|
||||||
|
/// - If [`None`], the peer will be unbanned
|
||||||
|
pub ban: Option<Duration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Data within [`crate::services::AddressBookResponse::GetBans`].
|
||||||
|
pub struct BanState<A: NetZoneAddress> {
|
||||||
|
/// Address of the peer.
|
||||||
|
pub address: A,
|
||||||
|
/// - If [`Some`], the peer is banned until this [`Instant`]
|
||||||
|
/// - If [`None`], the peer is not currently banned
|
||||||
|
pub unban_instant: Option<Instant>,
|
||||||
|
}
|
|
@ -105,7 +105,15 @@ impl<N: NetworkZone> Service<AddressBookRequest<N>> for DummyAddressBook {
|
||||||
AddressBookRequest::NewConnection { .. } | AddressBookRequest::IncomingPeerList(_) => {
|
AddressBookRequest::NewConnection { .. } | AddressBookRequest::IncomingPeerList(_) => {
|
||||||
AddressBookResponse::Ok
|
AddressBookResponse::Ok
|
||||||
}
|
}
|
||||||
AddressBookRequest::IsPeerBanned(_) => AddressBookResponse::IsPeerBanned(false),
|
AddressBookRequest::GetBan(_) => AddressBookResponse::GetBan {
|
||||||
|
unban_instant: None,
|
||||||
|
},
|
||||||
|
AddressBookRequest::PeerlistSize
|
||||||
|
| AddressBookRequest::ConnectionCount
|
||||||
|
| AddressBookRequest::SetBan(_)
|
||||||
|
| AddressBookRequest::GetBans => {
|
||||||
|
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ use cuprate_wire::{
|
||||||
NetworkAddress,
|
NetworkAddress,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod ban;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
mod constants;
|
mod constants;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
use cuprate_pruning::{PruningError, PruningSeed};
|
use cuprate_pruning::{PruningError, PruningSeed};
|
||||||
use cuprate_wire::{CoreSyncData, PeerListEntryBase};
|
use cuprate_wire::{CoreSyncData, PeerListEntryBase};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
client::InternalPeerID, handles::ConnectionHandle, NetZoneAddress, NetworkAddressIncorrectZone,
|
ban::{BanState, SetBan},
|
||||||
NetworkZone,
|
client::InternalPeerID,
|
||||||
|
handles::ConnectionHandle,
|
||||||
|
NetZoneAddress, NetworkAddressIncorrectZone, NetworkZone,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A request to the core sync service for our node's [`CoreSyncData`].
|
/// A request to the core sync service for our node's [`CoreSyncData`].
|
||||||
|
@ -86,16 +90,20 @@ pub enum AddressBookRequest<Z: NetworkZone> {
|
||||||
/// The peers rpc credits per hash
|
/// The peers rpc credits per hash
|
||||||
rpc_credits_per_hash: u32,
|
rpc_credits_per_hash: u32,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Tells the address book about a peer list received from a peer.
|
/// Tells the address book about a peer list received from a peer.
|
||||||
IncomingPeerList(Vec<ZoneSpecificPeerListEntryBase<Z::Addr>>),
|
IncomingPeerList(Vec<ZoneSpecificPeerListEntryBase<Z::Addr>>),
|
||||||
|
|
||||||
/// Takes a random white peer from the peer list. If height is specified
|
/// Takes a random white peer from the peer list. If height is specified
|
||||||
/// then the peer list should retrieve a peer that should have a full
|
/// then the peer list should retrieve a peer that should have a full
|
||||||
/// block at that height according to it's pruning seed
|
/// block at that height according to it's pruning seed
|
||||||
TakeRandomWhitePeer { height: Option<usize> },
|
TakeRandomWhitePeer { height: Option<usize> },
|
||||||
|
|
||||||
/// Takes a random gray peer from the peer list. If height is specified
|
/// Takes a random gray peer from the peer list. If height is specified
|
||||||
/// then the peer list should retrieve a peer that should have a full
|
/// then the peer list should retrieve a peer that should have a full
|
||||||
/// block at that height according to it's pruning seed
|
/// block at that height according to it's pruning seed
|
||||||
TakeRandomGrayPeer { height: Option<usize> },
|
TakeRandomGrayPeer { height: Option<usize> },
|
||||||
|
|
||||||
/// Takes a random peer from the peer list. If height is specified
|
/// Takes a random peer from the peer list. If height is specified
|
||||||
/// then the peer list should retrieve a peer that should have a full
|
/// then the peer list should retrieve a peer that should have a full
|
||||||
/// block at that height according to it's pruning seed.
|
/// block at that height according to it's pruning seed.
|
||||||
|
@ -103,17 +111,56 @@ pub enum AddressBookRequest<Z: NetworkZone> {
|
||||||
/// The address book will look in the white peer list first, then the gray
|
/// The address book will look in the white peer list first, then the gray
|
||||||
/// one if no peer is found.
|
/// one if no peer is found.
|
||||||
TakeRandomPeer { height: Option<usize> },
|
TakeRandomPeer { height: Option<usize> },
|
||||||
|
|
||||||
/// Gets the specified number of white peers, or less if we don't have enough.
|
/// Gets the specified number of white peers, or less if we don't have enough.
|
||||||
GetWhitePeers(usize),
|
GetWhitePeers(usize),
|
||||||
|
|
||||||
|
/// Get the amount of white & grey peers.
|
||||||
|
PeerlistSize,
|
||||||
|
|
||||||
|
/// Get the amount of incoming & outgoing connections.
|
||||||
|
ConnectionCount,
|
||||||
|
|
||||||
|
/// (Un)ban a peer.
|
||||||
|
SetBan(SetBan<Z::Addr>),
|
||||||
|
|
||||||
/// Checks if the given peer is banned.
|
/// Checks if the given peer is banned.
|
||||||
IsPeerBanned(Z::Addr),
|
GetBan(Z::Addr),
|
||||||
|
|
||||||
|
/// Get the state of all bans.
|
||||||
|
GetBans,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A response from the address book service.
|
/// A response from the address book service.
|
||||||
pub enum AddressBookResponse<Z: NetworkZone> {
|
pub enum AddressBookResponse<Z: NetworkZone> {
|
||||||
|
/// Generic OK response.
|
||||||
|
///
|
||||||
|
/// Response to:
|
||||||
|
/// - [`AddressBookRequest::NewConnection`]
|
||||||
|
/// - [`AddressBookRequest::IncomingPeerList`]
|
||||||
Ok,
|
Ok,
|
||||||
|
|
||||||
|
/// Response to:
|
||||||
|
/// - [`AddressBookRequest::TakeRandomWhitePeer`]
|
||||||
|
/// - [`AddressBookRequest::TakeRandomGrayPeer`]
|
||||||
|
/// - [`AddressBookRequest::TakeRandomPeer`]
|
||||||
Peer(ZoneSpecificPeerListEntryBase<Z::Addr>),
|
Peer(ZoneSpecificPeerListEntryBase<Z::Addr>),
|
||||||
|
|
||||||
|
/// Response to [`AddressBookRequest::GetWhitePeers`].
|
||||||
Peers(Vec<ZoneSpecificPeerListEntryBase<Z::Addr>>),
|
Peers(Vec<ZoneSpecificPeerListEntryBase<Z::Addr>>),
|
||||||
/// Contains `true` if the peer is banned.
|
|
||||||
IsPeerBanned(bool),
|
/// Response to [`AddressBookRequest::PeerlistSize`].
|
||||||
|
PeerlistSize { white: usize, grey: usize },
|
||||||
|
|
||||||
|
/// Response to [`AddressBookRequest::ConnectionCount`].
|
||||||
|
ConnectionCount { incoming: usize, outgoing: usize },
|
||||||
|
|
||||||
|
/// Response to [`AddressBookRequest::GetBan`].
|
||||||
|
///
|
||||||
|
/// This returns [`None`] if the peer is not banned,
|
||||||
|
/// else it returns how long the peer is banned for.
|
||||||
|
GetBan { unban_instant: Option<Instant> },
|
||||||
|
|
||||||
|
/// Response to [`AddressBookRequest::GetBans`].
|
||||||
|
GetBans(Vec<BanState<Z::Addr>>),
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,16 +79,16 @@ where
|
||||||
|
|
||||||
// If peer is banned, drop connection
|
// If peer is banned, drop connection
|
||||||
if let Some(addr) = &addr {
|
if let Some(addr) = &addr {
|
||||||
let AddressBookResponse::IsPeerBanned(banned) = address_book
|
let AddressBookResponse::GetBan { unban_instant } = address_book
|
||||||
.ready()
|
.ready()
|
||||||
.await?
|
.await?
|
||||||
.call(AddressBookRequest::IsPeerBanned(*addr))
|
.call(AddressBookRequest::GetBan(*addr))
|
||||||
.await?
|
.await?
|
||||||
else {
|
else {
|
||||||
panic!("Address book returned incorrect response!");
|
panic!("Address book returned incorrect response!");
|
||||||
};
|
};
|
||||||
|
|
||||||
if banned {
|
if unban_instant.is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -817,8 +817,17 @@ define_request_and_response! {
|
||||||
hard_fork_info,
|
hard_fork_info,
|
||||||
cc73fe71162d564ffda8e549b79a350bca53c454 =>
|
cc73fe71162d564ffda8e549b79a350bca53c454 =>
|
||||||
core_rpc_server_commands_defs.h => 1958..=1995,
|
core_rpc_server_commands_defs.h => 1958..=1995,
|
||||||
HardForkInfo (empty),
|
HardForkInfo,
|
||||||
Request {},
|
|
||||||
|
#[doc = serde_doc_test!(
|
||||||
|
HARD_FORK_INFO_REQUEST => HardForkInfoRequest {
|
||||||
|
version: 16,
|
||||||
|
}
|
||||||
|
)]
|
||||||
|
#[derive(Copy)]
|
||||||
|
Request {
|
||||||
|
version: u8,
|
||||||
|
},
|
||||||
|
|
||||||
#[doc = serde_doc_test!(
|
#[doc = serde_doc_test!(
|
||||||
HARD_FORK_INFO_RESPONSE => HardForkInfoResponse {
|
HARD_FORK_INFO_RESPONSE => HardForkInfoResponse {
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
//!
|
//!
|
||||||
//! The 2nd allows any caller to send [`WriteRequest`][req_w]s.
|
//! The 2nd allows any caller to send [`WriteRequest`][req_w]s.
|
||||||
//!
|
//!
|
||||||
//! The `DatabaseReadHandle` can be shared as it is cheaply [`Clone`]able, however,
|
//! The [`BlockchainReadHandle`] can be shared as it is cheaply [`Clone`]able, however,
|
||||||
//! the `DatabaseWriteHandle` cannot be cloned. There is only 1 place in Cuprate that
|
//! the [`BlockchainWriteHandle`] cannot be cloned. There is only 1 place in Cuprate that
|
||||||
//! writes, so it is passed there and used.
|
//! writes, so it is passed there and used.
|
||||||
//!
|
//!
|
||||||
//! ## Initialization
|
//! ## Initialization
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
//! Database reader thread-pool definitions and logic.
|
//! Database reader thread-pool definitions and logic.
|
||||||
|
|
||||||
|
#![expect(
|
||||||
|
unreachable_code,
|
||||||
|
unused_variables,
|
||||||
|
clippy::unnecessary_wraps,
|
||||||
|
clippy::needless_pass_by_value,
|
||||||
|
reason = "TODO: finish implementing the signatures from <https://github.com/Cuprate/cuprate/pull/297>"
|
||||||
|
)]
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
|
@ -18,7 +26,7 @@ use cuprate_database_service::{init_thread_pool, DatabaseReadService, ReaderThre
|
||||||
use cuprate_helper::map::combine_low_high_bits_to_u128;
|
use cuprate_helper::map::combine_low_high_bits_to_u128;
|
||||||
use cuprate_types::{
|
use cuprate_types::{
|
||||||
blockchain::{BlockchainReadRequest, BlockchainResponse},
|
blockchain::{BlockchainReadRequest, BlockchainResponse},
|
||||||
Chain, ChainId, ExtendedBlockHeader, OutputOnChain,
|
Chain, ChainId, ExtendedBlockHeader, OutputHistogramInput, OutputOnChain,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -107,6 +115,12 @@ fn map_request(
|
||||||
R::CompactChainHistory => compact_chain_history(env),
|
R::CompactChainHistory => compact_chain_history(env),
|
||||||
R::FindFirstUnknown(block_ids) => find_first_unknown(env, &block_ids),
|
R::FindFirstUnknown(block_ids) => find_first_unknown(env, &block_ids),
|
||||||
R::AltBlocksInChain(chain_id) => alt_blocks_in_chain(env, chain_id),
|
R::AltBlocksInChain(chain_id) => alt_blocks_in_chain(env, chain_id),
|
||||||
|
R::Block { height } => block(env, height),
|
||||||
|
R::BlockByHash(hash) => block_by_hash(env, hash),
|
||||||
|
R::TotalTxCount => total_tx_count(env),
|
||||||
|
R::DatabaseSize => database_size(env),
|
||||||
|
R::OutputHistogram(input) => output_histogram(env, input),
|
||||||
|
R::CoinbaseTxSum { height, count } => coinbase_tx_sum(env, height, count),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SOMEDAY: post-request handling, run some code for each request? */
|
/* SOMEDAY: post-request handling, run some code for each request? */
|
||||||
|
@ -601,3 +615,36 @@ fn alt_blocks_in_chain(env: &ConcreteEnv, chain_id: ChainId) -> ResponseResult {
|
||||||
|
|
||||||
Ok(BlockchainResponse::AltBlocksInChain(blocks))
|
Ok(BlockchainResponse::AltBlocksInChain(blocks))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::Block`]
|
||||||
|
fn block(env: &ConcreteEnv, block_height: BlockHeight) -> ResponseResult {
|
||||||
|
Ok(BlockchainResponse::Block(todo!()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::BlockByHash`]
|
||||||
|
fn block_by_hash(env: &ConcreteEnv, block_hash: BlockHash) -> ResponseResult {
|
||||||
|
Ok(BlockchainResponse::Block(todo!()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::TotalTxCount`]
|
||||||
|
fn total_tx_count(env: &ConcreteEnv) -> ResponseResult {
|
||||||
|
Ok(BlockchainResponse::TotalTxCount(todo!()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::DatabaseSize`]
|
||||||
|
fn database_size(env: &ConcreteEnv) -> ResponseResult {
|
||||||
|
Ok(BlockchainResponse::DatabaseSize {
|
||||||
|
database_size: todo!(),
|
||||||
|
free_space: todo!(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::OutputHistogram`]
|
||||||
|
fn output_histogram(env: &ConcreteEnv, input: OutputHistogramInput) -> ResponseResult {
|
||||||
|
Ok(BlockchainResponse::OutputHistogram(todo!()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::CoinbaseTxSum`]
|
||||||
|
fn coinbase_tx_sum(env: &ConcreteEnv, height: usize, count: u64) -> ResponseResult {
|
||||||
|
Ok(BlockchainResponse::CoinbaseTxSum(todo!()))
|
||||||
|
}
|
||||||
|
|
|
@ -10,10 +10,12 @@ pub mod ops;
|
||||||
#[cfg(feature = "service")]
|
#[cfg(feature = "service")]
|
||||||
pub mod service;
|
pub mod service;
|
||||||
pub mod tables;
|
pub mod tables;
|
||||||
|
mod tx;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
pub use config::Config;
|
pub use config::Config;
|
||||||
pub use free::{open, transaction_blob_hash};
|
pub use free::{open, transaction_blob_hash};
|
||||||
|
pub use tx::TxEntry;
|
||||||
|
|
||||||
//re-exports
|
//re-exports
|
||||||
pub use cuprate_database;
|
pub use cuprate_database;
|
||||||
|
|
|
@ -21,9 +21,7 @@
|
||||||
//!
|
//!
|
||||||
//! The 2nd allows any caller to send [`WriteRequest`][req_w]s.
|
//! The 2nd allows any caller to send [`WriteRequest`][req_w]s.
|
||||||
//!
|
//!
|
||||||
//! The `DatabaseReadHandle` can be shared as it is cheaply [`Clone`]able, however,
|
//! Both the handles are cheaply [`Clone`]able.
|
||||||
//! the `DatabaseWriteHandle` cannot be cloned. There is only 1 place in Cuprate that
|
|
||||||
//! writes, so it is passed there and used.
|
|
||||||
//!
|
//!
|
||||||
//! ## Initialization
|
//! ## Initialization
|
||||||
//! The database & thread-pool system can be initialized with [`init()`].
|
//! The database & thread-pool system can be initialized with [`init()`].
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
||||||
|
|
||||||
use cuprate_types::TransactionVerificationData;
|
use cuprate_types::TransactionVerificationData;
|
||||||
|
|
||||||
use crate::types::{KeyImage, TransactionBlobHash, TransactionHash};
|
use crate::{tx::TxEntry, types::{KeyImage, TransactionBlobHash, TransactionHash}};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxpoolReadRequest
|
//---------------------------------------------------------------------------------------------------- TxpoolReadRequest
|
||||||
/// The transaction pool [`tower::Service`] read request type.
|
/// The transaction pool [`tower::Service`] read request type.
|
||||||
|
@ -16,14 +16,23 @@ use crate::types::{KeyImage, TransactionBlobHash, TransactionHash};
|
||||||
pub enum TxpoolReadRequest {
|
pub enum TxpoolReadRequest {
|
||||||
/// A request for the blob (raw bytes) of a transaction with the given hash.
|
/// A request for the blob (raw bytes) of a transaction with the given hash.
|
||||||
TxBlob(TransactionHash),
|
TxBlob(TransactionHash),
|
||||||
|
|
||||||
/// A request for the [`TransactionVerificationData`] of a transaction in the tx pool.
|
/// A request for the [`TransactionVerificationData`] of a transaction in the tx pool.
|
||||||
TxVerificationData(TransactionHash),
|
TxVerificationData(TransactionHash),
|
||||||
|
|
||||||
/// A request to filter (remove) all **known** transactions from the set.
|
/// A request to filter (remove) all **known** transactions from the set.
|
||||||
///
|
///
|
||||||
/// The hash is **not** the transaction hash, it is the hash of the serialized tx-blob.
|
/// The hash is **not** the transaction hash, it is the hash of the serialized tx-blob.
|
||||||
FilterKnownTxBlobHashes(HashSet<TransactionBlobHash>),
|
FilterKnownTxBlobHashes(HashSet<TransactionBlobHash>),
|
||||||
|
|
||||||
/// A request to pull some transactions for an incoming block.
|
/// A request to pull some transactions for an incoming block.
|
||||||
TxsForBlock(Vec<TransactionHash>),
|
TxsForBlock(Vec<TransactionHash>),
|
||||||
|
|
||||||
|
/// Get information on all transactions in the pool.
|
||||||
|
Backlog,
|
||||||
|
|
||||||
|
/// Get the number of transactions in the pool.
|
||||||
|
Size,
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxpoolReadResponse
|
//---------------------------------------------------------------------------------------------------- TxpoolReadResponse
|
||||||
|
@ -32,8 +41,10 @@ pub enum TxpoolReadRequest {
|
||||||
pub enum TxpoolReadResponse {
|
pub enum TxpoolReadResponse {
|
||||||
/// A response containing the raw bytes of a transaction.
|
/// A response containing the raw bytes of a transaction.
|
||||||
TxBlob { tx_blob: Vec<u8>, state_stem: bool },
|
TxBlob { tx_blob: Vec<u8>, state_stem: bool },
|
||||||
|
|
||||||
/// A response of [`TransactionVerificationData`].
|
/// A response of [`TransactionVerificationData`].
|
||||||
TxVerificationData(TransactionVerificationData),
|
TxVerificationData(TransactionVerificationData),
|
||||||
|
|
||||||
/// The response for [`TxpoolReadRequest::FilterKnownTxBlobHashes`].
|
/// The response for [`TxpoolReadRequest::FilterKnownTxBlobHashes`].
|
||||||
FilterKnownTxBlobHashes {
|
FilterKnownTxBlobHashes {
|
||||||
/// The blob hashes that are unknown.
|
/// The blob hashes that are unknown.
|
||||||
|
@ -41,6 +52,7 @@ pub enum TxpoolReadResponse {
|
||||||
/// The tx hashes of the blob hashes that were known but were in the stem pool.
|
/// The tx hashes of the blob hashes that were known but were in the stem pool.
|
||||||
stem_pool_hashes: Vec<TransactionHash>,
|
stem_pool_hashes: Vec<TransactionHash>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The response for [`TxpoolReadRequest::TxsForBlock`].
|
/// The response for [`TxpoolReadRequest::TxsForBlock`].
|
||||||
TxsForBlock {
|
TxsForBlock {
|
||||||
/// The txs we had in the txpool.
|
/// The txs we had in the txpool.
|
||||||
|
@ -48,6 +60,18 @@ pub enum TxpoolReadResponse {
|
||||||
/// The indexes of the missing txs.
|
/// The indexes of the missing txs.
|
||||||
missing: Vec<usize>,
|
missing: Vec<usize>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Response to [`TxpoolReadRequest::Backlog`].
|
||||||
|
///
|
||||||
|
/// The inner `Vec` contains information on all
|
||||||
|
/// the transactions currently in the pool.
|
||||||
|
Backlog(Vec<TxEntry>),
|
||||||
|
|
||||||
|
/// Response to [`TxpoolReadRequest::Size`].
|
||||||
|
///
|
||||||
|
/// The inner value is the amount of
|
||||||
|
/// transactions currently in the pool.
|
||||||
|
Size(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxpoolWriteRequest
|
//---------------------------------------------------------------------------------------------------- TxpoolWriteRequest
|
||||||
|
@ -65,15 +89,18 @@ pub enum TxpoolWriteRequest {
|
||||||
/// [`true`] if this tx is in the stem state.
|
/// [`true`] if this tx is in the stem state.
|
||||||
state_stem: bool,
|
state_stem: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Remove a transaction with the given hash from the pool.
|
/// Remove a transaction with the given hash from the pool.
|
||||||
///
|
///
|
||||||
/// Returns [`TxpoolWriteResponse::Ok`].
|
/// Returns [`TxpoolWriteResponse::Ok`].
|
||||||
RemoveTransaction(TransactionHash),
|
RemoveTransaction(TransactionHash),
|
||||||
|
|
||||||
/// Promote a transaction from the stem pool to the fluff pool.
|
/// Promote a transaction from the stem pool to the fluff pool.
|
||||||
/// If the tx is already in the fluff pool this does nothing.
|
/// If the tx is already in the fluff pool this does nothing.
|
||||||
///
|
///
|
||||||
/// Returns [`TxpoolWriteResponse::Ok`].
|
/// Returns [`TxpoolWriteResponse::Ok`].
|
||||||
Promote(TransactionHash),
|
Promote(TransactionHash),
|
||||||
|
|
||||||
/// Tell the tx-pool about a new block.
|
/// Tell the tx-pool about a new block.
|
||||||
NewBlock {
|
NewBlock {
|
||||||
/// The new blockchain height.
|
/// The new blockchain height.
|
||||||
|
@ -85,11 +112,14 @@ pub enum TxpoolWriteRequest {
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxpoolWriteResponse
|
//---------------------------------------------------------------------------------------------------- TxpoolWriteResponse
|
||||||
/// The transaction pool [`tower::Service`] write response type.
|
/// The transaction pool [`tower::Service`] write response type.
|
||||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
|
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
pub enum TxpoolWriteResponse {
|
pub enum TxpoolWriteResponse {
|
||||||
/// A [`TxpoolWriteRequest::AddTransaction`] response.
|
/// Response to:
|
||||||
|
/// - [`TxpoolWriteRequest::RemoveTransaction`]
|
||||||
|
Ok,
|
||||||
|
|
||||||
|
/// Response to [`TxpoolWriteRequest::AddTransaction`].
|
||||||
///
|
///
|
||||||
/// If the inner value is [`Some`] the tx was not added to the pool as it double spends a tx with the given hash.
|
/// If the inner value is [`Some`] the tx was not added to the pool as it double spends a tx with the given hash.
|
||||||
AddTransaction(Option<TransactionHash>),
|
AddTransaction(Option<TransactionHash>),
|
||||||
Ok,
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
#![expect(
|
||||||
|
unreachable_code,
|
||||||
|
unused_variables,
|
||||||
|
clippy::unnecessary_wraps,
|
||||||
|
reason = "TODO: finish implementing the signatures from <https://github.com/Cuprate/cuprate/pull/297>"
|
||||||
|
)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
|
@ -64,6 +71,8 @@ fn map_request(
|
||||||
filter_known_tx_blob_hashes(env, blob_hashes)
|
filter_known_tx_blob_hashes(env, blob_hashes)
|
||||||
}
|
}
|
||||||
TxpoolReadRequest::TxsForBlock(txs_needed) => txs_for_block(env, txs_needed),
|
TxpoolReadRequest::TxsForBlock(txs_needed) => txs_for_block(env, txs_needed),
|
||||||
|
TxpoolReadRequest::Backlog => backlog(env),
|
||||||
|
TxpoolReadRequest::Size => size(env),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,3 +194,15 @@ fn txs_for_block(env: &ConcreteEnv, txs: Vec<TransactionHash>) -> ReadResponseRe
|
||||||
missing: missing_tx_indexes,
|
missing: missing_tx_indexes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`TxpoolReadRequest::Backlog`].
|
||||||
|
#[inline]
|
||||||
|
fn backlog(env: &ConcreteEnv) -> ReadResponseResult {
|
||||||
|
Ok(TxpoolReadResponse::Backlog(todo!()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`TxpoolReadRequest::Size`].
|
||||||
|
#[inline]
|
||||||
|
fn size(env: &ConcreteEnv) -> ReadResponseResult {
|
||||||
|
Ok(TxpoolReadResponse::Size(todo!()))
|
||||||
|
}
|
||||||
|
|
14
storage/txpool/src/tx.rs
Normal file
14
storage/txpool/src/tx.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
//! Transaction metadata.
|
||||||
|
|
||||||
|
/// Data about a transaction in the pool.
|
||||||
|
///
|
||||||
|
/// Used in [`TxpoolReadResponse::Backlog`](crate::service::interface::TxpoolReadResponse::Backlog).
|
||||||
|
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||||
|
pub struct TxEntry {
|
||||||
|
/// The transaction's weight.
|
||||||
|
pub weight: u64,
|
||||||
|
/// The transaction's fee.
|
||||||
|
pub fee: u64,
|
||||||
|
/// How long the transaction has been in the pool.
|
||||||
|
pub time_in_pool: std::time::Duration,
|
||||||
|
}
|
|
@ -608,7 +608,10 @@ define_request_and_response! {
|
||||||
r#"{
|
r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": "0",
|
"id": "0",
|
||||||
"method": "hard_fork_info"
|
"method": "hard_fork_info",
|
||||||
|
"params": {
|
||||||
|
"version": 16
|
||||||
|
}
|
||||||
}"#;
|
}"#;
|
||||||
Response =
|
Response =
|
||||||
r#"{
|
r#"{
|
||||||
|
|
|
@ -27,6 +27,7 @@ curve25519-dalek = { workspace = true }
|
||||||
monero-serai = { workspace = true }
|
monero-serai = { workspace = true }
|
||||||
hex = { workspace = true, features = ["serde", "alloc"], optional = true }
|
hex = { workspace = true, features = ["serde", "alloc"], optional = true }
|
||||||
serde = { workspace = true, features = ["derive"], optional = true }
|
serde = { workspace = true, features = ["derive"], optional = true }
|
||||||
|
strum = { workspace = true, features = ["derive"] }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
|
||||||
proptest = { workspace = true, optional = true }
|
proptest = { workspace = true, optional = true }
|
||||||
|
|
|
@ -8,9 +8,11 @@ use std::{
|
||||||
ops::Range,
|
ops::Range,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use monero_serai::block::Block;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation},
|
types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation},
|
||||||
AltBlockInformation, ChainId,
|
AltBlockInformation, ChainId, CoinbaseTxSum, OutputHistogramEntry, OutputHistogramInput,
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- ReadRequest
|
//---------------------------------------------------------------------------------------------------- ReadRequest
|
||||||
|
@ -103,6 +105,29 @@ pub enum BlockchainReadRequest {
|
||||||
|
|
||||||
/// A request for all alt blocks in the chain with the given [`ChainId`].
|
/// A request for all alt blocks in the chain with the given [`ChainId`].
|
||||||
AltBlocksInChain(ChainId),
|
AltBlocksInChain(ChainId),
|
||||||
|
|
||||||
|
/// Get a [`Block`] by its height.
|
||||||
|
Block { height: usize },
|
||||||
|
|
||||||
|
/// Get a [`Block`] by its hash.
|
||||||
|
BlockByHash([u8; 32]),
|
||||||
|
|
||||||
|
/// Get the total amount of non-coinbase transactions in the chain.
|
||||||
|
TotalTxCount,
|
||||||
|
|
||||||
|
/// Get the current size of the database.
|
||||||
|
DatabaseSize,
|
||||||
|
|
||||||
|
/// Get an output histogram.
|
||||||
|
///
|
||||||
|
/// TODO: document fields after impl.
|
||||||
|
OutputHistogram(OutputHistogramInput),
|
||||||
|
|
||||||
|
/// Get the coinbase amount and the fees amount for
|
||||||
|
/// `N` last blocks starting at particular height.
|
||||||
|
///
|
||||||
|
/// TODO: document fields after impl.
|
||||||
|
CoinbaseTxSum { height: usize, count: u64 },
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- WriteRequest
|
//---------------------------------------------------------------------------------------------------- WriteRequest
|
||||||
|
@ -147,6 +172,7 @@ pub enum BlockchainWriteRequest {
|
||||||
/// This pairs with [`BlockchainReadRequest`] and [`BlockchainWriteRequest`],
|
/// This pairs with [`BlockchainReadRequest`] and [`BlockchainWriteRequest`],
|
||||||
/// see those two for more info.
|
/// see those two for more info.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[expect(clippy::large_enum_variant)]
|
||||||
pub enum BlockchainResponse {
|
pub enum BlockchainResponse {
|
||||||
//------------------------------------------------------ Reads
|
//------------------------------------------------------ Reads
|
||||||
/// Response to [`BlockchainReadRequest::BlockExtendedHeader`].
|
/// Response to [`BlockchainReadRequest::BlockExtendedHeader`].
|
||||||
|
@ -215,18 +241,41 @@ pub enum BlockchainResponse {
|
||||||
cumulative_difficulty: u128,
|
cumulative_difficulty: u128,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The response for [`BlockchainReadRequest::FindFirstUnknown`].
|
/// Response to [`BlockchainReadRequest::FindFirstUnknown`].
|
||||||
///
|
///
|
||||||
/// Contains the index of the first unknown block and its expected height.
|
/// Contains the index of the first unknown block and its expected height.
|
||||||
///
|
///
|
||||||
/// This will be [`None`] if all blocks were known.
|
/// This will be [`None`] if all blocks were known.
|
||||||
FindFirstUnknown(Option<(usize, usize)>),
|
FindFirstUnknown(Option<(usize, usize)>),
|
||||||
|
|
||||||
/// The response for [`BlockchainReadRequest::AltBlocksInChain`].
|
/// Response to [`BlockchainReadRequest::AltBlocksInChain`].
|
||||||
///
|
///
|
||||||
/// Contains all the alt blocks in the alt-chain in chronological order.
|
/// Contains all the alt blocks in the alt-chain in chronological order.
|
||||||
AltBlocksInChain(Vec<AltBlockInformation>),
|
AltBlocksInChain(Vec<AltBlockInformation>),
|
||||||
|
|
||||||
|
/// Response to:
|
||||||
|
/// - [`BlockchainReadRequest::Block`].
|
||||||
|
/// - [`BlockchainReadRequest::BlockByHash`].
|
||||||
|
Block(Block),
|
||||||
|
|
||||||
|
/// Response to [`BlockchainReadRequest::TotalTxCount`].
|
||||||
|
TotalTxCount(usize),
|
||||||
|
|
||||||
|
/// Response to [`BlockchainReadRequest::DatabaseSize`].
|
||||||
|
DatabaseSize {
|
||||||
|
/// The size of the database file in bytes.
|
||||||
|
database_size: u64,
|
||||||
|
/// The amount of free bytes there are
|
||||||
|
/// the disk where the database is located.
|
||||||
|
free_space: u64,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Response to [`BlockchainReadRequest::OutputHistogram`].
|
||||||
|
OutputHistogram(Vec<OutputHistogramEntry>),
|
||||||
|
|
||||||
|
/// Response to [`BlockchainReadRequest::CoinbaseTxSum`].
|
||||||
|
CoinbaseTxSum(CoinbaseTxSum),
|
||||||
|
|
||||||
//------------------------------------------------------ Writes
|
//------------------------------------------------------ Writes
|
||||||
/// A generic Ok response to indicate a request was successfully handled.
|
/// A generic Ok response to indicate a request was successfully handled.
|
||||||
///
|
///
|
||||||
|
@ -236,7 +285,8 @@ pub enum BlockchainResponse {
|
||||||
/// - [`BlockchainWriteRequest::ReverseReorg`]
|
/// - [`BlockchainWriteRequest::ReverseReorg`]
|
||||||
/// - [`BlockchainWriteRequest::FlushAltBlocks`]
|
/// - [`BlockchainWriteRequest::FlushAltBlocks`]
|
||||||
Ok,
|
Ok,
|
||||||
/// The response for [`BlockchainWriteRequest::PopBlocks`].
|
|
||||||
|
/// Response to [`BlockchainWriteRequest::PopBlocks`].
|
||||||
///
|
///
|
||||||
/// The inner value is the alt-chain ID for the old main chain blocks.
|
/// The inner value is the alt-chain ID for the old main chain blocks.
|
||||||
PopBlocks(ChainId),
|
PopBlocks(ChainId),
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
//! The [`HardFork`] type.
|
//! The [`HardFork`] type.
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use strum::{
|
||||||
|
AsRefStr, Display, EnumCount, EnumIs, EnumString, FromRepr, IntoStaticStr, VariantArray,
|
||||||
|
};
|
||||||
|
|
||||||
use monero_serai::block::BlockHeader;
|
use monero_serai::block::BlockHeader;
|
||||||
|
|
||||||
/// Target block time for hf 1.
|
/// Target block time for hf 1.
|
||||||
|
@ -27,7 +31,25 @@ pub enum HardForkError {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An identifier for every hard-fork Monero has had.
|
/// An identifier for every hard-fork Monero has had.
|
||||||
#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash)]
|
#[derive(
|
||||||
|
Default,
|
||||||
|
Debug,
|
||||||
|
PartialEq,
|
||||||
|
Eq,
|
||||||
|
PartialOrd,
|
||||||
|
Ord,
|
||||||
|
Copy,
|
||||||
|
Clone,
|
||||||
|
Hash,
|
||||||
|
EnumCount,
|
||||||
|
Display,
|
||||||
|
AsRefStr,
|
||||||
|
EnumIs,
|
||||||
|
EnumString,
|
||||||
|
FromRepr,
|
||||||
|
IntoStaticStr,
|
||||||
|
VariantArray,
|
||||||
|
)]
|
||||||
#[cfg_attr(any(feature = "proptest"), derive(proptest_derive::Arbitrary))]
|
#[cfg_attr(any(feature = "proptest"), derive(proptest_derive::Arbitrary))]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum HardFork {
|
pub enum HardFork {
|
||||||
|
@ -47,58 +69,75 @@ pub enum HardFork {
|
||||||
V13,
|
V13,
|
||||||
V14,
|
V14,
|
||||||
V15,
|
V15,
|
||||||
// remember to update from_vote!
|
|
||||||
V16,
|
V16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HardFork {
|
impl HardFork {
|
||||||
|
/// The latest [`HardFork`].
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use cuprate_types::HardFork;
|
||||||
|
/// assert_eq!(HardFork::LATEST, HardFork::V16);
|
||||||
|
/// ```
|
||||||
|
pub const LATEST: Self = Self::VARIANTS[Self::COUNT - 1];
|
||||||
|
|
||||||
/// Returns the hard-fork for a blocks [`BlockHeader::hardfork_version`] field.
|
/// Returns the hard-fork for a blocks [`BlockHeader::hardfork_version`] field.
|
||||||
///
|
///
|
||||||
/// ref: <https://monero-book.cuprate.org/consensus_rules/hardforks.html#blocks-version-and-vote>
|
/// ref: <https://monero-book.cuprate.org/consensus_rules/hardforks.html#blocks-version-and-vote>
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
|
||||||
/// Will return [`Err`] if the version is not a valid [`HardFork`].
|
/// Will return [`Err`] if the version is not a valid [`HardFork`].
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use cuprate_types::{HardFork, HardForkError};
|
||||||
|
/// # use strum::VariantArray;
|
||||||
|
/// assert_eq!(HardFork::from_version(0), Err(HardForkError::HardForkUnknown));
|
||||||
|
/// assert_eq!(HardFork::from_version(17), Err(HardForkError::HardForkUnknown));
|
||||||
|
///
|
||||||
|
/// for (version, hf) in HardFork::VARIANTS.iter().enumerate() {
|
||||||
|
/// // +1 because enumerate starts at 0, hf starts at 1.
|
||||||
|
/// assert_eq!(*hf, HardFork::from_version(version as u8 + 1).unwrap());
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn from_version(version: u8) -> Result<Self, HardForkError> {
|
pub const fn from_version(version: u8) -> Result<Self, HardForkError> {
|
||||||
Ok(match version {
|
match Self::from_repr(version) {
|
||||||
1 => Self::V1,
|
Some(this) => Ok(this),
|
||||||
2 => Self::V2,
|
None => Err(HardForkError::HardForkUnknown),
|
||||||
3 => Self::V3,
|
}
|
||||||
4 => Self::V4,
|
|
||||||
5 => Self::V5,
|
|
||||||
6 => Self::V6,
|
|
||||||
7 => Self::V7,
|
|
||||||
8 => Self::V8,
|
|
||||||
9 => Self::V9,
|
|
||||||
10 => Self::V10,
|
|
||||||
11 => Self::V11,
|
|
||||||
12 => Self::V12,
|
|
||||||
13 => Self::V13,
|
|
||||||
14 => Self::V14,
|
|
||||||
15 => Self::V15,
|
|
||||||
16 => Self::V16,
|
|
||||||
_ => return Err(HardForkError::HardForkUnknown),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the hard-fork for a blocks [`BlockHeader::hardfork_signal`] (vote) field.
|
/// Returns the hard-fork for a blocks [`BlockHeader::hardfork_signal`] (vote) field.
|
||||||
///
|
///
|
||||||
/// <https://monero-book.cuprate.org/consensus_rules/hardforks.html#blocks-version-and-vote>
|
/// <https://monero-book.cuprate.org/consensus_rules/hardforks.html#blocks-version-and-vote>
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use cuprate_types::{HardFork, HardForkError};
|
||||||
|
/// # use strum::VariantArray;
|
||||||
|
/// // 0 is interpreted as 1.
|
||||||
|
/// assert_eq!(HardFork::from_vote(0), HardFork::V1);
|
||||||
|
/// // Unknown defaults to `LATEST`.
|
||||||
|
/// assert_eq!(HardFork::from_vote(17), HardFork::V16);
|
||||||
|
///
|
||||||
|
/// for (vote, hf) in HardFork::VARIANTS.iter().enumerate() {
|
||||||
|
/// // +1 because enumerate starts at 0, hf starts at 1.
|
||||||
|
/// assert_eq!(*hf, HardFork::from_vote(vote as u8 + 1));
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_vote(vote: u8) -> Self {
|
pub fn from_vote(vote: u8) -> Self {
|
||||||
if vote == 0 {
|
if vote == 0 {
|
||||||
// A vote of 0 is interpreted as 1 as that's what Monero used to default to.
|
// A vote of 0 is interpreted as 1 as that's what Monero used to default to.
|
||||||
return Self::V1;
|
Self::V1
|
||||||
}
|
} else {
|
||||||
// This must default to the latest hard-fork!
|
// This must default to the latest hard-fork!
|
||||||
Self::from_version(vote).unwrap_or(Self::V16)
|
Self::from_version(vote).unwrap_or(Self::LATEST)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`HardFork`] version and vote from this block header.
|
/// Returns the [`HardFork`] version and vote from this block header.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
|
||||||
/// Will return [`Err`] if the [`BlockHeader::hardfork_version`] is not a valid [`HardFork`].
|
/// Will return [`Err`] if the [`BlockHeader::hardfork_version`] is not a valid [`HardFork`].
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_block_header(header: &BlockHeader) -> Result<(Self, Self), HardForkError> {
|
pub fn from_block_header(header: &BlockHeader) -> Result<(Self, Self), HardForkError> {
|
||||||
|
@ -109,22 +148,49 @@ impl HardFork {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the raw hard-fork value, as it would appear in [`BlockHeader::hardfork_version`].
|
/// Returns the raw hard-fork value, as it would appear in [`BlockHeader::hardfork_version`].
|
||||||
pub const fn as_u8(&self) -> u8 {
|
///
|
||||||
*self as u8
|
/// ```rust
|
||||||
|
/// # use cuprate_types::{HardFork, HardForkError};
|
||||||
|
/// # use strum::VariantArray;
|
||||||
|
/// for (i, hf) in HardFork::VARIANTS.iter().enumerate() {
|
||||||
|
/// // +1 because enumerate starts at 0, hf starts at 1.
|
||||||
|
/// assert_eq!(hf.as_u8(), i as u8 + 1);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub const fn as_u8(self) -> u8 {
|
||||||
|
self as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the next hard-fork.
|
/// Returns the next hard-fork.
|
||||||
pub fn next_fork(&self) -> Option<Self> {
|
pub fn next_fork(self) -> Option<Self> {
|
||||||
Self::from_version(*self as u8 + 1).ok()
|
Self::from_version(self as u8 + 1).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the target block time for this hardfork.
|
/// Returns the target block time for this hardfork.
|
||||||
///
|
///
|
||||||
/// ref: <https://monero-book.cuprate.org/consensus_rules/blocks/difficulty.html#target-seconds>
|
/// ref: <https://monero-book.cuprate.org/consensus_rules/blocks/difficulty.html#target-seconds>
|
||||||
pub const fn block_time(&self) -> Duration {
|
pub const fn block_time(self) -> Duration {
|
||||||
match self {
|
match self {
|
||||||
Self::V1 => BLOCK_TIME_V1,
|
Self::V1 => BLOCK_TIME_V1,
|
||||||
_ => BLOCK_TIME_V2,
|
_ => BLOCK_TIME_V2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if `self` is [`Self::LATEST`].
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use cuprate_types::HardFork;
|
||||||
|
/// # use strum::VariantArray;
|
||||||
|
///
|
||||||
|
/// for hf in HardFork::VARIANTS.iter() {
|
||||||
|
/// if *hf == HardFork::LATEST {
|
||||||
|
/// assert!(hf.is_latest());
|
||||||
|
/// } else {
|
||||||
|
/// assert!(!hf.is_latest());
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub const fn is_latest(self) -> bool {
|
||||||
|
matches!(self, Self::LATEST)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,9 @@ pub use transaction_verification_data::{
|
||||||
CachedVerificationState, TransactionVerificationData, TxVersion,
|
CachedVerificationState, TransactionVerificationData, TxVersion,
|
||||||
};
|
};
|
||||||
pub use types::{
|
pub use types::{
|
||||||
AltBlockInformation, Chain, ChainId, ExtendedBlockHeader, OutputOnChain,
|
AltBlockInformation, Chain, ChainId, ChainInfo, CoinbaseTxSum, ExtendedBlockHeader,
|
||||||
VerifiedBlockInformation, VerifiedTransactionInformation,
|
FeeEstimate, HardForkInfo, MinerData, MinerDataTxBacklogEntry, OutputHistogramEntry,
|
||||||
|
OutputHistogramInput, OutputOnChain, VerifiedBlockInformation, VerifiedTransactionInformation,
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Feature-gated
|
//---------------------------------------------------------------------------------------------------- Feature-gated
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
//! Various shared data types in Cuprate.
|
//! Various shared data types in Cuprate.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
|
|
||||||
use curve25519_dalek::edwards::EdwardsPoint;
|
use curve25519_dalek::edwards::EdwardsPoint;
|
||||||
|
@ -11,7 +10,6 @@ use monero_serai::{
|
||||||
|
|
||||||
use crate::HardFork;
|
use crate::HardFork;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- ExtendedBlockHeader
|
|
||||||
/// Extended header data of a block.
|
/// Extended header data of a block.
|
||||||
///
|
///
|
||||||
/// This contains various metadata of a block, but not the block blob itself.
|
/// This contains various metadata of a block, but not the block blob itself.
|
||||||
|
@ -37,7 +35,6 @@ pub struct ExtendedBlockHeader {
|
||||||
pub long_term_weight: usize,
|
pub long_term_weight: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- VerifiedTransactionInformation
|
|
||||||
/// Verified information of a transaction.
|
/// Verified information of a transaction.
|
||||||
///
|
///
|
||||||
/// This represents a valid transaction
|
/// This represents a valid transaction
|
||||||
|
@ -61,7 +58,6 @@ pub struct VerifiedTransactionInformation {
|
||||||
pub tx_hash: [u8; 32],
|
pub tx_hash: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- VerifiedBlockInformation
|
|
||||||
/// Verified information of a block.
|
/// Verified information of a block.
|
||||||
///
|
///
|
||||||
/// This represents a block that has already been verified to be correct.
|
/// This represents a block that has already been verified to be correct.
|
||||||
|
@ -94,14 +90,12 @@ pub struct VerifiedBlockInformation {
|
||||||
pub cumulative_difficulty: u128,
|
pub cumulative_difficulty: u128,
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- ChainID
|
|
||||||
/// A unique ID for an alt chain.
|
/// A unique ID for an alt chain.
|
||||||
///
|
///
|
||||||
/// The inner value is meaningless.
|
/// The inner value is meaningless.
|
||||||
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||||
pub struct ChainId(pub NonZero<u64>);
|
pub struct ChainId(pub NonZero<u64>);
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Chain
|
|
||||||
/// An identifier for a chain.
|
/// An identifier for a chain.
|
||||||
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||||
pub enum Chain {
|
pub enum Chain {
|
||||||
|
@ -111,7 +105,6 @@ pub enum Chain {
|
||||||
Alt(ChainId),
|
Alt(ChainId),
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- AltBlockInformation
|
|
||||||
/// A block on an alternative chain.
|
/// A block on an alternative chain.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct AltBlockInformation {
|
pub struct AltBlockInformation {
|
||||||
|
@ -141,7 +134,6 @@ pub struct AltBlockInformation {
|
||||||
pub chain_id: ChainId,
|
pub chain_id: ChainId,
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- OutputOnChain
|
|
||||||
/// An already existing transaction output.
|
/// An already existing transaction output.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub struct OutputOnChain {
|
pub struct OutputOnChain {
|
||||||
|
@ -155,6 +147,104 @@ pub struct OutputOnChain {
|
||||||
pub commitment: EdwardsPoint,
|
pub commitment: EdwardsPoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Input required to generate an output histogram.
|
||||||
|
///
|
||||||
|
/// Used in RPC's `get_output_histogram`.
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct OutputHistogramInput {
|
||||||
|
pub amounts: Vec<u64>,
|
||||||
|
pub min_count: u64,
|
||||||
|
pub max_count: u64,
|
||||||
|
pub unlocked: bool,
|
||||||
|
pub recent_cutoff: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A single entry in an output histogram.
|
||||||
|
///
|
||||||
|
/// Used in RPC's `get_output_histogram`.
|
||||||
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct OutputHistogramEntry {
|
||||||
|
pub amount: u64,
|
||||||
|
pub total_instances: u64,
|
||||||
|
pub unlocked_instances: u64,
|
||||||
|
pub recent_instances: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Data of summed coinbase transactions.
|
||||||
|
///
|
||||||
|
/// Used in RPC's `get_coinbase_tx_sum`.
|
||||||
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct CoinbaseTxSum {
|
||||||
|
pub emission_amount: u128,
|
||||||
|
pub fee_amount: u128,
|
||||||
|
pub wide_emission_amount: u128,
|
||||||
|
pub wide_fee_amount: u128,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Data to create a custom block template.
|
||||||
|
///
|
||||||
|
/// Used in RPC's `get_miner_data`.
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct MinerData {
|
||||||
|
pub major_version: u8,
|
||||||
|
pub height: u64,
|
||||||
|
pub prev_id: [u8; 32],
|
||||||
|
pub seed_hash: [u8; 32],
|
||||||
|
pub difficulty: u128,
|
||||||
|
pub median_weight: u64,
|
||||||
|
pub already_generated_coins: u64,
|
||||||
|
pub tx_backlog: Vec<MinerDataTxBacklogEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A transaction in the txpool.
|
||||||
|
///
|
||||||
|
/// Used in [`MinerData::tx_backlog`].
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct MinerDataTxBacklogEntry {
|
||||||
|
pub id: [u8; 32],
|
||||||
|
pub weight: u64,
|
||||||
|
pub fee: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information on a [`HardFork`].
|
||||||
|
///
|
||||||
|
/// Used in RPC's `hard_fork_info`.
|
||||||
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct HardForkInfo {
|
||||||
|
pub earliest_height: u64,
|
||||||
|
pub enabled: bool,
|
||||||
|
pub state: u32,
|
||||||
|
pub threshold: u32,
|
||||||
|
pub version: u8,
|
||||||
|
pub votes: u32,
|
||||||
|
pub voting: u8,
|
||||||
|
pub window: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Estimated fee data.
|
||||||
|
///
|
||||||
|
/// Used in RPC's `get_fee_estimate`.
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct FeeEstimate {
|
||||||
|
pub fee: u64,
|
||||||
|
pub fees: Vec<u64>,
|
||||||
|
pub quantization_mask: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information on a (maybe alternate) chain.
|
||||||
|
///
|
||||||
|
/// Used in RPC's `get_alternate_chains`.
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct ChainInfo {
|
||||||
|
pub block_hash: [u8; 32],
|
||||||
|
pub block_hashes: Vec<[u8; 32]>,
|
||||||
|
pub difficulty: u128,
|
||||||
|
pub height: u64,
|
||||||
|
pub length: u64,
|
||||||
|
pub main_chain_parent_block: [u8; 32],
|
||||||
|
pub wide_difficulty: u128,
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Tests
|
//---------------------------------------------------------------------------------------------------- Tests
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
Loading…
Reference in a new issue