cuprated/rpc/service/
blockchain_manager.rs
1use 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::BlockTemplate;
12
13use crate::rpc::rpc_handler::{
14 BlockchainManagerHandle, BlockchainManagerRequest, BlockchainManagerResponse,
15};
16
17pub async fn pop_blocks(
19 blockchain_manager: &mut BlockchainManagerHandle,
20 amount: u64,
21) -> Result<u64, Error> {
22 let BlockchainManagerResponse::PopBlocks { new_height } = blockchain_manager
23 .ready()
24 .await?
25 .call(BlockchainManagerRequest::PopBlocks {
26 amount: u64_to_usize(amount),
27 })
28 .await?
29 else {
30 unreachable!();
31 };
32
33 Ok(usize_to_u64(new_height))
34}
35
36pub async fn prune(blockchain_manager: &mut BlockchainManagerHandle) -> Result<PruningSeed, Error> {
38 let BlockchainManagerResponse::Prune(seed) = blockchain_manager
39 .ready()
40 .await?
41 .call(BlockchainManagerRequest::Prune)
42 .await?
43 else {
44 unreachable!();
45 };
46
47 Ok(seed)
48}
49
50pub async fn pruned(blockchain_manager: &mut BlockchainManagerHandle) -> Result<bool, Error> {
52 let BlockchainManagerResponse::Pruned(pruned) = blockchain_manager
53 .ready()
54 .await?
55 .call(BlockchainManagerRequest::Pruned)
56 .await?
57 else {
58 unreachable!();
59 };
60
61 Ok(pruned)
62}
63
64pub async fn relay_block(
66 blockchain_manager: &mut BlockchainManagerHandle,
67 block: Box<Block>,
68) -> Result<(), Error> {
69 let BlockchainManagerResponse::Ok = blockchain_manager
70 .ready()
71 .await?
72 .call(BlockchainManagerRequest::RelayBlock(block))
73 .await?
74 else {
75 unreachable!();
76 };
77
78 Ok(())
79}
80
81pub async fn syncing(blockchain_manager: &mut BlockchainManagerHandle) -> Result<bool, Error> {
83 let BlockchainManagerResponse::Syncing(syncing) = blockchain_manager
84 .ready()
85 .await?
86 .call(BlockchainManagerRequest::Syncing)
87 .await?
88 else {
89 unreachable!();
90 };
91
92 Ok(syncing)
93}
94
95pub async fn synced(blockchain_manager: &mut BlockchainManagerHandle) -> Result<bool, Error> {
97 let BlockchainManagerResponse::Synced(syncing) = blockchain_manager
98 .ready()
99 .await?
100 .call(BlockchainManagerRequest::Synced)
101 .await?
102 else {
103 unreachable!();
104 };
105
106 Ok(syncing)
107}
108
109pub async fn target(
111 blockchain_manager: &mut BlockchainManagerHandle,
112) -> Result<std::time::Duration, Error> {
113 let BlockchainManagerResponse::Target(target) = blockchain_manager
114 .ready()
115 .await?
116 .call(BlockchainManagerRequest::Target)
117 .await?
118 else {
119 unreachable!();
120 };
121
122 Ok(target)
123}
124
125pub async fn target_height(blockchain_manager: &mut BlockchainManagerHandle) -> Result<u64, Error> {
127 let BlockchainManagerResponse::TargetHeight { height } = blockchain_manager
128 .ready()
129 .await?
130 .call(BlockchainManagerRequest::TargetHeight)
131 .await?
132 else {
133 unreachable!();
134 };
135
136 Ok(usize_to_u64(height))
137}
138
139pub async fn generate_blocks(
141 blockchain_manager: &mut BlockchainManagerHandle,
142 amount_of_blocks: u64,
143 prev_block: Option<[u8; 32]>,
144 starting_nonce: u32,
145 wallet_address: String,
146) -> Result<(Vec<[u8; 32]>, u64), Error> {
147 let BlockchainManagerResponse::GenerateBlocks { blocks, height } = blockchain_manager
148 .ready()
149 .await?
150 .call(BlockchainManagerRequest::GenerateBlocks {
151 amount_of_blocks,
152 prev_block,
153 starting_nonce,
154 wallet_address,
155 })
156 .await?
157 else {
158 unreachable!();
159 };
160
161 Ok((blocks, usize_to_u64(height)))
162}
163
164pub async fn spans<Z: NetworkZone>(
166 blockchain_manager: &mut BlockchainManagerHandle,
167) -> Result<Vec<Span>, Error> {
168 let vec: Vec<cuprate_p2p_core::types::Span<Z::Addr>> =
178 todo!("waiting on blockchain downloader/syncer: <https://github.com/Cuprate/cuprate/pull/320#discussion_r1811089758>");
179
180 let vec = vec
182 .into_iter()
183 .map(|span| Span {
184 connection_id: String::from(ConnectionId::DEFAULT_STR),
185 nblocks: span.nblocks,
186 rate: span.rate,
187 remote_address: span.remote_address.to_string(),
188 size: span.size,
189 speed: span.speed,
190 start_block_height: span.start_block_height,
191 })
192 .collect();
193
194 Ok(vec)
195}
196
197pub async fn next_needed_pruning_seed(
199 blockchain_manager: &mut BlockchainManagerHandle,
200) -> Result<PruningSeed, Error> {
201 let BlockchainManagerResponse::NextNeededPruningSeed(seed) = blockchain_manager
202 .ready()
203 .await?
204 .call(BlockchainManagerRequest::NextNeededPruningSeed)
205 .await?
206 else {
207 unreachable!();
208 };
209
210 Ok(seed)
211}
212
213pub async fn create_block_template(
215 blockchain_manager: &mut BlockchainManagerHandle,
216 prev_block: [u8; 32],
217 account_public_address: String,
218 extra_nonce: Vec<u8>,
219) -> Result<Box<BlockTemplate>, Error> {
220 let BlockchainManagerResponse::CreateBlockTemplate(block_template) = blockchain_manager
221 .ready()
222 .await?
223 .call(BlockchainManagerRequest::CreateBlockTemplate {
224 prev_block,
225 account_public_address,
226 extra_nonce,
227 })
228 .await?
229 else {
230 unreachable!();
231 };
232
233 Ok(block_template)
234}
235
236pub async fn sync(blockchain_manager: &mut BlockchainManagerHandle) -> Result<(), Error> {
238 let BlockchainManagerResponse::Ok = blockchain_manager
239 .ready()
240 .await?
241 .call(BlockchainManagerRequest::Sync)
242 .await?
243 else {
244 unreachable!();
245 };
246
247 Ok(())
248}
249
250pub async fn stop(blockchain_manager: &mut BlockchainManagerHandle) -> Result<(), Error> {
252 let BlockchainManagerResponse::Ok = blockchain_manager
253 .ready()
254 .await?
255 .call(BlockchainManagerRequest::Stop)
256 .await?
257 else {
258 unreachable!();
259 };
260
261 Ok(())
262}