From 6ec5bc37a94ae236a31fe29fea79c971ddae6ebc Mon Sep 17 00:00:00 2001 From: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com> Date: Fri, 13 Sep 2024 00:03:03 +0100 Subject: [PATCH] add function for incoming blocks --- binaries/cuprated/src/blockchain.rs | 4 +- binaries/cuprated/src/blockchain/free.rs | 93 ++++++++++++++++++ binaries/cuprated/src/blockchain/manager.rs | 20 ++-- .../src/blockchain/manager/handler.rs | 11 ++- binaries/cuprated/src/main.rs | 3 +- p2p/address-book/src/lib.rs | 1 - p2p_state.bin | Bin 172430 -> 172852 bytes 7 files changed, 118 insertions(+), 14 deletions(-) create mode 100644 binaries/cuprated/src/blockchain/free.rs diff --git a/binaries/cuprated/src/blockchain.rs b/binaries/cuprated/src/blockchain.rs index eb23224e..46cc6a43 100644 --- a/binaries/cuprated/src/blockchain.rs +++ b/binaries/cuprated/src/blockchain.rs @@ -16,6 +16,7 @@ use cuprate_types::{ VerifiedBlockInformation, }; +mod free; mod manager; mod syncer; mod types; @@ -120,7 +121,8 @@ pub async fn init_blockchain_manager( blockchain_read_handle, blockchain_context_service, block_verifier_service, - ).await; + ) + .await; tokio::spawn(manager.run(batch_rx)); } diff --git a/binaries/cuprated/src/blockchain/free.rs b/binaries/cuprated/src/blockchain/free.rs new file mode 100644 index 00000000..becdf307 --- /dev/null +++ b/binaries/cuprated/src/blockchain/free.rs @@ -0,0 +1,93 @@ +use crate::blockchain::manager::IncomingBlock; +use cuprate_blockchain::service::BlockchainReadHandle; +use cuprate_consensus::transactions::new_tx_verification_data; +use cuprate_helper::cast::usize_to_u64; +use cuprate_types::blockchain::{BlockchainReadRequest, BlockchainResponse}; +use cuprate_types::Chain; +use monero_serai::block::Block; +use monero_serai::transaction::Transaction; +use rayon::prelude::*; +use std::collections::HashMap; +use std::sync::OnceLock; +use tokio::sync::{mpsc, oneshot}; +use tower::{Service, ServiceExt}; + +static INCOMING_BLOCK_TX: OnceLock> = OnceLock::new(); + +#[derive(thiserror::Error)] +pub enum IncomingBlockError { + #[error("Unknown transactions in block.")] + UnknownTransactions(Vec), + #[error("The block has an unknown parent.")] + Orphan, + #[error(transparent)] + InvalidBlock(anyhow::Error), +} + +pub async fn handle_incoming_block( + block: Block, + given_txs: Vec, + blockchain_read_handle: &mut BlockchainReadHandle, +) -> Result<(), IncomingBlockError> { + if !block_exists(block.header.previous, blockchain_read_handle).expect("TODO") { + return Err(IncomingBlockError::Orphan); + } + + let block_hash = block.hash(); + + if block_exists(block_hash, blockchain_read_handle) + .await + .expect("TODO") + { + return Ok(()); + } + + let prepped_txs = given_txs + .into_par_iter() + .map(|tx| { + let tx = new_tx_verification_data(tx)?; + Ok((tx.tx_hash, tx)) + }) + .collect::>() + .map_err(IncomingBlockError::InvalidBlock)?; + + // TODO: Get transactions from the tx pool first. + if given_txs.len() != block.transactions.len() { + return Err(IncomingBlockError::UnknownTransactions( + (0..usize_to_u64(block.transactions.len())).collect(), + )); + } + + let Some(incoming_block_tx) = INCOMING_BLOCK_TX.get() else { + return Ok(()); + }; + + let (response_tx, response_rx) = oneshot::channel(); + + incoming_block_tx + .send(IncomingBlock { + block, + prepped_txs, + response_tx, + }) + .await + .expect("TODO: don't actually panic here"); + + response_rx.await.map_err(IncomingBlockError::InvalidBlock) +} + +async fn block_exists( + block_hash: [u8; 32], + blockchain_read_handle: &mut BlockchainReadHandle, +) -> Result { + let BlockchainResponse::FindBlock(chain) = blockchain_read_handle + .ready() + .await? + .call(BlockchainReadRequest::FindBlock(block_hash)) + .await? + else { + panic!("Invalid blockchain response!"); + }; + + Ok(chain.is_some()) +} diff --git a/binaries/cuprated/src/blockchain/manager.rs b/binaries/cuprated/src/blockchain/manager.rs index e1e78d46..69de3399 100644 --- a/binaries/cuprated/src/blockchain/manager.rs +++ b/binaries/cuprated/src/blockchain/manager.rs @@ -1,6 +1,5 @@ mod handler; -use std::collections::HashMap; use crate::blockchain::types::ConsensusBlockchainReadHandle; use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle}; use cuprate_consensus::context::RawBlockChainContext; @@ -14,15 +13,16 @@ use cuprate_types::blockchain::{BlockchainReadRequest, BlockchainResponse}; use cuprate_types::{Chain, TransactionVerificationData}; use futures::StreamExt; use monero_serai::block::Block; +use std::collections::HashMap; use tokio::sync::mpsc; -use tokio::sync::{Notify, oneshot}; +use tokio::sync::{oneshot, Notify}; use tower::{Service, ServiceExt}; use tracing::error; pub struct IncomingBlock { - block: Block, - prepped_txs: HashMap<[u8; 32], TransactionVerificationData>, - response_tx: oneshot::Sender>, + pub block: Block, + pub prepped_txs: HashMap<[u8; 32], TransactionVerificationData>, + pub response_tx: oneshot::Sender>, } pub struct BlockchainManager { @@ -35,7 +35,6 @@ pub struct BlockchainManager { TxVerifierService, ConsensusBlockchainReadHandle, >, - // TODO: stop_current_block_downloader: Notify, } @@ -56,7 +55,8 @@ impl BlockchainManager { .expect("TODO") .call(BlockChainContextRequest::GetContext) .await - .expect("TODO") else { + .expect("TODO") + else { panic!("Blockchain context service returned wrong response!"); }; @@ -69,7 +69,11 @@ impl BlockchainManager { } } - pub async fn run(mut self, mut block_batch_rx: mpsc::Receiver, mut block_single_rx: mpsc::Receiver) { + pub async fn run( + mut self, + mut block_batch_rx: mpsc::Receiver, + mut block_single_rx: mpsc::Receiver, + ) { loop { tokio::select! { Some(batch) = block_batch_rx.recv() => { diff --git a/binaries/cuprated/src/blockchain/manager/handler.rs b/binaries/cuprated/src/blockchain/manager/handler.rs index 6dcffef7..f9f6ce80 100644 --- a/binaries/cuprated/src/blockchain/manager/handler.rs +++ b/binaries/cuprated/src/blockchain/manager/handler.rs @@ -63,9 +63,13 @@ impl super::BlockchainManager { .expect("Block batch should not be empty"); if first_block.header.previous == self.cached_blockchain_context.top_hash { - self.handle_incoming_block_batch_main_chain(batch).await.expect("TODO"); + self.handle_incoming_block_batch_main_chain(batch) + .await + .expect("TODO"); } else { - self.handle_incoming_block_batch_alt_chain(batch).await.expect("TODO"); + self.handle_incoming_block_batch_alt_chain(batch) + .await + .expect("TODO"); } } @@ -295,7 +299,8 @@ impl super::BlockchainManager { .expect("TODO") .call(BlockChainContextRequest::GetContext) .await - .expect("TODO") else { + .expect("TODO") + else { panic!("Incorrect response!"); }; diff --git a/binaries/cuprated/src/main.rs b/binaries/cuprated/src/main.rs index 0a885363..2c26c118 100644 --- a/binaries/cuprated/src/main.rs +++ b/binaries/cuprated/src/main.rs @@ -59,7 +59,8 @@ fn main() { context_svc, block_verifier, config.block_downloader_config(), - ).await; + ) + .await; // TODO: this can be removed as long as the main thread does not exit, so when command handling // is added diff --git a/p2p/address-book/src/lib.rs b/p2p/address-book/src/lib.rs index ae35a1bb..c0903485 100644 --- a/p2p/address-book/src/lib.rs +++ b/p2p/address-book/src/lib.rs @@ -98,5 +98,4 @@ mod sealed { { type BorshAddr = T::Addr; } - } diff --git a/p2p_state.bin b/p2p_state.bin index 281771cac6fd217c1d42942fc5489e431caa63a0..fc17e050f72079bd7b70ecf81a388975afba2996 100644 GIT binary patch delta 4664 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 DW~I!Y