diff --git a/binaries/cuprated/src/main.rs b/binaries/cuprated/src/main.rs index 76eb85e8..04392260 100644 --- a/binaries/cuprated/src/main.rs +++ b/binaries/cuprated/src/main.rs @@ -8,6 +8,7 @@ unused_variables, clippy::needless_pass_by_value, clippy::unused_async, + unreachable_code, reason = "TODO: remove after v1.0.0" )] diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 8ba25eab..0ea89349 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -23,13 +23,6 @@ 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,6 +30,13 @@ 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, @@ -53,7 +53,7 @@ impl CupratedRpcHandler { impl RpcHandler for CupratedRpcHandler { fn restricted(&self) -> bool { - self.restricted + self.state.restricted } } diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index c331cd25..42bd4b26 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use anyhow::Error; +use anyhow::{anyhow, Error}; use futures::StreamExt; use tower::{Service, ServiceExt}; @@ -160,33 +160,32 @@ async fn get_block_header_by_hash( mut state: CupratedRpcHandlerState, request: GetBlockHeaderByHashRequest, ) -> Result { - let restricted = todo!(); - if restricted && request.hashes.len() > RESTRICTED_BLOCK_COUNT { - let message = "Too many block headers requested in restricted mode"; - return Err(todo!()); + if state.restricted && request.hashes.len() > RESTRICTED_BLOCK_COUNT { + let err = anyhow!("Too many block headers requested in restricted mode"); + return Err(err); } async fn get( state: &mut CupratedRpcHandlerState, hex: String, fill_pow_hash: bool, - ) -> Result { + ) -> Result { let Ok(bytes) = hex::decode(&hex) else { - let message = format!("Failed to parse hex representation of block hash. Hex = {hex}."); - return Err(todo!()); + let err = anyhow!("Failed to parse hex representation of block hash. Hex = {hex}."); + return Err(err); }; let Ok(hash) = bytes.try_into() else { - let message = "TODO"; - return Err(todo!()); + let err = anyhow!("TODO"); + return Err(err); }; - let ready = state.blockchain.ready().await.expect("TODO"); - - let BlockchainResponse::BlockByHash(block) = ready + let BlockchainResponse::BlockByHash(block) = state + .blockchain + .ready() + .await? .call(BlockchainReadRequest::BlockByHash(hash)) - .await - .expect("TODO") + .await? else { unreachable!(); }; @@ -196,15 +195,11 @@ async fn get_block_header_by_hash( Ok(block_header) } - let block_header = get(&mut state, request.hash, request.fill_pow_hash) - .await - .unwrap(); + let block_header = get(&mut state, request.hash, request.fill_pow_hash).await?; - let block_headers = Vec::with_capacity(request.hashes.len()); + let mut block_headers = Vec::with_capacity(request.hashes.len()); for hash in request.hashes { - let hash = get(&mut state, hash, request.fill_pow_hash) - .await - .expect("TODO"); + let hash = get(&mut state, hash, request.fill_pow_hash).await?; block_headers.push(hash); } @@ -216,10 +211,43 @@ async fn get_block_header_by_hash( } async fn get_block_header_by_height( - state: CupratedRpcHandlerState, + mut state: CupratedRpcHandlerState, request: GetBlockHeaderByHeightRequest, ) -> Result { - todo!() + let BlockchainResponse::ChainHeight(chain_height, _) = state + .blockchain + .ready() + .await? + .call(BlockchainReadRequest::ChainHeight) + .await? + else { + unreachable!(); + }; + + let height = chain_height.saturating_sub(1); + + if request.height > usize_to_u64(height) { + let err = anyhow!( + "Requested block height: {} greater than current top block height: {height}", + request.height + ); + return Err(err); + } + + let BlockchainResponse::Block(block) = state + .blockchain + .ready() + .await? + .call(BlockchainReadRequest::Block(height)) + .await? + else { + unreachable!(); + }; + + Ok(GetBlockHeaderByHeightResponse { + base: AccessResponseBase::ok(), + block_header: BlockHeader::from(&block), + }) } async fn get_block_headers_range( diff --git a/types/src/lib.rs b/types/src/lib.rs index 0b0dbe67..f06454a6 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -3,6 +3,17 @@ #![cfg_attr(any(feature = "proptest"), allow(non_local_definitions))] // Allow some lints when running in debug mode. #![cfg_attr(debug_assertions, allow(clippy::todo, clippy::multiple_crate_versions))] +#![allow( + unused_imports, + unreachable_pub, + unused_crate_dependencies, + dead_code, + unused_variables, + clippy::needless_pass_by_value, + clippy::unused_async, + unreachable_code, + reason = "TODO: remove after cuprated RpcHandler impl" +)] //---------------------------------------------------------------------------------------------------- Public API // Import private modules, export public types.