From 96099eb5cce25a28d3ee98e83728d67aa4cd88bc Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Mon, 23 Sep 2024 18:34:57 -0400 Subject: [PATCH 01/23] add request methods --- binaries/cuprated/src/rpc.rs | 1 + binaries/cuprated/src/rpc/handler.rs | 30 +- binaries/cuprated/src/rpc/request.rs | 18 + .../cuprated/src/rpc/request/blockchain.rs | 366 ++++++++++++++++++ .../src/rpc/request/blockchain_manager.rs | 45 +++ binaries/cuprated/src/rpc/request/p2p.rs | 25 ++ binaries/cuprated/src/rpc/request/txpool.rs | 25 ++ storage/blockchain/src/service/mod.rs | 4 - storage/service/src/service/write.rs | 2 +- storage/txpool/src/service/interface.rs | 3 +- 10 files changed, 501 insertions(+), 18 deletions(-) create mode 100644 binaries/cuprated/src/rpc/request.rs create mode 100644 binaries/cuprated/src/rpc/request/blockchain.rs create mode 100644 binaries/cuprated/src/rpc/request/blockchain_manager.rs create mode 100644 binaries/cuprated/src/rpc/request/p2p.rs create mode 100644 binaries/cuprated/src/rpc/request/txpool.rs diff --git a/binaries/cuprated/src/rpc.rs b/binaries/cuprated/src/rpc.rs index 9ebcd1b82..8978e5d2b 100644 --- a/binaries/cuprated/src/rpc.rs +++ b/binaries/cuprated/src/rpc.rs @@ -6,5 +6,6 @@ mod bin; mod handler; mod json; mod other; +mod request; pub use handler::{CupratedRpcHandler, CupratedRpcHandlerState}; diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 8ba25eab6..7c8c7eb58 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -7,7 +7,7 @@ use futures::{channel::oneshot::channel, future::BoxFuture}; use serde::{Deserialize, Serialize}; 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; @@ -16,20 +16,13 @@ use cuprate_rpc_types::{ json::{JsonRpcRequest, JsonRpcResponse}, other::{OtherRequest, OtherResponse}, }; -use cuprate_txpool::service::TxpoolReadHandle; +use cuprate_txpool::service::{TxpoolReadHandle, TxpoolWriteHandle}; use crate::rpc::{bin, json, other}; /// 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, - /// State needed for request -> response mapping. pub state: CupratedRpcHandlerState, } @@ -37,11 +30,24 @@ pub struct CupratedRpcHandler { /// TODO #[derive(Clone)] pub struct CupratedRpcHandlerState { + /// 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, + /// Read handle to the blockchain database. - pub blockchain: BlockchainReadHandle, + pub blockchain_read: BlockchainReadHandle, + + /// Write handle to the blockchain database. + pub blockchain_write: BlockchainWriteHandle, /// Read handle to the transaction pool database. - pub txpool: TxpoolReadHandle, + pub txpool_read: TxpoolReadHandle, + + /// Write handle to the transaction pool database. + pub txpool_write: TxpoolWriteHandle, } impl CupratedRpcHandler { @@ -53,7 +59,7 @@ impl CupratedRpcHandler { impl RpcHandler for CupratedRpcHandler { fn restricted(&self) -> bool { - self.restricted + self.state.restricted } } diff --git a/binaries/cuprated/src/rpc/request.rs b/binaries/cuprated/src/rpc/request.rs new file mode 100644 index 000000000..ac26ebe06 --- /dev/null +++ b/binaries/cuprated/src/rpc/request.rs @@ -0,0 +1,18 @@ +//! Convenience functions for requests/responses. +//! +//! This module implements many methods on +//! [`CupratedRpcHandlerState`](crate::rpc::CupratedRpcHandlerState) +//! 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 blockchain; +mod blockchain_manager; +mod p2p; +mod txpool; diff --git a/binaries/cuprated/src/rpc/request/blockchain.rs b/binaries/cuprated/src/rpc/request/blockchain.rs new file mode 100644 index 000000000..d8ee2e779 --- /dev/null +++ b/binaries/cuprated/src/rpc/request/blockchain.rs @@ -0,0 +1,366 @@ +//! Functions for [`BlockchainReadRequest`] and [`BlockchainWriteRequest`]. + +use std::{ + collections::{HashMap, HashSet}, + ops::Range, + sync::Arc, +}; + +use anyhow::{anyhow, Error}; +use futures::StreamExt; +use monero_serai::block::Block; +use tower::{Service, ServiceExt}; + +use cuprate_consensus::BlockchainResponse; +use cuprate_helper::{ + cast::{u64_to_usize, usize_to_u64}, + map::split_u128_into_low_high_bits, +}; +use cuprate_types::{ + blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, + Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, +}; + +use crate::rpc::CupratedRpcHandlerState; + +impl CupratedRpcHandlerState { + /// [`BlockchainReadRequest::BlockExtendedHeader`]. + pub(super) async fn block_extended_header( + &mut self, + height: u64, + ) -> Result { + let BlockchainResponse::BlockExtendedHeader(header) = self + .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 self, + height: u64, + chain: Chain, + ) -> Result<[u8; 32], Error> { + let BlockchainResponse::BlockHash(hash) = self + .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 self, + block_hash: [u8; 32], + ) -> Result, Error> { + let BlockchainResponse::FindBlock(option) = self + .blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::FindBlock(block_hash)) + .await? + else { + unreachable!(); + }; + + Ok(option) + } + + /// [`BlockchainReadRequest::FilterUnknownHashes`]. + pub(super) async fn filter_unknown_hashes( + &mut self, + block_hashes: HashSet<[u8; 32]>, + ) -> Result, Error> { + let BlockchainResponse::FilterUnknownHashes(output) = self + .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 self, + range: Range, + chain: Chain, + ) -> Result, Error> { + let BlockchainResponse::BlockExtendedHeaderInRange(output) = self + .blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::BlockExtendedHeaderInRange( + range, chain, + )) + .await? + else { + unreachable!(); + }; + + Ok(output) + } + + /// [`BlockchainReadRequest::ChainHeight`]. + pub(super) async fn chain_height(&mut self) -> Result<(u64, [u8; 32]), Error> { + let BlockchainResponse::ChainHeight(height, hash) = self + .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 self, block_height: u64) -> Result { + let BlockchainResponse::GeneratedCoins(generated_coins) = self + .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 self, + outputs: HashMap>, + ) -> Result>, Error> { + let BlockchainResponse::Outputs(outputs) = self + .blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::Outputs(outputs)) + .await? + else { + unreachable!(); + }; + + Ok(outputs) + } + + /// [`BlockchainReadRequest::NumberOutputsWithAmount`] + pub(super) async fn number_outputs_with_amount( + &mut self, + output_amounts: Vec, + ) -> Result, Error> { + let BlockchainResponse::NumberOutputsWithAmount(map) = self + .blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::NumberOutputsWithAmount( + output_amounts, + )) + .await? + else { + unreachable!(); + }; + + Ok(map) + } + + /// [`BlockchainReadRequest::KeyImagesSpent`] + pub(super) async fn key_images_spent( + &mut self, + key_images: HashSet<[u8; 32]>, + ) -> Result { + let BlockchainResponse::KeyImagesSpent(is_spent) = self + .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 self) -> Result<(Vec<[u8; 32]>, u128), Error> { + let BlockchainResponse::CompactChainHistory { + block_ids, + cumulative_difficulty, + } = self + .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 self, + hashes: Vec<[u8; 32]>, + ) -> Result, Error> { + let BlockchainResponse::FindFirstUnknown(resp) = self + .blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::FindFirstUnknown(hashes)) + .await? + else { + unreachable!(); + }; + + Ok(resp.map(|(index, height)| (index, usize_to_u64(height)))) + } + + //------------------------------------------------------------------------------------------ new + + // /// [`BlockchainReadRequest::Block`]. + // pub(super) async fn block(&mut self, height: u64) -> Result { + // let BlockchainResponse::Block(block) = self + // + // .blockchain_read + // .ready() + // .await? + // .call(BlockchainReadRequest::Block(u64_to_usize(height))) + // .await? + // else { + // unreachable!(); + // }; + + // Ok(block) + // } + + // /// [`BlockchainReadRequest::BlockByHash`]. + // pub(super) async fn block_by_hash(&mut self, hash: [u8; 32]) -> Result { + // let BlockchainResponse::BlockByHash(block) = self + // + // .blockchain_read + // .ready() + // .await? + // .call(BlockchainReadRequest::BlockByHash(hash)) + // .await? + // else { + // unreachable!(); + // }; + + // Ok(block) + // } + + // /// [`BlockchainReadRequest::BlockExtendedHeaderByHash`]. + // pub(super) async fn block_extended_header_by_hash( + // &mut self, + // hash: [u8; 32], + // ) -> Result { + // let BlockchainResponse::BlockExtendedHeaderByHash(header) = self + // + // .blockchain_read + // .ready() + // .await? + // .call(BlockchainReadRequest::BlockExtendedHeaderByHash(hash)) + // .await? + // else { + // unreachable!(); + // }; + + // Ok(header) + // } + + // /// [`BlockchainReadRequest::TopBlockFull`]. + // pub(super) async fn top_block_full(&mut self) -> Result<(Block, ExtendedBlockHeader), Error> { + // let BlockchainResponse::TopBlockFull(block, header) = self + // + // .blockchain_read + // .ready() + // .await? + // .call(BlockchainReadRequest::TopBlockFull) + // .await? + // else { + // unreachable!(); + // }; + + // Ok((block, header)) + // } + + // /// [`BlockchainReadRequest::CurrentHardFork`] + // pub(super) async fn current_hard_fork(&mut self) -> Result { + // let BlockchainResponse::CurrentHardFork(hard_fork) = self + // + // .blockchain_read + // .ready() + // .await? + // .call(BlockchainReadRequest::CurrentHardFork) + // .await? + // else { + // unreachable!(); + // }; + + // Ok(hard_fork) + // } + + // /// [`BlockchainReadRequest::PopBlocks`] + // pub(super) async fn pop_blocks(&mut self, nblocks: u64) -> Result { + // let BlockchainResponse::PopBlocks(height) = self + // + // .blockchain_write + // .ready() + // .await? + // .call(BlockchainWriteRequest::PopBlocks(nblocks)) + // .await? + // else { + // unreachable!(); + // }; + + // Ok(usize_to_u64(height)) + // } + + // /// [`BlockchainReadRequest::CumulativeBlockWeightLimit`] + // pub(super) async fn cumulative_block_weight_limit(&mut self) -> Result { + // let BlockchainResponse::CumulativeBlockWeightLimit(limit) = self + // + // .blockchain_read + // .ready() + // .await? + // .call(BlockchainReadRequest::CumulativeBlockWeightLimit) + // .await? + // else { + // unreachable!(); + // }; + + // Ok(limit) + // } +} diff --git a/binaries/cuprated/src/rpc/request/blockchain_manager.rs b/binaries/cuprated/src/rpc/request/blockchain_manager.rs new file mode 100644 index 000000000..861c21ceb --- /dev/null +++ b/binaries/cuprated/src/rpc/request/blockchain_manager.rs @@ -0,0 +1,45 @@ +//! Functions for TODO: doc enum message. + +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, +}; + +use anyhow::{anyhow, Error}; +use futures::StreamExt; +use monero_serai::block::Block; +use tower::{Service, ServiceExt}; + +use cuprate_consensus::BlockchainResponse; +use cuprate_helper::{ + cast::{u64_to_usize, usize_to_u64}, + map::split_u128_into_low_high_bits, +}; +use cuprate_types::{ + blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, + Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, +}; + +use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; + +#[expect( + unreachable_code, + clippy::needless_pass_by_ref_mut, + reason = "TODO: remove after impl" +)] +impl CupratedRpcHandlerState { + /// TODO: doc enum message + pub(super) async fn pop_blocks(&mut self) -> Result<(u64, [u8; 32]), Error> { + Ok(todo!()) + } + + /// TODO: doc enum message + pub(super) async fn prune(&mut self) -> Result<(), Error> { + Ok(todo!()) + } + + /// TODO: doc enum message + pub(super) async fn pruned(&mut self) -> Result { + Ok(todo!()) + } +} diff --git a/binaries/cuprated/src/rpc/request/p2p.rs b/binaries/cuprated/src/rpc/request/p2p.rs new file mode 100644 index 000000000..b6c16b31f --- /dev/null +++ b/binaries/cuprated/src/rpc/request/p2p.rs @@ -0,0 +1,25 @@ +//! Functions for TODO: doc enum message. + +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, +}; + +use anyhow::{anyhow, Error}; +use futures::StreamExt; +use monero_serai::block::Block; +use tower::{Service, ServiceExt}; + +use cuprate_consensus::BlockchainResponse; +use cuprate_helper::{ + cast::{u64_to_usize, usize_to_u64}, + map::split_u128_into_low_high_bits, +}; +use cuprate_types::{ + blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, + Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, +}; + +use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; + +impl CupratedRpcHandlerState {} diff --git a/binaries/cuprated/src/rpc/request/txpool.rs b/binaries/cuprated/src/rpc/request/txpool.rs new file mode 100644 index 000000000..b6c16b31f --- /dev/null +++ b/binaries/cuprated/src/rpc/request/txpool.rs @@ -0,0 +1,25 @@ +//! Functions for TODO: doc enum message. + +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, +}; + +use anyhow::{anyhow, Error}; +use futures::StreamExt; +use monero_serai::block::Block; +use tower::{Service, ServiceExt}; + +use cuprate_consensus::BlockchainResponse; +use cuprate_helper::{ + cast::{u64_to_usize, usize_to_u64}, + map::split_u128_into_low_high_bits, +}; +use cuprate_types::{ + blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, + Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, +}; + +use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; + +impl CupratedRpcHandlerState {} diff --git a/storage/blockchain/src/service/mod.rs b/storage/blockchain/src/service/mod.rs index aa322d06e..fed0bd6d4 100644 --- a/storage/blockchain/src/service/mod.rs +++ b/storage/blockchain/src/service/mod.rs @@ -21,10 +21,6 @@ //! //! 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. -//! //! ## Initialization //! The database & thread-pool system can be initialized with [`init()`]. //! diff --git a/storage/service/src/service/write.rs b/storage/service/src/service/write.rs index f75d61517..d2cb862e6 100644 --- a/storage/service/src/service/write.rs +++ b/storage/service/src/service/write.rs @@ -21,7 +21,7 @@ const WRITER_THREAD_NAME: &str = concat!(module_path!(), "::DatabaseWriter"); /// Calling [`tower::Service::call`] with a [`DatabaseWriteHandle`] /// will return an `async`hronous channel that can be `.await`ed upon /// to receive the corresponding response. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct DatabaseWriteHandle { /// Sender channel to the database write thread-pool. /// diff --git a/storage/txpool/src/service/interface.rs b/storage/txpool/src/service/interface.rs index 450b28d63..411b7844f 100644 --- a/storage/txpool/src/service/interface.rs +++ b/storage/txpool/src/service/interface.rs @@ -29,6 +29,7 @@ pub enum TxpoolReadResponse { //---------------------------------------------------------------------------------------------------- TxpoolWriteRequest /// The transaction pool [`tower::Service`] write request type. +#[derive(Clone)] pub enum TxpoolWriteRequest { /// Add a transaction to the pool. /// @@ -49,7 +50,7 @@ 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. /// From 4dc3b2c66f485656a96ff9c65cf343b5b1094f4a Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Mon, 23 Sep 2024 20:50:05 -0400 Subject: [PATCH 02/23] add p2p messages --- .../cuprated/src/rpc/request/blockchain.rs | 3 +- binaries/cuprated/src/rpc/request/p2p.rs | 98 ++++++++++++++++++- p2p/address-book/src/book.rs | 5 + .../src/client/handshaker/builder/dummy.rs | 5 + p2p/p2p-core/src/services.rs | 56 +++++++++++ 5 files changed, 163 insertions(+), 4 deletions(-) diff --git a/binaries/cuprated/src/rpc/request/blockchain.rs b/binaries/cuprated/src/rpc/request/blockchain.rs index d8ee2e779..8b3145fed 100644 --- a/binaries/cuprated/src/rpc/request/blockchain.rs +++ b/binaries/cuprated/src/rpc/request/blockchain.rs @@ -11,13 +11,12 @@ use futures::StreamExt; use monero_serai::block::Block; use tower::{Service, ServiceExt}; -use cuprate_consensus::BlockchainResponse; use cuprate_helper::{ cast::{u64_to_usize, usize_to_u64}, map::split_u128_into_low_high_bits, }; use cuprate_types::{ - blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, + blockchain::{BlockchainReadRequest, BlockchainResponse, BlockchainWriteRequest}, Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, }; diff --git a/binaries/cuprated/src/rpc/request/p2p.rs b/binaries/cuprated/src/rpc/request/p2p.rs index b6c16b31f..22f46d746 100644 --- a/binaries/cuprated/src/rpc/request/p2p.rs +++ b/binaries/cuprated/src/rpc/request/p2p.rs @@ -2,6 +2,7 @@ use std::{ collections::{HashMap, HashSet}, + convert::Infallible, sync::Arc, }; @@ -10,11 +11,15 @@ use futures::StreamExt; use monero_serai::block::Block; use tower::{Service, ServiceExt}; -use cuprate_consensus::BlockchainResponse; use cuprate_helper::{ cast::{u64_to_usize, usize_to_u64}, map::split_u128_into_low_high_bits, }; +use cuprate_p2p_core::{ + client::handshaker::builder::DummyAddressBook, + services::{AddressBookRequest, AddressBookResponse}, + AddressBook, ClearNet, +}; use cuprate_types::{ blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, @@ -22,4 +27,93 @@ use cuprate_types::{ use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; -impl CupratedRpcHandlerState {} +#[expect(clippy::needless_pass_by_ref_mut, reason = "TODO: remove after impl")] +impl CupratedRpcHandlerState { + /// [`AddressBookRequest::PeerlistSize`] + pub(super) async fn peerlist_size(&mut self) -> Result<(u64, u64), Error> { + let AddressBookResponse::::PeerlistSize { white, grey } = + >>::ready( + &mut DummyAddressBook, + ) + .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(&mut self) -> Result<(u64, u64), Error> { + let AddressBookResponse::::ConnectionCount { incoming, outgoing } = + >>::ready( + &mut DummyAddressBook, + ) + .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(&mut self, peer: Infallible) -> Result<(), Error> { + let AddressBookResponse::::Ok = , + >>::ready(&mut DummyAddressBook) + .await + .expect("TODO") + .call(AddressBookRequest::SetBan(peer)) + .await + .expect("TODO") else { + unreachable!(); + }; + + Ok(()) + } + + /// [`AddressBookRequest::GetBan`] + pub(super) async fn get_ban(&mut self, peer: Infallible) -> Result<(), Error> { + let AddressBookResponse::::GetBan(ban) = + >>::ready( + &mut DummyAddressBook, + ) + .await + .expect("TODO") + .call(AddressBookRequest::GetBan(peer)) + .await + .expect("TODO") + else { + unreachable!(); + }; + + Ok(()) + } + + /// [`AddressBookRequest::GetBans`] + pub(super) async fn get_bans(&mut self) -> Result<(), Error> { + let AddressBookResponse::::GetBans(bans) = + >>::ready( + &mut DummyAddressBook, + ) + .await + .expect("TODO") + .call(AddressBookRequest::GetBans) + .await + .expect("TODO") + else { + unreachable!(); + }; + + Ok(todo!()) + } +} diff --git a/p2p/address-book/src/book.rs b/p2p/address-book/src/book.rs index 9c2298161..b21b45ea9 100644 --- a/p2p/address-book/src/book.rs +++ b/p2p/address-book/src/book.rs @@ -411,6 +411,11 @@ impl Service> for AddressBook { AddressBookRequest::IsPeerBanned(addr) => Ok(AddressBookResponse::IsPeerBanned( self.is_peer_banned(&addr), )), + AddressBookRequest::PeerlistSize + | AddressBookRequest::ConnectionCount + | AddressBookRequest::SetBan(_) + | AddressBookRequest::GetBan(_) + | AddressBookRequest::GetBans => todo!(), }; ready(response) diff --git a/p2p/p2p-core/src/client/handshaker/builder/dummy.rs b/p2p/p2p-core/src/client/handshaker/builder/dummy.rs index e3c4335a0..51f8af3c0 100644 --- a/p2p/p2p-core/src/client/handshaker/builder/dummy.rs +++ b/p2p/p2p-core/src/client/handshaker/builder/dummy.rs @@ -128,6 +128,11 @@ impl Service> for DummyAddressBook { AddressBookResponse::Ok } AddressBookRequest::IsPeerBanned(_) => AddressBookResponse::IsPeerBanned(false), + AddressBookRequest::PeerlistSize + | AddressBookRequest::ConnectionCount + | AddressBookRequest::SetBan(_) + | AddressBookRequest::GetBan(_) + | AddressBookRequest::GetBans => todo!(), })) } } diff --git a/p2p/p2p-core/src/services.rs b/p2p/p2p-core/src/services.rs index ba8768484..dd9d25125 100644 --- a/p2p/p2p-core/src/services.rs +++ b/p2p/p2p-core/src/services.rs @@ -108,16 +108,20 @@ pub enum AddressBookRequest { /// 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>), + /// 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 }, + /// 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 }, + /// 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. @@ -125,17 +129,69 @@ pub enum AddressBookRequest { /// The address book will look in the white peer list first, then the gray /// one if no peer is found. TakeRandomPeer { height: Option }, + /// Gets the specified number of white peers, or less if we don't have enough. GetWhitePeers(usize), + /// Checks if the given peer is banned. IsPeerBanned(Z::Addr), + + /// TODO + PeerlistSize, + + /// TODO + ConnectionCount, + + /// TODO: `cuprate_rpc_types::json::SetBanRequest` input + SetBan(std::convert::Infallible), + + /// TODO + GetBan(std::convert::Infallible), + + /// TODO + GetBans, } /// A response from the address book service. pub enum AddressBookResponse { + /// TODO + /// + /// Response to: + /// - [`AddressBookRequest::NewConnection`] + /// - [`AddressBookRequest::IncomingPeerList`] Ok, + + /// Response to: + /// - [`AddressBookRequest::TakeRandomWhitePeer`] + /// - [`AddressBookRequest::TakeRandomGrayPeer`] + /// - [`AddressBookRequest::TakeRandomPeer`] Peer(ZoneSpecificPeerListEntryBase), + + /// Response to [`AddressBookRequest::GetWhitePeers`]. Peers(Vec>), + + /// Response to [`AddressBookRequest::IsPeerBanned`]. + /// /// Contains `true` if the peer is banned. IsPeerBanned(bool), + + /// Response to [`AddressBookRequest::PeerlistSize`]. + /// + /// TODO + PeerlistSize { white: usize, grey: usize }, + + /// Response to [`AddressBookRequest::ConnectionCount`]. + /// + /// TODO + ConnectionCount { incoming: usize, outgoing: usize }, + + /// Response to [`AddressBookRequest::GetBan`]. + /// + /// TODO + GetBan(std::convert::Infallible), + + /// Response to [`AddressBookRequest::GetBans`]. + /// + /// TODO + GetBans(std::convert::Infallible), } From e8de295b57a33b39245c1ada1bbe9e2f00275531 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Tue, 24 Sep 2024 18:02:39 -0400 Subject: [PATCH 03/23] add txpool msgs --- binaries/cuprated/src/rpc/request.rs | 2 +- .../cuprated/src/rpc/request/address_book.rs | 120 ++++++++++++++++++ binaries/cuprated/src/rpc/request/p2p.rs | 119 ----------------- binaries/cuprated/src/rpc/request/txpool.rs | 48 ++++++- storage/txpool/src/service/interface.rs | 32 ++++- storage/txpool/src/service/read.rs | 1 + 6 files changed, 197 insertions(+), 125 deletions(-) create mode 100644 binaries/cuprated/src/rpc/request/address_book.rs delete mode 100644 binaries/cuprated/src/rpc/request/p2p.rs diff --git a/binaries/cuprated/src/rpc/request.rs b/binaries/cuprated/src/rpc/request.rs index ac26ebe06..6e59a8821 100644 --- a/binaries/cuprated/src/rpc/request.rs +++ b/binaries/cuprated/src/rpc/request.rs @@ -12,7 +12,7 @@ //! the [`blockchain`] modules contains methods for the //! blockchain database [`tower::Service`] API. +mod address_book; mod blockchain; mod blockchain_manager; -mod p2p; mod txpool; diff --git a/binaries/cuprated/src/rpc/request/address_book.rs b/binaries/cuprated/src/rpc/request/address_book.rs new file mode 100644 index 000000000..78ed5fb45 --- /dev/null +++ b/binaries/cuprated/src/rpc/request/address_book.rs @@ -0,0 +1,120 @@ +//! Functions for TODO: doc enum message. + +use std::{ + collections::{HashMap, HashSet}, + convert::Infallible, + sync::Arc, +}; + +use anyhow::{anyhow, Error}; +use futures::StreamExt; +use monero_serai::block::Block; +use tower::{Service, ServiceExt}; + +use cuprate_helper::{ + cast::{u64_to_usize, usize_to_u64}, + map::split_u128_into_low_high_bits, +}; +use cuprate_p2p_core::{ + client::handshaker::builder::DummyAddressBook, + services::{AddressBookRequest, AddressBookResponse}, + AddressBook, ClearNet, NetworkZone, +}; +use cuprate_types::{ + blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, + Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, +}; + +use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; + +/// [`AddressBookRequest::PeerlistSize`] +pub(super) async fn peerlist_size( + address_book: &mut impl AddressBook, +) -> 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( + address_book: &mut impl AddressBook, +) -> 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( + address_book: &mut impl AddressBook, + peer: Infallible, +) -> 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( + address_book: &mut impl AddressBook, + peer: Infallible, +) -> Result<(), Error> { + let AddressBookResponse::GetBan(ban) = address_book + .ready() + .await + .expect("TODO") + .call(AddressBookRequest::GetBan(peer)) + .await + .expect("TODO") + else { + unreachable!(); + }; + + Ok(()) +} + +/// [`AddressBookRequest::GetBans`] +pub(super) async fn get_bans( + address_book: &mut impl AddressBook, +) -> Result<(), Error> { + let AddressBookResponse::GetBans(bans) = address_book + .ready() + .await + .expect("TODO") + .call(AddressBookRequest::GetBans) + .await + .expect("TODO") + else { + unreachable!(); + }; + + Ok(todo!()) +} diff --git a/binaries/cuprated/src/rpc/request/p2p.rs b/binaries/cuprated/src/rpc/request/p2p.rs deleted file mode 100644 index 22f46d746..000000000 --- a/binaries/cuprated/src/rpc/request/p2p.rs +++ /dev/null @@ -1,119 +0,0 @@ -//! Functions for TODO: doc enum message. - -use std::{ - collections::{HashMap, HashSet}, - convert::Infallible, - sync::Arc, -}; - -use anyhow::{anyhow, Error}; -use futures::StreamExt; -use monero_serai::block::Block; -use tower::{Service, ServiceExt}; - -use cuprate_helper::{ - cast::{u64_to_usize, usize_to_u64}, - map::split_u128_into_low_high_bits, -}; -use cuprate_p2p_core::{ - client::handshaker::builder::DummyAddressBook, - services::{AddressBookRequest, AddressBookResponse}, - AddressBook, ClearNet, -}; -use cuprate_types::{ - blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, - Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, -}; - -use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; - -#[expect(clippy::needless_pass_by_ref_mut, reason = "TODO: remove after impl")] -impl CupratedRpcHandlerState { - /// [`AddressBookRequest::PeerlistSize`] - pub(super) async fn peerlist_size(&mut self) -> Result<(u64, u64), Error> { - let AddressBookResponse::::PeerlistSize { white, grey } = - >>::ready( - &mut DummyAddressBook, - ) - .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(&mut self) -> Result<(u64, u64), Error> { - let AddressBookResponse::::ConnectionCount { incoming, outgoing } = - >>::ready( - &mut DummyAddressBook, - ) - .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(&mut self, peer: Infallible) -> Result<(), Error> { - let AddressBookResponse::::Ok = , - >>::ready(&mut DummyAddressBook) - .await - .expect("TODO") - .call(AddressBookRequest::SetBan(peer)) - .await - .expect("TODO") else { - unreachable!(); - }; - - Ok(()) - } - - /// [`AddressBookRequest::GetBan`] - pub(super) async fn get_ban(&mut self, peer: Infallible) -> Result<(), Error> { - let AddressBookResponse::::GetBan(ban) = - >>::ready( - &mut DummyAddressBook, - ) - .await - .expect("TODO") - .call(AddressBookRequest::GetBan(peer)) - .await - .expect("TODO") - else { - unreachable!(); - }; - - Ok(()) - } - - /// [`AddressBookRequest::GetBans`] - pub(super) async fn get_bans(&mut self) -> Result<(), Error> { - let AddressBookResponse::::GetBans(bans) = - >>::ready( - &mut DummyAddressBook, - ) - .await - .expect("TODO") - .call(AddressBookRequest::GetBans) - .await - .expect("TODO") - else { - unreachable!(); - }; - - Ok(todo!()) - } -} diff --git a/binaries/cuprated/src/rpc/request/txpool.rs b/binaries/cuprated/src/rpc/request/txpool.rs index b6c16b31f..517661e9c 100644 --- a/binaries/cuprated/src/rpc/request/txpool.rs +++ b/binaries/cuprated/src/rpc/request/txpool.rs @@ -2,10 +2,12 @@ use std::{ collections::{HashMap, HashSet}, + convert::Infallible, sync::Arc, }; use anyhow::{anyhow, Error}; +use cuprate_database_service::DatabaseReadService; use futures::StreamExt; use monero_serai::block::Block; use tower::{Service, ServiceExt}; @@ -15,6 +17,10 @@ use cuprate_helper::{ cast::{u64_to_usize, usize_to_u64}, map::split_u128_into_low_high_bits, }; +use cuprate_txpool::service::{ + interface::{TxpoolReadRequest, TxpoolReadResponse}, + TxpoolReadHandle, +}; use cuprate_types::{ blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, @@ -22,4 +28,44 @@ use cuprate_types::{ use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; -impl CupratedRpcHandlerState {} +/// [`TxpoolReadRequest::Backlog`] +pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result, Error> { + let TxpoolReadResponse::Backlog(backlog) = txpool_read + .ready() + .await + .expect("TODO") + .call(TxpoolReadRequest::Backlog) + .await + .expect("TODO") + else { + unreachable!(); + }; + + Ok(backlog) +} + +/// [`TxpoolReadRequest::Size`] +pub(super) async fn size(txpool_read: &mut TxpoolReadHandle) -> Result { + let TxpoolReadResponse::Size(size) = txpool_read + .ready() + .await + .expect("TODO") + .call(TxpoolReadRequest::Size) + .await + .expect("TODO") + else { + unreachable!(); + }; + + Ok(usize_to_u64(size)) +} + +// [`::Flush`] +#[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(()) +} diff --git a/storage/txpool/src/service/interface.rs b/storage/txpool/src/service/interface.rs index 411b7844f..b3f4f75ca 100644 --- a/storage/txpool/src/service/interface.rs +++ b/storage/txpool/src/service/interface.rs @@ -12,19 +12,39 @@ use crate::types::TransactionHash; 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), + + /// TODO + Backlog, + + /// TODO + 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), - /// A response of [`TransactionVerificationData`]. + + /// Response to [`TxpoolReadRequest::TxVerificationData`]. TxVerificationData(TransactionVerificationData), + + /// Response to [`TxpoolReadRequest::Backlog`]. + /// + /// TODO + Backlog(Vec), + + /// Response to [`TxpoolReadRequest::Size`]. + /// + /// TODO + Size(usize), } //---------------------------------------------------------------------------------------------------- TxpoolWriteRequest @@ -42,6 +62,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`]. @@ -52,9 +73,12 @@ pub enum TxpoolWriteRequest { /// The transaction pool [`tower::Service`] write response type. #[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), - Ok, } diff --git a/storage/txpool/src/service/read.rs b/storage/txpool/src/service/read.rs index f0068130f..5e755298f 100644 --- a/storage/txpool/src/service/read.rs +++ b/storage/txpool/src/service/read.rs @@ -58,6 +58,7 @@ 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 | TxpoolReadRequest::Size => todo!(), } } From dfbdec3157f5300c399a9b24392321ef97ccb7d5 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Tue, 24 Sep 2024 18:27:46 -0400 Subject: [PATCH 04/23] add blockchain_context msgs --- binaries/cuprated/src/rpc/request.rs | 1 + .../src/rpc/request/blockchain_context.rs | 86 +++++++++++++++++++ consensus/fast-sync/src/fast_sync.rs | 2 +- consensus/src/block.rs | 6 +- consensus/src/block/batch_prepare.rs | 4 +- consensus/src/context.rs | 57 ++++++++++-- consensus/src/context/task.rs | 7 +- consensus/src/tests/context.rs | 7 +- 8 files changed, 153 insertions(+), 17 deletions(-) create mode 100644 binaries/cuprated/src/rpc/request/blockchain_context.rs diff --git a/binaries/cuprated/src/rpc/request.rs b/binaries/cuprated/src/rpc/request.rs index 6e59a8821..fa2dab0e4 100644 --- a/binaries/cuprated/src/rpc/request.rs +++ b/binaries/cuprated/src/rpc/request.rs @@ -14,5 +14,6 @@ mod address_book; mod blockchain; +mod blockchain_context; mod blockchain_manager; mod txpool; diff --git a/binaries/cuprated/src/rpc/request/blockchain_context.rs b/binaries/cuprated/src/rpc/request/blockchain_context.rs new file mode 100644 index 000000000..161006998 --- /dev/null +++ b/binaries/cuprated/src/rpc/request/blockchain_context.rs @@ -0,0 +1,86 @@ +//! Functions for [`BlockChainContextRequest`] and [`BlockChainContextResponse`]. + +use std::{ + collections::{HashMap, HashSet}, + convert::Infallible, + ops::Range, + sync::Arc, +}; + +use anyhow::{anyhow, Error}; +use futures::StreamExt; +use monero_serai::block::Block; +use randomx_rs::RandomXVM; +use tower::{Service, ServiceExt}; + +use cuprate_consensus::context::{ + BlockChainContext, BlockChainContextRequest, BlockChainContextResponse, + BlockChainContextService, +}; +use cuprate_helper::{ + cast::{u64_to_usize, usize_to_u64}, + map::split_u128_into_low_high_bits, +}; +use cuprate_types::{ + blockchain::{BlockchainReadRequest, BlockchainResponse, BlockchainWriteRequest}, + Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, +}; + +use crate::rpc::CupratedRpcHandlerState; + +/// [`BlockChainContextRequest::Context`]. +pub(super) async fn context( + service: &mut BlockChainContextService, + height: u64, +) -> Result { + 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 { + 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 { + let BlockChainContextResponse::FeeEstimate(hf_info) = service + .ready() + .await + .expect("TODO") + .call(BlockChainContextRequest::FeeEstimate { grace_blocks }) + .await + .expect("TODO") + else { + unreachable!(); + }; + + Ok(hf_info) +} diff --git a/consensus/fast-sync/src/fast_sync.rs b/consensus/fast-sync/src/fast_sync.rs index b4fc12b09..ec4ea297c 100644 --- a/consensus/fast-sync/src/fast_sync.rs +++ b/consensus/fast-sync/src/fast_sync.rs @@ -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!"); diff --git a/consensus/src/block.rs b/consensus/src/block.rs index 3d0db9955..0d1ba2f36 100644 --- a/consensus/src/block.rs +++ b/consensus/src/block.rs @@ -337,7 +337,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!"); @@ -360,7 +360,7 @@ where let BlockChainContextResponse::RxVms(rx_vms) = context_svc .ready() .await? - .call(BlockChainContextRequest::GetCurrentRxVm) + .call(BlockChainContextRequest::CurrentRxVm) .await? else { panic!("Blockchain context service returned wrong response!"); @@ -419,7 +419,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!"); diff --git a/consensus/src/block/batch_prepare.rs b/consensus/src/block/batch_prepare.rs index 9c778481b..123ec6cb5 100644 --- a/consensus/src/block/batch_prepare.rs +++ b/consensus/src/block/batch_prepare.rs @@ -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::CurrentRxVm) .await? else { panic!("Blockchain context service returned wrong response!"); diff --git a/consensus/src/context.rs b/consensus/src/context.rs index 5bdb1ce4b..7778e3098 100644 --- a/consensus/src/context.rs +++ b/consensus/src/context.rs @@ -221,15 +221,18 @@ pub struct NewBlockData { #[derive(Debug, Clone)] pub enum BlockChainContextRequest { /// Get the current blockchain context. - GetContext, + Context, + /// Gets the current `RandomX` VM. - GetCurrentRxVm, + CurrentRxVm, + /// 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)), + /// 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,10 @@ pub enum BlockChainContextRequest { /// This will panic if the number of blocks will pop the genesis block. numb_blocks: usize, }, + /// Clear the alt chain context caches. ClearAltCache, + //----------------------------------------------------------------------------------------------------------- AltChainRequests /// A request for an alt chain context cache. /// @@ -261,6 +268,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 +279,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 +290,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 +305,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 @@ -307,25 +318,61 @@ pub enum BlockChainContextRequest { /// An internal token to prevent external crates calling this request. _token: AltChainRequestToken, }, + + /// TODO + HardForkInfo(HardFork), + + /// TODO + FeeEstimate { + /// TODO + grace_blocks: u64, + } } 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), + + // TODO: why does this return a `HashMap` when the request is `CurrentRxVm`? + /// Response to [`BlockChainContextRequest::CurrentRxVm`] + /// /// A map of seed height to `RandomX` VMs. RxVms(HashMap>), + /// A list of difficulties. BatchDifficulties(Vec), + /// An alt chain context cache. AltChainContextCache(Box), + /// A difficulty cache for an alt chain. AltChainDifficultyCache(DifficultyCache), + /// A randomX VM for an alt chain. AltChainRxVM(Arc), + /// A weight cache for an alt chain AltChainWeightCache(BlockWeightsCache), - /// A generic Ok response. - Ok, + + /// Response to [`BlockChainContextRequest::HardForkInfo`] + /// + /// TODO + HardForkInfo(std::convert::Infallible /* TODO */), + + /// Response to [`BlockChainContextRequest::FeeEstimate`] + /// + /// TODO + FeeEstimate(std::convert::Infallible /* TODO */), } /// The blockchain context service. diff --git a/consensus/src/context/task.rs b/consensus/src/context/task.rs index 82b466c4b..75aff942a 100644 --- a/consensus/src/context/task.rs +++ b/consensus/src/context/task.rs @@ -153,7 +153,7 @@ impl ContextTask { req: BlockChainContextRequest, ) -> Result { 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 ContextTask { }, }) } - BlockChainContextRequest::GetCurrentRxVm => { + BlockChainContextRequest::CurrentRxVm => { BlockChainContextResponse::RxVms(self.rx_vm_cache.get_vms().await) } BlockChainContextRequest::BatchGetDifficulties(blocks) => { @@ -325,6 +325,9 @@ impl ContextTask { self.alt_chain_cache_map.add_alt_cache(prev_id, cache); BlockChainContextResponse::Ok } + BlockChainContextRequest::HardForkInfo(_) | BlockChainContextRequest::FeeEstimate { .. } => { + todo!() + } }) } diff --git a/consensus/src/tests/context.rs b/consensus/src/tests/context.rs index bbf7bb0d7..fdef0ac8d 100644 --- a/consensus/src/tests/context.rs +++ b/consensus/src/tests/context.rs @@ -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!") }; From e8cb951615c27d13ac62e5e61501a164d184bfc9 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Tue, 24 Sep 2024 20:39:08 -0400 Subject: [PATCH 05/23] add blockchain msgs --- .../cuprated/src/rpc/request/blockchain.rs | 657 +++++++++--------- .../src/rpc/request/blockchain_manager.rs | 29 +- storage/blockchain/src/service/read.rs | 6 + types/src/blockchain.rs | 49 ++ 4 files changed, 383 insertions(+), 358 deletions(-) diff --git a/binaries/cuprated/src/rpc/request/blockchain.rs b/binaries/cuprated/src/rpc/request/blockchain.rs index 8b3145fed..59a443fb2 100644 --- a/binaries/cuprated/src/rpc/request/blockchain.rs +++ b/binaries/cuprated/src/rpc/request/blockchain.rs @@ -7,6 +7,7 @@ use std::{ }; use anyhow::{anyhow, Error}; +use cuprate_blockchain::service::BlockchainReadHandle; use futures::StreamExt; use monero_serai::block::Block; use tower::{Service, ServiceExt}; @@ -22,344 +23,320 @@ use cuprate_types::{ use crate::rpc::CupratedRpcHandlerState; -impl CupratedRpcHandlerState { - /// [`BlockchainReadRequest::BlockExtendedHeader`]. - pub(super) async fn block_extended_header( - &mut self, - height: u64, - ) -> Result { - let BlockchainResponse::BlockExtendedHeader(header) = self - .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 self, - height: u64, - chain: Chain, - ) -> Result<[u8; 32], Error> { - let BlockchainResponse::BlockHash(hash) = self - .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 self, - block_hash: [u8; 32], - ) -> Result, Error> { - let BlockchainResponse::FindBlock(option) = self - .blockchain_read - .ready() - .await? - .call(BlockchainReadRequest::FindBlock(block_hash)) - .await? - else { - unreachable!(); - }; - - Ok(option) - } - - /// [`BlockchainReadRequest::FilterUnknownHashes`]. - pub(super) async fn filter_unknown_hashes( - &mut self, - block_hashes: HashSet<[u8; 32]>, - ) -> Result, Error> { - let BlockchainResponse::FilterUnknownHashes(output) = self - .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 self, - range: Range, - chain: Chain, - ) -> Result, Error> { - let BlockchainResponse::BlockExtendedHeaderInRange(output) = self - .blockchain_read - .ready() - .await? - .call(BlockchainReadRequest::BlockExtendedHeaderInRange( - range, chain, - )) - .await? - else { - unreachable!(); - }; - - Ok(output) - } - - /// [`BlockchainReadRequest::ChainHeight`]. - pub(super) async fn chain_height(&mut self) -> Result<(u64, [u8; 32]), Error> { - let BlockchainResponse::ChainHeight(height, hash) = self - .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 self, block_height: u64) -> Result { - let BlockchainResponse::GeneratedCoins(generated_coins) = self - .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 self, - outputs: HashMap>, - ) -> Result>, Error> { - let BlockchainResponse::Outputs(outputs) = self - .blockchain_read - .ready() - .await? - .call(BlockchainReadRequest::Outputs(outputs)) - .await? - else { - unreachable!(); - }; - - Ok(outputs) - } - - /// [`BlockchainReadRequest::NumberOutputsWithAmount`] - pub(super) async fn number_outputs_with_amount( - &mut self, - output_amounts: Vec, - ) -> Result, Error> { - let BlockchainResponse::NumberOutputsWithAmount(map) = self - .blockchain_read - .ready() - .await? - .call(BlockchainReadRequest::NumberOutputsWithAmount( - output_amounts, - )) - .await? - else { - unreachable!(); - }; - - Ok(map) - } - - /// [`BlockchainReadRequest::KeyImagesSpent`] - pub(super) async fn key_images_spent( - &mut self, - key_images: HashSet<[u8; 32]>, - ) -> Result { - let BlockchainResponse::KeyImagesSpent(is_spent) = self - .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 self) -> Result<(Vec<[u8; 32]>, u128), Error> { - let BlockchainResponse::CompactChainHistory { - block_ids, - cumulative_difficulty, - } = self - .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 self, - hashes: Vec<[u8; 32]>, - ) -> Result, Error> { - let BlockchainResponse::FindFirstUnknown(resp) = self - .blockchain_read - .ready() - .await? - .call(BlockchainReadRequest::FindFirstUnknown(hashes)) - .await? - else { - unreachable!(); - }; - - Ok(resp.map(|(index, height)| (index, usize_to_u64(height)))) - } - - //------------------------------------------------------------------------------------------ new - - // /// [`BlockchainReadRequest::Block`]. - // pub(super) async fn block(&mut self, height: u64) -> Result { - // let BlockchainResponse::Block(block) = self - // - // .blockchain_read - // .ready() - // .await? - // .call(BlockchainReadRequest::Block(u64_to_usize(height))) - // .await? - // else { - // unreachable!(); - // }; - - // Ok(block) - // } - - // /// [`BlockchainReadRequest::BlockByHash`]. - // pub(super) async fn block_by_hash(&mut self, hash: [u8; 32]) -> Result { - // let BlockchainResponse::BlockByHash(block) = self - // - // .blockchain_read - // .ready() - // .await? - // .call(BlockchainReadRequest::BlockByHash(hash)) - // .await? - // else { - // unreachable!(); - // }; - - // Ok(block) - // } - - // /// [`BlockchainReadRequest::BlockExtendedHeaderByHash`]. - // pub(super) async fn block_extended_header_by_hash( - // &mut self, - // hash: [u8; 32], - // ) -> Result { - // let BlockchainResponse::BlockExtendedHeaderByHash(header) = self - // - // .blockchain_read - // .ready() - // .await? - // .call(BlockchainReadRequest::BlockExtendedHeaderByHash(hash)) - // .await? - // else { - // unreachable!(); - // }; - - // Ok(header) - // } - - // /// [`BlockchainReadRequest::TopBlockFull`]. - // pub(super) async fn top_block_full(&mut self) -> Result<(Block, ExtendedBlockHeader), Error> { - // let BlockchainResponse::TopBlockFull(block, header) = self - // - // .blockchain_read - // .ready() - // .await? - // .call(BlockchainReadRequest::TopBlockFull) - // .await? - // else { - // unreachable!(); - // }; - - // Ok((block, header)) - // } - - // /// [`BlockchainReadRequest::CurrentHardFork`] - // pub(super) async fn current_hard_fork(&mut self) -> Result { - // let BlockchainResponse::CurrentHardFork(hard_fork) = self - // - // .blockchain_read - // .ready() - // .await? - // .call(BlockchainReadRequest::CurrentHardFork) - // .await? - // else { - // unreachable!(); - // }; - - // Ok(hard_fork) - // } - - // /// [`BlockchainReadRequest::PopBlocks`] - // pub(super) async fn pop_blocks(&mut self, nblocks: u64) -> Result { - // let BlockchainResponse::PopBlocks(height) = self - // - // .blockchain_write - // .ready() - // .await? - // .call(BlockchainWriteRequest::PopBlocks(nblocks)) - // .await? - // else { - // unreachable!(); - // }; - - // Ok(usize_to_u64(height)) - // } - - // /// [`BlockchainReadRequest::CumulativeBlockWeightLimit`] - // pub(super) async fn cumulative_block_weight_limit(&mut self) -> Result { - // let BlockchainResponse::CumulativeBlockWeightLimit(limit) = self - // - // .blockchain_read - // .ready() - // .await? - // .call(BlockchainReadRequest::CumulativeBlockWeightLimit) - // .await? - // else { - // unreachable!(); - // }; - - // Ok(limit) - // } +/// [`BlockchainReadRequest::BlockExtendedHeader`]. +pub(super) async fn block_extended_header( + mut blockchain_read: BlockchainReadHandle, + height: u64, +) -> Result { + 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, 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, 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, + chain: Chain, +) -> Result, 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 { + 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>, +) -> Result>, 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, +) -> Result, 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 { + 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, 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 { + 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::Difficulty`] +pub(super) async fn difficulty( + mut blockchain_read: BlockchainReadHandle, + block_height: u64, +) -> Result { + let BlockchainResponse::Difficulty(difficulty) = blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::Difficulty(u64_to_usize( + block_height, + ))) + .await? + else { + unreachable!(); + }; + + Ok(difficulty) +} + +/// [`BlockchainReadRequest::OutputHistogram`] +pub(super) async fn output_histogram( + mut blockchain_read: BlockchainReadHandle, +) -> Result<(), Error> { + let BlockchainResponse::OutputHistogram(_) = blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::OutputHistogram) + .await? + else { + unreachable!(); + }; + + Ok(todo!()) +} + +/// [`BlockchainReadRequest::CoinbaseTxSum`] +pub(super) async fn coinbase_tx_sum( + mut blockchain_read: BlockchainReadHandle, +) -> Result<(), Error> { + let BlockchainResponse::CoinbaseTxSum(_) = blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::CoinbaseTxSum) + .await? + else { + unreachable!(); + }; + + Ok(todo!()) +} + +/// [`BlockchainReadRequest::MinerData`] +pub(super) async fn miner_data(mut blockchain_read: BlockchainReadHandle) -> Result<(), Error> { + let BlockchainResponse::MinerData(_) = blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::MinerData) + .await? + else { + unreachable!(); + }; + + Ok(todo!()) } diff --git a/binaries/cuprated/src/rpc/request/blockchain_manager.rs b/binaries/cuprated/src/rpc/request/blockchain_manager.rs index 861c21ceb..cafa9afe0 100644 --- a/binaries/cuprated/src/rpc/request/blockchain_manager.rs +++ b/binaries/cuprated/src/rpc/request/blockchain_manager.rs @@ -22,24 +22,17 @@ use cuprate_types::{ use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; -#[expect( - unreachable_code, - clippy::needless_pass_by_ref_mut, - reason = "TODO: remove after impl" -)] -impl CupratedRpcHandlerState { - /// TODO: doc enum message - pub(super) async fn pop_blocks(&mut self) -> Result<(u64, [u8; 32]), Error> { - Ok(todo!()) - } +/// TODO: doc enum message +pub(super) async fn pop_blocks() -> Result<(u64, [u8; 32]), Error> { + Ok(todo!()) +} - /// TODO: doc enum message - pub(super) async fn prune(&mut self) -> Result<(), Error> { - Ok(todo!()) - } +/// TODO: doc enum message +pub(super) async fn prune() -> Result<(), Error> { + Ok(todo!()) +} - /// TODO: doc enum message - pub(super) async fn pruned(&mut self) -> Result { - Ok(todo!()) - } +/// TODO: doc enum message +pub(super) async fn pruned() -> Result { + Ok(todo!()) } diff --git a/storage/blockchain/src/service/read.rs b/storage/blockchain/src/service/read.rs index b0e7e044c..1dd02d115 100644 --- a/storage/blockchain/src/service/read.rs +++ b/storage/blockchain/src/service/read.rs @@ -107,6 +107,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::TotalTxCount + | R::DatabaseSize + | R::Difficulty(_) + | R::OutputHistogram + | R::CoinbaseTxSum + | R::MinerData => todo!(), } /* SOMEDAY: post-request handling, run some code for each request? */ diff --git a/types/src/blockchain.rs b/types/src/blockchain.rs index f2b96db00..3d87d8837 100644 --- a/types/src/blockchain.rs +++ b/types/src/blockchain.rs @@ -103,6 +103,24 @@ pub enum BlockchainReadRequest { /// A request for all alt blocks in the chain with the given [`ChainId`]. AltBlocksInChain(ChainId), + + /// TODO + TotalTxCount, + + /// TODO + DatabaseSize, + + // TODO + Difficulty(usize), + + /// TODO + OutputHistogram, + + /// TODO + CoinbaseTxSum, + + /// TODO + MinerData, } //---------------------------------------------------------------------------------------------------- WriteRequest @@ -227,6 +245,36 @@ pub enum BlockchainResponse { /// Contains all the alt blocks in the alt-chain in chronological order. AltBlocksInChain(Vec), + /// The response for [`BlockchainReadRequest::TotalTxCount`]. + /// + /// TODO + TotalTxCount(usize), + + /// The response for [`BlockchainReadRequest::TotalTxCount`]. + /// + /// TODO + DatabaseSize { database_size: u64, free_space: u64 }, + + /// The response for [`BlockchainReadRequest::TotalTxCount`]. + /// + // TODO + Difficulty(u128), + + /// The response for [`BlockchainReadRequest::TotalTxCount`]. + /// + /// TODO + OutputHistogram(std::convert::Infallible), + + /// The response for [`BlockchainReadRequest::TotalTxCount`]. + /// + /// TODO + CoinbaseTxSum(std::convert::Infallible), + + /// The response for [`BlockchainReadRequest::TotalTxCount`]. + /// + /// TODO + MinerData(std::convert::Infallible), + //------------------------------------------------------ Writes /// A generic Ok response to indicate a request was successfully handled. /// @@ -236,6 +284,7 @@ pub enum BlockchainResponse { /// - [`BlockchainWriteRequest::ReverseReorg`] /// - [`BlockchainWriteRequest::FlushAltBlocks`] Ok, + /// The response for [`BlockchainWriteRequest::PopBlocks`]. /// /// The inner value is the alt-chain ID for the old main chain blocks. From e618bb7a9e4435863785ceda6f65fc1e3c65eb9b Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Tue, 24 Sep 2024 20:39:25 -0400 Subject: [PATCH 06/23] fmt --- consensus/src/context.rs | 2 +- consensus/src/context/task.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/consensus/src/context.rs b/consensus/src/context.rs index 7778e3098..0d6428ca3 100644 --- a/consensus/src/context.rs +++ b/consensus/src/context.rs @@ -326,7 +326,7 @@ pub enum BlockChainContextRequest { FeeEstimate { /// TODO grace_blocks: u64, - } + }, } pub enum BlockChainContextResponse { diff --git a/consensus/src/context/task.rs b/consensus/src/context/task.rs index 75aff942a..74142c526 100644 --- a/consensus/src/context/task.rs +++ b/consensus/src/context/task.rs @@ -325,7 +325,8 @@ impl ContextTask { self.alt_chain_cache_map.add_alt_cache(prev_id, cache); BlockChainContextResponse::Ok } - BlockChainContextRequest::HardForkInfo(_) | BlockChainContextRequest::FeeEstimate { .. } => { + BlockChainContextRequest::HardForkInfo(_) + | BlockChainContextRequest::FeeEstimate { .. } => { todo!() } }) From a1b3bdabef3823e5c5cc8c3d442d3f4cd5c143e3 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Wed, 25 Sep 2024 15:47:32 -0400 Subject: [PATCH 07/23] blockchain_manager msgs --- .../src/rpc/request/blockchain_manager.rs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/binaries/cuprated/src/rpc/request/blockchain_manager.rs b/binaries/cuprated/src/rpc/request/blockchain_manager.rs index cafa9afe0..652855bc9 100644 --- a/binaries/cuprated/src/rpc/request/blockchain_manager.rs +++ b/binaries/cuprated/src/rpc/request/blockchain_manager.rs @@ -36,3 +36,28 @@ pub(super) async fn prune() -> Result<(), Error> { pub(super) async fn pruned() -> Result { Ok(todo!()) } + +/// TODO: doc enum message +pub(super) async fn relay_block() -> Result { + Ok(todo!()) +} + +/// TODO: doc enum message +pub(super) async fn syncing() -> Result { + Ok(todo!()) +} + +/// TODO: doc enum message +pub(super) async fn synced() -> Result { + Ok(todo!()) +} + +/// TODO: doc enum message +pub(super) async fn target() -> Result { + Ok(todo!()) +} + +/// TODO: doc enum message +pub(super) async fn target_height() -> Result { + Ok(todo!()) +} From cf3095446e0058e60c6ea81c12b126a6a20f09dd Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Thu, 26 Sep 2024 20:14:48 -0400 Subject: [PATCH 08/23] blockchain manager msg types --- binaries/cuprated/src/rpc/handler.rs | 85 +++++++++- .../cuprated/src/rpc/request/address_book.rs | 26 +-- .../cuprated/src/rpc/request/blockchain.rs | 16 +- .../src/rpc/request/blockchain_context.rs | 23 +-- .../src/rpc/request/blockchain_manager.rs | 156 +++++++++++++----- binaries/cuprated/src/rpc/request/txpool.rs | 23 +-- 6 files changed, 212 insertions(+), 117 deletions(-) diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 7c8c7eb58..b021dcb55 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -3,13 +3,11 @@ 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, BlockchainWriteHandle}; -use cuprate_helper::asynch::InfallibleOneshotReceiver; -use cuprate_json_rpc::Id; use cuprate_rpc_interface::RpcHandler; use cuprate_rpc_types::{ bin::{BinRequest, BinResponse}, @@ -20,6 +18,82 @@ 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 { + /// Input is the amount of blocks to pop. + PopBlocks { amount: usize }, + + /// TODO + Prune, + + /// TODO + Pruned, + + /// TODO + RelayBlock(Block), + + /// TODO + Syncing, + + /// TODO + Synced, + + /// TODO + Target, + + /// TODO + TargetHeight, +} + +/// TODO: use real type when public. +#[derive(Clone)] +pub enum BlockchainManagerResponse { + /// TODO + /// + /// Response to: + /// - [`BlockchainManagerRequest::Prune`] + /// - [`BlockchainManagerRequest::RelayBlock`] + Ok, + + /// Response to [`BlockchainManagerRequest::PopBlocks`] + /// + /// TODO + PopBlocks { new_height: usize }, + + /// Response to [`BlockchainManagerRequest::Pruned`] + /// + /// TODO + Pruned(bool), + + /// Response to [`BlockchainManagerRequest::Syncing`] + /// + /// TODO + Syncing(bool), + + /// Response to [`BlockchainManagerRequest::Synced`] + /// + /// TODO + Synced(bool), + + /// Response to [`BlockchainManagerRequest::Target`] + /// + /// TODO + Target { height: usize }, + + /// Response to [`BlockchainManagerRequest::TargetHeight`] + /// + /// TODO + TargetHeight { height: usize }, +} + +/// TODO: use real type when public. +pub type BlockchainManagerHandle = cuprate_database_service::DatabaseReadService< + BlockchainManagerRequest, + BlockchainManagerResponse, +>; + /// TODO #[derive(Clone)] pub struct CupratedRpcHandler { @@ -43,6 +117,9 @@ pub struct CupratedRpcHandlerState { /// Write handle to the blockchain database. pub blockchain_write: BlockchainWriteHandle, + /// Handle to the blockchain manager. + pub blockchain_manager: BlockchainManagerHandle, + /// Read handle to the transaction pool database. pub txpool_read: TxpoolReadHandle, diff --git a/binaries/cuprated/src/rpc/request/address_book.rs b/binaries/cuprated/src/rpc/request/address_book.rs index 78ed5fb45..d939dd47f 100644 --- a/binaries/cuprated/src/rpc/request/address_book.rs +++ b/binaries/cuprated/src/rpc/request/address_book.rs @@ -1,31 +1,15 @@ //! Functions for TODO: doc enum message. -use std::{ - collections::{HashMap, HashSet}, - convert::Infallible, - sync::Arc, -}; +use std::convert::Infallible; -use anyhow::{anyhow, Error}; -use futures::StreamExt; -use monero_serai::block::Block; -use tower::{Service, ServiceExt}; +use anyhow::Error; +use tower::ServiceExt; -use cuprate_helper::{ - cast::{u64_to_usize, usize_to_u64}, - map::split_u128_into_low_high_bits, -}; +use cuprate_helper::cast::usize_to_u64; use cuprate_p2p_core::{ - client::handshaker::builder::DummyAddressBook, services::{AddressBookRequest, AddressBookResponse}, - AddressBook, ClearNet, NetworkZone, + AddressBook, NetworkZone, }; -use cuprate_types::{ - blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, - Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, -}; - -use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; /// [`AddressBookRequest::PeerlistSize`] pub(super) async fn peerlist_size( diff --git a/binaries/cuprated/src/rpc/request/blockchain.rs b/binaries/cuprated/src/rpc/request/blockchain.rs index 59a443fb2..7bc601262 100644 --- a/binaries/cuprated/src/rpc/request/blockchain.rs +++ b/binaries/cuprated/src/rpc/request/blockchain.rs @@ -3,26 +3,18 @@ use std::{ collections::{HashMap, HashSet}, ops::Range, - sync::Arc, }; -use anyhow::{anyhow, Error}; +use anyhow::Error; use cuprate_blockchain::service::BlockchainReadHandle; -use futures::StreamExt; -use monero_serai::block::Block; use tower::{Service, ServiceExt}; -use cuprate_helper::{ - cast::{u64_to_usize, usize_to_u64}, - map::split_u128_into_low_high_bits, -}; +use cuprate_helper::cast::{u64_to_usize, usize_to_u64}; use cuprate_types::{ - blockchain::{BlockchainReadRequest, BlockchainResponse, BlockchainWriteRequest}, - Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, + blockchain::{BlockchainReadRequest, BlockchainResponse}, + Chain, ExtendedBlockHeader, OutputOnChain, }; -use crate::rpc::CupratedRpcHandlerState; - /// [`BlockchainReadRequest::BlockExtendedHeader`]. pub(super) async fn block_extended_header( mut blockchain_read: BlockchainReadHandle, diff --git a/binaries/cuprated/src/rpc/request/blockchain_context.rs b/binaries/cuprated/src/rpc/request/blockchain_context.rs index 161006998..1cf69d601 100644 --- a/binaries/cuprated/src/rpc/request/blockchain_context.rs +++ b/binaries/cuprated/src/rpc/request/blockchain_context.rs @@ -1,32 +1,15 @@ //! Functions for [`BlockChainContextRequest`] and [`BlockChainContextResponse`]. -use std::{ - collections::{HashMap, HashSet}, - convert::Infallible, - ops::Range, - sync::Arc, -}; +use std::convert::Infallible; -use anyhow::{anyhow, Error}; -use futures::StreamExt; -use monero_serai::block::Block; -use randomx_rs::RandomXVM; +use anyhow::Error; use tower::{Service, ServiceExt}; use cuprate_consensus::context::{ BlockChainContext, BlockChainContextRequest, BlockChainContextResponse, BlockChainContextService, }; -use cuprate_helper::{ - cast::{u64_to_usize, usize_to_u64}, - map::split_u128_into_low_high_bits, -}; -use cuprate_types::{ - blockchain::{BlockchainReadRequest, BlockchainResponse, BlockchainWriteRequest}, - Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, -}; - -use crate::rpc::CupratedRpcHandlerState; +use cuprate_types::HardFork; /// [`BlockChainContextRequest::Context`]. pub(super) async fn context( diff --git a/binaries/cuprated/src/rpc/request/blockchain_manager.rs b/binaries/cuprated/src/rpc/request/blockchain_manager.rs index 652855bc9..c254b5a6d 100644 --- a/binaries/cuprated/src/rpc/request/blockchain_manager.rs +++ b/binaries/cuprated/src/rpc/request/blockchain_manager.rs @@ -1,63 +1,139 @@ //! Functions for TODO: doc enum message. -use std::{ - collections::{HashMap, HashSet}, - sync::Arc, -}; - -use anyhow::{anyhow, Error}; -use futures::StreamExt; +use anyhow::Error; use monero_serai::block::Block; use tower::{Service, ServiceExt}; -use cuprate_consensus::BlockchainResponse; -use cuprate_helper::{ - cast::{u64_to_usize, usize_to_u64}, - map::split_u128_into_low_high_bits, -}; -use cuprate_types::{ - blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, - Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, +use cuprate_helper::cast::{u64_to_usize, usize_to_u64}; + +use crate::rpc::handler::{ + BlockchainManagerHandle, BlockchainManagerRequest, BlockchainManagerResponse, }; -use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; +/// [`BlockchainManagerResponse::PopBlocks`] +pub(super) async fn pop_blocks( + blockchain_manager: &mut BlockchainManagerHandle, + amount: u64, +) -> Result { + let BlockchainManagerResponse::PopBlocks { new_height } = blockchain_manager + .ready() + .await? + .call(BlockchainManagerRequest::PopBlocks { + amount: u64_to_usize(amount), + }) + .await? + else { + unreachable!(); + }; -/// TODO: doc enum message -pub(super) async fn pop_blocks() -> Result<(u64, [u8; 32]), Error> { - Ok(todo!()) + Ok(usize_to_u64(new_height)) } -/// TODO: doc enum message -pub(super) async fn prune() -> Result<(), Error> { - Ok(todo!()) +/// [`BlockchainManagerResponse::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(()) } -/// TODO: doc enum message -pub(super) async fn pruned() -> Result { - Ok(todo!()) +/// [`BlockchainManagerResponse::Pruned`] +pub(super) async fn pruned( + blockchain_manager: &mut BlockchainManagerHandle, +) -> Result { + let BlockchainManagerResponse::Pruned(pruned) = blockchain_manager + .ready() + .await? + .call(BlockchainManagerRequest::Pruned) + .await? + else { + unreachable!(); + }; + + Ok(pruned) } -/// TODO: doc enum message -pub(super) async fn relay_block() -> Result { - Ok(todo!()) +/// [`BlockchainManagerResponse::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(()) } -/// TODO: doc enum message -pub(super) async fn syncing() -> Result { - Ok(todo!()) +/// [`BlockchainManagerResponse::Syncing`] +pub(super) async fn syncing( + blockchain_manager: &mut BlockchainManagerHandle, +) -> Result { + let BlockchainManagerResponse::Syncing(syncing) = blockchain_manager + .ready() + .await? + .call(BlockchainManagerRequest::Syncing) + .await? + else { + unreachable!(); + }; + + Ok(syncing) } -/// TODO: doc enum message -pub(super) async fn synced() -> Result { - Ok(todo!()) +/// [`BlockchainManagerResponse::Synced`] +pub(super) async fn synced( + blockchain_manager: &mut BlockchainManagerHandle, +) -> Result { + let BlockchainManagerResponse::Synced(syncing) = blockchain_manager + .ready() + .await? + .call(BlockchainManagerRequest::Synced) + .await? + else { + unreachable!(); + }; + + Ok(syncing) } -/// TODO: doc enum message -pub(super) async fn target() -> Result { - Ok(todo!()) +/// [`BlockchainManagerResponse::Target`] +pub(super) async fn target(blockchain_manager: &mut BlockchainManagerHandle) -> Result { + let BlockchainManagerResponse::Target { height } = blockchain_manager + .ready() + .await? + .call(BlockchainManagerRequest::Target) + .await? + else { + unreachable!(); + }; + + Ok(usize_to_u64(height)) } -/// TODO: doc enum message -pub(super) async fn target_height() -> Result { - Ok(todo!()) +/// [`BlockchainManagerResponse::TargetHeight`] +pub(super) async fn target_height( + blockchain_manager: &mut BlockchainManagerHandle, +) -> Result { + let BlockchainManagerResponse::TargetHeight { height } = blockchain_manager + .ready() + .await? + .call(BlockchainManagerRequest::TargetHeight) + .await? + else { + unreachable!(); + }; + + Ok(usize_to_u64(height)) } diff --git a/binaries/cuprated/src/rpc/request/txpool.rs b/binaries/cuprated/src/rpc/request/txpool.rs index 517661e9c..71fa834c7 100644 --- a/binaries/cuprated/src/rpc/request/txpool.rs +++ b/binaries/cuprated/src/rpc/request/txpool.rs @@ -1,32 +1,15 @@ //! Functions for TODO: doc enum message. -use std::{ - collections::{HashMap, HashSet}, - convert::Infallible, - sync::Arc, -}; +use std::convert::Infallible; -use anyhow::{anyhow, Error}; -use cuprate_database_service::DatabaseReadService; -use futures::StreamExt; -use monero_serai::block::Block; +use anyhow::Error; use tower::{Service, ServiceExt}; -use cuprate_consensus::BlockchainResponse; -use cuprate_helper::{ - cast::{u64_to_usize, usize_to_u64}, - map::split_u128_into_low_high_bits, -}; +use cuprate_helper::cast::usize_to_u64; use cuprate_txpool::service::{ interface::{TxpoolReadRequest, TxpoolReadResponse}, TxpoolReadHandle, }; -use cuprate_types::{ - blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, - Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, -}; - -use crate::rpc::{CupratedRpcHandler, CupratedRpcHandlerState}; /// [`TxpoolReadRequest::Backlog`] pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result, Error> { From 02a99f3bb9e4c12586f795d6f59f32e62932a4f8 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Thu, 26 Sep 2024 20:36:52 -0400 Subject: [PATCH 09/23] add DB fn signatures --- consensus/src/context/task.rs | 2 +- p2p/address-book/src/book.rs | 2 +- .../src/client/handshaker/builder/dummy.rs | 2 +- storage/blockchain/src/service/read.rs | 64 +++++++++++++++++-- storage/txpool/src/service/read.rs | 22 ++++++- types/src/blockchain.rs | 16 +++++ 6 files changed, 98 insertions(+), 10 deletions(-) diff --git a/consensus/src/context/task.rs b/consensus/src/context/task.rs index 74142c526..f65fdcbb8 100644 --- a/consensus/src/context/task.rs +++ b/consensus/src/context/task.rs @@ -327,7 +327,7 @@ impl ContextTask { } BlockChainContextRequest::HardForkInfo(_) | BlockChainContextRequest::FeeEstimate { .. } => { - todo!() + todo!("finish https://github.com/Cuprate/cuprate/pull/297") } }) } diff --git a/p2p/address-book/src/book.rs b/p2p/address-book/src/book.rs index b21b45ea9..6117b6eda 100644 --- a/p2p/address-book/src/book.rs +++ b/p2p/address-book/src/book.rs @@ -415,7 +415,7 @@ impl Service> for AddressBook { | AddressBookRequest::ConnectionCount | AddressBookRequest::SetBan(_) | AddressBookRequest::GetBan(_) - | AddressBookRequest::GetBans => todo!(), + | AddressBookRequest::GetBans => todo!("finish https://github.com/Cuprate/cuprate/pull/297"), }; ready(response) diff --git a/p2p/p2p-core/src/client/handshaker/builder/dummy.rs b/p2p/p2p-core/src/client/handshaker/builder/dummy.rs index 51f8af3c0..c75446594 100644 --- a/p2p/p2p-core/src/client/handshaker/builder/dummy.rs +++ b/p2p/p2p-core/src/client/handshaker/builder/dummy.rs @@ -132,7 +132,7 @@ impl Service> for DummyAddressBook { | AddressBookRequest::ConnectionCount | AddressBookRequest::SetBan(_) | AddressBookRequest::GetBan(_) - | AddressBookRequest::GetBans => todo!(), + | AddressBookRequest::GetBans => todo!("finish https://github.com/Cuprate/cuprate/pull/297"), })) } } diff --git a/storage/blockchain/src/service/read.rs b/storage/blockchain/src/service/read.rs index 1dd02d115..bed2cf2c3 100644 --- a/storage/blockchain/src/service/read.rs +++ b/storage/blockchain/src/service/read.rs @@ -1,5 +1,12 @@ //! Database reader thread-pool definitions and logic. +#![expect( + unreachable_code, + unused_variables, + clippy::unnecessary_wraps, + reason = "TODO: finish implementing the signatures from " +)] + //---------------------------------------------------------------------------------------------------- Import use std::{ collections::{HashMap, HashSet}, @@ -107,12 +114,14 @@ 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::TotalTxCount - | R::DatabaseSize - | R::Difficulty(_) - | R::OutputHistogram - | R::CoinbaseTxSum - | R::MinerData => todo!(), + 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::Difficulty(height) => difficulty(env, height), + R::OutputHistogram => output_histogram(env), + R::CoinbaseTxSum => coinbase_tx_sum(env), + R::MinerData => miner_data(env), } /* SOMEDAY: post-request handling, run some code for each request? */ @@ -607,3 +616,46 @@ 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::Difficulty()`] +fn difficulty(env: &ConcreteEnv, block_height: BlockHeight) -> ResponseResult { + Ok(BlockchainResponse::Difficulty(todo!())) +} + +/// [`BlockchainReadRequest::OutputHistogram`] +fn output_histogram(env: &ConcreteEnv) -> ResponseResult { + Ok(BlockchainResponse::OutputHistogram(todo!())) +} + +/// [`BlockchainReadRequest::CoinbaseTxSum`] +fn coinbase_tx_sum(env: &ConcreteEnv) -> ResponseResult { + Ok(BlockchainResponse::CoinbaseTxSum(todo!())) +} + +/// [`BlockchainReadRequest::MinerData`] +fn miner_data(env: &ConcreteEnv) -> ResponseResult { + Ok(BlockchainResponse::MinerData(todo!())) +} diff --git a/storage/txpool/src/service/read.rs b/storage/txpool/src/service/read.rs index 5e755298f..3135322e3 100644 --- a/storage/txpool/src/service/read.rs +++ b/storage/txpool/src/service/read.rs @@ -1,3 +1,10 @@ +#![expect( + unreachable_code, + unused_variables, + clippy::unnecessary_wraps, + reason = "TODO: finish implementing the signatures from " +)] + use std::sync::Arc; use rayon::ThreadPool; @@ -58,7 +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 | TxpoolReadRequest::Size => todo!(), + TxpoolReadRequest::Backlog => backlog(env), + TxpoolReadRequest::Size => size(env), } } @@ -102,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!())) +} diff --git a/types/src/blockchain.rs b/types/src/blockchain.rs index 3d87d8837..7126c2140 100644 --- a/types/src/blockchain.rs +++ b/types/src/blockchain.rs @@ -8,6 +8,8 @@ use std::{ ops::Range, }; +use monero_serai::block::Block; + use crate::{ types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation}, AltBlockInformation, ChainId, @@ -104,6 +106,12 @@ pub enum BlockchainReadRequest { /// A request for all alt blocks in the chain with the given [`ChainId`]. AltBlocksInChain(ChainId), + /// TODO + Block(usize), + + /// TODO + BlockByHash([u8; 32]), + /// TODO TotalTxCount, @@ -165,6 +173,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`]. @@ -245,6 +254,13 @@ pub enum BlockchainResponse { /// Contains all the alt blocks in the alt-chain in chronological order. AltBlocksInChain(Vec), + /// The response for: + /// - [`BlockchainReadRequest::Block`]. + /// - [`BlockchainReadRequest::BlockByHash`]. + /// + /// TODO + Block(Block), + /// The response for [`BlockchainReadRequest::TotalTxCount`]. /// /// TODO From 6878a25266217ef57eeac914ca4e39ffdff71a6b Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Thu, 26 Sep 2024 20:41:42 -0400 Subject: [PATCH 10/23] add statics module --- binaries/cuprated/src/main.rs | 7 +++++- binaries/cuprated/src/statics.rs | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 binaries/cuprated/src/statics.rs diff --git a/binaries/cuprated/src/main.rs b/binaries/cuprated/src/main.rs index 76eb85e8d..7ac490523 100644 --- a/binaries/cuprated/src/main.rs +++ b/binaries/cuprated/src/main.rs @@ -15,8 +15,13 @@ mod blockchain; mod config; mod p2p; mod rpc; +mod statics; mod txpool; fn main() { - todo!() + // Initialize global static `LazyLock` data. + statics::init_lazylock_statics(); + + // TODO: do other stuff + todo!(); } diff --git a/binaries/cuprated/src/statics.rs b/binaries/cuprated/src/statics.rs new file mode 100644 index 000000000..b8e4386a3 --- /dev/null +++ b/binaries/cuprated/src/statics.rs @@ -0,0 +1,43 @@ +//! Global `static`s used throughout `cuprated`. + +use std::{ + sync::{atomic::AtomicU64, LazyLock}, + time::{SystemTime, UNIX_EPOCH}, +}; + +/// Define all the `static`s in the file/module. +/// +/// This wraps all `static`s inside a `LazyLock` and generates +/// a [`init_lazylock_statics`] function that must/should be +/// used by `main()` early on. +macro_rules! define_lazylock_statics { + ($( + $( #[$attr:meta] )* + $name:ident: $t:ty = $init_fn:expr; + )*) => { + /// Initialize global static `LazyLock` data. + pub fn init_lazylock_statics() { + $( + LazyLock::force(&$name); + )* + } + + $( + $(#[$attr])* + pub static $name: LazyLock<$t> = LazyLock::new(|| $init_fn); + )* + }; +} + +define_lazylock_statics! { + /// The start time of `cuprated`. + /// + /// This must/should be set early on in `main()`. + START_INSTANT: SystemTime = SystemTime::now(); + + /// Start time of `cuprated` as a UNIX timestamp. + START_INSTANT_UNIX: u64 = START_INSTANT + .duration_since(UNIX_EPOCH) + .expect("Failed to set `cuprated` startup time.") + .as_secs(); +} From f9ff59345c362f3fe4a45abc4cd29f7f653043f9 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Tue, 1 Oct 2024 21:03:56 -0400 Subject: [PATCH 11/23] p2p msg changes, docs --- binaries/cuprated/src/main.rs | 1 + binaries/cuprated/src/rpc.rs | 2 +- binaries/cuprated/src/rpc/bin.rs | 18 ++--- binaries/cuprated/src/rpc/handler.rs | 80 ++++++++++--------- binaries/cuprated/src/rpc/json.rs | 64 +++++++-------- binaries/cuprated/src/rpc/other.rs | 58 +++++++------- binaries/cuprated/src/rpc/request.rs | 4 +- .../cuprated/src/rpc/request/address_book.rs | 10 +-- .../cuprated/src/rpc/request/blockchain.rs | 2 +- .../src/rpc/request/blockchain_manager.rs | 24 +++--- binaries/cuprated/src/rpc/request/txpool.rs | 2 +- p2p/address-book/src/book.rs | 20 +++-- p2p/p2p-core/src/ban.rs | 19 +++++ .../src/client/handshaker/builder/dummy.rs | 9 ++- p2p/p2p-core/src/lib.rs | 1 + p2p/p2p-core/src/services.rs | 43 ++++------ p2p/p2p/src/inbound_server.rs | 6 +- 17 files changed, 196 insertions(+), 167 deletions(-) create mode 100644 p2p/p2p-core/src/ban.rs diff --git a/binaries/cuprated/src/main.rs b/binaries/cuprated/src/main.rs index 775843df9..55a38cc2c 100644 --- a/binaries/cuprated/src/main.rs +++ b/binaries/cuprated/src/main.rs @@ -3,6 +3,7 @@ #![allow( unused_imports, unreachable_pub, + unreachable_code, unused_crate_dependencies, dead_code, unused_variables, diff --git a/binaries/cuprated/src/rpc.rs b/binaries/cuprated/src/rpc.rs index 8978e5d2b..fe8e5f214 100644 --- a/binaries/cuprated/src/rpc.rs +++ b/binaries/cuprated/src/rpc.rs @@ -8,4 +8,4 @@ mod json; mod other; mod request; -pub use handler::{CupratedRpcHandler, CupratedRpcHandlerState}; +pub use handler::CupratedRpcHandler; diff --git a/binaries/cuprated/src/rpc/bin.rs b/binaries/cuprated/src/rpc/bin.rs index 60d92c127..b4e676dcc 100644 --- a/binaries/cuprated/src/rpc/bin.rs +++ b/binaries/cuprated/src/rpc/bin.rs @@ -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 { 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 { todo!() } async fn get_blocks_by_height( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetBlocksByHeightRequest, ) -> Result { todo!() } async fn get_hashes( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetHashesRequest, ) -> Result { todo!() } async fn get_output_indexes( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetOutputIndexesRequest, ) -> Result { todo!() } async fn get_outs( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetOutsRequest, ) -> Result { todo!() } async fn get_transaction_pool_hashes( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetTransactionPoolHashesRequest, ) -> Result { todo!() } async fn get_output_distribution( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetOutputDistributionRequest, ) -> Result { todo!() diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index b021dcb55..24c52cfbc 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -22,35 +22,44 @@ use crate::rpc::{bin, json, other}; #[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 }, - /// TODO + /// Start pruning the blockchain. Prune, - /// TODO + /// Is the blockchain pruned? Pruned, - /// TODO + /// Relay a block to the network. RelayBlock(Block), - /// TODO + /// 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, - /// TODO + /// Is the blockchain fully synced? Synced, - /// TODO + /// Current target block time. Target, - /// TODO + /// The height of the next block in the chain. TargetHeight, } /// TODO: use real type when public. #[derive(Clone)] pub enum BlockchainManagerResponse { - /// TODO + /// General OK response. /// /// Response to: /// - [`BlockchainManagerRequest::Prune`] @@ -58,33 +67,21 @@ pub enum BlockchainManagerResponse { Ok, /// Response to [`BlockchainManagerRequest::PopBlocks`] - /// - /// TODO PopBlocks { new_height: usize }, /// Response to [`BlockchainManagerRequest::Pruned`] - /// - /// TODO Pruned(bool), /// Response to [`BlockchainManagerRequest::Syncing`] - /// - /// TODO Syncing(bool), /// Response to [`BlockchainManagerRequest::Synced`] - /// - /// TODO Synced(bool), /// Response to [`BlockchainManagerRequest::Target`] - /// - /// TODO - Target { height: usize }, + Target(std::time::Duration), /// Response to [`BlockchainManagerRequest::TargetHeight`] - /// - /// TODO TargetHeight { height: usize }, } @@ -97,19 +94,10 @@ pub type BlockchainManagerHandle = cuprate_database_service::DatabaseReadService /// TODO #[derive(Clone)] pub struct CupratedRpcHandler { - /// State needed for request -> response mapping. - pub state: CupratedRpcHandlerState, -} - -/// TODO -#[derive(Clone)] -pub struct CupratedRpcHandlerState { /// 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, /// Read handle to the blockchain database. pub blockchain_read: BlockchainReadHandle, @@ -129,14 +117,28 @@ pub struct CupratedRpcHandlerState { impl CupratedRpcHandler { /// TODO - pub fn init() { - todo!() + pub const fn new( + restricted: bool, + blockchain_read: BlockchainReadHandle, + blockchain_write: BlockchainWriteHandle, + blockchain_manager: BlockchainManagerHandle, + txpool_read: TxpoolReadHandle, + txpool_write: TxpoolWriteHandle, + ) -> Self { + Self { + restricted, + blockchain_read, + blockchain_write, + blockchain_manager, + txpool_read, + txpool_write, + } } } impl RpcHandler for CupratedRpcHandler { fn restricted(&self) -> bool { - self.state.restricted + self.restricted } } @@ -150,7 +152,7 @@ impl Service 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)) } } @@ -165,7 +167,7 @@ impl Service 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)) } } @@ -180,7 +182,7 @@ impl Service 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)) } } diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index 41398d480..88b38b92f 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -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 { 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 { todo!() } async fn on_get_block_hash( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: OnGetBlockHashRequest, ) -> Result { todo!() } async fn submit_block( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: SubmitBlockRequest, ) -> Result { todo!() } async fn generate_blocks( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GenerateBlocksRequest, ) -> Result { todo!() } async fn get_last_block_header( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetLastBlockHeaderRequest, ) -> Result { todo!() } async fn get_block_header_by_hash( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetBlockHeaderByHashRequest, ) -> Result { todo!() } async fn get_block_header_by_height( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetBlockHeaderByHeightRequest, ) -> Result { todo!() } async fn get_block_headers_range( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetBlockHeadersRangeRequest, ) -> Result { todo!() } async fn get_block( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetBlockRequest, ) -> Result { todo!() } async fn get_connections( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetConnectionsRequest, ) -> Result { todo!() } async fn get_info( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetInfoRequest, ) -> Result { todo!() } async fn hard_fork_info( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: HardForkInfoRequest, ) -> Result { todo!() } async fn set_bans( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: SetBansRequest, ) -> Result { todo!() } async fn get_bans( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetBansRequest, ) -> Result { todo!() } async fn banned( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: BannedRequest, ) -> Result { todo!() } async fn flush_transaction_pool( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: FlushTransactionPoolRequest, ) -> Result { todo!() } async fn get_output_histogram( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetOutputHistogramRequest, ) -> Result { todo!() } async fn get_coinbase_tx_sum( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetCoinbaseTxSumRequest, ) -> Result { todo!() } async fn get_version( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetVersionRequest, ) -> Result { todo!() } async fn get_fee_estimate( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetFeeEstimateRequest, ) -> Result { todo!() } async fn get_alternate_chains( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetAlternateChainsRequest, ) -> Result { todo!() } async fn relay_tx( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: RelayTxRequest, ) -> Result { todo!() } async fn sync_info( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: SyncInfoRequest, ) -> Result { todo!() } async fn get_transaction_pool_backlog( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetTransactionPoolBacklogRequest, ) -> Result { todo!() } async fn get_miner_data( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetMinerDataRequest, ) -> Result { todo!() } async fn prune_blockchain( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: PruneBlockchainRequest, ) -> Result { todo!() } async fn calc_pow( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: CalcPowRequest, ) -> Result { todo!() } async fn flush_cache( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: FlushCacheRequest, ) -> Result { todo!() } async fn add_aux_pow( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: AddAuxPowRequest, ) -> Result { todo!() } async fn get_tx_ids_loose( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetTxIdsLooseRequest, ) -> Result { todo!() diff --git a/binaries/cuprated/src/rpc/other.rs b/binaries/cuprated/src/rpc/other.rs index c0df39931..16b58c41e 100644 --- a/binaries/cuprated/src/rpc/other.rs +++ b/binaries/cuprated/src/rpc/other.rs @@ -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 { 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 { todo!() } async fn get_transactions( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetTransactionsRequest, ) -> Result { todo!() } async fn get_alt_blocks_hashes( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetAltBlocksHashesRequest, ) -> Result { todo!() } async fn is_key_image_spent( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: IsKeyImageSpentRequest, ) -> Result { todo!() } async fn send_raw_transaction( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: SendRawTransactionRequest, ) -> Result { todo!() } async fn start_mining( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: StartMiningRequest, ) -> Result { todo!() } async fn stop_mining( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: StopMiningRequest, ) -> Result { todo!() } async fn mining_status( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: MiningStatusRequest, ) -> Result { todo!() } async fn save_bc( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: SaveBcRequest, ) -> Result { todo!() } async fn get_peer_list( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetPeerListRequest, ) -> Result { todo!() } async fn set_log_hash_rate( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: SetLogHashRateRequest, ) -> Result { todo!() } async fn set_log_level( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: SetLogLevelRequest, ) -> Result { todo!() } async fn set_log_categories( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: SetLogCategoriesRequest, ) -> Result { todo!() } async fn set_bootstrap_daemon( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: SetBootstrapDaemonRequest, ) -> Result { todo!() } async fn get_transaction_pool( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetTransactionPoolRequest, ) -> Result { todo!() } async fn get_transaction_pool_stats( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetTransactionPoolStatsRequest, ) -> Result { todo!() } async fn stop_daemon( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: StopDaemonRequest, ) -> Result { todo!() } async fn get_limit( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetLimitRequest, ) -> Result { todo!() } async fn set_limit( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: SetLimitRequest, ) -> Result { todo!() } async fn out_peers( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: OutPeersRequest, ) -> Result { todo!() } async fn in_peers( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: InPeersRequest, ) -> Result { todo!() } async fn get_net_stats( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetNetStatsRequest, ) -> Result { todo!() } async fn get_outs( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetOutsRequest, ) -> Result { todo!() } async fn update( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: UpdateRequest, ) -> Result { todo!() } async fn pop_blocks( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: PopBlocksRequest, ) -> Result { todo!() } async fn get_transaction_pool_hashes( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetTransactionPoolHashesRequest, ) -> Result { todo!() } async fn get_public_nodes( - state: CupratedRpcHandlerState, + state: CupratedRpcHandler, request: GetPublicNodesRequest, ) -> Result { todo!() diff --git a/binaries/cuprated/src/rpc/request.rs b/binaries/cuprated/src/rpc/request.rs index fa2dab0e4..17e12b956 100644 --- a/binaries/cuprated/src/rpc/request.rs +++ b/binaries/cuprated/src/rpc/request.rs @@ -1,7 +1,7 @@ //! Convenience functions for requests/responses. //! -//! This module implements many methods on -//! [`CupratedRpcHandlerState`](crate::rpc::CupratedRpcHandlerState) +//! 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. //! diff --git a/binaries/cuprated/src/rpc/request/address_book.rs b/binaries/cuprated/src/rpc/request/address_book.rs index d939dd47f..2aa58e84b 100644 --- a/binaries/cuprated/src/rpc/request/address_book.rs +++ b/binaries/cuprated/src/rpc/request/address_book.rs @@ -50,7 +50,7 @@ pub(super) async fn connection_count( /// [`AddressBookRequest::SetBan`] pub(super) async fn set_ban( address_book: &mut impl AddressBook, - peer: Infallible, + peer: cuprate_p2p_core::ban::SetBan, ) -> Result<(), Error> { let AddressBookResponse::Ok = address_book .ready() @@ -69,9 +69,9 @@ pub(super) async fn set_ban( /// [`AddressBookRequest::GetBan`] pub(super) async fn get_ban( address_book: &mut impl AddressBook, - peer: Infallible, -) -> Result<(), Error> { - let AddressBookResponse::GetBan(ban) = address_book + peer: Z::Addr, +) -> Result, Error> { + let AddressBookResponse::GetBan { unban_instant } = address_book .ready() .await .expect("TODO") @@ -82,7 +82,7 @@ pub(super) async fn get_ban( unreachable!(); }; - Ok(()) + Ok(unban_instant) } /// [`AddressBookRequest::GetBans`] diff --git a/binaries/cuprated/src/rpc/request/blockchain.rs b/binaries/cuprated/src/rpc/request/blockchain.rs index 7bc601262..0e04f5ff8 100644 --- a/binaries/cuprated/src/rpc/request/blockchain.rs +++ b/binaries/cuprated/src/rpc/request/blockchain.rs @@ -1,4 +1,4 @@ -//! Functions for [`BlockchainReadRequest`] and [`BlockchainWriteRequest`]. +//! Functions for [`BlockchainReadRequest`]. use std::{ collections::{HashMap, HashSet}, diff --git a/binaries/cuprated/src/rpc/request/blockchain_manager.rs b/binaries/cuprated/src/rpc/request/blockchain_manager.rs index c254b5a6d..31b155c94 100644 --- a/binaries/cuprated/src/rpc/request/blockchain_manager.rs +++ b/binaries/cuprated/src/rpc/request/blockchain_manager.rs @@ -10,7 +10,7 @@ use crate::rpc::handler::{ BlockchainManagerHandle, BlockchainManagerRequest, BlockchainManagerResponse, }; -/// [`BlockchainManagerResponse::PopBlocks`] +/// [`BlockchainManagerRequest::PopBlocks`] pub(super) async fn pop_blocks( blockchain_manager: &mut BlockchainManagerHandle, amount: u64, @@ -29,7 +29,7 @@ pub(super) async fn pop_blocks( Ok(usize_to_u64(new_height)) } -/// [`BlockchainManagerResponse::Prune`] +/// [`BlockchainManagerRequest::Prune`] pub(super) async fn prune(blockchain_manager: &mut BlockchainManagerHandle) -> Result<(), Error> { let BlockchainManagerResponse::Ok = blockchain_manager .ready() @@ -43,7 +43,7 @@ pub(super) async fn prune(blockchain_manager: &mut BlockchainManagerHandle) -> R Ok(()) } -/// [`BlockchainManagerResponse::Pruned`] +/// [`BlockchainManagerRequest::Pruned`] pub(super) async fn pruned( blockchain_manager: &mut BlockchainManagerHandle, ) -> Result { @@ -59,7 +59,7 @@ pub(super) async fn pruned( Ok(pruned) } -/// [`BlockchainManagerResponse::RelayBlock`] +/// [`BlockchainManagerRequest::RelayBlock`] pub(super) async fn relay_block( blockchain_manager: &mut BlockchainManagerHandle, block: Block, @@ -76,7 +76,7 @@ pub(super) async fn relay_block( Ok(()) } -/// [`BlockchainManagerResponse::Syncing`] +/// [`BlockchainManagerRequest::Syncing`] pub(super) async fn syncing( blockchain_manager: &mut BlockchainManagerHandle, ) -> Result { @@ -92,7 +92,7 @@ pub(super) async fn syncing( Ok(syncing) } -/// [`BlockchainManagerResponse::Synced`] +/// [`BlockchainManagerRequest::Synced`] pub(super) async fn synced( blockchain_manager: &mut BlockchainManagerHandle, ) -> Result { @@ -108,9 +108,11 @@ pub(super) async fn synced( Ok(syncing) } -/// [`BlockchainManagerResponse::Target`] -pub(super) async fn target(blockchain_manager: &mut BlockchainManagerHandle) -> Result { - let BlockchainManagerResponse::Target { height } = blockchain_manager +/// [`BlockchainManagerRequest::Target`] +pub(super) async fn target( + blockchain_manager: &mut BlockchainManagerHandle, +) -> Result { + let BlockchainManagerResponse::Target(target) = blockchain_manager .ready() .await? .call(BlockchainManagerRequest::Target) @@ -119,10 +121,10 @@ pub(super) async fn target(blockchain_manager: &mut BlockchainManagerHandle) -> unreachable!(); }; - Ok(usize_to_u64(height)) + Ok(target) } -/// [`BlockchainManagerResponse::TargetHeight`] +/// [`BlockchainManagerRequest::TargetHeight`] pub(super) async fn target_height( blockchain_manager: &mut BlockchainManagerHandle, ) -> Result { diff --git a/binaries/cuprated/src/rpc/request/txpool.rs b/binaries/cuprated/src/rpc/request/txpool.rs index 71fa834c7..f7c01683c 100644 --- a/binaries/cuprated/src/rpc/request/txpool.rs +++ b/binaries/cuprated/src/rpc/request/txpool.rs @@ -43,7 +43,7 @@ pub(super) async fn size(txpool_read: &mut TxpoolReadHandle) -> Result AddressBook { 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 { + self.banned_peers.get(&peer.ban_id()).copied() + } + fn handle_incoming_peer_list( &mut self, mut peer_list: Vec>, @@ -408,14 +417,15 @@ impl Service> for AddressBook { 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::GetBan(_) - | AddressBookRequest::GetBans => todo!("finish https://github.com/Cuprate/cuprate/pull/297"), + | AddressBookRequest::GetBans => { + todo!("finish https://github.com/Cuprate/cuprate/pull/297") + } }; ready(response) diff --git a/p2p/p2p-core/src/ban.rs b/p2p/p2p-core/src/ban.rs new file mode 100644 index 000000000..da883e4bd --- /dev/null +++ b/p2p/p2p-core/src/ban.rs @@ -0,0 +1,19 @@ +//! Data structures related to bans. + +use std::time::{Duration, Instant}; + +use crate::NetZoneAddress; + +/// TODO +pub struct SetBan { + pub address: A, + pub ban: bool, + pub duration: Duration, +} + +/// TODO +pub struct BanState { + pub address: A, + pub banned: bool, + pub unban_instant: Instant, +} diff --git a/p2p/p2p-core/src/client/handshaker/builder/dummy.rs b/p2p/p2p-core/src/client/handshaker/builder/dummy.rs index 5ce51d25d..8bb966dbf 100644 --- a/p2p/p2p-core/src/client/handshaker/builder/dummy.rs +++ b/p2p/p2p-core/src/client/handshaker/builder/dummy.rs @@ -105,12 +105,15 @@ impl Service> 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::GetBan(_) - | AddressBookRequest::GetBans => todo!("finish https://github.com/Cuprate/cuprate/pull/297"), + | AddressBookRequest::GetBans => { + todo!("finish https://github.com/Cuprate/cuprate/pull/297") + } })) } } diff --git a/p2p/p2p-core/src/lib.rs b/p2p/p2p-core/src/lib.rs index c9a58f524..ed3536533 100644 --- a/p2p/p2p-core/src/lib.rs +++ b/p2p/p2p-core/src/lib.rs @@ -75,6 +75,7 @@ use cuprate_wire::{ NetworkAddress, }; +pub mod ban; pub mod client; mod constants; pub mod error; diff --git a/p2p/p2p-core/src/services.rs b/p2p/p2p-core/src/services.rs index 5c952e769..9c38c0d68 100644 --- a/p2p/p2p-core/src/services.rs +++ b/p2p/p2p-core/src/services.rs @@ -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`]. @@ -111,22 +115,19 @@ pub enum AddressBookRequest { /// Gets the specified number of white peers, or less if we don't have enough. GetWhitePeers(usize), - /// Checks if the given peer is banned. - IsPeerBanned(Z::Addr), - - /// TODO + /// Get the amount of white & grey peers. PeerlistSize, - /// TODO + /// Get the amount of incoming & outgoing connections. ConnectionCount, - /// TODO: `cuprate_rpc_types::json::SetBanRequest` input - SetBan(std::convert::Infallible), + /// (Un)ban a peer. + SetBan(SetBan), - /// TODO - GetBan(std::convert::Infallible), + /// Checks if the given peer is banned. + GetBan(Z::Addr), - /// TODO + /// Get the state of all bans. GetBans, } @@ -148,28 +149,18 @@ pub enum AddressBookResponse { /// Response to [`AddressBookRequest::GetWhitePeers`]. Peers(Vec>), - /// Response to [`AddressBookRequest::IsPeerBanned`]. - /// - /// Contains `true` if the peer is banned. - IsPeerBanned(bool), - /// Response to [`AddressBookRequest::PeerlistSize`]. - /// - /// TODO PeerlistSize { white: usize, grey: usize }, /// Response to [`AddressBookRequest::ConnectionCount`]. - /// - /// TODO ConnectionCount { incoming: usize, outgoing: usize }, /// Response to [`AddressBookRequest::GetBan`]. /// - /// TODO - GetBan(std::convert::Infallible), + /// This returns [`None`] if the peer is not banned, + /// else it returns how long the peer is banned for. + GetBan { unban_instant: Option }, /// Response to [`AddressBookRequest::GetBans`]. - /// - /// TODO - GetBans(std::convert::Infallible), + GetBans(Vec>), } diff --git a/p2p/p2p/src/inbound_server.rs b/p2p/p2p/src/inbound_server.rs index 0d50d5491..6e793bd19 100644 --- a/p2p/p2p/src/inbound_server.rs +++ b/p2p/p2p/src/inbound_server.rs @@ -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; } } From cf331885b610a00e4c3f94f04989971f9acb520e Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Wed, 2 Oct 2024 16:06:49 -0400 Subject: [PATCH 12/23] txpool docs/types --- binaries/cuprated/src/rpc/request/txpool.rs | 15 +++++++++------ storage/txpool/src/lib.rs | 2 ++ storage/txpool/src/service/interface.rs | 14 ++++++++------ storage/txpool/src/tx.rs | 14 ++++++++++++++ 4 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 storage/txpool/src/tx.rs diff --git a/binaries/cuprated/src/rpc/request/txpool.rs b/binaries/cuprated/src/rpc/request/txpool.rs index f7c01683c..4c3c9d31a 100644 --- a/binaries/cuprated/src/rpc/request/txpool.rs +++ b/binaries/cuprated/src/rpc/request/txpool.rs @@ -6,14 +6,17 @@ use anyhow::Error; use tower::{Service, ServiceExt}; use cuprate_helper::cast::usize_to_u64; -use cuprate_txpool::service::{ - interface::{TxpoolReadRequest, TxpoolReadResponse}, - TxpoolReadHandle, +use cuprate_txpool::{ + service::{ + interface::{TxpoolReadRequest, TxpoolReadResponse}, + TxpoolReadHandle, + }, + TxEntry, }; /// [`TxpoolReadRequest::Backlog`] -pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result, Error> { - let TxpoolReadResponse::Backlog(backlog) = txpool_read +pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result, Error> { + let TxpoolReadResponse::Backlog(tx_entries) = txpool_read .ready() .await .expect("TODO") @@ -24,7 +27,7 @@ pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result), + /// The inner `Vec` contains information on all + /// the transactions currently in the pool. + Backlog(Vec), /// Response to [`TxpoolReadRequest::Size`]. /// - /// TODO + /// The inner value is the amount of + /// transactions currently in the pool. Size(usize), } diff --git a/storage/txpool/src/tx.rs b/storage/txpool/src/tx.rs new file mode 100644 index 000000000..6425326a4 --- /dev/null +++ b/storage/txpool/src/tx.rs @@ -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, +} From 64a3e5d5e9d5b38937eb9e12e8efe8a1555303df Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Wed, 2 Oct 2024 17:04:02 -0400 Subject: [PATCH 13/23] blockchain docs/types --- .../cuprated/src/rpc/request/blockchain.rs | 33 ++++--- storage/blockchain/src/service/read.rs | 13 +-- types/src/blockchain.rs | 85 ++++++++++--------- types/src/lib.rs | 3 +- types/src/types.rs | 59 +++++++++++-- 5 files changed, 126 insertions(+), 67 deletions(-) diff --git a/binaries/cuprated/src/rpc/request/blockchain.rs b/binaries/cuprated/src/rpc/request/blockchain.rs index 0e04f5ff8..4324fdc48 100644 --- a/binaries/cuprated/src/rpc/request/blockchain.rs +++ b/binaries/cuprated/src/rpc/request/blockchain.rs @@ -12,7 +12,8 @@ use tower::{Service, ServiceExt}; use cuprate_helper::cast::{u64_to_usize, usize_to_u64}; use cuprate_types::{ blockchain::{BlockchainReadRequest, BlockchainResponse}, - Chain, ExtendedBlockHeader, OutputOnChain, + Chain, CoinbaseTxSum, ExtendedBlockHeader, MinerData, OutputHistogramEntry, + OutputHistogramInput, OutputOnChain, }; /// [`BlockchainReadRequest::BlockExtendedHeader`]. @@ -290,38 +291,46 @@ pub(super) async fn difficulty( /// [`BlockchainReadRequest::OutputHistogram`] pub(super) async fn output_histogram( mut blockchain_read: BlockchainReadHandle, -) -> Result<(), Error> { - let BlockchainResponse::OutputHistogram(_) = blockchain_read + input: OutputHistogramInput, +) -> Result, Error> { + let BlockchainResponse::OutputHistogram(histogram) = blockchain_read .ready() .await? - .call(BlockchainReadRequest::OutputHistogram) + .call(BlockchainReadRequest::OutputHistogram(input)) .await? else { unreachable!(); }; - Ok(todo!()) + Ok(histogram) } /// [`BlockchainReadRequest::CoinbaseTxSum`] pub(super) async fn coinbase_tx_sum( mut blockchain_read: BlockchainReadHandle, -) -> Result<(), Error> { - let BlockchainResponse::CoinbaseTxSum(_) = blockchain_read + height: u64, + count: u64, +) -> Result { + let BlockchainResponse::CoinbaseTxSum(sum) = blockchain_read .ready() .await? - .call(BlockchainReadRequest::CoinbaseTxSum) + .call(BlockchainReadRequest::CoinbaseTxSum { + height: u64_to_usize(height), + count, + }) .await? else { unreachable!(); }; - Ok(todo!()) + Ok(sum) } /// [`BlockchainReadRequest::MinerData`] -pub(super) async fn miner_data(mut blockchain_read: BlockchainReadHandle) -> Result<(), Error> { - let BlockchainResponse::MinerData(_) = blockchain_read +pub(super) async fn miner_data( + mut blockchain_read: BlockchainReadHandle, +) -> Result { + let BlockchainResponse::MinerData(data) = blockchain_read .ready() .await? .call(BlockchainReadRequest::MinerData) @@ -330,5 +339,5 @@ pub(super) async fn miner_data(mut blockchain_read: BlockchainReadHandle) -> Res unreachable!(); }; - Ok(todo!()) + Ok(data) } diff --git a/storage/blockchain/src/service/read.rs b/storage/blockchain/src/service/read.rs index bed2cf2c3..05af6ca5e 100644 --- a/storage/blockchain/src/service/read.rs +++ b/storage/blockchain/src/service/read.rs @@ -4,6 +4,7 @@ unreachable_code, unused_variables, clippy::unnecessary_wraps, + clippy::needless_pass_by_value, reason = "TODO: finish implementing the signatures from " )] @@ -25,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::{ @@ -114,13 +115,13 @@ 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::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::Difficulty(height) => difficulty(env, height), - R::OutputHistogram => output_histogram(env), - R::CoinbaseTxSum => coinbase_tx_sum(env), + R::OutputHistogram(input) => output_histogram(env, input), + R::CoinbaseTxSum { height, count } => coinbase_tx_sum(env, height, count), R::MinerData => miner_data(env), } @@ -646,12 +647,12 @@ fn difficulty(env: &ConcreteEnv, block_height: BlockHeight) -> ResponseResult { } /// [`BlockchainReadRequest::OutputHistogram`] -fn output_histogram(env: &ConcreteEnv) -> ResponseResult { +fn output_histogram(env: &ConcreteEnv, input: OutputHistogramInput) -> ResponseResult { Ok(BlockchainResponse::OutputHistogram(todo!())) } /// [`BlockchainReadRequest::CoinbaseTxSum`] -fn coinbase_tx_sum(env: &ConcreteEnv) -> ResponseResult { +fn coinbase_tx_sum(env: &ConcreteEnv, height: usize, count: u64) -> ResponseResult { Ok(BlockchainResponse::CoinbaseTxSum(todo!())) } diff --git a/types/src/blockchain.rs b/types/src/blockchain.rs index 7126c2140..b72e5501f 100644 --- a/types/src/blockchain.rs +++ b/types/src/blockchain.rs @@ -12,7 +12,8 @@ use monero_serai::block::Block; use crate::{ types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation}, - AltBlockInformation, ChainId, + AltBlockInformation, ChainId, CoinbaseTxSum, MinerData, OutputHistogramEntry, + OutputHistogramInput, }; //---------------------------------------------------------------------------------------------------- ReadRequest @@ -106,28 +107,40 @@ pub enum BlockchainReadRequest { /// A request for all alt blocks in the chain with the given [`ChainId`]. AltBlocksInChain(ChainId), - /// TODO - Block(usize), + /// Get a [`Block`] by its height. + Block { + height: usize, + }, - /// TODO + /// Get a [`Block`] by its hash. BlockByHash([u8; 32]), - /// TODO + /// Get the total amount of non-coinbase transactions in the chain. TotalTxCount, - /// TODO + /// Get the current size of the database. DatabaseSize, - // TODO + // Get the difficulty for the next block in the chain. Difficulty(usize), - /// TODO - OutputHistogram, + /// Get an output histogram. + /// + /// TODO: document fields after impl. + OutputHistogram(OutputHistogramInput), - /// TODO - CoinbaseTxSum, + /// 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, + }, - /// TODO + /// Get the necessary data to create a custom block template. + /// + /// These are used by p2pool. MinerData, } @@ -242,54 +255,46 @@ 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), - /// The response for: + /// Response to: /// - [`BlockchainReadRequest::Block`]. /// - [`BlockchainReadRequest::BlockByHash`]. - /// - /// TODO Block(Block), - /// The response for [`BlockchainReadRequest::TotalTxCount`]. - /// - /// TODO + /// Response to [`BlockchainReadRequest::TotalTxCount`]. TotalTxCount(usize), - /// The response for [`BlockchainReadRequest::TotalTxCount`]. - /// - /// TODO - DatabaseSize { database_size: u64, free_space: u64 }, + /// 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, + }, - /// The response for [`BlockchainReadRequest::TotalTxCount`]. - /// - // TODO + /// Response to [`BlockchainReadRequest::Difficulty`]. Difficulty(u128), - /// The response for [`BlockchainReadRequest::TotalTxCount`]. - /// - /// TODO - OutputHistogram(std::convert::Infallible), + /// Response to [`BlockchainReadRequest::OutputHistogram`]. + OutputHistogram(Vec), - /// The response for [`BlockchainReadRequest::TotalTxCount`]. - /// - /// TODO - CoinbaseTxSum(std::convert::Infallible), + /// Response to [`BlockchainReadRequest::CoinbaseTxSum`]. + CoinbaseTxSum(CoinbaseTxSum), - /// The response for [`BlockchainReadRequest::TotalTxCount`]. - /// - /// TODO - MinerData(std::convert::Infallible), + /// Response to [`BlockchainReadRequest::MinerData`]. + MinerData(MinerData), //------------------------------------------------------ Writes /// A generic Ok response to indicate a request was successfully handled. @@ -301,7 +306,7 @@ pub enum BlockchainResponse { /// - [`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), diff --git a/types/src/lib.rs b/types/src/lib.rs index 0b0dbe679..02b2f6c50 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -20,7 +20,8 @@ pub use transaction_verification_data::{ CachedVerificationState, TransactionVerificationData, TxVersion, }; pub use types::{ - AltBlockInformation, Chain, ChainId, ExtendedBlockHeader, OutputOnChain, + AltBlockInformation, Chain, ChainId, CoinbaseTxSum, ExtendedBlockHeader, MinerData, + MinerDataTxBacklogEntry, OutputHistogramEntry, OutputHistogramInput, OutputOnChain, VerifiedBlockInformation, VerifiedTransactionInformation, }; diff --git a/types/src/types.rs b/types/src/types.rs index a60ce6c60..e09a166c9 100644 --- a/types/src/types.rs +++ b/types/src/types.rs @@ -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); -//---------------------------------------------------------------------------------------------------- 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,57 @@ pub struct OutputOnChain { pub commitment: EdwardsPoint, } +/// TODO +#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct OutputHistogramInput { + pub amounts: Vec, + pub min_count: u64, + pub max_count: u64, + pub unlocked: bool, + pub recent_cutoff: u64, +} + +/// TODO +#[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, +} + +/// TODO +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct CoinbaseTxSum { + pub emission_amount: u64, + pub emission_amount_top64: u64, + pub fee_amount: u64, + pub fee_amount_top64: u64, + pub wide_emission_amount: u128, + pub wide_fee_amount: u128, +} + +/// TODO +#[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, +} + +/// TODO +#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct MinerDataTxBacklogEntry { + pub id: [u8; 32], + pub weight: u64, + pub fee: u64, +} + //---------------------------------------------------------------------------------------------------- Tests #[cfg(test)] mod test { From 42d6f97847b2786b3eeae274541831f60a15120d Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Wed, 2 Oct 2024 20:02:07 -0400 Subject: [PATCH 14/23] `AlternateChains`, docs --- .../src/rpc/request/blockchain_context.rs | 10 +-- consensus/src/context.rs | 20 +++--- consensus/src/context/task.rs | 3 +- types/src/lib.rs | 6 +- types/src/types.rs | 65 ++++++++++++++++--- 5 files changed, 78 insertions(+), 26 deletions(-) diff --git a/binaries/cuprated/src/rpc/request/blockchain_context.rs b/binaries/cuprated/src/rpc/request/blockchain_context.rs index 1cf69d601..b616593d4 100644 --- a/binaries/cuprated/src/rpc/request/blockchain_context.rs +++ b/binaries/cuprated/src/rpc/request/blockchain_context.rs @@ -9,7 +9,7 @@ use cuprate_consensus::context::{ BlockChainContext, BlockChainContextRequest, BlockChainContextResponse, BlockChainContextService, }; -use cuprate_types::HardFork; +use cuprate_types::{FeeEstimate, HardFork, HardForkInfo}; /// [`BlockChainContextRequest::Context`]. pub(super) async fn context( @@ -34,7 +34,7 @@ pub(super) async fn context( pub(super) async fn hard_fork_info( service: &mut BlockChainContextService, hard_fork: HardFork, -) -> Result { +) -> Result { let BlockChainContextResponse::HardForkInfo(hf_info) = service .ready() .await @@ -53,8 +53,8 @@ pub(super) async fn hard_fork_info( pub(super) async fn fee_estimate( service: &mut BlockChainContextService, grace_blocks: u64, -) -> Result { - let BlockChainContextResponse::FeeEstimate(hf_info) = service +) -> Result { + let BlockChainContextResponse::FeeEstimate(fee) = service .ready() .await .expect("TODO") @@ -65,5 +65,5 @@ pub(super) async fn fee_estimate( unreachable!(); }; - Ok(hf_info) + Ok(fee) } diff --git a/consensus/src/context.rs b/consensus/src/context.rs index 0d6428ca3..ef0ee623a 100644 --- a/consensus/src/context.rs +++ b/consensus/src/context.rs @@ -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; @@ -319,14 +319,17 @@ pub enum BlockChainContextRequest { _token: AltChainRequestToken, }, - /// TODO + /// Get information on a certain hardfork. HardForkInfo(HardFork), - /// TODO + /// Get the current fee estimate. FeeEstimate { /// TODO grace_blocks: u64, }, + + /// Get information on all the current alternate chains. + AlternateChains, } pub enum BlockChainContextResponse { @@ -365,14 +368,15 @@ pub enum BlockChainContextResponse { AltChainWeightCache(BlockWeightsCache), /// Response to [`BlockChainContextRequest::HardForkInfo`] - /// - /// TODO - HardForkInfo(std::convert::Infallible /* TODO */), + HardForkInfo(HardForkInfo), /// Response to [`BlockChainContextRequest::FeeEstimate`] + FeeEstimate(FeeEstimate), + + /// Response to [`BlockChainContextRequest::AlternateChains`] /// - /// TODO - FeeEstimate(std::convert::Infallible /* TODO */), + /// If the inner [`Vec::is_empty`], there were no alternate chains. + AlternateChains(Vec), } /// The blockchain context service. diff --git a/consensus/src/context/task.rs b/consensus/src/context/task.rs index f65fdcbb8..0717eca50 100644 --- a/consensus/src/context/task.rs +++ b/consensus/src/context/task.rs @@ -326,7 +326,8 @@ impl ContextTask { BlockChainContextResponse::Ok } BlockChainContextRequest::HardForkInfo(_) - | BlockChainContextRequest::FeeEstimate { .. } => { + | BlockChainContextRequest::FeeEstimate { .. } + | BlockChainContextRequest::AlternateChains => { todo!("finish https://github.com/Cuprate/cuprate/pull/297") } }) diff --git a/types/src/lib.rs b/types/src/lib.rs index 02b2f6c50..3031c9886 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -20,9 +20,9 @@ pub use transaction_verification_data::{ CachedVerificationState, TransactionVerificationData, TxVersion, }; pub use types::{ - AltBlockInformation, Chain, ChainId, CoinbaseTxSum, ExtendedBlockHeader, MinerData, - MinerDataTxBacklogEntry, OutputHistogramEntry, OutputHistogramInput, OutputOnChain, - VerifiedBlockInformation, VerifiedTransactionInformation, + AltBlockInformation, Chain, ChainId, ChainInfo, CoinbaseTxSum, ExtendedBlockHeader, + FeeEstimate, HardForkInfo, MinerData, MinerDataTxBacklogEntry, OutputHistogramEntry, + OutputHistogramInput, OutputOnChain, VerifiedBlockInformation, VerifiedTransactionInformation, }; //---------------------------------------------------------------------------------------------------- Feature-gated diff --git a/types/src/types.rs b/types/src/types.rs index e09a166c9..7d5c377f6 100644 --- a/types/src/types.rs +++ b/types/src/types.rs @@ -147,7 +147,9 @@ pub struct OutputOnChain { pub commitment: EdwardsPoint, } -/// TODO +/// 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, @@ -157,7 +159,9 @@ pub struct OutputHistogramInput { pub recent_cutoff: u64, } -/// TODO +/// 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, @@ -166,18 +170,20 @@ pub struct OutputHistogramEntry { pub recent_instances: u64, } -/// TODO +/// 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: u64, - pub emission_amount_top64: u64, - pub fee_amount: u64, - pub fee_amount_top64: u64, + pub emission_amount: u128, + pub fee_amount: u128, pub wide_emission_amount: u128, pub wide_fee_amount: u128, } -/// TODO +/// 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, @@ -190,7 +196,9 @@ pub struct MinerData { pub tx_backlog: Vec, } -/// TODO +/// 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], @@ -198,6 +206,45 @@ pub struct MinerDataTxBacklogEntry { 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, + 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 { From e7f052f1d0e58499002b702f51c5903dcbfa3fe4 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Wed, 2 Oct 2024 20:20:01 -0400 Subject: [PATCH 15/23] fixes --- binaries/cuprated/src/rpc/handler.rs | 2 +- .../src/rpc/request/blockchain_manager.rs | 2 +- binaries/cuprated/src/rpc/request/txpool.rs | 2 +- consensus/src/context.rs | 47 +++++++++---------- consensus/src/context/task.rs | 2 +- p2p/p2p-core/src/ban.rs | 4 +- p2p/p2p-core/src/services.rs | 2 +- types/src/blockchain.rs | 2 - 8 files changed, 30 insertions(+), 33 deletions(-) diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 24c52cfbc..0120d4efa 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -116,7 +116,7 @@ pub struct CupratedRpcHandler { } impl CupratedRpcHandler { - /// TODO + /// Create a new [`Self`]. pub const fn new( restricted: bool, blockchain_read: BlockchainReadHandle, diff --git a/binaries/cuprated/src/rpc/request/blockchain_manager.rs b/binaries/cuprated/src/rpc/request/blockchain_manager.rs index 31b155c94..4dc91c821 100644 --- a/binaries/cuprated/src/rpc/request/blockchain_manager.rs +++ b/binaries/cuprated/src/rpc/request/blockchain_manager.rs @@ -1,4 +1,4 @@ -//! Functions for TODO: doc enum message. +//! Functions for [`BlockchainManagerRequest`] & [`BlockchainManagerResponse`]. use anyhow::Error; use monero_serai::block::Block; diff --git a/binaries/cuprated/src/rpc/request/txpool.rs b/binaries/cuprated/src/rpc/request/txpool.rs index 4c3c9d31a..a36778eb4 100644 --- a/binaries/cuprated/src/rpc/request/txpool.rs +++ b/binaries/cuprated/src/rpc/request/txpool.rs @@ -1,4 +1,4 @@ -//! Functions for TODO: doc enum message. +//! Functions for [`TxpoolReadRequest`]. use std::convert::Infallible; diff --git a/consensus/src/context.rs b/consensus/src/context.rs index ef0ee623a..f90bd0a9c 100644 --- a/consensus/src/context.rs +++ b/consensus/src/context.rs @@ -254,9 +254,21 @@ pub enum BlockChainContextRequest { 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. /// @@ -318,18 +330,6 @@ pub enum BlockChainContextRequest { /// An internal token to prevent external crates calling this request. _token: AltChainRequestToken, }, - - /// Get information on a certain hardfork. - HardForkInfo(HardFork), - - /// Get the current fee estimate. - FeeEstimate { - /// TODO - grace_blocks: u64, - }, - - /// Get information on all the current alternate chains. - AlternateChains, } pub enum BlockChainContextResponse { @@ -346,7 +346,6 @@ pub enum BlockChainContextResponse { /// Response to [`BlockChainContextRequest::Context`] Context(BlockChainContext), - // TODO: why does this return a `HashMap` when the request is `CurrentRxVm`? /// Response to [`BlockChainContextRequest::CurrentRxVm`] /// /// A map of seed height to `RandomX` VMs. @@ -355,6 +354,17 @@ pub enum BlockChainContextResponse { /// A list of difficulties. BatchDifficulties(Vec), + /// 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), + /// An alt chain context cache. AltChainContextCache(Box), @@ -366,17 +376,6 @@ pub enum BlockChainContextResponse { /// A weight cache for an alt chain AltChainWeightCache(BlockWeightsCache), - - /// Response to [`BlockChainContextRequest::HardForkInfo`] - HardForkInfo(HardForkInfo), - - /// Response to [`BlockChainContextRequest::FeeEstimate`] - FeeEstimate(FeeEstimate), - - /// Response to [`BlockChainContextRequest::AlternateChains`] - /// - /// If the inner [`Vec::is_empty`], there were no alternate chains. - AlternateChains(Vec), } /// The blockchain context service. diff --git a/consensus/src/context/task.rs b/consensus/src/context/task.rs index 0717eca50..d5d1a8d0b 100644 --- a/consensus/src/context/task.rs +++ b/consensus/src/context/task.rs @@ -327,7 +327,7 @@ impl ContextTask { } BlockChainContextRequest::HardForkInfo(_) | BlockChainContextRequest::FeeEstimate { .. } - | BlockChainContextRequest::AlternateChains => { + | BlockChainContextRequest::AltChains => { todo!("finish https://github.com/Cuprate/cuprate/pull/297") } }) diff --git a/p2p/p2p-core/src/ban.rs b/p2p/p2p-core/src/ban.rs index da883e4bd..38db41f7a 100644 --- a/p2p/p2p-core/src/ban.rs +++ b/p2p/p2p-core/src/ban.rs @@ -4,14 +4,14 @@ use std::time::{Duration, Instant}; use crate::NetZoneAddress; -/// TODO +/// Data within [`crate::services::AddressBookRequest::SetBan`]. pub struct SetBan { pub address: A, pub ban: bool, pub duration: Duration, } -/// TODO +/// Data within [`crate::services::AddressBookResponse::GetBans`]. pub struct BanState { pub address: A, pub banned: bool, diff --git a/p2p/p2p-core/src/services.rs b/p2p/p2p-core/src/services.rs index 9c38c0d68..495b71928 100644 --- a/p2p/p2p-core/src/services.rs +++ b/p2p/p2p-core/src/services.rs @@ -133,7 +133,7 @@ pub enum AddressBookRequest { /// A response from the address book service. pub enum AddressBookResponse { - /// TODO + /// Generic OK response. /// /// Response to: /// - [`AddressBookRequest::NewConnection`] diff --git a/types/src/blockchain.rs b/types/src/blockchain.rs index b72e5501f..e29ba304b 100644 --- a/types/src/blockchain.rs +++ b/types/src/blockchain.rs @@ -139,8 +139,6 @@ pub enum BlockchainReadRequest { }, /// Get the necessary data to create a custom block template. - /// - /// These are used by p2pool. MinerData, } From 2228d4d741038e0efe415c1af2cbc27c6ed0cfa2 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 4 Oct 2024 16:10:06 -0400 Subject: [PATCH 16/23] remove blockchain write handle, fix docs --- binaries/cuprated/src/rpc/handler.rs | 13 ++++--------- storage/blockchain/src/service/mod.rs | 5 +++++ storage/txpool/src/service.rs | 4 +--- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 0120d4efa..af2e3f2c0 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -102,17 +102,14 @@ pub struct CupratedRpcHandler { /// Read handle to the blockchain database. pub blockchain_read: BlockchainReadHandle, - /// Write handle to the blockchain database. - pub blockchain_write: BlockchainWriteHandle, - /// Handle to the blockchain manager. pub blockchain_manager: BlockchainManagerHandle, /// Read handle to the transaction pool database. pub txpool_read: TxpoolReadHandle, - /// Write handle to the transaction pool database. - pub txpool_write: TxpoolWriteHandle, + /// TODO: handle to txpool service. + pub txpool_manager: std::convert::Infallible, } impl CupratedRpcHandler { @@ -120,18 +117,16 @@ impl CupratedRpcHandler { pub const fn new( restricted: bool, blockchain_read: BlockchainReadHandle, - blockchain_write: BlockchainWriteHandle, blockchain_manager: BlockchainManagerHandle, txpool_read: TxpoolReadHandle, - txpool_write: TxpoolWriteHandle, + txpool_manager: std::convert::Infallible, ) -> Self { Self { restricted, blockchain_read, - blockchain_write, blockchain_manager, txpool_read, - txpool_write, + txpool_manager, } } } diff --git a/storage/blockchain/src/service/mod.rs b/storage/blockchain/src/service/mod.rs index fed0bd6d4..5fe4af9a4 100644 --- a/storage/blockchain/src/service/mod.rs +++ b/storage/blockchain/src/service/mod.rs @@ -21,6 +21,11 @@ //! //! The 2nd allows any caller to send [`WriteRequest`][req_w]s. //! +//! The [`BlockchainReadHandle`] can be shared as it is cheaply [`Clone`]able. +//! +//! Although [`BlockchainWriteHandle`] can also be cloned, there is only 1 place +//! in Cuprate that writes (the blockchain manager), so it is passed there and used. +//! //! ## Initialization //! The database & thread-pool system can be initialized with [`init()`]. //! diff --git a/storage/txpool/src/service.rs b/storage/txpool/src/service.rs index d87adcead..91a7060c0 100644 --- a/storage/txpool/src/service.rs +++ b/storage/txpool/src/service.rs @@ -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()`]. From d0888c8cf32059632fb56d5cb83045a5be0c1472 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 4 Oct 2024 16:20:25 -0400 Subject: [PATCH 17/23] remove `BlockchainReadRequest::Difficulty` --- .../cuprated/src/rpc/request/blockchain.rs | 19 ------------------- storage/blockchain/src/service/read.rs | 6 ------ types/src/blockchain.rs | 15 ++------------- 3 files changed, 2 insertions(+), 38 deletions(-) diff --git a/binaries/cuprated/src/rpc/request/blockchain.rs b/binaries/cuprated/src/rpc/request/blockchain.rs index 4324fdc48..c4016c937 100644 --- a/binaries/cuprated/src/rpc/request/blockchain.rs +++ b/binaries/cuprated/src/rpc/request/blockchain.rs @@ -269,25 +269,6 @@ pub(super) async fn database_size( Ok((database_size, free_space)) } -/// [`BlockchainReadRequest::Difficulty`] -pub(super) async fn difficulty( - mut blockchain_read: BlockchainReadHandle, - block_height: u64, -) -> Result { - let BlockchainResponse::Difficulty(difficulty) = blockchain_read - .ready() - .await? - .call(BlockchainReadRequest::Difficulty(u64_to_usize( - block_height, - ))) - .await? - else { - unreachable!(); - }; - - Ok(difficulty) -} - /// [`BlockchainReadRequest::OutputHistogram`] pub(super) async fn output_histogram( mut blockchain_read: BlockchainReadHandle, diff --git a/storage/blockchain/src/service/read.rs b/storage/blockchain/src/service/read.rs index 05af6ca5e..1530bd433 100644 --- a/storage/blockchain/src/service/read.rs +++ b/storage/blockchain/src/service/read.rs @@ -119,7 +119,6 @@ fn map_request( R::BlockByHash(hash) => block_by_hash(env, hash), R::TotalTxCount => total_tx_count(env), R::DatabaseSize => database_size(env), - R::Difficulty(height) => difficulty(env, height), R::OutputHistogram(input) => output_histogram(env, input), R::CoinbaseTxSum { height, count } => coinbase_tx_sum(env, height, count), R::MinerData => miner_data(env), @@ -641,11 +640,6 @@ fn database_size(env: &ConcreteEnv) -> ResponseResult { }) } -/// [`BlockchainReadRequest::Difficulty()`] -fn difficulty(env: &ConcreteEnv, block_height: BlockHeight) -> ResponseResult { - Ok(BlockchainResponse::Difficulty(todo!())) -} - /// [`BlockchainReadRequest::OutputHistogram`] fn output_histogram(env: &ConcreteEnv, input: OutputHistogramInput) -> ResponseResult { Ok(BlockchainResponse::OutputHistogram(todo!())) diff --git a/types/src/blockchain.rs b/types/src/blockchain.rs index e29ba304b..8913657c8 100644 --- a/types/src/blockchain.rs +++ b/types/src/blockchain.rs @@ -108,9 +108,7 @@ pub enum BlockchainReadRequest { AltBlocksInChain(ChainId), /// Get a [`Block`] by its height. - Block { - height: usize, - }, + Block { height: usize }, /// Get a [`Block`] by its hash. BlockByHash([u8; 32]), @@ -121,9 +119,6 @@ pub enum BlockchainReadRequest { /// Get the current size of the database. DatabaseSize, - // Get the difficulty for the next block in the chain. - Difficulty(usize), - /// Get an output histogram. /// /// TODO: document fields after impl. @@ -133,10 +128,7 @@ pub enum BlockchainReadRequest { /// `N` last blocks starting at particular height. /// /// TODO: document fields after impl. - CoinbaseTxSum { - height: usize, - count: u64, - }, + CoinbaseTxSum { height: usize, count: u64 }, /// Get the necessary data to create a custom block template. MinerData, @@ -282,9 +274,6 @@ pub enum BlockchainResponse { free_space: u64, }, - /// Response to [`BlockchainReadRequest::Difficulty`]. - Difficulty(u128), - /// Response to [`BlockchainReadRequest::OutputHistogram`]. OutputHistogram(Vec), From aaed13ad69b568d2f6cc556b1a98d74bff13f173 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 4 Oct 2024 16:22:49 -0400 Subject: [PATCH 18/23] remove `BlockchainReadRequest::MinerData` --- binaries/cuprated/src/rpc/request/blockchain.rs | 16 ---------------- storage/blockchain/src/service/read.rs | 6 ------ types/src/blockchain.rs | 9 +-------- 3 files changed, 1 insertion(+), 30 deletions(-) diff --git a/binaries/cuprated/src/rpc/request/blockchain.rs b/binaries/cuprated/src/rpc/request/blockchain.rs index c4016c937..8af80e509 100644 --- a/binaries/cuprated/src/rpc/request/blockchain.rs +++ b/binaries/cuprated/src/rpc/request/blockchain.rs @@ -306,19 +306,3 @@ pub(super) async fn coinbase_tx_sum( Ok(sum) } - -/// [`BlockchainReadRequest::MinerData`] -pub(super) async fn miner_data( - mut blockchain_read: BlockchainReadHandle, -) -> Result { - let BlockchainResponse::MinerData(data) = blockchain_read - .ready() - .await? - .call(BlockchainReadRequest::MinerData) - .await? - else { - unreachable!(); - }; - - Ok(data) -} diff --git a/storage/blockchain/src/service/read.rs b/storage/blockchain/src/service/read.rs index 1530bd433..a3b82bdb2 100644 --- a/storage/blockchain/src/service/read.rs +++ b/storage/blockchain/src/service/read.rs @@ -121,7 +121,6 @@ fn map_request( R::DatabaseSize => database_size(env), R::OutputHistogram(input) => output_histogram(env, input), R::CoinbaseTxSum { height, count } => coinbase_tx_sum(env, height, count), - R::MinerData => miner_data(env), } /* SOMEDAY: post-request handling, run some code for each request? */ @@ -649,8 +648,3 @@ fn output_histogram(env: &ConcreteEnv, input: OutputHistogramInput) -> ResponseR fn coinbase_tx_sum(env: &ConcreteEnv, height: usize, count: u64) -> ResponseResult { Ok(BlockchainResponse::CoinbaseTxSum(todo!())) } - -/// [`BlockchainReadRequest::MinerData`] -fn miner_data(env: &ConcreteEnv) -> ResponseResult { - Ok(BlockchainResponse::MinerData(todo!())) -} diff --git a/types/src/blockchain.rs b/types/src/blockchain.rs index 8913657c8..b7436f0a7 100644 --- a/types/src/blockchain.rs +++ b/types/src/blockchain.rs @@ -12,8 +12,7 @@ use monero_serai::block::Block; use crate::{ types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation}, - AltBlockInformation, ChainId, CoinbaseTxSum, MinerData, OutputHistogramEntry, - OutputHistogramInput, + AltBlockInformation, ChainId, CoinbaseTxSum, OutputHistogramEntry, OutputHistogramInput, }; //---------------------------------------------------------------------------------------------------- ReadRequest @@ -129,9 +128,6 @@ pub enum BlockchainReadRequest { /// /// TODO: document fields after impl. CoinbaseTxSum { height: usize, count: u64 }, - - /// Get the necessary data to create a custom block template. - MinerData, } //---------------------------------------------------------------------------------------------------- WriteRequest @@ -280,9 +276,6 @@ pub enum BlockchainResponse { /// Response to [`BlockchainReadRequest::CoinbaseTxSum`]. CoinbaseTxSum(CoinbaseTxSum), - /// Response to [`BlockchainReadRequest::MinerData`]. - MinerData(MinerData), - //------------------------------------------------------ Writes /// A generic Ok response to indicate a request was successfully handled. /// From 4f9c5f12ab983755529448ab2941a5ae35b238ed Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 4 Oct 2024 16:25:48 -0400 Subject: [PATCH 19/23] fix p2p ban types --- p2p/p2p-core/src/ban.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/p2p/p2p-core/src/ban.rs b/p2p/p2p-core/src/ban.rs index 38db41f7a..c3b17a419 100644 --- a/p2p/p2p-core/src/ban.rs +++ b/p2p/p2p-core/src/ban.rs @@ -6,14 +6,18 @@ use crate::NetZoneAddress; /// Data within [`crate::services::AddressBookRequest::SetBan`]. pub struct SetBan { + /// Address of the peer. pub address: A, - pub ban: bool, - pub duration: Duration, + /// - If [`Some`], how long this peer should be banned for + /// - If [`None`], the peer will be unbanned + pub ban: Option, } /// Data within [`crate::services::AddressBookResponse::GetBans`]. pub struct BanState { + /// Address of the peer. pub address: A, - pub banned: bool, - pub unban_instant: Instant, + /// - If [`Some`], when this peer will be unbanned + /// - If [`None`], the peer is not currently banned + pub unban_instant: Option, } From c886f807dd7efc62bf09f8cf8951961302c71f8b Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 4 Oct 2024 16:27:35 -0400 Subject: [PATCH 20/23] `CurrentRxVm` -> `CurrentRxVms` --- consensus/src/block.rs | 2 +- consensus/src/block/batch_prepare.rs | 2 +- consensus/src/context.rs | 6 +++--- consensus/src/context/task.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/consensus/src/block.rs b/consensus/src/block.rs index 0d1ba2f36..88e82f5ca 100644 --- a/consensus/src/block.rs +++ b/consensus/src/block.rs @@ -360,7 +360,7 @@ where let BlockChainContextResponse::RxVms(rx_vms) = context_svc .ready() .await? - .call(BlockChainContextRequest::CurrentRxVm) + .call(BlockChainContextRequest::CurrentRxVms) .await? else { panic!("Blockchain context service returned wrong response!"); diff --git a/consensus/src/block/batch_prepare.rs b/consensus/src/block/batch_prepare.rs index 123ec6cb5..029a5ae6c 100644 --- a/consensus/src/block/batch_prepare.rs +++ b/consensus/src/block/batch_prepare.rs @@ -136,7 +136,7 @@ where let BlockChainContextResponse::RxVms(rx_vms) = context_svc .ready() .await? - .call(BlockChainContextRequest::CurrentRxVm) + .call(BlockChainContextRequest::CurrentRxVms) .await? else { panic!("Blockchain context service returned wrong response!"); diff --git a/consensus/src/context.rs b/consensus/src/context.rs index f90bd0a9c..3c944a926 100644 --- a/consensus/src/context.rs +++ b/consensus/src/context.rs @@ -223,8 +223,8 @@ pub enum BlockChainContextRequest { /// Get the current blockchain context. Context, - /// Gets the current `RandomX` VM. - CurrentRxVm, + /// Gets all the current `RandomX` VMs. + CurrentRxVms, /// Get the next difficulties for these blocks. /// @@ -346,7 +346,7 @@ pub enum BlockChainContextResponse { /// Response to [`BlockChainContextRequest::Context`] Context(BlockChainContext), - /// Response to [`BlockChainContextRequest::CurrentRxVm`] + /// Response to [`BlockChainContextRequest::CurrentRxVms`] /// /// A map of seed height to `RandomX` VMs. RxVms(HashMap>), diff --git a/consensus/src/context/task.rs b/consensus/src/context/task.rs index d5d1a8d0b..c51c795ea 100644 --- a/consensus/src/context/task.rs +++ b/consensus/src/context/task.rs @@ -183,7 +183,7 @@ impl ContextTask { }, }) } - BlockChainContextRequest::CurrentRxVm => { + BlockChainContextRequest::CurrentRxVms => { BlockChainContextResponse::RxVms(self.rx_vm_cache.get_vms().await) } BlockChainContextRequest::BatchGetDifficulties(blocks) => { From 4fa37deec5b8534d00d64aa8750b147ea7c5ae1d Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Mon, 7 Oct 2024 19:51:21 -0400 Subject: [PATCH 21/23] storage: remove `Clone` off write handle --- storage/blockchain/src/service/mod.rs | 7 +++---- storage/service/src/service/write.rs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/storage/blockchain/src/service/mod.rs b/storage/blockchain/src/service/mod.rs index 5fe4af9a4..53bf1dfa3 100644 --- a/storage/blockchain/src/service/mod.rs +++ b/storage/blockchain/src/service/mod.rs @@ -21,10 +21,9 @@ //! //! The 2nd allows any caller to send [`WriteRequest`][req_w]s. //! -//! The [`BlockchainReadHandle`] can be shared as it is cheaply [`Clone`]able. -//! -//! Although [`BlockchainWriteHandle`] can also be cloned, there is only 1 place -//! in Cuprate that writes (the blockchain manager), so it is passed there and used. +//! 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 //! The database & thread-pool system can be initialized with [`init()`]. diff --git a/storage/service/src/service/write.rs b/storage/service/src/service/write.rs index d2cb862e6..f75d61517 100644 --- a/storage/service/src/service/write.rs +++ b/storage/service/src/service/write.rs @@ -21,7 +21,7 @@ const WRITER_THREAD_NAME: &str = concat!(module_path!(), "::DatabaseWriter"); /// Calling [`tower::Service::call`] with a [`DatabaseWriteHandle`] /// will return an `async`hronous channel that can be `.await`ed upon /// to receive the corresponding response. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct DatabaseWriteHandle { /// Sender channel to the database write thread-pool. /// From 337f42f7024d49a09f9fe0fdc6ffa74aaab40967 Mon Sep 17 00:00:00 2001 From: hinto-janai Date: Tue, 8 Oct 2024 16:50:46 -0400 Subject: [PATCH 22/23] Update p2p/p2p-core/src/ban.rs Co-authored-by: Boog900 --- p2p/p2p-core/src/ban.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/p2p/p2p-core/src/ban.rs b/p2p/p2p-core/src/ban.rs index c3b17a419..76fd3ebf7 100644 --- a/p2p/p2p-core/src/ban.rs +++ b/p2p/p2p-core/src/ban.rs @@ -17,7 +17,7 @@ pub struct SetBan { pub struct BanState { /// Address of the peer. pub address: A, - /// - If [`Some`], when this peer will be unbanned + /// - If [`Some`], the peer is banned until this [`Instant`] /// - If [`None`], the peer is not currently banned pub unban_instant: Option, } From 364ce370994dadfb9966a3b6c218a43e549a0f7b Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Tue, 8 Oct 2024 17:09:43 -0400 Subject: [PATCH 23/23] fix merge --- binaries/cuprated/src/blockchain/manager.rs | 2 +- binaries/cuprated/src/blockchain/manager/handler.rs | 2 +- binaries/cuprated/src/blockchain/syncer.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/binaries/cuprated/src/blockchain/manager.rs b/binaries/cuprated/src/blockchain/manager.rs index 568ed572d..118c8dd62 100644 --- a/binaries/cuprated/src/blockchain/manager.rs +++ b/binaries/cuprated/src/blockchain/manager.rs @@ -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 { diff --git a/binaries/cuprated/src/blockchain/manager/handler.rs b/binaries/cuprated/src/blockchain/manager/handler.rs index 303e2e492..9603bad54 100644 --- a/binaries/cuprated/src/blockchain/manager/handler.rs +++ b/binaries/cuprated/src/blockchain/manager/handler.rs @@ -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 { diff --git a/binaries/cuprated/src/blockchain/syncer.rs b/binaries/cuprated/src/blockchain/syncer.rs index 9de39a8ce..7d6874e0c 100644 --- a/binaries/cuprated/src/blockchain/syncer.rs +++ b/binaries/cuprated/src/blockchain/syncer.rs @@ -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!();