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()
|
||||
.await
|
||||
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
||||
.call(BlockChainContextRequest::GetContext)
|
||||
.call(BlockChainContextRequest::Context)
|
||||
.await
|
||||
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
||||
else {
|
||||
|
|
|
@ -464,7 +464,7 @@ impl super::BlockchainManager {
|
|||
.ready()
|
||||
.await
|
||||
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
||||
.call(BlockChainContextRequest::GetContext)
|
||||
.call(BlockChainContextRequest::Context)
|
||||
.await
|
||||
.expect(PANIC_CRITICAL_SERVICE_ERROR)
|
||||
else {
|
||||
|
|
|
@ -62,7 +62,7 @@ where
|
|||
let BlockChainContextResponse::Context(mut blockchain_ctx) = context_svc
|
||||
.ready()
|
||||
.await?
|
||||
.call(BlockChainContextRequest::GetContext)
|
||||
.call(BlockChainContextRequest::Context)
|
||||
.await?
|
||||
else {
|
||||
unreachable!();
|
||||
|
@ -131,7 +131,7 @@ where
|
|||
}
|
||||
|
||||
let BlockChainContextResponse::Context(ctx) = context_svc
|
||||
.oneshot(BlockChainContextRequest::GetContext)
|
||||
.oneshot(BlockChainContextRequest::Context)
|
||||
.await?
|
||||
else {
|
||||
unreachable!();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#![allow(
|
||||
unused_imports,
|
||||
unreachable_pub,
|
||||
unreachable_code,
|
||||
unused_crate_dependencies,
|
||||
dead_code,
|
||||
unused_variables,
|
||||
|
|
|
@ -6,5 +6,6 @@ mod bin;
|
|||
mod handler;
|
||||
mod json;
|
||||
mod other;
|
||||
mod request;
|
||||
|
||||
pub use handler::{CupratedRpcHandler, CupratedRpcHandlerState};
|
||||
pub use handler::CupratedRpcHandler;
|
||||
|
|
|
@ -10,11 +10,11 @@ use cuprate_rpc_types::{
|
|||
json::{GetOutputDistributionRequest, GetOutputDistributionResponse},
|
||||
};
|
||||
|
||||
use crate::rpc::CupratedRpcHandlerState;
|
||||
use crate::rpc::CupratedRpcHandler;
|
||||
|
||||
/// Map a [`BinRequest`] to the function that will lead to a [`BinResponse`].
|
||||
pub(super) async fn map_request(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: BinRequest,
|
||||
) -> Result<BinResponse, Error> {
|
||||
use BinRequest as Req;
|
||||
|
@ -36,49 +36,49 @@ pub(super) async fn map_request(
|
|||
}
|
||||
|
||||
async fn get_blocks(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetBlocksRequest,
|
||||
) -> Result<GetBlocksResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_blocks_by_height(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetBlocksByHeightRequest,
|
||||
) -> Result<GetBlocksByHeightResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_hashes(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetHashesRequest,
|
||||
) -> Result<GetHashesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_output_indexes(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetOutputIndexesRequest,
|
||||
) -> Result<GetOutputIndexesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_outs(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetOutsRequest,
|
||||
) -> Result<GetOutsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transaction_pool_hashes(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetTransactionPoolHashesRequest,
|
||||
) -> Result<GetTransactionPoolHashesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_output_distribution(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetOutputDistributionRequest,
|
||||
) -> Result<GetOutputDistributionResponse, Error> {
|
||||
todo!()
|
||||
|
|
|
@ -3,51 +3,131 @@
|
|||
use std::task::{Context, Poll};
|
||||
|
||||
use anyhow::Error;
|
||||
use futures::{channel::oneshot::channel, future::BoxFuture};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use futures::future::BoxFuture;
|
||||
use monero_serai::block::Block;
|
||||
use tower::Service;
|
||||
|
||||
use cuprate_blockchain::service::BlockchainReadHandle;
|
||||
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
||||
use cuprate_json_rpc::Id;
|
||||
use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle};
|
||||
use cuprate_rpc_interface::RpcHandler;
|
||||
use cuprate_rpc_types::{
|
||||
bin::{BinRequest, BinResponse},
|
||||
json::{JsonRpcRequest, JsonRpcResponse},
|
||||
other::{OtherRequest, OtherResponse},
|
||||
};
|
||||
use cuprate_txpool::service::TxpoolReadHandle;
|
||||
use cuprate_txpool::service::{TxpoolReadHandle, TxpoolWriteHandle};
|
||||
|
||||
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
|
||||
#[derive(Clone)]
|
||||
pub struct CupratedRpcHandler {
|
||||
/// Should this RPC server be [restricted](RpcHandler::restricted)?
|
||||
//
|
||||
// INVARIANT:
|
||||
// We don't need to include this in `state` and check for
|
||||
// `self.is_restricted()` because `cuprate-rpc-interface` handles that.
|
||||
pub restricted: bool,
|
||||
///
|
||||
/// This is not `pub` on purpose, as it should not be mutated after [`Self::new`].
|
||||
restricted: bool,
|
||||
|
||||
/// State needed for request -> response mapping.
|
||||
pub state: CupratedRpcHandlerState,
|
||||
}
|
||||
|
||||
/// TODO
|
||||
#[derive(Clone)]
|
||||
pub struct CupratedRpcHandlerState {
|
||||
/// 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.
|
||||
pub txpool: TxpoolReadHandle,
|
||||
pub txpool_read: TxpoolReadHandle,
|
||||
|
||||
/// TODO: handle to txpool service.
|
||||
pub txpool_manager: std::convert::Infallible,
|
||||
}
|
||||
|
||||
impl CupratedRpcHandler {
|
||||
/// TODO
|
||||
pub fn init() {
|
||||
todo!()
|
||||
/// Create a new [`Self`].
|
||||
pub const fn new(
|
||||
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 {
|
||||
let state = CupratedRpcHandlerState::clone(&self.state);
|
||||
let state = self.clone();
|
||||
Box::pin(json::map_request(state, request))
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +162,7 @@ impl Service<BinRequest> for CupratedRpcHandler {
|
|||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +177,7 @@ impl Service<OtherRequest> for CupratedRpcHandler {
|
|||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,11 @@ use cuprate_rpc_types::json::{
|
|||
SyncInfoRequest, SyncInfoResponse,
|
||||
};
|
||||
|
||||
use crate::rpc::CupratedRpcHandlerState;
|
||||
use crate::rpc::CupratedRpcHandler;
|
||||
|
||||
/// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`].
|
||||
pub(super) async fn map_request(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: JsonRpcRequest,
|
||||
) -> Result<JsonRpcResponse, Error> {
|
||||
use JsonRpcRequest as Req;
|
||||
|
@ -84,210 +84,210 @@ pub(super) async fn map_request(
|
|||
}
|
||||
|
||||
async fn get_block_count(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetBlockCountRequest,
|
||||
) -> Result<GetBlockCountResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn on_get_block_hash(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: OnGetBlockHashRequest,
|
||||
) -> Result<OnGetBlockHashResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn submit_block(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: SubmitBlockRequest,
|
||||
) -> Result<SubmitBlockResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn generate_blocks(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GenerateBlocksRequest,
|
||||
) -> Result<GenerateBlocksResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_last_block_header(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetLastBlockHeaderRequest,
|
||||
) -> Result<GetLastBlockHeaderResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_block_header_by_hash(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetBlockHeaderByHashRequest,
|
||||
) -> Result<GetBlockHeaderByHashResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_block_header_by_height(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetBlockHeaderByHeightRequest,
|
||||
) -> Result<GetBlockHeaderByHeightResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_block_headers_range(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetBlockHeadersRangeRequest,
|
||||
) -> Result<GetBlockHeadersRangeResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_block(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetBlockRequest,
|
||||
) -> Result<GetBlockResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_connections(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetConnectionsRequest,
|
||||
) -> Result<GetConnectionsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_info(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetInfoRequest,
|
||||
) -> Result<GetInfoResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn hard_fork_info(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: HardForkInfoRequest,
|
||||
) -> Result<HardForkInfoResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_bans(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: SetBansRequest,
|
||||
) -> Result<SetBansResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_bans(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetBansRequest,
|
||||
) -> Result<GetBansResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn banned(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: BannedRequest,
|
||||
) -> Result<BannedResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn flush_transaction_pool(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: FlushTransactionPoolRequest,
|
||||
) -> Result<FlushTransactionPoolResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_output_histogram(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetOutputHistogramRequest,
|
||||
) -> Result<GetOutputHistogramResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_coinbase_tx_sum(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetCoinbaseTxSumRequest,
|
||||
) -> Result<GetCoinbaseTxSumResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_version(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetVersionRequest,
|
||||
) -> Result<GetVersionResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_fee_estimate(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetFeeEstimateRequest,
|
||||
) -> Result<GetFeeEstimateResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_alternate_chains(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetAlternateChainsRequest,
|
||||
) -> Result<GetAlternateChainsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn relay_tx(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: RelayTxRequest,
|
||||
) -> Result<RelayTxResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn sync_info(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: SyncInfoRequest,
|
||||
) -> Result<SyncInfoResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transaction_pool_backlog(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetTransactionPoolBacklogRequest,
|
||||
) -> Result<GetTransactionPoolBacklogResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_miner_data(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetMinerDataRequest,
|
||||
) -> Result<GetMinerDataResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn prune_blockchain(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: PruneBlockchainRequest,
|
||||
) -> Result<PruneBlockchainResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn calc_pow(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: CalcPowRequest,
|
||||
) -> Result<CalcPowResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn flush_cache(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: FlushCacheRequest,
|
||||
) -> Result<FlushCacheResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn add_aux_pow(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: AddAuxPowRequest,
|
||||
) -> Result<AddAuxPowResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_tx_ids_loose(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetTxIdsLooseRequest,
|
||||
) -> Result<GetTxIdsLooseResponse, Error> {
|
||||
todo!()
|
||||
|
|
|
@ -17,11 +17,11 @@ use cuprate_rpc_types::other::{
|
|||
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`].
|
||||
pub(super) async fn map_request(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: OtherRequest,
|
||||
) -> Result<OtherResponse, Error> {
|
||||
use OtherRequest as Req;
|
||||
|
@ -71,189 +71,189 @@ pub(super) async fn map_request(
|
|||
}
|
||||
|
||||
async fn get_height(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetHeightRequest,
|
||||
) -> Result<GetHeightResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transactions(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetTransactionsRequest,
|
||||
) -> Result<GetTransactionsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_alt_blocks_hashes(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetAltBlocksHashesRequest,
|
||||
) -> Result<GetAltBlocksHashesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn is_key_image_spent(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: IsKeyImageSpentRequest,
|
||||
) -> Result<IsKeyImageSpentResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn send_raw_transaction(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: SendRawTransactionRequest,
|
||||
) -> Result<SendRawTransactionResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn start_mining(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: StartMiningRequest,
|
||||
) -> Result<StartMiningResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn stop_mining(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: StopMiningRequest,
|
||||
) -> Result<StopMiningResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn mining_status(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: MiningStatusRequest,
|
||||
) -> Result<MiningStatusResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn save_bc(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: SaveBcRequest,
|
||||
) -> Result<SaveBcResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_peer_list(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetPeerListRequest,
|
||||
) -> Result<GetPeerListResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_log_hash_rate(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: SetLogHashRateRequest,
|
||||
) -> Result<SetLogHashRateResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_log_level(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: SetLogLevelRequest,
|
||||
) -> Result<SetLogLevelResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_log_categories(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: SetLogCategoriesRequest,
|
||||
) -> Result<SetLogCategoriesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_bootstrap_daemon(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: SetBootstrapDaemonRequest,
|
||||
) -> Result<SetBootstrapDaemonResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transaction_pool(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetTransactionPoolRequest,
|
||||
) -> Result<GetTransactionPoolResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transaction_pool_stats(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetTransactionPoolStatsRequest,
|
||||
) -> Result<GetTransactionPoolStatsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn stop_daemon(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: StopDaemonRequest,
|
||||
) -> Result<StopDaemonResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_limit(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetLimitRequest,
|
||||
) -> Result<GetLimitResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_limit(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: SetLimitRequest,
|
||||
) -> Result<SetLimitResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn out_peers(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: OutPeersRequest,
|
||||
) -> Result<OutPeersResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn in_peers(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: InPeersRequest,
|
||||
) -> Result<InPeersResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_net_stats(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetNetStatsRequest,
|
||||
) -> Result<GetNetStatsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_outs(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetOutsRequest,
|
||||
) -> Result<GetOutsResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn update(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: UpdateRequest,
|
||||
) -> Result<UpdateResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn pop_blocks(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: PopBlocksRequest,
|
||||
) -> Result<PopBlocksResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_transaction_pool_hashes(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetTransactionPoolHashesRequest,
|
||||
) -> Result<GetTransactionPoolHashesResponse, Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn get_public_nodes(
|
||||
state: CupratedRpcHandlerState,
|
||||
state: CupratedRpcHandler,
|
||||
request: GetPublicNodesRequest,
|
||||
) -> Result<GetPublicNodesResponse, Error> {
|
||||
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
|
||||
.ready()
|
||||
.await?
|
||||
.call(BlockChainContextRequest::GetContext)
|
||||
.call(BlockChainContextRequest::Context)
|
||||
.await?
|
||||
else {
|
||||
panic!("Context service returned wrong response!");
|
||||
|
|
|
@ -351,7 +351,7 @@ where
|
|||
let BlockChainContextResponse::Context(checked_context) = context_svc
|
||||
.ready()
|
||||
.await?
|
||||
.call(BlockChainContextRequest::GetContext)
|
||||
.call(BlockChainContextRequest::Context)
|
||||
.await?
|
||||
else {
|
||||
panic!("Context service returned wrong response!");
|
||||
|
@ -374,7 +374,7 @@ where
|
|||
let BlockChainContextResponse::RxVms(rx_vms) = context_svc
|
||||
.ready()
|
||||
.await?
|
||||
.call(BlockChainContextRequest::GetCurrentRxVm)
|
||||
.call(BlockChainContextRequest::CurrentRxVms)
|
||||
.await?
|
||||
else {
|
||||
panic!("Blockchain context service returned wrong response!");
|
||||
|
@ -433,7 +433,7 @@ where
|
|||
context
|
||||
} else {
|
||||
let BlockChainContextResponse::Context(checked_context) = context_svc
|
||||
.oneshot(BlockChainContextRequest::GetContext)
|
||||
.oneshot(BlockChainContextRequest::Context)
|
||||
.await?
|
||||
else {
|
||||
panic!("Context service returned wrong response!");
|
||||
|
|
|
@ -93,7 +93,7 @@ where
|
|||
let BlockChainContextResponse::Context(checked_context) = context_svc
|
||||
.ready()
|
||||
.await?
|
||||
.call(BlockChainContextRequest::GetContext)
|
||||
.call(BlockChainContextRequest::Context)
|
||||
.await?
|
||||
else {
|
||||
panic!("Context service returned wrong response!");
|
||||
|
@ -136,7 +136,7 @@ where
|
|||
let BlockChainContextResponse::RxVms(rx_vms) = context_svc
|
||||
.ready()
|
||||
.await?
|
||||
.call(BlockChainContextRequest::GetCurrentRxVm)
|
||||
.call(BlockChainContextRequest::CurrentRxVms)
|
||||
.await?
|
||||
else {
|
||||
panic!("Blockchain context service returned wrong response!");
|
||||
|
|
|
@ -31,7 +31,7 @@ mod alt_chains;
|
|||
mod task;
|
||||
mod tokens;
|
||||
|
||||
use cuprate_types::Chain;
|
||||
use cuprate_types::{Chain, ChainInfo, FeeEstimate, HardForkInfo};
|
||||
use difficulty::DifficultyCache;
|
||||
use rx_vms::RandomXVm;
|
||||
use weight::BlockWeightsCache;
|
||||
|
@ -221,15 +221,18 @@ pub struct NewBlockData {
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum BlockChainContextRequest {
|
||||
/// Get the current blockchain context.
|
||||
GetContext,
|
||||
/// Gets the current `RandomX` VM.
|
||||
GetCurrentRxVm,
|
||||
Context,
|
||||
|
||||
/// Gets all the current `RandomX` VMs.
|
||||
CurrentRxVms,
|
||||
|
||||
/// Get the next difficulties for these blocks.
|
||||
///
|
||||
/// Inputs: a list of block timestamps and hfs
|
||||
///
|
||||
/// The number of difficulties returned will be one more than the number of timestamps/ hfs.
|
||||
BatchGetDifficulties(Vec<(u64, HardFork)>),
|
||||
|
||||
/// 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,
|
||||
/// 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.
|
||||
NewRXVM(([u8; 32], Arc<RandomXVm>)),
|
||||
|
||||
/// A request to add a new block to the cache.
|
||||
Update(NewBlockData),
|
||||
|
||||
/// Pop blocks from the cache to the specified height.
|
||||
PopBlocks {
|
||||
/// 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.
|
||||
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.
|
||||
ClearAltCache,
|
||||
|
||||
/// Get information on all the current alternate chains.
|
||||
AltChains,
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------- AltChainRequests
|
||||
/// 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.
|
||||
_token: AltChainRequestToken,
|
||||
},
|
||||
|
||||
/// 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
|
||||
|
@ -271,6 +291,7 @@ pub enum BlockChainContextRequest {
|
|||
/// An internal token to prevent external crates calling this request.
|
||||
_token: AltChainRequestToken,
|
||||
},
|
||||
|
||||
/// 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
|
||||
|
@ -281,6 +302,7 @@ pub enum BlockChainContextRequest {
|
|||
/// An internal token to prevent external crates calling this request.
|
||||
_token: AltChainRequestToken,
|
||||
},
|
||||
|
||||
/// A request for a RX VM for an alternative chin.
|
||||
///
|
||||
/// Response variant: [`BlockChainContextResponse::AltChainRxVM`].
|
||||
|
@ -295,6 +317,7 @@ pub enum BlockChainContextRequest {
|
|||
/// An internal token to prevent external crates calling this request.
|
||||
_token: AltChainRequestToken,
|
||||
},
|
||||
|
||||
/// 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
|
||||
|
@ -310,22 +333,49 @@ pub enum BlockChainContextRequest {
|
|||
}
|
||||
|
||||
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),
|
||||
|
||||
/// Response to [`BlockChainContextRequest::CurrentRxVms`]
|
||||
///
|
||||
/// A map of seed height to `RandomX` VMs.
|
||||
RxVms(HashMap<usize, Arc<RandomXVm>>),
|
||||
|
||||
/// A list of difficulties.
|
||||
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.
|
||||
AltChainContextCache(Box<AltChainContextCache>),
|
||||
|
||||
/// A difficulty cache for an alt chain.
|
||||
AltChainDifficultyCache(DifficultyCache),
|
||||
|
||||
/// A randomX VM for an alt chain.
|
||||
AltChainRxVM(Arc<RandomXVm>),
|
||||
|
||||
/// A weight cache for an alt chain
|
||||
AltChainWeightCache(BlockWeightsCache),
|
||||
/// A generic Ok response.
|
||||
Ok,
|
||||
}
|
||||
|
||||
/// The blockchain context service.
|
||||
|
|
|
@ -153,7 +153,7 @@ impl<D: Database + Clone + Send + 'static> ContextTask<D> {
|
|||
req: BlockChainContextRequest,
|
||||
) -> Result<BlockChainContextResponse, tower::BoxError> {
|
||||
Ok(match req {
|
||||
BlockChainContextRequest::GetContext => {
|
||||
BlockChainContextRequest::Context => {
|
||||
tracing::debug!("Getting blockchain context");
|
||||
|
||||
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)
|
||||
}
|
||||
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);
|
||||
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
|
||||
.clone()
|
||||
.oneshot(BlockChainContextRequest::GetContext)
|
||||
.oneshot(BlockChainContextRequest::Context)
|
||||
.await?
|
||||
else {
|
||||
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 BlockChainContextResponse::Context(context) = ctx_svc
|
||||
.oneshot(BlockChainContextRequest::GetContext)
|
||||
.await?
|
||||
let BlockChainContextResponse::Context(context) =
|
||||
ctx_svc.oneshot(BlockChainContextRequest::Context).await?
|
||||
else {
|
||||
panic!("context service returned incorrect response!")
|
||||
};
|
||||
|
|
|
@ -229,6 +229,15 @@ impl<Z: BorshNetworkZone> AddressBook<Z> {
|
|||
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(
|
||||
&mut self,
|
||||
mut peer_list: Vec<ZoneSpecificPeerListEntryBase<Z::Addr>>,
|
||||
|
@ -408,9 +417,15 @@ impl<Z: BorshNetworkZone> Service<AddressBookRequest<Z>> for AddressBook<Z> {
|
|||
AddressBookRequest::GetWhitePeers(len) => {
|
||||
Ok(AddressBookResponse::Peers(self.get_white_peers(len)))
|
||||
}
|
||||
AddressBookRequest::IsPeerBanned(addr) => Ok(AddressBookResponse::IsPeerBanned(
|
||||
self.is_peer_banned(&addr),
|
||||
)),
|
||||
AddressBookRequest::GetBan(addr) => Ok(AddressBookResponse::GetBan {
|
||||
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)
|
||||
|
|
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(_) => {
|
||||
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,
|
||||
};
|
||||
|
||||
pub mod ban;
|
||||
pub mod client;
|
||||
mod constants;
|
||||
pub mod error;
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use cuprate_pruning::{PruningError, PruningSeed};
|
||||
use cuprate_wire::{CoreSyncData, PeerListEntryBase};
|
||||
|
||||
use crate::{
|
||||
client::InternalPeerID, handles::ConnectionHandle, NetZoneAddress, NetworkAddressIncorrectZone,
|
||||
NetworkZone,
|
||||
ban::{BanState, SetBan},
|
||||
client::InternalPeerID,
|
||||
handles::ConnectionHandle,
|
||||
NetZoneAddress, NetworkAddressIncorrectZone, NetworkZone,
|
||||
};
|
||||
|
||||
/// 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
|
||||
rpc_credits_per_hash: u32,
|
||||
},
|
||||
|
||||
/// Tells the address book about a peer list received from a peer.
|
||||
IncomingPeerList(Vec<ZoneSpecificPeerListEntryBase<Z::Addr>>),
|
||||
|
||||
/// 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
|
||||
/// block at that height according to it's pruning seed
|
||||
TakeRandomWhitePeer { height: Option<usize> },
|
||||
|
||||
/// 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
|
||||
/// block at that height according to it's pruning seed
|
||||
TakeRandomGrayPeer { height: Option<usize> },
|
||||
|
||||
/// 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
|
||||
/// 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
|
||||
/// one if no peer is found.
|
||||
TakeRandomPeer { height: Option<usize> },
|
||||
|
||||
/// Gets the specified number of white peers, or less if we don't have enough.
|
||||
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.
|
||||
IsPeerBanned(Z::Addr),
|
||||
GetBan(Z::Addr),
|
||||
|
||||
/// Get the state of all bans.
|
||||
GetBans,
|
||||
}
|
||||
|
||||
/// A response from the address book service.
|
||||
pub enum AddressBookResponse<Z: NetworkZone> {
|
||||
/// Generic OK response.
|
||||
///
|
||||
/// Response to:
|
||||
/// - [`AddressBookRequest::NewConnection`]
|
||||
/// - [`AddressBookRequest::IncomingPeerList`]
|
||||
Ok,
|
||||
|
||||
/// Response to:
|
||||
/// - [`AddressBookRequest::TakeRandomWhitePeer`]
|
||||
/// - [`AddressBookRequest::TakeRandomGrayPeer`]
|
||||
/// - [`AddressBookRequest::TakeRandomPeer`]
|
||||
Peer(ZoneSpecificPeerListEntryBase<Z::Addr>),
|
||||
|
||||
/// Response to [`AddressBookRequest::GetWhitePeers`].
|
||||
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 let Some(addr) = &addr {
|
||||
let AddressBookResponse::IsPeerBanned(banned) = address_book
|
||||
let AddressBookResponse::GetBan { unban_instant } = address_book
|
||||
.ready()
|
||||
.await?
|
||||
.call(AddressBookRequest::IsPeerBanned(*addr))
|
||||
.call(AddressBookRequest::GetBan(*addr))
|
||||
.await?
|
||||
else {
|
||||
panic!("Address book returned incorrect response!");
|
||||
};
|
||||
|
||||
if banned {
|
||||
if unban_instant.is_some() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
//!
|
||||
//! The 2nd allows any caller to send [`WriteRequest`][req_w]s.
|
||||
//!
|
||||
//! The `DatabaseReadHandle` can be shared as it is cheaply [`Clone`]able, however,
|
||||
//! the `DatabaseWriteHandle` cannot be cloned. There is only 1 place in Cuprate that
|
||||
//! The [`BlockchainReadHandle`] can be shared as it is cheaply [`Clone`]able, however,
|
||||
//! the [`BlockchainWriteHandle`] cannot be cloned. There is only 1 place in Cuprate that
|
||||
//! writes, so it is passed there and used.
|
||||
//!
|
||||
//! ## Initialization
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
//! 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
|
||||
use std::{
|
||||
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_types::{
|
||||
blockchain::{BlockchainReadRequest, BlockchainResponse},
|
||||
Chain, ChainId, ExtendedBlockHeader, OutputOnChain,
|
||||
Chain, ChainId, ExtendedBlockHeader, OutputHistogramInput, OutputOnChain,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
@ -107,6 +115,12 @@ fn map_request(
|
|||
R::CompactChainHistory => compact_chain_history(env),
|
||||
R::FindFirstUnknown(block_ids) => find_first_unknown(env, &block_ids),
|
||||
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? */
|
||||
|
@ -601,3 +615,36 @@ fn alt_blocks_in_chain(env: &ConcreteEnv, chain_id: ChainId) -> ResponseResult {
|
|||
|
||||
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")]
|
||||
pub mod service;
|
||||
pub mod tables;
|
||||
mod tx;
|
||||
pub mod types;
|
||||
|
||||
pub use config::Config;
|
||||
pub use free::open;
|
||||
pub use tx::TxEntry;
|
||||
|
||||
//re-exports
|
||||
pub use cuprate_database;
|
||||
|
|
|
@ -21,9 +21,7 @@
|
|||
//!
|
||||
//! The 2nd allows any caller to send [`WriteRequest`][req_w]s.
|
||||
//!
|
||||
//! The `DatabaseReadHandle` can be shared as it is cheaply [`Clone`]able, however,
|
||||
//! the `DatabaseWriteHandle` cannot be cloned. There is only 1 place in Cuprate that
|
||||
//! writes, so it is passed there and used.
|
||||
//! Both the handles are cheaply [`Clone`]able.
|
||||
//!
|
||||
//! ## Initialization
|
||||
//! The database & thread-pool system can be initialized with [`init()`].
|
||||
|
|
|
@ -5,30 +5,53 @@ use std::sync::Arc;
|
|||
|
||||
use cuprate_types::TransactionVerificationData;
|
||||
|
||||
use crate::types::TransactionHash;
|
||||
use crate::{tx::TxEntry, types::TransactionHash};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- TxpoolReadRequest
|
||||
/// The transaction pool [`tower::Service`] read request type.
|
||||
pub enum TxpoolReadRequest {
|
||||
/// A request for the blob (raw bytes) of a transaction with the given hash.
|
||||
TxBlob(TransactionHash),
|
||||
|
||||
/// A request for the [`TransactionVerificationData`] of a transaction in the tx pool.
|
||||
TxVerificationData(TransactionHash),
|
||||
|
||||
/// Get information on all transactions in the pool.
|
||||
Backlog,
|
||||
|
||||
/// Get the number of transactions in the pool.
|
||||
Size,
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- TxpoolReadResponse
|
||||
/// The transaction pool [`tower::Service`] read response type.
|
||||
#[expect(clippy::large_enum_variant)]
|
||||
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.
|
||||
TxBlob(Vec<u8>),
|
||||
/// A response of [`TransactionVerificationData`].
|
||||
|
||||
/// Response to [`TxpoolReadRequest::TxVerificationData`].
|
||||
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
|
||||
/// The transaction pool [`tower::Service`] write request type.
|
||||
#[derive(Clone)]
|
||||
pub enum TxpoolWriteRequest {
|
||||
/// Add a transaction to the pool.
|
||||
///
|
||||
|
@ -41,6 +64,7 @@ pub enum TxpoolWriteRequest {
|
|||
/// [`true`] if this tx is in the stem state.
|
||||
state_stem: bool,
|
||||
},
|
||||
|
||||
/// Remove a transaction with the given hash from the pool.
|
||||
///
|
||||
/// Returns [`TxpoolWriteResponse::Ok`].
|
||||
|
@ -49,11 +73,14 @@ pub enum TxpoolWriteRequest {
|
|||
|
||||
//---------------------------------------------------------------------------------------------------- TxpoolWriteResponse
|
||||
/// The transaction pool [`tower::Service`] write response type.
|
||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||
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.
|
||||
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 rayon::ThreadPool;
|
||||
|
@ -58,6 +65,8 @@ fn map_request(
|
|||
match request {
|
||||
TxpoolReadRequest::TxBlob(tx_hash) => tx_blob(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)
|
||||
}
|
||||
|
||||
/// [`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,
|
||||
};
|
||||
|
||||
use monero_serai::block::Block;
|
||||
|
||||
use crate::{
|
||||
types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation},
|
||||
AltBlockInformation, ChainId,
|
||||
AltBlockInformation, ChainId, CoinbaseTxSum, OutputHistogramEntry, OutputHistogramInput,
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- ReadRequest
|
||||
|
@ -103,6 +105,29 @@ pub enum BlockchainReadRequest {
|
|||
|
||||
/// A request for all alt blocks in the chain with the given [`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
|
||||
|
@ -147,6 +172,7 @@ pub enum BlockchainWriteRequest {
|
|||
/// This pairs with [`BlockchainReadRequest`] and [`BlockchainWriteRequest`],
|
||||
/// see those two for more info.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[expect(clippy::large_enum_variant)]
|
||||
pub enum BlockchainResponse {
|
||||
//------------------------------------------------------ Reads
|
||||
/// Response to [`BlockchainReadRequest::BlockExtendedHeader`].
|
||||
|
@ -215,18 +241,41 @@ pub enum BlockchainResponse {
|
|||
cumulative_difficulty: u128,
|
||||
},
|
||||
|
||||
/// The response for [`BlockchainReadRequest::FindFirstUnknown`].
|
||||
/// Response to [`BlockchainReadRequest::FindFirstUnknown`].
|
||||
///
|
||||
/// Contains the index of the first unknown block and its expected height.
|
||||
///
|
||||
/// This will be [`None`] if all blocks were known.
|
||||
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.
|
||||
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
|
||||
/// A generic Ok response to indicate a request was successfully handled.
|
||||
///
|
||||
|
@ -236,7 +285,8 @@ pub enum BlockchainResponse {
|
|||
/// - [`BlockchainWriteRequest::ReverseReorg`]
|
||||
/// - [`BlockchainWriteRequest::FlushAltBlocks`]
|
||||
Ok,
|
||||
/// The response for [`BlockchainWriteRequest::PopBlocks`].
|
||||
|
||||
/// Response to [`BlockchainWriteRequest::PopBlocks`].
|
||||
///
|
||||
/// The inner value is the alt-chain ID for the old main chain blocks.
|
||||
PopBlocks(ChainId),
|
||||
|
|
|
@ -20,8 +20,9 @@ pub use transaction_verification_data::{
|
|||
CachedVerificationState, TransactionVerificationData, TxVersion,
|
||||
};
|
||||
pub use types::{
|
||||
AltBlockInformation, Chain, ChainId, ExtendedBlockHeader, OutputOnChain,
|
||||
VerifiedBlockInformation, VerifiedTransactionInformation,
|
||||
AltBlockInformation, Chain, ChainId, ChainInfo, CoinbaseTxSum, ExtendedBlockHeader,
|
||||
FeeEstimate, HardForkInfo, MinerData, MinerDataTxBacklogEntry, OutputHistogramEntry,
|
||||
OutputHistogramInput, OutputOnChain, VerifiedBlockInformation, VerifiedTransactionInformation,
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Feature-gated
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//! Various shared data types in Cuprate.
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use std::num::NonZero;
|
||||
|
||||
use curve25519_dalek::edwards::EdwardsPoint;
|
||||
|
@ -11,7 +10,6 @@ use monero_serai::{
|
|||
|
||||
use crate::HardFork;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- ExtendedBlockHeader
|
||||
/// Extended header data of a block.
|
||||
///
|
||||
/// 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,
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- VerifiedTransactionInformation
|
||||
/// Verified information of a transaction.
|
||||
///
|
||||
/// This represents a valid transaction
|
||||
|
@ -61,7 +58,6 @@ pub struct VerifiedTransactionInformation {
|
|||
pub tx_hash: [u8; 32],
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- VerifiedBlockInformation
|
||||
/// Verified information of a block.
|
||||
///
|
||||
/// This represents a block that has already been verified to be correct.
|
||||
|
@ -94,14 +90,12 @@ pub struct VerifiedBlockInformation {
|
|||
pub cumulative_difficulty: u128,
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- ChainID
|
||||
/// A unique ID for an alt chain.
|
||||
///
|
||||
/// The inner value is meaningless.
|
||||
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||
pub struct ChainId(pub NonZero<u64>);
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Chain
|
||||
/// An identifier for a chain.
|
||||
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||
pub enum Chain {
|
||||
|
@ -111,7 +105,6 @@ pub enum Chain {
|
|||
Alt(ChainId),
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- AltBlockInformation
|
||||
/// A block on an alternative chain.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct AltBlockInformation {
|
||||
|
@ -141,7 +134,6 @@ pub struct AltBlockInformation {
|
|||
pub chain_id: ChainId,
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- OutputOnChain
|
||||
/// An already existing transaction output.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct OutputOnChain {
|
||||
|
@ -155,6 +147,104 @@ pub struct OutputOnChain {
|
|||
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
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
|
Loading…
Reference in a new issue