mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-22 11:39:26 +00:00
cuprated: internal signatures required for RPC (#297)
Some checks failed
CI / fmt (push) Has been cancelled
CI / typo (push) Has been cancelled
CI / ci (macos-latest, stable, bash) (push) Has been cancelled
CI / ci (ubuntu-latest, stable, bash) (push) Has been cancelled
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Has been cancelled
Doc / build (push) Has been cancelled
Doc / deploy (push) Has been cancelled
Some checks failed
CI / fmt (push) Has been cancelled
CI / typo (push) Has been cancelled
CI / ci (macos-latest, stable, bash) (push) Has been cancelled
CI / ci (ubuntu-latest, stable, bash) (push) Has been cancelled
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Has been cancelled
Doc / build (push) Has been cancelled
Doc / deploy (push) Has been cancelled
* add request methods * add p2p messages * add txpool msgs * add blockchain_context msgs * add blockchain msgs * fmt * blockchain_manager msgs * blockchain manager msg types * add DB fn signatures * add statics module * p2p msg changes, docs * txpool docs/types * blockchain docs/types * `AlternateChains`, docs * fixes * remove blockchain write handle, fix docs * remove `BlockchainReadRequest::Difficulty` * remove `BlockchainReadRequest::MinerData` * fix p2p ban types * `CurrentRxVm` -> `CurrentRxVms` * storage: remove `Clone` off write handle * Update p2p/p2p-core/src/ban.rs Co-authored-by: Boog900 <boog900@tutanota.com> * fix merge --------- Co-authored-by: Boog900 <boog900@tutanota.com>
This commit is contained in:
parent
8be369846e
commit
9923d8d69d
37 changed files with 1336 additions and 158 deletions
|
@ -69,7 +69,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 {
|
||||||
|
|
|
@ -464,7 +464,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
pub use free::open;
|
||||||
|
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()`].
|
||||||
|
|
|
@ -5,30 +5,53 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use cuprate_types::TransactionVerificationData;
|
use cuprate_types::TransactionVerificationData;
|
||||||
|
|
||||||
use crate::types::TransactionHash;
|
use crate::{tx::TxEntry, types::TransactionHash};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxpoolReadRequest
|
//---------------------------------------------------------------------------------------------------- TxpoolReadRequest
|
||||||
/// The transaction pool [`tower::Service`] read request type.
|
/// The transaction pool [`tower::Service`] read request type.
|
||||||
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),
|
||||||
|
|
||||||
|
/// Get information on all transactions in the pool.
|
||||||
|
Backlog,
|
||||||
|
|
||||||
|
/// Get the number of transactions in the pool.
|
||||||
|
Size,
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxpoolReadResponse
|
//---------------------------------------------------------------------------------------------------- TxpoolReadResponse
|
||||||
/// The transaction pool [`tower::Service`] read response type.
|
/// The transaction pool [`tower::Service`] read response type.
|
||||||
#[expect(clippy::large_enum_variant)]
|
#[expect(clippy::large_enum_variant)]
|
||||||
pub enum TxpoolReadResponse {
|
pub enum TxpoolReadResponse {
|
||||||
/// A response containing the raw bytes of a transaction.
|
/// Response to [`TxpoolReadRequest::TxBlob`].
|
||||||
|
///
|
||||||
|
/// The inner value is the raw bytes of a transaction.
|
||||||
// TODO: use bytes::Bytes.
|
// TODO: use bytes::Bytes.
|
||||||
TxBlob(Vec<u8>),
|
TxBlob(Vec<u8>),
|
||||||
/// A response of [`TransactionVerificationData`].
|
|
||||||
|
/// Response to [`TxpoolReadRequest::TxVerificationData`].
|
||||||
TxVerificationData(TransactionVerificationData),
|
TxVerificationData(TransactionVerificationData),
|
||||||
|
|
||||||
|
/// 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
|
||||||
/// The transaction pool [`tower::Service`] write request type.
|
/// The transaction pool [`tower::Service`] write request type.
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum TxpoolWriteRequest {
|
pub enum TxpoolWriteRequest {
|
||||||
/// Add a transaction to the pool.
|
/// Add a transaction to the pool.
|
||||||
///
|
///
|
||||||
|
@ -41,6 +64,7 @@ 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`].
|
||||||
|
@ -49,11 +73,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::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use rayon::ThreadPool;
|
use rayon::ThreadPool;
|
||||||
|
@ -58,6 +65,8 @@ fn map_request(
|
||||||
match request {
|
match request {
|
||||||
TxpoolReadRequest::TxBlob(tx_hash) => tx_blob(env, &tx_hash),
|
TxpoolReadRequest::TxBlob(tx_hash) => tx_blob(env, &tx_hash),
|
||||||
TxpoolReadRequest::TxVerificationData(tx_hash) => tx_verification_data(env, &tx_hash),
|
TxpoolReadRequest::TxVerificationData(tx_hash) => tx_verification_data(env, &tx_hash),
|
||||||
|
TxpoolReadRequest::Backlog => backlog(env),
|
||||||
|
TxpoolReadRequest::Size => size(env),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,3 +110,15 @@ fn tx_verification_data(env: &ConcreteEnv, tx_hash: &TransactionHash) -> ReadRes
|
||||||
|
|
||||||
get_transaction_verification_data(tx_hash, &tables).map(TxpoolReadResponse::TxVerificationData)
|
get_transaction_verification_data(tx_hash, &tables).map(TxpoolReadResponse::TxVerificationData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`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,
|
||||||
|
}
|
|
@ -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),
|
||||||
|
|
|
@ -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