cuprated/rpc/service/
blockchain_context.rs
1use anyhow::{anyhow, Error};
4use monero_serai::block::Block;
5use tower::{Service, ServiceExt};
6
7use cuprate_consensus_context::{
8 BlockChainContextRequest, BlockChainContextResponse, BlockchainContext,
9 BlockchainContextService,
10};
11use cuprate_types::{
12 rpc::{FeeEstimate, HardForkInfo},
13 HardFork,
14};
15
16pub(crate) async fn hard_fork_info(
20 blockchain_context: &mut BlockchainContextService,
21 hard_fork: HardFork,
22) -> Result<HardForkInfo, Error> {
23 let BlockChainContextResponse::HardForkInfo(hf_info) = blockchain_context
24 .ready()
25 .await
26 .map_err(|e| anyhow!(e))?
27 .call(BlockChainContextRequest::HardForkInfo(hard_fork))
28 .await
29 .map_err(|e| anyhow!(e))?
30 else {
31 unreachable!();
32 };
33
34 Ok(hf_info)
35}
36
37pub(crate) async fn fee_estimate(
39 blockchain_context: &mut BlockchainContextService,
40 grace_blocks: u64,
41) -> Result<FeeEstimate, Error> {
42 let BlockChainContextResponse::FeeEstimate(fee) = blockchain_context
43 .ready()
44 .await
45 .map_err(|e| anyhow!(e))?
46 .call(BlockChainContextRequest::FeeEstimate { grace_blocks })
47 .await
48 .map_err(|e| anyhow!(e))?
49 else {
50 unreachable!();
51 };
52
53 Ok(fee)
54}
55
56pub(crate) async fn calculate_pow(
58 blockchain_context: &mut BlockchainContextService,
59 hardfork: HardFork,
60 block: Block,
61 seed_hash: [u8; 32],
62) -> Result<[u8; 32], Error> {
63 let Some(height) = block.number() else {
64 return Err(anyhow!("Block is missing height"));
65 };
66
67 let block = Box::new(block);
68
69 let BlockChainContextResponse::CalculatePow(hash) = blockchain_context
70 .ready()
71 .await
72 .map_err(|e| anyhow!(e))?
73 .call(BlockChainContextRequest::CalculatePow {
74 hardfork,
75 height,
76 block,
77 seed_hash,
78 })
79 .await
80 .map_err(|e| anyhow!(e))?
81 else {
82 unreachable!();
83 };
84
85 Ok(hash)
86}
87
88pub async fn batch_get_difficulties(
90 blockchain_context: &mut BlockchainContextService,
91 difficulties: Vec<(u64, HardFork)>,
92) -> Result<Vec<u128>, Error> {
93 let BlockChainContextResponse::BatchDifficulties(resp) = blockchain_context
94 .ready()
95 .await
96 .map_err(|e| anyhow!(e))?
97 .call(BlockChainContextRequest::BatchGetDifficulties(difficulties))
98 .await
99 .map_err(|e| anyhow!(e))?
100 else {
101 unreachable!();
102 };
103
104 Ok(resp)
105}