diff --git a/binaries/cuprated/src/rpc/blockchain.rs b/binaries/cuprated/src/rpc/blockchain.rs index 328d3988..39fa1ae4 100644 --- a/binaries/cuprated/src/rpc/blockchain.rs +++ b/binaries/cuprated/src/rpc/blockchain.rs @@ -18,7 +18,7 @@ use cuprate_helper::{ }; use cuprate_types::{ blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, - Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation, + Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, }; use crate::rpc::{CupratedRpcHandlerState, RESTRICTED_BLOCK_COUNT, RESTRICTED_BLOCK_HEADER_RANGE}; @@ -131,6 +131,23 @@ pub(super) async fn top_block_full( Ok((block, header)) } +/// [`BlockchainResponse::CurrentHardFork`] +pub(super) async fn current_hard_fork( + state: &mut CupratedRpcHandlerState, +) -> Result { + let BlockchainResponse::CurrentHardFork(hard_fork) = state + .blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::CurrentHardFork) + .await? + else { + unreachable!(); + }; + + Ok(hard_fork) +} + /// [`BlockchainResponse::BlockHash`] with [`Chain::Main`]. pub(super) async fn block_hash( state: &mut CupratedRpcHandlerState, diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index 8ea7496f..3c623c6d 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -35,7 +35,7 @@ use cuprate_rpc_types::{ misc::{BlockHeader, Status}, CORE_RPC_VERSION, }; -use cuprate_types::{blockchain::BlockchainReadRequest, Chain}; +use cuprate_types::{blockchain::BlockchainReadRequest, Chain, HardFork}; use crate::{ rpc::{ @@ -377,16 +377,22 @@ async fn get_info( /// async fn hard_fork_info( - state: CupratedRpcHandlerState, + mut state: CupratedRpcHandlerState, request: HardForkInfoRequest, ) -> Result { + let hard_fork = if request.version > 0 { + HardFork::from_version(request.version)? + } else { + blockchain::current_hard_fork(&mut state).await? + }; + Ok(HardForkInfoResponse { base: AccessResponseBase::ok(), earliest_height: todo!(), - enabled: todo!(), + enabled: hard_fork.is_current(), state: todo!(), threshold: todo!(), - version: todo!(), + version: hard_fork.as_u8(), votes: todo!(), voting: todo!(), window: todo!(), diff --git a/rpc/types/src/json.rs b/rpc/types/src/json.rs index cfefcf96..c5138c23 100644 --- a/rpc/types/src/json.rs +++ b/rpc/types/src/json.rs @@ -815,8 +815,17 @@ define_request_and_response! { hard_fork_info, cc73fe71162d564ffda8e549b79a350bca53c454 => core_rpc_server_commands_defs.h => 1958..=1995, - HardForkInfo (empty), - Request {}, + HardForkInfo, + + #[doc = serde_doc_test!( + HARD_FORK_INFO => HardForkInfo { + version: 16, + } + )] + #[derive(Copy)] + Request { + version: u8, + }, #[doc = serde_doc_test!( HARD_FORK_INFO_RESPONSE => HardForkInfoResponse { @@ -825,9 +834,9 @@ define_request_and_response! { enabled: true, state: 0, threshold: 0, - version: 16, + version: 3, votes: 10080, - voting: 16, + voting: 3, window: 10080 } )] diff --git a/storage/blockchain/src/ops/blockchain.rs b/storage/blockchain/src/ops/blockchain.rs index ed368ade..dcea6d41 100644 --- a/storage/blockchain/src/ops/blockchain.rs +++ b/storage/blockchain/src/ops/blockchain.rs @@ -2,10 +2,11 @@ //---------------------------------------------------------------------------------------------------- Import use cuprate_database::{DatabaseRo, RuntimeError}; +use cuprate_types::HardFork; use crate::{ - ops::macros::doc_error, - tables::{BlockHeights, BlockInfos}, + ops::{block, macros::doc_error}, + tables::{BlockHeights, BlockInfos, Tables}, types::BlockHeight, }; @@ -78,6 +79,15 @@ pub fn cumulative_generated_coins( } } +/// TODO +/// +#[doc = doc_error!()] +#[inline] +pub fn current_hard_fork(tables: &impl Tables) -> Result { + let (header, _) = block::get_block_extended_header_top(tables)?; + Ok(header.version) +} + //---------------------------------------------------------------------------------------------------- Tests #[cfg(test)] mod test { diff --git a/storage/blockchain/src/service/read.rs b/storage/blockchain/src/service/read.rs index 0f8e013a..8f2d8507 100644 --- a/storage/blockchain/src/service/read.rs +++ b/storage/blockchain/src/service/read.rs @@ -95,6 +95,7 @@ fn map_request( R::BlockExtendedHeaderByHash(hash) => block_extended_header_by_hash(env, hash), R::TopBlockExtendedHeader => top_block_extended_header_by_hash(env), R::TopBlockFull => top_block_full(env), + R::CurrentHardFork => current_hard_fork(env), R::BlockHash(height, chain) => block_hash(env, height, chain), R::FindBlock(_) => todo!("Add alt blocks to DB"), R::FilterUnknownHashes(hashes) => filter_unknown_hashes(env, hashes), @@ -283,6 +284,19 @@ fn top_block_full(env: &ConcreteEnv) -> ResponseResult { Ok(BlockchainResponse::TopBlockFull(block, header)) } +/// [`BlockchainReadRequest::CurrentHardFork`]. +#[inline] +fn current_hard_fork(env: &ConcreteEnv) -> ResponseResult { + // Single-threaded, no `ThreadLocal` required. + let env_inner = env.env_inner(); + let tx_ro = env_inner.tx_ro()?; + let tables = env_inner.open_tables(&tx_ro)?; + + Ok(BlockchainResponse::CurrentHardFork( + blockchain::current_hard_fork(&tables)?, + )) +} + /// [`BlockchainReadRequest::BlockHash`]. #[inline] fn block_hash(env: &ConcreteEnv, block_height: BlockHeight, chain: Chain) -> ResponseResult { @@ -364,7 +378,7 @@ fn chain_height(env: &ConcreteEnv) -> ResponseResult { let table_block_heights = env_inner.open_db_ro::(&tx_ro)?; let table_block_infos = env_inner.open_db_ro::(&tx_ro)?; - let chain_height = crate::ops::blockchain::chain_height(&table_block_heights)?; + let chain_height = blockchain::chain_height(&table_block_heights)?; let block_hash = get_block_info(&chain_height.saturating_sub(1), &table_block_infos)?.block_hash; diff --git a/test-utils/src/rpc/data/json.rs b/test-utils/src/rpc/data/json.rs index a05af670..3d463062 100644 --- a/test-utils/src/rpc/data/json.rs +++ b/test-utils/src/rpc/data/json.rs @@ -608,7 +608,10 @@ define_request_and_response! { r#"{ "jsonrpc": "2.0", "id": "0", - "method": "hard_fork_info" + "method": "hard_fork_info", + "params": { + "version": 16 + } }"#; Response = r#"{ diff --git a/types/src/blockchain.rs b/types/src/blockchain.rs index 51c3fb5d..a38acc60 100644 --- a/types/src/blockchain.rs +++ b/types/src/blockchain.rs @@ -11,7 +11,10 @@ use std::{ use monero_serai::block::Block; -use crate::types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation}; +use crate::{ + types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation}, + HardFork, +}; //---------------------------------------------------------------------------------------------------- ReadRequest /// A read request to the blockchain database. @@ -53,6 +56,9 @@ pub enum BlockchainReadRequest { /// TODO TopBlockFull, + /// TODO + CurrentHardFork, + /// Request a block's hash. /// /// The input is the block's height and the chain it is on. @@ -163,14 +169,25 @@ pub enum BlockchainWriteRequest { pub enum BlockchainResponse { //------------------------------------------------------ Reads /// Response to [`BlockchainReadRequest::Block`]. + /// + /// Inner value is TODO. Block(Block), /// Response to [`BlockchainReadRequest::BlockByHash`]. + /// + /// Inner value is TODO. BlockByHash(Block), /// Response to [`BlockchainReadRequest::TopBlock`]. + /// + /// Inner value is TODO. TopBlock(Block), + /// Response to [`BlockchainReadRequest::CurrentHardFork`]. + /// + /// Inner value is TODO. + CurrentHardFork(HardFork), + /// Response to [`BlockchainReadRequest::BlockExtendedHeader`]. /// /// Inner value is the extended headed of the requested block. diff --git a/types/src/hard_fork.rs b/types/src/hard_fork.rs index 412448e2..d3e0b1cc 100644 --- a/types/src/hard_fork.rs +++ b/types/src/hard_fork.rs @@ -48,11 +48,14 @@ pub enum HardFork { V13, V14, V15, - // remember to update from_vote! + // remember to update [`Self::CURRENT`]! V16, } impl HardFork { + /// TODO + pub const CURRENT: Self = Self::V16; + /// Returns the hard-fork for a blocks [`BlockHeader::hardfork_version`] field. /// /// ref: @@ -93,7 +96,7 @@ impl HardFork { return Self::V1; } // This must default to the latest hard-fork! - Self::from_version(vote).unwrap_or(Self::V16) + Self::from_version(vote).unwrap_or(Self::CURRENT) } /// Returns the [`HardFork`] version and vote from this block header. @@ -128,4 +131,9 @@ impl HardFork { _ => BLOCK_TIME_V2, } } + + /// TODO + pub const fn is_current(self) -> bool { + matches!(self, Self::CURRENT) + } }