cuprated/rpc/request/
blockchain_context.rs

1//! Functions for [`BlockChainContextRequest`] and [`BlockChainContextResponse`].
2
3use std::convert::Infallible;
4
5use anyhow::{anyhow, Error};
6use monero_serai::block::Block;
7use tower::{Service, ServiceExt};
8
9use cuprate_consensus_context::{
10    BlockChainContextRequest, BlockChainContextResponse, BlockchainContext,
11    BlockchainContextService,
12};
13use cuprate_helper::cast::u64_to_usize;
14use cuprate_types::{FeeEstimate, HardFork, HardForkInfo};
15
16// FIXME: use `anyhow::Error` over `tower::BoxError` in blockchain context.
17
18pub(crate) async fn context(
19    blockchain_context: &mut BlockchainContextService,
20) -> Result<BlockchainContext, Error> {
21    // TODO: Remove this whole function just call directly in all usages.
22    let context = blockchain_context.blockchain_context().clone();
23
24    Ok(context)
25}
26
27/// [`BlockChainContextRequest::HardForkInfo`].
28pub(crate) async fn hard_fork_info(
29    blockchain_context: &mut BlockchainContextService,
30    hard_fork: HardFork,
31) -> Result<HardForkInfo, Error> {
32    let BlockChainContextResponse::HardForkInfo(hf_info) = blockchain_context
33        .ready()
34        .await
35        .map_err(|e| anyhow!(e))?
36        .call(BlockChainContextRequest::HardForkInfo(hard_fork))
37        .await
38        .map_err(|e| anyhow!(e))?
39    else {
40        unreachable!();
41    };
42
43    Ok(hf_info)
44}
45
46/// [`BlockChainContextRequest::FeeEstimate`].
47pub(crate) async fn fee_estimate(
48    blockchain_context: &mut BlockchainContextService,
49    grace_blocks: u64,
50) -> Result<FeeEstimate, Error> {
51    let BlockChainContextResponse::FeeEstimate(fee) = blockchain_context
52        .ready()
53        .await
54        .map_err(|e| anyhow!(e))?
55        .call(BlockChainContextRequest::FeeEstimate { grace_blocks })
56        .await
57        .map_err(|e| anyhow!(e))?
58    else {
59        unreachable!();
60    };
61
62    Ok(fee)
63}
64
65/// [`BlockChainContextRequest::CalculatePow`]
66pub(crate) async fn calculate_pow(
67    blockchain_context: &mut BlockchainContextService,
68    hardfork: HardFork,
69    height: u64,
70    block: Box<Block>,
71    seed_hash: [u8; 32],
72) -> Result<[u8; 32], Error> {
73    let BlockChainContextResponse::CalculatePow(hash) = blockchain_context
74        .ready()
75        .await
76        .map_err(|e| anyhow!(e))?
77        .call(BlockChainContextRequest::CalculatePow {
78            hardfork,
79            height: u64_to_usize(height),
80            block,
81            seed_hash,
82        })
83        .await
84        .map_err(|e| anyhow!(e))?
85    else {
86        unreachable!();
87    };
88
89    Ok(hash)
90}