use helpers, get_block, add return struct todos

This commit is contained in:
hinto.janai 2024-09-08 20:33:16 -04:00
parent f86baa2eef
commit 06b583e97d
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
2 changed files with 231 additions and 97 deletions

View file

@ -5,6 +5,7 @@
mod bin; mod bin;
mod constants; mod constants;
mod handler; mod handler;
mod helper;
mod json; mod json;
mod other; mod other;

View file

@ -31,11 +31,14 @@ use cuprate_rpc_types::{
SetBansRequest, SetBansResponse, SubmitBlockRequest, SubmitBlockResponse, SyncInfoRequest, SetBansRequest, SetBansResponse, SubmitBlockRequest, SubmitBlockResponse, SyncInfoRequest,
SyncInfoResponse, SyncInfoResponse,
}, },
misc::BlockHeader, misc::{BlockHeader, Status},
}; };
use cuprate_types::{blockchain::BlockchainReadRequest, Chain}; use cuprate_types::{blockchain::BlockchainReadRequest, Chain};
use crate::rpc::{CupratedRpcHandlerState, RESTRICTED_BLOCK_COUNT, RESTRICTED_BLOCK_HEADER_RANGE}; use crate::{
rpc::helper,
rpc::{CupratedRpcHandlerState, RESTRICTED_BLOCK_COUNT, RESTRICTED_BLOCK_HEADER_RANGE},
};
/// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`]. /// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`].
pub(super) async fn map_request( pub(super) async fn map_request(
@ -96,62 +99,55 @@ pub(super) async fn map_request(
} }
async fn get_block_count( async fn get_block_count(
state: CupratedRpcHandlerState, mut state: CupratedRpcHandlerState,
request: GetBlockCountRequest, request: GetBlockCountRequest,
) -> Result<GetBlockCountResponse, Error> { ) -> Result<GetBlockCountResponse, Error> {
let BlockchainResponse::ChainHeight(count, hash) = state
.blockchain
.oneshot(BlockchainReadRequest::ChainHeight)
.await?
else {
unreachable!();
};
Ok(GetBlockCountResponse { Ok(GetBlockCountResponse {
base: ResponseBase::ok(), base: ResponseBase::ok(),
count: usize_to_u64(count), count: helper::top_height(&mut state).await?,
}) })
} }
async fn on_get_block_hash( async fn on_get_block_hash(
state: CupratedRpcHandlerState, mut state: CupratedRpcHandlerState,
request: OnGetBlockHashRequest, request: OnGetBlockHashRequest,
) -> Result<OnGetBlockHashResponse, Error> { ) -> Result<OnGetBlockHashResponse, Error> {
let BlockchainResponse::BlockHash(hash) = state let [height] = request.block_height;
.blockchain let hash = helper::block_hash(&mut state, height).await?;
.oneshot(BlockchainReadRequest::BlockHash( let block_hash = hex::encode(hash);
u64_to_usize(request.block_height[0]),
Chain::Main,
))
.await?
else {
unreachable!();
};
Ok(OnGetBlockHashResponse { Ok(OnGetBlockHashResponse { block_hash })
block_hash: hex::encode(hash),
})
} }
async fn submit_block( async fn submit_block(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: SubmitBlockRequest, request: SubmitBlockRequest,
) -> Result<SubmitBlockResponse, Error> { ) -> Result<SubmitBlockResponse, Error> {
todo!() Ok(SubmitBlockResponse {
base: ResponseBase::ok(),
block_id: todo!(),
})
} }
async fn generate_blocks( async fn generate_blocks(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GenerateBlocksRequest, request: GenerateBlocksRequest,
) -> Result<GenerateBlocksResponse, Error> { ) -> Result<GenerateBlocksResponse, Error> {
todo!() Ok(GenerateBlocksResponse {
base: ResponseBase::ok(),
blocks: todo!(),
height: todo!(),
})
} }
async fn get_last_block_header( async fn get_last_block_header(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetLastBlockHeaderRequest, request: GetLastBlockHeaderRequest,
) -> Result<GetLastBlockHeaderResponse, Error> { ) -> Result<GetLastBlockHeaderResponse, Error> {
todo!() Ok(GetLastBlockHeaderResponse {
base: ResponseBase::ok(),
block_header: todo!(),
})
} }
async fn get_block_header_by_hash( async fn get_block_header_by_hash(
@ -179,16 +175,7 @@ async fn get_block_header_by_hash(
return Err(anyhow!("TODO")); return Err(anyhow!("TODO"));
}; };
let BlockchainResponse::BlockByHash(block) = state let block = helper::block_by_hash(state, hash).await?;
.blockchain
.ready()
.await?
.call(BlockchainReadRequest::BlockByHash(hash))
.await?
else {
unreachable!();
};
let block_header = BlockHeader::from(&block); let block_header = BlockHeader::from(&block);
Ok(block_header) Ok(block_header)
@ -213,34 +200,16 @@ async fn get_block_header_by_height(
mut state: CupratedRpcHandlerState, mut state: CupratedRpcHandlerState,
request: GetBlockHeaderByHeightRequest, request: GetBlockHeaderByHeightRequest,
) -> Result<GetBlockHeaderByHeightResponse, Error> { ) -> Result<GetBlockHeaderByHeightResponse, Error> {
let BlockchainResponse::ChainHeight(chain_height, _) = state let (height, _) = helper::top_height(&mut state).await?;
.blockchain
.ready()
.await?
.call(BlockchainReadRequest::ChainHeight)
.await?
else {
unreachable!();
};
let height = chain_height.saturating_sub(1); if request.height > height {
if request.height > usize_to_u64(height) {
return Err(anyhow!( return Err(anyhow!(
"Requested block height: {} greater than current top block height: {height}", "Requested block height: {} greater than current top block height: {height}",
request.height request.height
)); ));
} }
let BlockchainResponse::Block(block) = state let block = helper::block(&mut state, height).await?;
.blockchain
.ready()
.await?
.call(BlockchainReadRequest::Block(height))
.await?
else {
unreachable!();
};
Ok(GetBlockHeaderByHeightResponse { Ok(GetBlockHeaderByHeightResponse {
base: AccessResponseBase::ok(), base: AccessResponseBase::ok(),
@ -252,21 +221,10 @@ async fn get_block_headers_range(
mut state: CupratedRpcHandlerState, mut state: CupratedRpcHandlerState,
request: GetBlockHeadersRangeRequest, request: GetBlockHeadersRangeRequest,
) -> Result<GetBlockHeadersRangeResponse, Error> { ) -> Result<GetBlockHeadersRangeResponse, Error> {
let BlockchainResponse::ChainHeight(chain_height, _) = state let (height, _) = helper::top_height(&mut state).await?;
.blockchain
.ready()
.await?
.call(BlockchainReadRequest::ChainHeight)
.await?
else {
unreachable!();
};
let height = chain_height.saturating_sub(1); if request.start_height >= height
let height_u64 = usize_to_u64(height); || request.end_height >= height
if request.start_height >= height_u64
|| request.end_height >= height_u64
|| request.start_height > request.end_height || request.start_height > request.end_height
{ {
return Err(anyhow!("Invalid start/end heights")); return Err(anyhow!("Invalid start/end heights"));
@ -285,6 +243,7 @@ async fn get_block_headers_range(
{ {
let ready = state.blockchain.ready().await?; let ready = state.blockchain.ready().await?;
let height = u64_to_usize(height);
for block in request.start_height..=request.end_height { for block in request.start_height..=request.end_height {
let task = tokio::task::spawn(ready.call(BlockchainReadRequest::Block(height))); let task = tokio::task::spawn(ready.call(BlockchainReadRequest::Block(height)));
tasks.push(task); tasks.push(task);
@ -305,155 +264,329 @@ async fn get_block_headers_range(
} }
async fn get_block( async fn get_block(
state: CupratedRpcHandlerState, mut state: CupratedRpcHandlerState,
request: GetBlockRequest, request: GetBlockRequest,
) -> Result<GetBlockResponse, Error> { ) -> Result<GetBlockResponse, Error> {
todo!() let block = if !request.hash.is_empty() {
let hex = request.hash;
let Ok(bytes) = hex::decode(&hex) else {
return Err(anyhow!(
"Failed to parse hex representation of block hash. Hex = {hex}."
));
};
let Ok(hash) = bytes.try_into() else {
return Err(anyhow!("TODO"));
};
helper::block_by_hash(&mut state, hash).await?
} else {
let (height, _) = helper::top_height(&mut state).await?;
if request.height > height {
return Err(anyhow!(
"Requested block height: {} greater than current top block height: {height}",
request.height
));
}
helper::block(&mut state, height).await?
};
let block_header = (&block).into();
let blob = hex::encode(block.block_blob);
let miner_tx_hash = hex::encode(block.block.miner_transaction.hash());
let tx_hashes = block
.txs
.into_iter()
.map(|tx| hex::encode(tx.tx_hash))
.collect();
Ok(GetBlockResponse {
base: AccessResponseBase::ok(),
blob,
json: todo!(), // TODO: make `JSON` type in `cuprate_rpc_types`
miner_tx_hash,
tx_hashes,
block_header,
})
} }
async fn get_connections( async fn get_connections(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetConnectionsRequest, request: GetConnectionsRequest,
) -> Result<GetConnectionsResponse, Error> { ) -> Result<GetConnectionsResponse, Error> {
todo!() Ok(GetConnectionsResponse {
base: ResponseBase::ok(),
connections: todo!(),
})
} }
async fn get_info( async fn get_info(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetInfoRequest, request: GetInfoRequest,
) -> Result<GetInfoResponse, Error> { ) -> Result<GetInfoResponse, Error> {
todo!() Ok(GetInfoResponse {
base: AccessResponseBase::ok(),
adjusted_time: todo!(),
alt_blocks_count: todo!(),
block_size_limit: todo!(),
block_size_median: todo!(),
block_weight_limit: todo!(),
block_weight_median: todo!(),
bootstrap_daemon_address: todo!(),
busy_syncing: todo!(),
cumulative_difficulty_top64: todo!(),
cumulative_difficulty: todo!(),
database_size: todo!(),
difficulty_top64: todo!(),
difficulty: todo!(),
free_space: todo!(),
grey_peerlist_size: todo!(),
height: todo!(),
height_without_bootstrap: todo!(),
incoming_connections_count: todo!(),
mainnet: todo!(),
nettype: todo!(),
offline: todo!(),
outgoing_connections_count: todo!(),
restricted: todo!(),
rpc_connections_count: todo!(),
stagenet: todo!(),
start_time: todo!(),
synchronized: todo!(),
target_height: todo!(),
target: todo!(),
testnet: todo!(),
top_block_hash: todo!(),
tx_count: todo!(),
tx_pool_size: todo!(),
update_available: todo!(),
version: todo!(),
was_bootstrap_ever_used: todo!(),
white_peerlist_size: todo!(),
wide_cumulative_difficulty: todo!(),
wide_difficulty: todo!(),
})
} }
async fn hard_fork_info( async fn hard_fork_info(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: HardForkInfoRequest, request: HardForkInfoRequest,
) -> Result<HardForkInfoResponse, Error> { ) -> Result<HardForkInfoResponse, Error> {
todo!() Ok(HardForkInfoResponse {
base: AccessResponseBase::ok(),
earliest_height: todo!(),
enabled: todo!(),
state: todo!(),
threshold: todo!(),
version: todo!(),
votes: todo!(),
voting: todo!(),
window: todo!(),
})
} }
async fn set_bans( async fn set_bans(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: SetBansRequest, request: SetBansRequest,
) -> Result<SetBansResponse, Error> { ) -> Result<SetBansResponse, Error> {
todo!() todo!();
Ok(SetBansResponse {
base: ResponseBase::ok(),
})
} }
async fn get_bans( async fn get_bans(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetBansRequest, request: GetBansRequest,
) -> Result<GetBansResponse, Error> { ) -> Result<GetBansResponse, Error> {
todo!() Ok(GetBansResponse {
base: ResponseBase::ok(),
bans: todo!(),
})
} }
async fn banned( async fn banned(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: BannedRequest, request: BannedRequest,
) -> Result<BannedResponse, Error> { ) -> Result<BannedResponse, Error> {
todo!() Ok(BannedResponse {
banned: todo!(),
seconds: todo!(),
status: todo!(),
})
} }
async fn flush_transaction_pool( async fn flush_transaction_pool(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: FlushTransactionPoolRequest, request: FlushTransactionPoolRequest,
) -> Result<FlushTransactionPoolResponse, Error> { ) -> Result<FlushTransactionPoolResponse, Error> {
todo!() todo!();
Ok(FlushTransactionPoolResponse { status: Status::Ok })
} }
async fn get_output_histogram( async fn get_output_histogram(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetOutputHistogramRequest, request: GetOutputHistogramRequest,
) -> Result<GetOutputHistogramResponse, Error> { ) -> Result<GetOutputHistogramResponse, Error> {
todo!() Ok(GetOutputHistogramResponse {
base: AccessResponseBase::ok(),
histogram: todo!(),
})
} }
async fn get_coinbase_tx_sum( async fn get_coinbase_tx_sum(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetCoinbaseTxSumRequest, request: GetCoinbaseTxSumRequest,
) -> Result<GetCoinbaseTxSumResponse, Error> { ) -> Result<GetCoinbaseTxSumResponse, Error> {
todo!() Ok(GetCoinbaseTxSumResponse {
base: AccessResponseBase::ok(),
emission_amount: todo!(),
emission_amount_top64: todo!(),
fee_amount: todo!(),
fee_amount_top64: todo!(),
wide_emission_amount: todo!(),
wide_fee_amount: todo!(),
})
} }
async fn get_version( async fn get_version(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetVersionRequest, request: GetVersionRequest,
) -> Result<GetVersionResponse, Error> { ) -> Result<GetVersionResponse, Error> {
todo!() Ok(GetVersionResponse {
base: AccessResponseBase::ok(),
version: todo!(),
release: todo!(),
current_height: todo!(),
target_height: todo!(),
hard_forks: todo!(),
})
} }
async fn get_fee_estimate( async fn get_fee_estimate(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetFeeEstimateRequest, request: GetFeeEstimateRequest,
) -> Result<GetFeeEstimateResponse, Error> { ) -> Result<GetFeeEstimateResponse, Error> {
todo!() Ok(GetFeeEstimateResponse {
base: AccessResponseBase::ok(),
fee: todo!(),
fees: todo!(),
quantization_mask: todo!(),
})
} }
async fn get_alternate_chains( async fn get_alternate_chains(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetAlternateChainsRequest, request: GetAlternateChainsRequest,
) -> Result<GetAlternateChainsResponse, Error> { ) -> Result<GetAlternateChainsResponse, Error> {
todo!() Ok(GetAlternateChainsResponse {
base: AccessResponseBase::ok(),
chains: todo!(),
})
} }
async fn relay_tx( async fn relay_tx(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: RelayTxRequest, request: RelayTxRequest,
) -> Result<RelayTxResponse, Error> { ) -> Result<RelayTxResponse, Error> {
todo!() Ok(RelayTxResponse { status: todo!() })
} }
async fn sync_info( async fn sync_info(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: SyncInfoRequest, request: SyncInfoRequest,
) -> Result<SyncInfoResponse, Error> { ) -> Result<SyncInfoResponse, Error> {
todo!() Ok(SyncInfoResponse {
base: AccessResponseBase::ok(),
height: todo!(),
next_needed_pruning_seed: todo!(),
overview: todo!(),
peers: todo!(),
spans: todo!(),
target_height: todo!(),
})
} }
async fn get_transaction_pool_backlog( async fn get_transaction_pool_backlog(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetTransactionPoolBacklogRequest, request: GetTransactionPoolBacklogRequest,
) -> Result<GetTransactionPoolBacklogResponse, Error> { ) -> Result<GetTransactionPoolBacklogResponse, Error> {
todo!() Ok(GetTransactionPoolBacklogResponse {
base: AccessResponseBase::ok(),
backlog: todo!(),
})
} }
async fn get_miner_data( async fn get_miner_data(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetMinerDataRequest, request: GetMinerDataRequest,
) -> Result<GetMinerDataResponse, Error> { ) -> Result<GetMinerDataResponse, Error> {
todo!() Ok(GetMinerDataResponse {
base: AccessResponseBase::ok(),
major_version: todo!(),
height: todo!(),
prev_id: todo!(),
seed_hash: todo!(),
difficulty: todo!(),
median_weight: todo!(),
already_generated_coins: todo!(),
tx_backlog: todo!(),
})
} }
async fn prune_blockchain( async fn prune_blockchain(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: PruneBlockchainRequest, request: PruneBlockchainRequest,
) -> Result<PruneBlockchainResponse, Error> { ) -> Result<PruneBlockchainResponse, Error> {
todo!() Ok(PruneBlockchainResponse {
base: AccessResponseBase::ok(),
pruned: todo!(),
pruning_seed: todo!(),
})
} }
async fn calc_pow( async fn calc_pow(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: CalcPowRequest, request: CalcPowRequest,
) -> Result<CalcPowResponse, Error> { ) -> Result<CalcPowResponse, Error> {
todo!() Ok(CalcPowResponse { pow_hash: todo!() })
} }
async fn flush_cache( async fn flush_cache(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: FlushCacheRequest, request: FlushCacheRequest,
) -> Result<FlushCacheResponse, Error> { ) -> Result<FlushCacheResponse, Error> {
todo!() todo!();
Ok(FlushCacheResponse {
base: ResponseBase::ok(),
})
} }
async fn add_aux_pow( async fn add_aux_pow(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: AddAuxPowRequest, request: AddAuxPowRequest,
) -> Result<AddAuxPowResponse, Error> { ) -> Result<AddAuxPowResponse, Error> {
todo!() Ok(AddAuxPowResponse {
base: ResponseBase::ok(),
blocktemplate_blob: todo!(),
blockhashing_blob: todo!(),
merkle_root: todo!(),
merkle_tree_depth: todo!(),
aux_pow: todo!(),
})
} }
async fn get_tx_ids_loose( async fn get_tx_ids_loose(
state: CupratedRpcHandlerState, state: CupratedRpcHandlerState,
request: GetTxIdsLooseRequest, request: GetTxIdsLooseRequest,
) -> Result<GetTxIdsLooseResponse, Error> { ) -> Result<GetTxIdsLooseResponse, Error> {
todo!() Ok(GetTxIdsLooseResponse {
base: ResponseBase::ok(),
txids: todo!(),
})
} }