cuprated/rpc/request/
blockchain_manager.rs

1//! Functions for [`BlockchainManagerRequest`] & [`BlockchainManagerResponse`].
2
3use anyhow::Error;
4use monero_serai::block::Block;
5use tower::{Service, ServiceExt};
6
7use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
8use cuprate_p2p_core::{types::ConnectionId, NetworkZone};
9use cuprate_pruning::PruningSeed;
10use cuprate_rpc_types::misc::Span;
11use cuprate_types::{AddAuxPow, AuxPow, HardFork};
12
13use crate::rpc::{
14    constants::FIELD_NOT_SUPPORTED,
15    handler::{BlockchainManagerHandle, BlockchainManagerRequest, BlockchainManagerResponse},
16};
17
18/// [`BlockchainManagerRequest::PopBlocks`]
19pub(crate) async fn pop_blocks(
20    blockchain_manager: &mut BlockchainManagerHandle,
21    amount: u64,
22) -> Result<u64, Error> {
23    let BlockchainManagerResponse::PopBlocks { new_height } = blockchain_manager
24        .ready()
25        .await?
26        .call(BlockchainManagerRequest::PopBlocks {
27            amount: u64_to_usize(amount),
28        })
29        .await?
30    else {
31        unreachable!();
32    };
33
34    Ok(usize_to_u64(new_height))
35}
36
37/// [`BlockchainManagerRequest::Prune`]
38pub(crate) async fn prune(
39    blockchain_manager: &mut BlockchainManagerHandle,
40) -> Result<PruningSeed, Error> {
41    let BlockchainManagerResponse::Prune(seed) = blockchain_manager
42        .ready()
43        .await?
44        .call(BlockchainManagerRequest::Prune)
45        .await?
46    else {
47        unreachable!();
48    };
49
50    Ok(seed)
51}
52
53/// [`BlockchainManagerRequest::Pruned`]
54pub(crate) async fn pruned(
55    blockchain_manager: &mut BlockchainManagerHandle,
56) -> Result<bool, Error> {
57    let BlockchainManagerResponse::Pruned(pruned) = blockchain_manager
58        .ready()
59        .await?
60        .call(BlockchainManagerRequest::Pruned)
61        .await?
62    else {
63        unreachable!();
64    };
65
66    Ok(pruned)
67}
68
69/// [`BlockchainManagerRequest::RelayBlock`]
70pub(crate) async fn relay_block(
71    blockchain_manager: &mut BlockchainManagerHandle,
72    block: Block,
73) -> Result<(), Error> {
74    let BlockchainManagerResponse::Ok = blockchain_manager
75        .ready()
76        .await?
77        .call(BlockchainManagerRequest::RelayBlock(block))
78        .await?
79    else {
80        unreachable!();
81    };
82
83    Ok(())
84}
85
86/// [`BlockchainManagerRequest::Syncing`]
87pub(crate) async fn syncing(
88    blockchain_manager: &mut BlockchainManagerHandle,
89) -> Result<bool, Error> {
90    let BlockchainManagerResponse::Syncing(syncing) = blockchain_manager
91        .ready()
92        .await?
93        .call(BlockchainManagerRequest::Syncing)
94        .await?
95    else {
96        unreachable!();
97    };
98
99    Ok(syncing)
100}
101
102/// [`BlockchainManagerRequest::Synced`]
103pub(crate) async fn synced(
104    blockchain_manager: &mut BlockchainManagerHandle,
105) -> Result<bool, Error> {
106    let BlockchainManagerResponse::Synced(syncing) = blockchain_manager
107        .ready()
108        .await?
109        .call(BlockchainManagerRequest::Synced)
110        .await?
111    else {
112        unreachable!();
113    };
114
115    Ok(syncing)
116}
117
118/// [`BlockchainManagerRequest::Target`]
119pub(crate) async fn target(
120    blockchain_manager: &mut BlockchainManagerHandle,
121) -> Result<std::time::Duration, Error> {
122    let BlockchainManagerResponse::Target(target) = blockchain_manager
123        .ready()
124        .await?
125        .call(BlockchainManagerRequest::Target)
126        .await?
127    else {
128        unreachable!();
129    };
130
131    Ok(target)
132}
133
134/// [`BlockchainManagerRequest::TargetHeight`]
135pub(crate) async fn target_height(
136    blockchain_manager: &mut BlockchainManagerHandle,
137) -> Result<u64, Error> {
138    let BlockchainManagerResponse::TargetHeight { height } = blockchain_manager
139        .ready()
140        .await?
141        .call(BlockchainManagerRequest::TargetHeight)
142        .await?
143    else {
144        unreachable!();
145    };
146
147    Ok(usize_to_u64(height))
148}
149
150/// [`BlockchainManagerRequest::GenerateBlocks`]
151pub(crate) async fn generate_blocks(
152    blockchain_manager: &mut BlockchainManagerHandle,
153    amount_of_blocks: u64,
154    prev_block: [u8; 32],
155    starting_nonce: u32,
156    wallet_address: String,
157) -> Result<(Vec<[u8; 32]>, u64), Error> {
158    let BlockchainManagerResponse::GenerateBlocks { blocks, height } = blockchain_manager
159        .ready()
160        .await?
161        .call(BlockchainManagerRequest::GenerateBlocks {
162            amount_of_blocks,
163            prev_block,
164            starting_nonce,
165            wallet_address,
166        })
167        .await?
168    else {
169        unreachable!();
170    };
171
172    Ok((blocks, usize_to_u64(height)))
173}
174
175// [`BlockchainManagerRequest::Spans`]
176pub(crate) async fn spans<Z: NetworkZone>(
177    blockchain_manager: &mut BlockchainManagerHandle,
178) -> Result<Vec<Span>, Error> {
179    // let BlockchainManagerResponse::Spans(vec) = blockchain_manager
180    //     .ready()
181    //     .await?
182    //     .call(BlockchainManagerRequest::Spans)
183    //     .await?
184    // else {
185    //     unreachable!();
186    // };
187
188    let vec: Vec<cuprate_p2p_core::types::Span<Z::Addr>> = todo!();
189
190    // FIXME: impl this map somewhere instead of inline.
191    let vec = vec
192        .into_iter()
193        .map(|span| Span {
194            connection_id: String::from(ConnectionId::DEFAULT_STR),
195            nblocks: span.nblocks,
196            rate: span.rate,
197            remote_address: span.remote_address.to_string(),
198            size: span.size,
199            speed: span.speed,
200            start_block_height: span.start_block_height,
201        })
202        .collect();
203
204    Ok(vec)
205}
206
207/// [`BlockchainManagerRequest::NextNeededPruningSeed`]
208pub(crate) async fn next_needed_pruning_seed(
209    blockchain_manager: &mut BlockchainManagerHandle,
210) -> Result<PruningSeed, Error> {
211    let BlockchainManagerResponse::NextNeededPruningSeed(seed) = blockchain_manager
212        .ready()
213        .await?
214        .call(BlockchainManagerRequest::NextNeededPruningSeed)
215        .await?
216    else {
217        unreachable!();
218    };
219
220    Ok(seed)
221}