1#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use cuprate_hex::{Hex, HexVec};
10use cuprate_types::rpc::{
11 AuxPow, GetMinerDataTxBacklogEntry, HardForkEntry, HardForkInfo, TxBacklogEntry,
12};
13
14use crate::{
15 base::{AccessResponseBase, ResponseBase},
16 macros::define_request_and_response,
17 misc::{
18 BlockHeader, ChainInfo, ConnectionInfo, Distribution, GetBan, HistogramEntry, SetBan, Span,
19 Status, SyncInfoPeer,
20 },
21 rpc_call::RpcCallValue,
22};
23
24#[cfg(any(feature = "epee", feature = "serde"))]
25use crate::defaults::{default, default_one, default_true};
26
27define_request_and_response! {
35 get_block_template,
37
38 "cc73fe71162d564ffda8e549b79a350bca53c454" => core_rpc_server_commands_defs.h => 943..=994,
41
42 GetBlockTemplate ,
54
55 Request {
60 extra_nonce: HexVec = default::<HexVec>(), "default",
84 prev_block: HexVec = default::<HexVec>(), "default",
85
86 reserve_size: u64 ,
92
93 wallet_address: String,
94 },
95
96 ResponseBase {
109 blockhashing_blob: HexVec,
122 blocktemplate_blob: HexVec,
123 difficulty_top64: u64,
124 difficulty: u64,
125 expected_reward: u64,
126 height: u64,
127 next_seed_hash: HexVec,
129 prev_hash: Hex<32>,
130 reserved_offset: u64,
131 seed_hash: Hex<32>,
132 seed_height: u64,
133 wide_difficulty: String,
134 }
135}
136
137define_request_and_response! {
138 get_block_count,
139 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
140 core_rpc_server_commands_defs.h => 919..=933,
141 GetBlockCount (empty),
142
143 Request {},
144
145 ResponseBase {
146 count: u64,
147 }
148}
149
150define_request_and_response! {
151 on_get_block_hash,
152 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
153 core_rpc_server_commands_defs.h => 935..=939,
154
155 OnGetBlockHash,
156
157 #[cfg_attr(feature = "serde", serde(transparent))]
158 #[repr(transparent)]
159 #[derive(Copy)]
160 Request {
161 block_height: [u64; 1],
164 },
165
166 #[cfg_attr(feature = "serde", serde(transparent))]
167 #[repr(transparent)]
168 Response {
169 block_hash: Hex<32>,
170 }
171}
172
173define_request_and_response! {
174 submit_block,
175 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
176 core_rpc_server_commands_defs.h => 1114..=1128,
177
178 SubmitBlock,
179
180 #[cfg_attr(feature = "serde", serde(transparent))]
181 #[repr(transparent)]
182 Request {
183 block_blob: [HexVec; 1],
186 },
187
188 ResponseBase {
190 block_id: Hex<32>,
191 }
192}
193
194define_request_and_response! {
195 generateblocks,
196 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
197 core_rpc_server_commands_defs.h => 1130..=1161,
198
199 GenerateBlocks (restricted),
200
201 Request {
202 amount_of_blocks: u64,
203 prev_block: HexVec = default::<HexVec>(), "default",
204 starting_nonce: u32,
205 wallet_address: String,
206 },
207
208 ResponseBase {
209 blocks: Vec<Hex<32>>,
210 height: u64,
211 }
212}
213
214define_request_and_response! {
215 get_last_block_header,
216 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
217 core_rpc_server_commands_defs.h => 1214..=1238,
218
219 GetLastBlockHeader,
220
221 #[derive(Copy)]
222 Request {
223 fill_pow_hash: bool = default::<bool>(), "default",
224 },
225
226 AccessResponseBase {
227 block_header: BlockHeader,
228 }
229}
230
231define_request_and_response! {
232 get_block_header_by_hash,
233 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
234 core_rpc_server_commands_defs.h => 1240..=1269,
235 GetBlockHeaderByHash,
236
237 Request {
238 hash: Hex<32> = default::<Hex<32>>(), "default",
239 hashes: Vec<Hex<32>> = default::<Vec<Hex<32>>>(), "default",
240 fill_pow_hash: bool = default::<bool>(), "default",
241 },
242
243 AccessResponseBase {
244 block_header: BlockHeader,
245 block_headers: Vec<BlockHeader>,
246 }
247}
248
249define_request_and_response! {
250 get_block_header_by_height,
251 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
252 core_rpc_server_commands_defs.h => 1271..=1296,
253
254 GetBlockHeaderByHeight,
255
256 #[derive(Copy)]
257 Request {
258 height: u64,
259 fill_pow_hash: bool = default::<bool>(), "default",
260 },
261
262 AccessResponseBase {
263 block_header: BlockHeader,
264 }
265}
266
267define_request_and_response! {
268 get_block_headers_range,
269 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
270 core_rpc_server_commands_defs.h => 1756..=1783,
271
272 GetBlockHeadersRange,
273
274 #[derive(Copy)]
275 Request {
276 start_height: u64,
277 end_height: u64,
278 fill_pow_hash: bool = default::<bool>(), "default",
279 },
280
281 AccessResponseBase {
282 headers: Vec<BlockHeader>,
283 }
284}
285
286define_request_and_response! {
287 get_block,
288 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
289 core_rpc_server_commands_defs.h => 1298..=1313,
290 GetBlock,
291
292 Request {
293 hash: HexVec = default::<HexVec>(), "default",
299 height: u64 = default::<u64>(), "default",
300 fill_pow_hash: bool = default::<bool>(), "default",
301 },
302
303 AccessResponseBase {
304 blob: HexVec,
305 block_header: BlockHeader,
306 json: String,
309 miner_tx_hash: Hex<32>,
310 tx_hashes: Vec<Hex<32>>,
311 }
312}
313
314define_request_and_response! {
315 get_connections,
316 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
317 core_rpc_server_commands_defs.h => 1734..=1754,
318
319 GetConnections (restricted, empty),
320
321 Request {},
322
323 ResponseBase {
324 connections: Vec<ConnectionInfo>,
325 }
326}
327
328define_request_and_response! {
329 get_info,
330 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
331 core_rpc_server_commands_defs.h => 693..=789,
332 GetInfo (empty),
333 Request {},
334
335 AccessResponseBase {
336 adjusted_time: u64,
337 alt_blocks_count: u64,
338 block_size_limit: u64,
339 block_size_median: u64,
340 block_weight_limit: u64,
341 block_weight_median: u64,
342 bootstrap_daemon_address: String,
343 busy_syncing: bool,
344 cumulative_difficulty_top64: u64,
345 cumulative_difficulty: u64,
346 database_size: u64,
347 difficulty_top64: u64,
348 difficulty: u64,
349 free_space: u64,
350 grey_peerlist_size: u64,
351 height: u64,
352 height_without_bootstrap: u64,
353 incoming_connections_count: u64,
354 mainnet: bool,
355 nettype: String,
356 offline: bool,
357 outgoing_connections_count: u64,
358 restricted: bool,
359 rpc_connections_count: u64,
360 stagenet: bool,
361 start_time: u64,
362 synchronized: bool,
363 target_height: u64,
364 target: u64,
365 testnet: bool,
366 top_block_hash: Hex<32>,
367 tx_count: u64,
368 tx_pool_size: u64,
369 update_available: bool,
370 version: String,
371 was_bootstrap_ever_used: bool,
372 white_peerlist_size: u64,
373 wide_cumulative_difficulty: String,
374 wide_difficulty: String,
375 }
376}
377
378define_request_and_response! {
379 hard_fork_info,
380 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
381 core_rpc_server_commands_defs.h => 1958..=1995,
382 HardForkInfo,
383
384 #[derive(Copy)]
385 Request {
386 version: u8,
387 },
388
389 AccessResponseBase {
390 #[cfg_attr(feature = "serde", serde(flatten))]
392 hard_fork_info: HardForkInfo,
393 }
394}
395
396define_request_and_response! {
397 set_bans,
398 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
399 core_rpc_server_commands_defs.h => 2032..=2067,
400
401 SetBans (restricted),
402
403 Request {
404 bans: Vec<SetBan>,
405 },
406
407 ResponseBase {}
408}
409
410define_request_and_response! {
411 get_bans,
412 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
413 core_rpc_server_commands_defs.h => 1997..=2030,
414 GetBans (restricted, empty),
415 Request {},
416
417 ResponseBase {
418 bans: Vec<GetBan>,
419 }
420}
421
422define_request_and_response! {
423 banned,
424 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
425 core_rpc_server_commands_defs.h => 2069..=2094,
426
427 Banned (restricted),
428
429 Request {
430 address: String,
431 },
432
433 Response {
434 banned: bool,
435 seconds: u32,
436 status: Status,
437 }
438}
439
440define_request_and_response! {
441 flush_txpool,
442 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
443 core_rpc_server_commands_defs.h => 2096..=2116,
444
445 FlushTransactionPool (restricted),
446
447 Request {
448 txids: Vec<Hex<32>> = default::<Vec<Hex<32>>>(), "default",
449 },
450
451 #[repr(transparent)]
452 Response {
453 status: Status,
454 }
455}
456
457define_request_and_response! {
458 get_output_histogram,
459 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
460 core_rpc_server_commands_defs.h => 2118..=2168,
461 GetOutputHistogram,
462
463 Request {
464 amounts: Vec<u64> = default::<Vec<u64>>(), "default",
465 min_count: u64 = default::<u64>(), "default",
466 max_count: u64 = default::<u64>(), "default",
467 unlocked: bool = default::<bool>(), "default",
468 recent_cutoff: u64 = default::<u64>(), "default",
469 },
470
471 AccessResponseBase {
472 histogram: Vec<HistogramEntry>,
473 }
474}
475
476define_request_and_response! {
477 get_coinbase_tx_sum,
478 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
479 core_rpc_server_commands_defs.h => 2213..=2248,
480
481 GetCoinbaseTxSum (restricted),
482
483 Request {
484 height: u64,
485 count: u64,
486 },
487
488 AccessResponseBase {
489 emission_amount: u64,
490 emission_amount_top64: u64,
491 fee_amount: u64,
492 fee_amount_top64: u64,
493 wide_emission_amount: String,
494 wide_fee_amount: String,
495 }
496}
497
498define_request_and_response! {
499 get_version,
500 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
501 core_rpc_server_commands_defs.h => 2170..=2211,
502
503 GetVersion (empty),
504 Request {},
505
506 ResponseBase {
507 version: u32,
508 release: bool,
509 current_height: u64,
510 target_height: u64,
511 hard_forks: Vec<HardForkEntry>,
512 }
513}
514
515define_request_and_response! {
516 get_fee_estimate,
517 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
518 core_rpc_server_commands_defs.h => 2250..=2277,
519
520 GetFeeEstimate,
521
522 Request {
523 grace_blocks: u64 = default::<u64>(), "default",
524 },
525
526 AccessResponseBase {
527 fee: u64,
528 fees: Vec<u64>,
529 quantization_mask: u64 = default_one::<u64>(), "default_one",
530 }
531}
532
533define_request_and_response! {
534 get_alternate_chains,
535 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
536 core_rpc_server_commands_defs.h => 2279..=2310,
537 GetAlternateChains (restricted, empty),
538 Request {},
539
540 ResponseBase {
541 chains: Vec<ChainInfo>,
542 }
543}
544
545define_request_and_response! {
546 relay_tx,
547 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
548 core_rpc_server_commands_defs.h => 2361..=2381,
549
550 RelayTx (restricted),
551
552 Request {
553 txids: Vec<Hex<32>> = default::<Vec<Hex<32>>>(), "default",
554 },
555
556 #[repr(transparent)]
557 Response {
558 status: Status,
559 }
560}
561
562define_request_and_response! {
563 sync_info,
564 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
565 core_rpc_server_commands_defs.h => 2383..=2443,
566
567 SyncInfo (restricted, empty),
568
569 Request {},
570
571 AccessResponseBase {
572 height: u64,
573 next_needed_pruning_seed: u32,
574 overview: String,
575 peers: Vec<SyncInfoPeer>,
576 spans: Vec<Span>,
577 target_height: u64,
578 }
579}
580
581define_request_and_response! {
582 get_txpool_backlog,
583 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
584 core_rpc_server_commands_defs.h => 1637..=1664,
585 GetTransactionPoolBacklog (empty),
586 Request {},
587
588 ResponseBase {
589 backlog: Vec<TxBacklogEntry>,
591 }
592}
593
594define_request_and_response! {
595 get_output_distribution,
596 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
597 core_rpc_server_commands_defs.h => 2445..=2520,
598
599 GetOutputDistribution,
603
604 Request {
605 amounts: Vec<u64>,
606 binary: bool = default_true(), "default_true",
607 compress: bool = default::<bool>(), "default",
608 cumulative: bool = default::<bool>(), "default",
609 from_height: u64 = default::<u64>(), "default",
610 to_height: u64 = default::<u64>(), "default",
611 },
612
613 AccessResponseBase {
614 distributions: Vec<Distribution>,
615 }
616}
617
618define_request_and_response! {
619 get_miner_data,
620 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
621 core_rpc_server_commands_defs.h => 996..=1044,
622 GetMinerData (empty),
623 Request {},
624
625 ResponseBase {
626 major_version: u8,
627 height: u64,
628 prev_id: Hex<32>,
629 seed_hash: Hex<32>,
630 difficulty: String,
631 median_weight: u64,
632 already_generated_coins: u64,
633 tx_backlog: Vec<GetMinerDataTxBacklogEntry>,
634 }
635}
636
637define_request_and_response! {
638 prune_blockchain,
639 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
640 core_rpc_server_commands_defs.h => 2747..=2772,
641
642 PruneBlockchain (restricted),
643
644 #[derive(Copy)]
645 Request {
646 check: bool = default::<bool>(), "default",
647 },
648
649 ResponseBase {
650 pruned: bool,
651 pruning_seed: u32,
652 }
653}
654
655define_request_and_response! {
656 calc_pow,
657 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
658 core_rpc_server_commands_defs.h => 1046..=1066,
659
660 CalcPow (restricted),
661
662 Request {
663 major_version: u8,
664 height: u64,
665 block_blob: HexVec,
666 seed_hash: Hex<32>,
667 },
668
669 #[cfg_attr(feature = "serde", serde(transparent))]
670 #[repr(transparent)]
671 Response {
672 pow_hash: Hex<32>,
673 }
674}
675
676define_request_and_response! {
677 flush_cache,
678 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
679 core_rpc_server_commands_defs.h => 2774..=2796,
680
681 FlushCache (restricted),
682
683 #[derive(Copy)]
684 Request {
685 bad_txs: bool,
686 bad_blocks: bool,
687 },
688
689 ResponseBase {}
690}
691
692define_request_and_response! {
693 add_aux_pow,
694 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
695 core_rpc_server_commands_defs.h => 1068..=1112,
696
697 AddAuxPow,
698
699 Request {
700 blocktemplate_blob: HexVec,
701 aux_pow: Vec<AuxPow>,
702 },
703
704 ResponseBase {
705 blocktemplate_blob: HexVec,
706 blockhashing_blob: HexVec,
707 merkle_root: Hex<32>,
708 merkle_tree_depth: u64,
709 aux_pow: Vec<AuxPow>,
710 }
711}
712
713define_request_and_response! {
714 UNDOCUMENTED_METHOD,
715 "cc73fe71162d564ffda8e549b79a350bca53c454" =>
716 core_rpc_server_commands_defs.h => 2798..=2823,
717
718 GetTxIdsLoose,
719
720 Request {
721 txid_template: String,
722 num_matching_bits: u32,
723 },
724 ResponseBase {
725 txids: Vec<Hex<32>>,
726 }
727}
728
729#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
738#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
739#[cfg_attr(
740 feature = "serde",
741 serde(rename_all = "snake_case", tag = "method", content = "params")
742)]
743pub enum JsonRpcRequest {
744 GetBlockTemplate(GetBlockTemplateRequest),
745 GetBlockCount(GetBlockCountRequest),
746 OnGetBlockHash(OnGetBlockHashRequest),
747 SubmitBlock(SubmitBlockRequest),
748 GenerateBlocks(GenerateBlocksRequest),
749 GetLastBlockHeader(GetLastBlockHeaderRequest),
750 GetBlockHeaderByHash(GetBlockHeaderByHashRequest),
751 GetBlockHeaderByHeight(GetBlockHeaderByHeightRequest),
752 GetBlockHeadersRange(GetBlockHeadersRangeRequest),
753 GetBlock(GetBlockRequest),
754 GetConnections(GetConnectionsRequest),
755 GetInfo(GetInfoRequest),
756 HardForkInfo(HardForkInfoRequest),
757 SetBans(SetBansRequest),
758 GetBans(GetBansRequest),
759 Banned(BannedRequest),
760 FlushTransactionPool(FlushTransactionPoolRequest),
761 GetOutputHistogram(GetOutputHistogramRequest),
762 GetCoinbaseTxSum(GetCoinbaseTxSumRequest),
763 GetVersion(GetVersionRequest),
764 GetFeeEstimate(GetFeeEstimateRequest),
765 GetAlternateChains(GetAlternateChainsRequest),
766 RelayTx(RelayTxRequest),
767 SyncInfo(SyncInfoRequest),
768 GetTransactionPoolBacklog(GetTransactionPoolBacklogRequest),
769 GetMinerData(GetMinerDataRequest),
770 PruneBlockchain(PruneBlockchainRequest),
771 CalcPow(CalcPowRequest),
772 FlushCache(FlushCacheRequest),
773 AddAuxPow(AddAuxPowRequest),
774 GetTxIdsLoose(GetTxIdsLooseRequest),
775}
776
777impl RpcCallValue for JsonRpcRequest {
778 fn is_restricted(&self) -> bool {
779 match self {
780 Self::GetBlockTemplate(x) => x.is_restricted(),
781 Self::GetBlockCount(x) => x.is_restricted(),
782 Self::OnGetBlockHash(x) => x.is_restricted(),
783 Self::SubmitBlock(x) => x.is_restricted(),
784 Self::GetLastBlockHeader(x) => x.is_restricted(),
785 Self::GetBlockHeaderByHash(x) => x.is_restricted(),
786 Self::GetBlockHeaderByHeight(x) => x.is_restricted(),
787 Self::GetBlockHeadersRange(x) => x.is_restricted(),
788 Self::GetBlock(x) => x.is_restricted(),
789 Self::GetInfo(x) => x.is_restricted(),
790 Self::HardForkInfo(x) => x.is_restricted(),
791 Self::GetOutputHistogram(x) => x.is_restricted(),
792 Self::GetVersion(x) => x.is_restricted(),
793 Self::GetFeeEstimate(x) => x.is_restricted(),
794 Self::GetTransactionPoolBacklog(x) => x.is_restricted(),
795 Self::GetMinerData(x) => x.is_restricted(),
796 Self::AddAuxPow(x) => x.is_restricted(),
797 Self::GetTxIdsLoose(x) => x.is_restricted(),
798 Self::GenerateBlocks(x) => x.is_restricted(),
799 Self::GetConnections(x) => x.is_restricted(),
800 Self::SetBans(x) => x.is_restricted(),
801 Self::GetBans(x) => x.is_restricted(),
802 Self::Banned(x) => x.is_restricted(),
803 Self::FlushTransactionPool(x) => x.is_restricted(),
804 Self::GetCoinbaseTxSum(x) => x.is_restricted(),
805 Self::GetAlternateChains(x) => x.is_restricted(),
806 Self::RelayTx(x) => x.is_restricted(),
807 Self::SyncInfo(x) => x.is_restricted(),
808 Self::PruneBlockchain(x) => x.is_restricted(),
809 Self::CalcPow(x) => x.is_restricted(),
810 Self::FlushCache(x) => x.is_restricted(),
811 }
812 }
813
814 fn is_empty(&self) -> bool {
815 match self {
816 Self::GetBlockTemplate(x) => x.is_empty(),
817 Self::GetBlockCount(x) => x.is_empty(),
818 Self::OnGetBlockHash(x) => x.is_empty(),
819 Self::SubmitBlock(x) => x.is_empty(),
820 Self::GetLastBlockHeader(x) => x.is_empty(),
821 Self::GetBlockHeaderByHash(x) => x.is_empty(),
822 Self::GetBlockHeaderByHeight(x) => x.is_empty(),
823 Self::GetBlockHeadersRange(x) => x.is_empty(),
824 Self::GetBlock(x) => x.is_empty(),
825 Self::GetInfo(x) => x.is_empty(),
826 Self::HardForkInfo(x) => x.is_empty(),
827 Self::GetOutputHistogram(x) => x.is_empty(),
828 Self::GetVersion(x) => x.is_empty(),
829 Self::GetFeeEstimate(x) => x.is_empty(),
830 Self::GetTransactionPoolBacklog(x) => x.is_empty(),
831 Self::GetMinerData(x) => x.is_empty(),
832 Self::AddAuxPow(x) => x.is_empty(),
833 Self::GetTxIdsLoose(x) => x.is_empty(),
834 Self::GenerateBlocks(x) => x.is_empty(),
835 Self::GetConnections(x) => x.is_empty(),
836 Self::SetBans(x) => x.is_empty(),
837 Self::GetBans(x) => x.is_empty(),
838 Self::Banned(x) => x.is_empty(),
839 Self::FlushTransactionPool(x) => x.is_empty(),
840 Self::GetCoinbaseTxSum(x) => x.is_empty(),
841 Self::GetAlternateChains(x) => x.is_empty(),
842 Self::RelayTx(x) => x.is_empty(),
843 Self::SyncInfo(x) => x.is_empty(),
844 Self::PruneBlockchain(x) => x.is_empty(),
845 Self::CalcPow(x) => x.is_empty(),
846 Self::FlushCache(x) => x.is_empty(),
847 }
848 }
849}
850
851#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
876#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
877#[cfg_attr(feature = "serde", serde(untagged, rename_all = "snake_case"))]
878pub enum JsonRpcResponse {
879 GetBlockTemplate(GetBlockTemplateResponse),
880 GetBlockCount(GetBlockCountResponse),
881 OnGetBlockHash(OnGetBlockHashResponse),
882 SubmitBlock(SubmitBlockResponse),
883 GenerateBlocks(GenerateBlocksResponse),
884 GetLastBlockHeader(GetLastBlockHeaderResponse),
885 GetBlockHeaderByHash(GetBlockHeaderByHashResponse),
886 GetBlockHeaderByHeight(GetBlockHeaderByHeightResponse),
887 GetBlockHeadersRange(GetBlockHeadersRangeResponse),
888 GetBlock(GetBlockResponse),
889 GetConnections(GetConnectionsResponse),
890 GetInfo(GetInfoResponse),
891 HardForkInfo(HardForkInfoResponse),
892 SetBans(SetBansResponse),
893 GetBans(GetBansResponse),
894 Banned(BannedResponse),
895 FlushTransactionPool(FlushTransactionPoolResponse),
896 GetOutputHistogram(GetOutputHistogramResponse),
897 GetCoinbaseTxSum(GetCoinbaseTxSumResponse),
898 GetVersion(GetVersionResponse),
899 GetFeeEstimate(GetFeeEstimateResponse),
900 GetAlternateChains(GetAlternateChainsResponse),
901 RelayTx(RelayTxResponse),
902 SyncInfo(SyncInfoResponse),
903 GetTransactionPoolBacklog(GetTransactionPoolBacklogResponse),
904 GetMinerData(GetMinerDataResponse),
905 PruneBlockchain(PruneBlockchainResponse),
906 CalcPow(CalcPowResponse),
907 FlushCache(FlushCacheResponse),
908 AddAuxPow(AddAuxPowResponse),
909 GetTxIdsLoose(GetTxIdsLooseResponse),
910}
911
912#[cfg(test)]
914mod test {
915 use std::fmt::Debug;
916
917 use hex_literal::hex;
918 use pretty_assertions::assert_eq;
919 use serde::de::DeserializeOwned;
920 use serde_json::{from_str, from_value, Value};
921
922 use cuprate_test_utils::rpc::data::json;
923 use cuprate_types::HardFork;
924
925 use super::*;
926
927 #[expect(clippy::needless_pass_by_value)]
928 fn test_json_request<T: DeserializeOwned + PartialEq + Debug>(
929 cuprate_test_utils_example_data: &str,
930 expected_type: T,
931 ) {
932 let value = from_str::<Value>(cuprate_test_utils_example_data).unwrap();
933 let Value::Object(map) = value else {
934 unreachable!();
935 };
936
937 let params = map.get("params").unwrap();
938 let response = from_value::<T>(params.clone()).unwrap();
939 assert_eq!(response, expected_type);
940 }
941
942 #[expect(clippy::needless_pass_by_value)]
943 fn test_json_response<T: DeserializeOwned + PartialEq + Debug>(
944 cuprate_test_utils_example_data: &str,
945 expected_type: T,
946 ) {
947 let value = from_str::<Value>(cuprate_test_utils_example_data).unwrap();
948 let Value::Object(map) = value else {
949 unreachable!();
950 };
951
952 let result = map.get("result").unwrap().clone();
953 let response = from_value::<T>(result).unwrap();
954 assert_eq!(response, expected_type);
955 }
956
957 #[test]
958 fn get_block_template_request() {
959 test_json_request(json::GET_BLOCK_TEMPLATE_REQUEST, GetBlockTemplateRequest {
960 reserve_size: 60,
961 extra_nonce: HexVec::default(),
962 prev_block: HexVec::default(),
963 wallet_address: "44GBHzv6ZyQdJkjqZje6KLZ3xSyN1hBSFAnLP6EAqJtCRVzMzZmeXTC2AHKDS9aEDTRKmo6a6o9r9j86pYfhCWDkKjbtcns".into(),
964 });
965 }
966
967 #[test]
968 fn get_block_template_response() {
969 test_json_response(json::GET_BLOCK_TEMPLATE_RESPONSE, GetBlockTemplateResponse {
970 base: ResponseBase::OK,
971 blockhashing_blob: HexVec(hex!("1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a00000000e0c20372be23d356347091025c5b5e8f2abf83ab618378565cce2b703491523401").into()),
972 blocktemplate_blob: HexVec(hex!("1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()),
973 difficulty_top64: 0,
974 difficulty: 283305047039,
975 expected_reward: 600000000000,
976 height: 3195018,
977 next_seed_hash: HexVec::new(),
978 prev_hash: Hex(hex!("9d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a")),
979 reserved_offset: 131,
980 seed_hash: Hex(hex!("e2aa0b7b55042cd48b02e395d78fa66a29815ccc1584e38db2d1f0e8485cd44f")),
981 seed_height: 3194880,
982 wide_difficulty: "0x41f64bf3ff".into(),
983 });
984 }
985
986 #[test]
987 fn get_block_count_response() {
988 test_json_response(
989 json::GET_BLOCK_COUNT_RESPONSE,
990 GetBlockCountResponse {
991 base: ResponseBase::OK,
992 count: 3195019,
993 },
994 );
995 }
996
997 #[test]
998 fn get_block_hash_request() {
999 test_json_request(
1000 json::ON_GET_BLOCK_HASH_REQUEST,
1001 OnGetBlockHashRequest {
1002 block_height: [912345],
1003 },
1004 );
1005 }
1006
1007 #[test]
1008 fn get_block_hash_response() {
1009 test_json_response(
1010 json::ON_GET_BLOCK_HASH_RESPONSE,
1011 OnGetBlockHashResponse {
1012 block_hash: Hex(hex!(
1013 "e22cf75f39ae720e8b71b3d120a5ac03f0db50bba6379e2850975b4859190bc6"
1014 )),
1015 },
1016 );
1017 }
1018
1019 #[test]
1020 fn submit_block_request() {
1021 test_json_request(json::SUBMIT_BLOCK_REQUEST, SubmitBlockRequest {
1022 block_blob: [HexVec(hex!("0707e6bdfedc053771512f1bc27c62731ae9e8f2443db64ce742f4e57f5cf8d393de28551e441a0000000002fb830a01ffbf830a018cfe88bee283060274c0aae2ef5730e680308d9c00b6da59187ad0352efe3c71d36eeeb28782f29f2501bd56b952c3ddc3e350c2631d3a5086cac172c56893831228b17de296ff4669de020200000000").into())],
1023 });
1024 }
1025
1026 #[test]
1027 fn generate_blocks_request() {
1028 test_json_request(json::GENERATE_BLOCKS_REQUEST, GenerateBlocksRequest {
1029 amount_of_blocks: 1,
1030 prev_block: HexVec::default(),
1031 wallet_address: "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A".into(),
1032 starting_nonce: 0
1033 });
1034 }
1035
1036 #[test]
1037 fn generate_blocks_response() {
1038 test_json_response(
1039 json::GENERATE_BLOCKS_RESPONSE,
1040 GenerateBlocksResponse {
1041 base: ResponseBase::OK,
1042 blocks: vec![Hex(hex!(
1043 "49b712db7760e3728586f8434ee8bc8d7b3d410dac6bb6e98bf5845c83b917e4"
1044 ))],
1045 height: 9783,
1046 },
1047 );
1048 }
1049
1050 #[test]
1051 fn get_last_block_header_response() {
1052 test_json_response(
1053 json::GET_LAST_BLOCK_HEADER_RESPONSE,
1054 GetLastBlockHeaderResponse {
1055 base: AccessResponseBase::OK,
1056 block_header: BlockHeader {
1057 block_size: 200419,
1058 block_weight: 200419,
1059 cumulative_difficulty: 366125734645190820,
1060 cumulative_difficulty_top64: 0,
1061 depth: 0,
1062 difficulty: 282052561854,
1063 difficulty_top64: 0,
1064 hash: Hex(hex!(
1065 "57238217820195ac4c08637a144a885491da167899cf1d20e8e7ce0ae0a3434e"
1066 )),
1067 height: 3195020,
1068 long_term_weight: 200419,
1069 major_version: HardFork::V16,
1070 miner_tx_hash: Hex(hex!(
1071 "7a42667237d4f79891bb407c49c712a9299fb87fce799833a7b633a3a9377dbd"
1072 )),
1073 minor_version: 16,
1074 nonce: 1885649739,
1075 num_txes: 37,
1076 orphan_status: false,
1077 pow_hash: HexVec::new(),
1078 prev_hash: Hex(hex!(
1079 "22c72248ae9c5a2863c94735d710a3525c499f70707d1c2f395169bc5c8a0da3"
1080 )),
1081 reward: 615702960000,
1082 timestamp: 1721245548,
1083 wide_cumulative_difficulty: "0x514bd6a74a7d0a4".into(),
1084 wide_difficulty: "0x41aba48bbe".into(),
1085 },
1086 },
1087 );
1088 }
1089
1090 #[test]
1091 fn get_block_header_by_hash_request() {
1092 test_json_request(
1093 json::GET_BLOCK_HEADER_BY_HASH_REQUEST,
1094 GetBlockHeaderByHashRequest {
1095 hash: Hex(hex!(
1096 "e22cf75f39ae720e8b71b3d120a5ac03f0db50bba6379e2850975b4859190bc6"
1097 )),
1098 hashes: vec![],
1099 fill_pow_hash: false,
1100 },
1101 );
1102 }
1103
1104 #[test]
1105 fn get_block_header_by_hash_response() {
1106 test_json_response(
1107 json::GET_BLOCK_HEADER_BY_HASH_RESPONSE,
1108 GetBlockHeaderByHashResponse {
1109 base: AccessResponseBase::OK,
1110 block_headers: vec![],
1111 block_header: BlockHeader {
1112 block_size: 210,
1113 block_weight: 210,
1114 cumulative_difficulty: 754734824984346,
1115 cumulative_difficulty_top64: 0,
1116 depth: 2282676,
1117 difficulty: 815625611,
1118 difficulty_top64: 0,
1119 hash: Hex(hex!(
1120 "e22cf75f39ae720e8b71b3d120a5ac03f0db50bba6379e2850975b4859190bc6"
1121 )),
1122 height: 912345,
1123 long_term_weight: 210,
1124 major_version: HardFork::V1,
1125 miner_tx_hash: Hex(hex!(
1126 "c7da3965f25c19b8eb7dd8db48dcd4e7c885e2491db77e289f0609bf8e08ec30"
1127 )),
1128 minor_version: 2,
1129 nonce: 1646,
1130 num_txes: 0,
1131 orphan_status: false,
1132 pow_hash: HexVec::new(),
1133 prev_hash: Hex(hex!(
1134 "b61c58b2e0be53fad5ef9d9731a55e8a81d972b8d90ed07c04fd37ca6403ff78"
1135 )),
1136 reward: 7388968946286,
1137 timestamp: 1452793716,
1138 wide_cumulative_difficulty: "0x2ae6d65248f1a".into(),
1139 wide_difficulty: "0x309d758b".into(),
1140 },
1141 },
1142 );
1143 }
1144
1145 #[test]
1146 fn block_header_by_height_request() {
1147 test_json_request(
1148 json::GET_BLOCK_HEADER_BY_HEIGHT_REQUEST,
1149 GetBlockHeaderByHeightRequest {
1150 height: 912345,
1151 fill_pow_hash: false,
1152 },
1153 );
1154 }
1155
1156 #[test]
1157 fn block_header_by_height_response() {
1158 test_json_response(
1159 json::GET_BLOCK_HEADER_BY_HEIGHT_RESPONSE,
1160 GetBlockHeaderByHeightResponse {
1161 base: AccessResponseBase::OK,
1162 block_header: BlockHeader {
1163 block_size: 210,
1164 block_weight: 210,
1165 cumulative_difficulty: 754734824984346,
1166 cumulative_difficulty_top64: 0,
1167 depth: 2282677,
1168 difficulty: 815625611,
1169 difficulty_top64: 0,
1170 hash: Hex(hex!(
1171 "e22cf75f39ae720e8b71b3d120a5ac03f0db50bba6379e2850975b4859190bc6"
1172 )),
1173 height: 912345,
1174 long_term_weight: 210,
1175 major_version: HardFork::V1,
1176 miner_tx_hash: Hex(hex!(
1177 "c7da3965f25c19b8eb7dd8db48dcd4e7c885e2491db77e289f0609bf8e08ec30"
1178 )),
1179 minor_version: 2,
1180 nonce: 1646,
1181 num_txes: 0,
1182 orphan_status: false,
1183 pow_hash: HexVec::new(),
1184 prev_hash: Hex(hex!(
1185 "b61c58b2e0be53fad5ef9d9731a55e8a81d972b8d90ed07c04fd37ca6403ff78"
1186 )),
1187 reward: 7388968946286,
1188 timestamp: 1452793716,
1189 wide_cumulative_difficulty: "0x2ae6d65248f1a".into(),
1190 wide_difficulty: "0x309d758b".into(),
1191 },
1192 },
1193 );
1194 }
1195
1196 #[test]
1197 fn block_headers_range_request() {
1198 test_json_request(
1199 json::GET_BLOCK_HEADERS_RANGE_REQUEST,
1200 GetBlockHeadersRangeRequest {
1201 start_height: 1545999,
1202 end_height: 1546000,
1203 fill_pow_hash: false,
1204 },
1205 );
1206 }
1207
1208 #[test]
1209 fn block_headers_range_response() {
1210 test_json_response(
1211 json::GET_BLOCK_HEADERS_RANGE_RESPONSE,
1212 GetBlockHeadersRangeResponse {
1213 base: AccessResponseBase::OK,
1214 headers: vec![
1215 BlockHeader {
1216 block_size: 301413,
1217 block_weight: 301413,
1218 cumulative_difficulty: 13185267971483472,
1219 cumulative_difficulty_top64: 0,
1220 depth: 1649024,
1221 difficulty: 134636057921,
1222 difficulty_top64: 0,
1223 hash: Hex(hex!(
1224 "86d1d20a40cefcf3dd410ff6967e0491613b77bf73ea8f1bf2e335cf9cf7d57a"
1225 )),
1226 height: 1545999,
1227 long_term_weight: 301413,
1228 major_version: HardFork::V6,
1229 miner_tx_hash: Hex(hex!(
1230 "9909c6f8a5267f043c3b2b079fb4eacc49ef9c1dee1c028eeb1a259b95e6e1d9"
1231 )),
1232 minor_version: 6,
1233 nonce: 3246403956,
1234 num_txes: 20,
1235 orphan_status: false,
1236 pow_hash: HexVec::new(),
1237 prev_hash: Hex(hex!(
1238 "0ef6e948f77b8f8806621003f5de24b1bcbea150bc0e376835aea099674a5db5"
1239 )),
1240 reward: 5025593029981,
1241 timestamp: 1523002893,
1242 wide_cumulative_difficulty: "0x2ed7ee6db56750".into(),
1243 wide_difficulty: "0x1f58ef3541".into(),
1244 },
1245 BlockHeader {
1246 block_size: 13322,
1247 block_weight: 13322,
1248 cumulative_difficulty: 13185402687569710,
1249 cumulative_difficulty_top64: 0,
1250 depth: 1649023,
1251 difficulty: 134716086238,
1252 difficulty_top64: 0,
1253 hash: Hex(hex!(
1254 "b408bf4cfcd7de13e7e370c84b8314c85b24f0ba4093ca1d6eeb30b35e34e91a"
1255 )),
1256 height: 1546000,
1257 long_term_weight: 13322,
1258 major_version: HardFork::V7,
1259 miner_tx_hash: Hex(hex!(
1260 "7f749c7c64acb35ef427c7454c45e6688781fbead9bbf222cb12ad1a96a4e8f6"
1261 )),
1262 minor_version: 7,
1263 nonce: 3737164176,
1264 num_txes: 1,
1265 orphan_status: false,
1266 pow_hash: HexVec::new(),
1267 prev_hash: Hex(hex!(
1268 "86d1d20a40cefcf3dd410ff6967e0491613b77bf73ea8f1bf2e335cf9cf7d57a"
1269 )),
1270 reward: 4851952181070,
1271 timestamp: 1523002931,
1272 wide_cumulative_difficulty: "0x2ed80dcb69bf2e".into(),
1273 wide_difficulty: "0x1f5db457de".into(),
1274 },
1275 ],
1276 },
1277 );
1278 }
1279
1280 #[test]
1281 fn get_block_request() {
1282 test_json_request(
1283 json::GET_BLOCK_REQUEST,
1284 GetBlockRequest {
1285 height: 2751506,
1286 hash: HexVec::new(),
1287 fill_pow_hash: false,
1288 },
1289 );
1290 }
1291
1292 #[test]
1293 fn get_block_response() {
1294 test_json_response(json::GET_BLOCK_RESPONSE, GetBlockResponse {
1295 base: AccessResponseBase::OK,
1296 blob: HexVec(hex!("1010c58bab9b06b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7807e07f502cef8a70101ff92f8a7010180e0a596bb1103d7cbf826b665d7a532c316982dc8dbc24f285cbc18bbcc27c7164cd9b3277a85d034019f629d8b36bd16a2bfce3ea80c31dc4d8762c67165aec21845494e32b7582fe00211000000297a787a000000000000000000000000").into()),
1297 block_header: BlockHeader {
1298 block_size: 106,
1299 block_weight: 106,
1300 cumulative_difficulty: 236046001376524168,
1301 cumulative_difficulty_top64: 0,
1302 depth: 443517,
1303 difficulty: 313732272488,
1304 difficulty_top64: 0,
1305 hash: Hex(hex!("43bd1f2b6556dcafa413d8372974af59e4e8f37dbf74dc6b2a9b7212d0577428")),
1306 height: 2751506,
1307 long_term_weight: 176470,
1308 major_version: HardFork::V16,
1309 miner_tx_hash: Hex(hex!("e49b854c5f339d7410a77f2a137281d8042a0ffc7ef9ab24cd670b67139b24cd")),
1310 minor_version: 16,
1311 nonce: 4110909056,
1312 num_txes: 0,
1313 orphan_status: false,
1314 pow_hash: HexVec::new(),
1315 prev_hash: Hex(hex!("b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7")),
1316 reward: 600000000000,
1317 timestamp: 1667941829,
1318 wide_cumulative_difficulty: "0x3469a966eb2f788".into(),
1319 wide_difficulty: "0x490be69168".into()
1320 },
1321 json: "{\n \"major_version\": 16, \n \"minor_version\": 16, \n \"timestamp\": 1667941829, \n \"prev_id\": \"b27bdecfc6cd0a46172d136c08831cf67660377ba992332363228b1b722781e7\", \n \"nonce\": 4110909056, \n \"miner_tx\": {\n \"version\": 2, \n \"unlock_time\": 2751566, \n \"vin\": [ {\n \"gen\": {\n \"height\": 2751506\n }\n }\n ], \n \"vout\": [ {\n \"amount\": 600000000000, \n \"target\": {\n \"tagged_key\": {\n \"key\": \"d7cbf826b665d7a532c316982dc8dbc24f285cbc18bbcc27c7164cd9b3277a85\", \n \"view_tag\": \"d0\"\n }\n }\n }\n ], \n \"extra\": [ 1, 159, 98, 157, 139, 54, 189, 22, 162, 191, 206, 62, 168, 12, 49, 220, 77, 135, 98, 198, 113, 101, 174, 194, 24, 69, 73, 78, 50, 183, 88, 47, 224, 2, 17, 0, 0, 0, 41, 122, 120, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n ], \n \"rct_signatures\": {\n \"type\": 0\n }\n }, \n \"tx_hashes\": [ ]\n}".into(),
1322 miner_tx_hash: Hex(hex!("e49b854c5f339d7410a77f2a137281d8042a0ffc7ef9ab24cd670b67139b24cd")),
1323 tx_hashes: vec![],
1324 });
1325 }
1326
1327 #[test]
1328 fn get_connections_response() {
1329 test_json_response(
1330 json::GET_CONNECTIONS_RESPONSE,
1331 GetConnectionsResponse {
1332 base: ResponseBase::OK,
1333 connections: vec![
1334 ConnectionInfo {
1335 address:
1336 "3evk3kezfjg44ma6tvesy7rbxwwpgpympj45xar5fo4qajrsmkoaqdqd.onion:18083"
1337 .into(),
1338 address_type: cuprate_types::AddressType::Tor,
1339 avg_download: 0,
1340 avg_upload: 0,
1341 connection_id: "22ef856d0f1d44cc95e84fecfd065fe2".into(),
1342 current_download: 0,
1343 current_upload: 0,
1344 height: 3195026,
1345 host: "3evk3kezfjg44ma6tvesy7rbxwwpgpympj45xar5fo4qajrsmkoaqdqd.onion"
1346 .into(),
1347 incoming: false,
1348 ip: String::new(),
1349 live_time: 76651,
1350 local_ip: false,
1351 localhost: false,
1352 peer_id: "0000000000000001".into(),
1353 port: String::new(),
1354 pruning_seed: 0,
1355 recv_count: 240328,
1356 recv_idle_time: 34,
1357 rpc_credits_per_hash: 0,
1358 rpc_port: 0,
1359 send_count: 3406572,
1360 send_idle_time: 30,
1361 state: cuprate_types::ConnectionState::Normal,
1362 support_flags: 0,
1363 },
1364 ConnectionInfo {
1365 address:
1366 "4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion:18083"
1367 .into(),
1368 address_type: cuprate_types::AddressType::Tor,
1369 avg_download: 0,
1370 avg_upload: 0,
1371 connection_id: "c7734e15936f485a86d2b0534f87e499".into(),
1372 current_download: 0,
1373 current_upload: 0,
1374 height: 3195024,
1375 host: "4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion"
1376 .into(),
1377 incoming: false,
1378 ip: String::new(),
1379 live_time: 76755,
1380 local_ip: false,
1381 localhost: false,
1382 peer_id: "0000000000000001".into(),
1383 port: String::new(),
1384 pruning_seed: 389,
1385 recv_count: 237657,
1386 recv_idle_time: 120,
1387 rpc_credits_per_hash: 0,
1388 rpc_port: 0,
1389 send_count: 3370566,
1390 send_idle_time: 120,
1391 state: cuprate_types::ConnectionState::Normal,
1392 support_flags: 0,
1393 },
1394 ],
1395 },
1396 );
1397 }
1398
1399 #[test]
1400 fn get_info_response() {
1401 test_json_response(
1402 json::GET_INFO_RESPONSE,
1403 GetInfoResponse {
1404 base: AccessResponseBase::OK,
1405 adjusted_time: 1721245289,
1406 alt_blocks_count: 16,
1407 block_size_limit: 600000,
1408 block_size_median: 300000,
1409 block_weight_limit: 600000,
1410 block_weight_median: 300000,
1411 bootstrap_daemon_address: String::new(),
1412 busy_syncing: false,
1413 cumulative_difficulty: 366127702242611947,
1414 cumulative_difficulty_top64: 0,
1415 database_size: 235169075200,
1416 difficulty: 280716748706,
1417 difficulty_top64: 0,
1418 free_space: 30521749504,
1419 grey_peerlist_size: 4996,
1420 height: 3195028,
1421 height_without_bootstrap: 3195028,
1422 incoming_connections_count: 62,
1423 mainnet: true,
1424 nettype: "mainnet".into(),
1425 offline: false,
1426 outgoing_connections_count: 1143,
1427 restricted: false,
1428 rpc_connections_count: 1,
1429 stagenet: false,
1430 start_time: 1720462427,
1431 synchronized: true,
1432 target: 120,
1433 target_height: 0,
1434 testnet: false,
1435 top_block_hash: Hex(hex!(
1436 "bdf06d18ed1931a8ee62654e9b6478cc459bc7072628b8e36f4524d339552946"
1437 )),
1438 tx_count: 43205750,
1439 tx_pool_size: 12,
1440 update_available: false,
1441 version: "0.18.3.3-release".into(),
1442 was_bootstrap_ever_used: false,
1443 white_peerlist_size: 1000,
1444 wide_cumulative_difficulty: "0x514bf349299d2eb".into(),
1445 wide_difficulty: "0x415c05a7a2".into(),
1446 },
1447 );
1448 }
1449
1450 #[test]
1451 fn hard_fork_info_request() {
1452 test_json_request(
1453 json::HARD_FORK_INFO_REQUEST,
1454 HardForkInfoRequest { version: 16 },
1455 );
1456 }
1457
1458 #[test]
1459 fn hard_fork_info_response() {
1460 test_json_response(
1461 json::HARD_FORK_INFO_RESPONSE,
1462 HardForkInfoResponse {
1463 base: AccessResponseBase::OK,
1464 hard_fork_info: HardForkInfo {
1465 earliest_height: 2689608,
1466 enabled: true,
1467 state: 0,
1468 threshold: 0,
1469 version: 16,
1470 votes: 10080,
1471 voting: 16,
1472 window: 10080,
1473 },
1474 },
1475 );
1476 }
1477
1478 #[test]
1479 fn set_bans_request() {
1480 test_json_request(
1481 json::SET_BANS_REQUEST,
1482 SetBansRequest {
1483 bans: vec![SetBan {
1484 host: "192.168.1.51".into(),
1485 ip: 0,
1486 ban: true,
1487 seconds: 30,
1488 }],
1489 },
1490 );
1491 }
1492
1493 #[test]
1494 fn set_bans_response() {
1495 test_json_response(
1496 json::SET_BANS_RESPONSE,
1497 SetBansResponse {
1498 base: ResponseBase::OK,
1499 },
1500 );
1501 }
1502
1503 #[test]
1504 fn get_bans_response() {
1505 test_json_response(
1506 json::GET_BANS_RESPONSE,
1507 GetBansResponse {
1508 base: ResponseBase::OK,
1509 bans: vec![
1510 GetBan {
1511 host: "104.248.206.131".into(),
1512 ip: 2211379304,
1513 seconds: 689754,
1514 },
1515 GetBan {
1516 host: "209.222.252.0/24".into(),
1517 ip: 0,
1518 seconds: 689754,
1519 },
1520 ],
1521 },
1522 );
1523 }
1524
1525 #[test]
1526 fn banned_request() {
1527 test_json_request(
1528 json::BANNED_REQUEST,
1529 BannedRequest {
1530 address: "95.216.203.255".into(),
1531 },
1532 );
1533 }
1534
1535 #[test]
1536 fn banned_response() {
1537 test_json_response(
1538 json::BANNED_RESPONSE,
1539 BannedResponse {
1540 banned: true,
1541 seconds: 689655,
1542 status: Status::Ok,
1543 },
1544 );
1545 }
1546
1547 #[test]
1548 fn flush_transaction_pool_request() {
1549 test_json_request(
1550 json::FLUSH_TRANSACTION_POOL_REQUEST,
1551 FlushTransactionPoolRequest {
1552 txids: vec![Hex(hex!(
1553 "dc16fa8eaffe1484ca9014ea050e13131d3acf23b419f33bb4cc0b32b6c49308"
1554 ))],
1555 },
1556 );
1557 }
1558
1559 #[test]
1560 fn flush_transaction_pool_response() {
1561 test_json_response(
1562 json::FLUSH_TRANSACTION_POOL_RESPONSE,
1563 FlushTransactionPoolResponse { status: Status::Ok },
1564 );
1565 }
1566
1567 #[test]
1568 fn get_output_histogram_request() {
1569 test_json_request(
1570 json::GET_OUTPUT_HISTOGRAM_REQUEST,
1571 GetOutputHistogramRequest {
1572 amounts: vec![20000000000],
1573 min_count: 0,
1574 max_count: 0,
1575 unlocked: false,
1576 recent_cutoff: 0,
1577 },
1578 );
1579 }
1580
1581 #[test]
1582 fn get_output_histogram_response() {
1583 test_json_response(
1584 json::GET_OUTPUT_HISTOGRAM_RESPONSE,
1585 GetOutputHistogramResponse {
1586 base: AccessResponseBase::OK,
1587 histogram: vec![HistogramEntry {
1588 amount: 20000000000,
1589 recent_instances: 0,
1590 total_instances: 381490,
1591 unlocked_instances: 0,
1592 }],
1593 },
1594 );
1595 }
1596
1597 #[test]
1598 fn get_coinbase_tx_sum_request() {
1599 test_json_request(
1600 json::GET_COINBASE_TX_SUM_REQUEST,
1601 GetCoinbaseTxSumRequest {
1602 height: 1563078,
1603 count: 2,
1604 },
1605 );
1606 }
1607
1608 #[test]
1609 fn get_coinbase_tx_sum_response() {
1610 test_json_response(
1611 json::GET_COINBASE_TX_SUM_RESPONSE,
1612 GetCoinbaseTxSumResponse {
1613 base: AccessResponseBase::OK,
1614 emission_amount: 9387854817320,
1615 emission_amount_top64: 0,
1616 fee_amount: 83981380000,
1617 fee_amount_top64: 0,
1618 wide_emission_amount: "0x889c7c06828".into(),
1619 wide_fee_amount: "0x138dae29a0".into(),
1620 },
1621 );
1622 }
1623
1624 #[test]
1625 fn get_version_response() {
1626 test_json_response(
1627 json::GET_VERSION_RESPONSE,
1628 GetVersionResponse {
1629 base: ResponseBase::OK,
1630 current_height: 3195051,
1631 hard_forks: [
1632 (1, HardFork::V1),
1633 (1009827, HardFork::V2),
1634 (1141317, HardFork::V3),
1635 (1220516, HardFork::V4),
1636 (1288616, HardFork::V5),
1637 (1400000, HardFork::V6),
1638 (1546000, HardFork::V7),
1639 (1685555, HardFork::V8),
1640 (1686275, HardFork::V9),
1641 (1788000, HardFork::V10),
1642 (1788720, HardFork::V11),
1643 (1978433, HardFork::V12),
1644 (2210000, HardFork::V13),
1645 (2210720, HardFork::V14),
1646 (2688888, HardFork::V15),
1647 (2689608, HardFork::V16),
1648 ]
1649 .into_iter()
1650 .map(|(height, hf_version)| HardForkEntry { height, hf_version })
1651 .collect(),
1652 release: true,
1653 version: 196621,
1654 target_height: 0,
1655 },
1656 );
1657 }
1658
1659 #[test]
1660 fn get_fee_estimate_response() {
1661 test_json_response(
1662 json::GET_FEE_ESTIMATE_RESPONSE,
1663 GetFeeEstimateResponse {
1664 base: AccessResponseBase::OK,
1665 fee: 20000,
1666 fees: vec![20000, 80000, 320000, 4000000],
1667 quantization_mask: 10000,
1668 },
1669 );
1670 }
1671
1672 #[test]
1673 fn get_alternate_chains_response() {
1674 test_json_response(
1675 json::GET_ALTERNATE_CHAINS_RESPONSE,
1676 GetAlternateChainsResponse {
1677 base: ResponseBase::OK,
1678 chains: vec![
1679 ChainInfo {
1680 block_hash: Hex(hex!(
1681 "4826c7d45d7cf4f02985b5c405b0e5d7f92c8d25e015492ce19aa3b209295dce"
1682 )),
1683 block_hashes: vec![Hex(hex!(
1684 "4826c7d45d7cf4f02985b5c405b0e5d7f92c8d25e015492ce19aa3b209295dce"
1685 ))],
1686 difficulty: 357404825113208373,
1687 difficulty_top64: 0,
1688 height: 3167471,
1689 length: 1,
1690 main_chain_parent_block: Hex(hex!(
1691 "69b5075ea627d6ba06b1c30b7e023884eeaef5282cf58ec847dab838ddbcdd86"
1692 )),
1693 wide_difficulty: "0x4f5c1cb79e22635".into(),
1694 },
1695 ChainInfo {
1696 block_hash: Hex(hex!(
1697 "33ee476f5a1c5b9d889274cbbe171f5e0112df7ed69021918042525485deb401"
1698 )),
1699 block_hashes: vec![Hex(hex!(
1700 "33ee476f5a1c5b9d889274cbbe171f5e0112df7ed69021918042525485deb401"
1701 ))],
1702 difficulty: 354736121711617293,
1703 difficulty_top64: 0,
1704 height: 3157465,
1705 length: 1,
1706 main_chain_parent_block: Hex(hex!(
1707 "fd522fcc4cefe5c8c0e5c5600981b3151772c285df3a4e38e5c4011cf466d2cb"
1708 )),
1709 wide_difficulty: "0x4ec469f8b9ee50d".into(),
1710 },
1711 ],
1712 },
1713 );
1714 }
1715
1716 #[test]
1717 fn relay_tx_request() {
1718 test_json_request(
1719 json::RELAY_TX_REQUEST,
1720 RelayTxRequest {
1721 txids: vec![Hex(hex!(
1722 "9fd75c429cbe52da9a52f2ffc5fbd107fe7fd2099c0d8de274dc8a67e0c98613"
1723 ))],
1724 },
1725 );
1726 }
1727
1728 #[test]
1729 fn relay_tx_response() {
1730 test_json_response(
1731 json::RELAY_TX_RESPONSE,
1732 RelayTxResponse { status: Status::Ok },
1733 );
1734 }
1735
1736 #[test]
1737 fn sync_info_response() {
1738 test_json_response(json::SYNC_INFO_RESPONSE, SyncInfoResponse {
1739 base: AccessResponseBase::OK,
1740 height: 3195157,
1741 next_needed_pruning_seed: 0,
1742 overview: "[]".into(),
1743 spans: vec![],
1744 peers: vec![
1745 SyncInfoPeer {
1746 info: ConnectionInfo {
1747 address: "142.93.128.65:44986".into(),
1748 address_type: cuprate_types::AddressType::Ipv4,
1749 avg_download: 1,
1750 avg_upload: 1,
1751 connection_id: "a5803c4c2dac49e7b201dccdef54c862".into(),
1752 current_download: 2,
1753 current_upload: 1,
1754 height: 3195157,
1755 host: "142.93.128.65".into(),
1756 incoming: true,
1757 ip: "142.93.128.65".into(),
1758 live_time: 18,
1759 local_ip: false,
1760 localhost: false,
1761 peer_id: "6830e9764d3e5687".into(),
1762 port: "44986".into(),
1763 pruning_seed: 0,
1764 recv_count: 20340,
1765 recv_idle_time: 0,
1766 rpc_credits_per_hash: 0,
1767 rpc_port: 18089,
1768 send_count: 32235,
1769 send_idle_time: 6,
1770 state: cuprate_types::ConnectionState::Normal,
1771 support_flags: 1
1772 }
1773 },
1774 SyncInfoPeer {
1775 info: ConnectionInfo {
1776 address: "4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion:18083".into(),
1777 address_type: cuprate_types::AddressType::Tor,
1778 avg_download: 0,
1779 avg_upload: 0,
1780 connection_id: "277f7c821bc546878c8bd29977e780f5".into(),
1781 current_download: 0,
1782 current_upload: 0,
1783 height: 3195157,
1784 host: "4iykytmumafy5kjahdqc7uzgcs34s2vwsadfjpk4znvsa5vmcxeup2qd.onion".into(),
1785 incoming: false,
1786 ip: String::new(),
1787 live_time: 2246,
1788 local_ip: false,
1789 localhost: false,
1790 peer_id: "0000000000000001".into(),
1791 port: String::new(),
1792 pruning_seed: 389,
1793 recv_count: 65164,
1794 recv_idle_time: 15,
1795 rpc_credits_per_hash: 0,
1796 rpc_port: 0,
1797 send_count: 99120,
1798 send_idle_time: 15,
1799 state: cuprate_types::ConnectionState::Normal,
1800 support_flags: 0
1801 }
1802 }
1803 ],
1804 target_height: 0,
1805 });
1806 }
1807
1808 #[test]
1818 fn get_output_distribution_request() {
1819 test_json_request(
1820 json::GET_OUTPUT_DISTRIBUTION_REQUEST,
1821 GetOutputDistributionRequest {
1822 amounts: vec![628780000],
1823 from_height: 1462078,
1824 binary: true,
1825 compress: false,
1826 cumulative: false,
1827 to_height: 0,
1828 },
1829 );
1830 }
1831
1832 #[test]
1848 fn get_miner_data_response() {
1849 test_json_response(
1850 json::GET_MINER_DATA_RESPONSE,
1851 GetMinerDataResponse {
1852 base: ResponseBase::OK,
1853 already_generated_coins: 18186022843595960691,
1854 difficulty: "0x48afae42de".into(),
1855 height: 2731375,
1856 major_version: 16,
1857 median_weight: 300000,
1858 prev_id: Hex(hex!(
1859 "78d50c5894d187c4946d54410990ca59a75017628174a9e8c7055fa4ca5c7c6d"
1860 )),
1861 seed_hash: Hex(hex!(
1862 "a6b869d50eca3a43ec26fe4c369859cf36ae37ce6ecb76457d31ffeb8a6ca8a6"
1863 )),
1864 tx_backlog: vec![
1865 GetMinerDataTxBacklogEntry {
1866 fee: 30700000,
1867 id: Hex(hex!(
1868 "9868490d6bb9207fdd9cf17ca1f6c791b92ca97de0365855ea5c089f67c22208"
1869 )),
1870 weight: 1535,
1871 },
1872 GetMinerDataTxBacklogEntry {
1873 fee: 44280000,
1874 id: Hex(hex!(
1875 "b6000b02bbec71e18ad704bcae09fb6e5ae86d897ced14a718753e76e86c0a0a"
1876 )),
1877 weight: 2214,
1878 },
1879 ],
1880 },
1881 );
1882 }
1883
1884 #[test]
1885 fn prune_blockchain_request() {
1886 test_json_request(
1887 json::PRUNE_BLOCKCHAIN_REQUEST,
1888 PruneBlockchainRequest { check: true },
1889 );
1890 }
1891
1892 #[test]
1893 fn prune_blockchain_response() {
1894 test_json_response(
1895 json::PRUNE_BLOCKCHAIN_RESPONSE,
1896 PruneBlockchainResponse {
1897 base: ResponseBase::OK,
1898 pruned: true,
1899 pruning_seed: 387,
1900 },
1901 );
1902 }
1903
1904 #[test]
1905 fn calc_pow_request() {
1906 test_json_request(json::CALC_POW_REQUEST, CalcPowRequest {
1907 major_version: 14,
1908 height: 2286447,
1909 block_blob: HexVec(hex!("0e0ed286da8006ecdc1aab3033cf1716c52f13f9d8ae0051615a2453643de94643b550d543becd0000000002abc78b0101ffefc68b0101fcfcf0d4b422025014bb4a1eade6622fd781cb1063381cad396efa69719b41aa28b4fce8c7ad4b5f019ce1dc670456b24a5e03c2d9058a2df10fec779e2579753b1847b74ee644f16b023c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051399a1bc46a846474f5b33db24eae173a26393b976054ee14f9feefe99925233802867097564c9db7a36af5bb5ed33ab46e63092bd8d32cef121608c3258edd55562812e21cc7e3ac73045745a72f7d74581d9a0849d6f30e8b2923171253e864f4e9ddea3acb5bc755f1c4a878130a70c26297540bc0b7a57affb6b35c1f03d8dbd54ece8457531f8cba15bb74516779c01193e212050423020e45aa2c15dcb").into()),
1910 seed_hash: Hex(hex!("d432f499205150873b2572b5f033c9c6e4b7c6f3394bd2dd93822cd7085e7307")),
1911 });
1912 }
1913
1914 #[test]
1915 fn calc_pow_response() {
1916 test_json_response(
1917 json::CALC_POW_RESPONSE,
1918 CalcPowResponse {
1919 pow_hash: Hex(hex!(
1920 "d0402d6834e26fb94a9ce38c6424d27d2069896a9b8b1ce685d79936bca6e0a8"
1921 )),
1922 },
1923 );
1924 }
1925
1926 #[test]
1927 fn flush_cache_request() {
1928 test_json_request(
1929 json::FLUSH_CACHE_REQUEST,
1930 FlushCacheRequest {
1931 bad_txs: true,
1932 bad_blocks: true,
1933 },
1934 );
1935 }
1936
1937 #[test]
1938 fn flush_cache_response() {
1939 test_json_response(
1940 json::FLUSH_CACHE_RESPONSE,
1941 FlushCacheResponse {
1942 base: ResponseBase::OK,
1943 },
1944 );
1945 }
1946
1947 #[test]
1948 fn add_aux_pow_request() {
1949 test_json_request(json::ADD_AUX_POW_REQUEST, AddAuxPowRequest {
1950 blocktemplate_blob: HexVec(hex!("1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()),
1951 aux_pow: vec![AuxPow {
1952 id: Hex(hex!("3200b4ea97c3b2081cd4190b58e49572b2319fed00d030ad51809dff06b5d8c8")),
1953 hash: Hex(hex!("7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a"))
1954 }]
1955 });
1956 }
1957
1958 #[test]
1959 fn add_aux_pow_response() {
1960 test_json_response(json::ADD_AUX_POW_RESPONSE, AddAuxPowResponse {
1961 base: ResponseBase::OK,
1962 aux_pow: vec![AuxPow {
1963 hash: Hex(hex!("7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a")),
1964 id: Hex(hex!("3200b4ea97c3b2081cd4190b58e49572b2319fed00d030ad51809dff06b5d8c8")),
1965 }],
1966 blockhashing_blob: HexVec(hex!("1010ee97e2a106e9f8ebe8887e5b609949ac8ea6143e560ed13552b110cb009b21f0cfca1eaccf00000000b2685c1283a646bc9020c758daa443be145b7370ce5a6efacb3e614117032e2c22").into()),
1967 blocktemplate_blob: HexVec(hex!("1010f4bae0b4069d648e741d85ca0e7acb4501f051b27e9b107d3cd7a3f03aa7f776089117c81a0000000002c681c30101ff8a81c3010180e0a596bb11033b7eedf47baf878f3490cb20b696079c34bd017fe59b0d070e74d73ffabc4bb0e05f011decb630f3148d0163b3bd39690dde4078e4cfb69fecf020d6278a27bad10c58023c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()),
1968 merkle_root: Hex(hex!("7b35762de164b20885e15dbe656b1138db06bb402fa1796f5765a23933d8859a")),
1969 merkle_tree_depth: 0,
1970 });
1971 }
1972}