cuprate_rpc_types/
other.rs

1//! JSON types from the [`other`](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#other-daemon-rpc-calls) endpoints.
2//!
3//! All types are originally defined in [`rpc/core_rpc_server_commands_defs.h`](https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h).
4
5//---------------------------------------------------------------------------------------------------- Import
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use crate::{
10    base::{AccessResponseBase, ResponseBase},
11    macros::define_request_and_response,
12    misc::{
13        GetOutputsOut, OutKey, Peer, PublicNode, SpentKeyImageInfo, Status, TxEntry, TxInfo,
14        TxpoolStats,
15    },
16    RpcCallValue,
17};
18
19#[cfg(any(feature = "serde", feature = "epee"))]
20use crate::defaults::{default_false, default_string, default_true, default_vec, default_zero};
21
22//---------------------------------------------------------------------------------------------------- Macro
23/// Adds a (de)serialization doc-test to a type in `other.rs`.
24///
25/// It expects a const string from `cuprate_test_utils::rpc::data`
26/// and the expected value it should (de)serialize into/from.
27///
28/// It tests that the provided const JSON string can properly
29/// (de)serialize into the expected value.
30///
31/// See below for example usage. This macro is only used in this file.
32macro_rules! serde_doc_test {
33    // This branch _only_ tests that the type can be deserialize
34    // from the string, not that any value is correct.
35    //
36    // Practically, this is used for structs that have
37    // many values that are complicated to test, e.g. `GET_TRANSACTIONS_RESPONSE`.
38    //
39    // HACK:
40    // The type itself doesn't need to be specified because it happens
41    // to just be the `CamelCase` version of the provided const.
42    (
43        // `const` string from `cuprate_test_utils::rpc::data`.
44        $cuprate_test_utils_rpc_const:ident
45    ) => {
46        paste::paste! {
47            concat!(
48                "```rust\n",
49                "use cuprate_test_utils::rpc::data::other::*;\n",
50                "use cuprate_rpc_types::{misc::*, base::*, other::*};\n",
51                "use serde_json::{Value, from_str, from_value};\n",
52                "\n",
53                "let string = from_str::<",
54                stringify!([<$cuprate_test_utils_rpc_const:camel>]),
55                ">(",
56                stringify!($cuprate_test_utils_rpc_const),
57                ").unwrap();\n",
58                "```\n",
59            )
60        }
61    };
62
63    // This branch tests that the type can be deserialize
64    // from the string AND that values are correct.
65    (
66        // `const` string from `cuprate_test_utils::rpc::data`
67        //  v
68        $cuprate_test_utils_rpc_const:ident => $expected:expr_2021
69        //                                     ^
70        //                     Expected value as an expression
71    ) => {
72        paste::paste! {
73            concat!(
74                "```rust\n",
75                "use cuprate_test_utils::rpc::data::other::*;\n",
76                "use cuprate_rpc_types::{misc::*, base::*, other::*};\n",
77                "use serde_json::{Value, from_str, from_value};\n",
78                "\n",
79                "// The expected data.\n",
80                "let expected = ",
81                stringify!($expected),
82                ";\n",
83                "\n",
84                "let string = from_str::<",
85                stringify!([<$cuprate_test_utils_rpc_const:camel>]),
86                ">(",
87                stringify!($cuprate_test_utils_rpc_const),
88                ").unwrap();\n",
89                "\n",
90                "assert_eq!(string, expected);\n",
91                "```\n",
92            )
93        }
94    };
95}
96
97//---------------------------------------------------------------------------------------------------- Definitions
98define_request_and_response! {
99    get_height,
100    cc73fe71162d564ffda8e549b79a350bca53c454 =>
101    core_rpc_server_commands_defs.h => 138..=160,
102    GetHeight (empty),
103    Request {},
104
105    #[doc = serde_doc_test!(
106        GET_HEIGHT_RESPONSE => GetHeightResponse {
107            base: ResponseBase::OK,
108            hash: "68bb1a1cff8e2a44c3221e8e1aff80bc6ca45d06fa8eff4d2a3a7ac31d4efe3f".into(),
109            height: 3195160,
110        }
111    )]
112    ResponseBase {
113        hash: String,
114        height: u64,
115    }
116}
117
118define_request_and_response! {
119    get_transactions,
120    cc73fe71162d564ffda8e549b79a350bca53c454 =>
121    core_rpc_server_commands_defs.h => 370..=451,
122    GetTransactions,
123
124    #[doc = serde_doc_test!(
125        GET_TRANSACTIONS_REQUEST => GetTransactionsRequest {
126            txs_hashes: vec!["d6e48158472848e6687173a91ae6eebfa3e1d778e65252ee99d7515d63090408".into()],
127            decode_as_json: false,
128            prune: false,
129            split: false,
130        }
131    )]
132    Request {
133        txs_hashes: Vec<String>,
134        // FIXME: this is documented as optional but it isn't serialized as an optional
135        // but it is set _somewhere_ to false in `monerod`
136        // <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L382>
137        decode_as_json: bool = default_false(), "default_false",
138        prune: bool = default_false(), "default_false",
139        split: bool = default_false(), "default_false",
140    },
141
142    #[doc = serde_doc_test!(GET_TRANSACTIONS_RESPONSE)]
143    AccessResponseBase {
144        txs_as_hex: Vec<String> = default_vec::<String>(), "default_vec",
145        /// `cuprate_rpc_types::json::tx::Transaction` should be used
146        /// to create this JSON string in a type-safe manner.
147        txs_as_json: Vec<String> = default_vec::<String>(), "default_vec",
148        missed_tx: Vec<String> = default_vec::<String>(), "default_vec",
149        txs: Vec<TxEntry> = default_vec::<TxEntry>(), "default_vec",
150    }
151}
152
153define_request_and_response! {
154    get_alt_blocks_hashes,
155    cc73fe71162d564ffda8e549b79a350bca53c454 =>
156    core_rpc_server_commands_defs.h => 288..=308,
157    GetAltBlocksHashes (empty),
158    Request {},
159
160    #[doc = serde_doc_test!(
161        GET_ALT_BLOCKS_HASHES_RESPONSE => GetAltBlocksHashesResponse {
162            base: AccessResponseBase::OK,
163            blks_hashes: vec!["8ee10db35b1baf943f201b303890a29e7d45437bd76c2bd4df0d2f2ee34be109".into()],
164        }
165    )]
166    AccessResponseBase {
167        blks_hashes: Vec<String>,
168    }
169}
170
171define_request_and_response! {
172    is_key_image_spent,
173    cc73fe71162d564ffda8e549b79a350bca53c454 =>
174    core_rpc_server_commands_defs.h => 454..=484,
175
176    IsKeyImageSpent,
177
178    #[doc = serde_doc_test!(
179        IS_KEY_IMAGE_SPENT_REQUEST => IsKeyImageSpentRequest {
180            key_images: vec![
181                "8d1bd8181bf7d857bdb281e0153d84cd55a3fcaa57c3e570f4a49f935850b5e3".into(),
182                "7319134bfc50668251f5b899c66b005805ee255c136f0e1cecbb0f3a912e09d4".into()
183            ]
184        }
185    )]
186    Request {
187        key_images: Vec<String>,
188    },
189
190    #[doc = serde_doc_test!(
191        IS_KEY_IMAGE_SPENT_RESPONSE => IsKeyImageSpentResponse {
192            base: AccessResponseBase::OK,
193            spent_status: vec![1, 1],
194        }
195    )]
196    AccessResponseBase {
197        /// FIXME: These are [`KeyImageSpentStatus`](crate::misc::KeyImageSpentStatus) in [`u8`] form.
198        spent_status: Vec<u8>,
199    }
200}
201
202define_request_and_response! {
203    send_raw_transaction,
204    cc73fe71162d564ffda8e549b79a350bca53c454 =>
205    core_rpc_server_commands_defs.h => 370..=451,
206
207    SendRawTransaction,
208
209    #[doc = serde_doc_test!(
210        SEND_RAW_TRANSACTION_REQUEST => SendRawTransactionRequest {
211            tx_as_hex: "dc16fa8eaffe1484ca9014ea050e13131d3acf23b419f33bb4cc0b32b6c49308".into(),
212            do_not_relay: false,
213            do_sanity_checks: true,
214        }
215    )]
216    Request {
217        tx_as_hex: String,
218        do_not_relay: bool = default_false(), "default_false",
219        do_sanity_checks: bool = default_true(), "default_true",
220    },
221
222    #[doc = serde_doc_test!(
223        SEND_RAW_TRANSACTION_RESPONSE => SendRawTransactionResponse {
224            base: AccessResponseBase {
225                response_base: ResponseBase {
226                    status: Status::Other("Failed".into()),
227                    untrusted: false,
228                },
229                credits: 0,
230                top_hash: "".into(),
231            },
232            double_spend: false,
233            fee_too_low: false,
234            invalid_input: false,
235            invalid_output: false,
236            low_mixin: false,
237            not_relayed: false,
238            overspend: false,
239            reason: "".into(),
240            sanity_check_failed: false,
241            too_big: false,
242            too_few_outputs: false,
243            tx_extra_too_big: false,
244            nonzero_unlock_time: false,
245        }
246    )]
247    AccessResponseBase {
248        double_spend: bool,
249        fee_too_low: bool,
250        invalid_input: bool,
251        invalid_output: bool,
252        low_mixin: bool,
253        nonzero_unlock_time: bool = default_false(), "default_false",
254        not_relayed: bool,
255        overspend: bool,
256        reason: String,
257        sanity_check_failed: bool,
258        too_big: bool,
259        too_few_outputs: bool,
260        tx_extra_too_big: bool,
261    }
262}
263
264define_request_and_response! {
265    start_mining,
266    cc73fe71162d564ffda8e549b79a350bca53c454 =>
267    core_rpc_server_commands_defs.h => 665..=691,
268
269    StartMining (restricted),
270
271    #[doc = serde_doc_test!(
272        START_MINING_REQUEST => StartMiningRequest {
273            do_background_mining: false,
274            ignore_battery: true,
275            miner_address: "47xu3gQpF569au9C2ajo5SSMrWji6xnoE5vhr94EzFRaKAGw6hEGFXYAwVADKuRpzsjiU1PtmaVgcjUJF89ghGPhUXkndHc".into(),
276            threads_count: 1
277        }
278    )]
279    Request {
280        miner_address: String,
281        threads_count: u64,
282        do_background_mining: bool,
283        ignore_battery: bool,
284    },
285
286    #[doc = serde_doc_test!(
287        START_MINING_RESPONSE => StartMiningResponse {
288            base: ResponseBase::OK,
289        }
290    )]
291    ResponseBase {}
292}
293
294define_request_and_response! {
295    stop_mining,
296    cc73fe71162d564ffda8e549b79a350bca53c454 =>
297    core_rpc_server_commands_defs.h => 825..=843,
298    StopMining (restricted, empty),
299    Request {},
300
301    #[doc = serde_doc_test!(
302        STOP_MINING_RESPONSE => StopMiningResponse {
303            base: ResponseBase::OK,
304        }
305    )]
306    ResponseBase {}
307}
308
309define_request_and_response! {
310    mining_status,
311    cc73fe71162d564ffda8e549b79a350bca53c454 =>
312    core_rpc_server_commands_defs.h => 846..=895,
313    MiningStatus (restricted),
314    Request {},
315
316    #[doc = serde_doc_test!(
317        MINING_STATUS_RESPONSE => MiningStatusResponse {
318            base: ResponseBase::OK,
319            active: false,
320            address: "".into(),
321            bg_idle_threshold: 0,
322            bg_ignore_battery: false,
323            bg_min_idle_seconds: 0,
324            bg_target: 0,
325            block_reward: 0,
326            block_target: 120,
327            difficulty: 292022797663,
328            difficulty_top64: 0,
329            is_background_mining_enabled: false,
330            pow_algorithm: "RandomX".into(),
331            speed: 0,
332            threads_count: 0,
333            wide_difficulty: "0x43fdea455f".into(),
334        }
335    )]
336    ResponseBase {
337        active: bool,
338        address: String,
339        bg_idle_threshold: u8,
340        bg_ignore_battery: bool,
341        bg_min_idle_seconds: u8,
342        bg_target: u8,
343        block_reward: u64,
344        block_target: u32,
345        difficulty: u64,
346        difficulty_top64: u64,
347        is_background_mining_enabled: bool,
348        pow_algorithm: String,
349        speed: u64,
350        threads_count: u32,
351        wide_difficulty: String,
352    }
353}
354
355define_request_and_response! {
356    save_bc,
357    cc73fe71162d564ffda8e549b79a350bca53c454 =>
358    core_rpc_server_commands_defs.h => 898..=916,
359    SaveBc (restricted),
360    Request {},
361
362    #[doc = serde_doc_test!(
363        SAVE_BC_RESPONSE => SaveBcResponse {
364            base: ResponseBase::OK,
365        }
366    )]
367    ResponseBase {}
368}
369
370define_request_and_response! {
371    get_peer_list,
372    cc73fe71162d564ffda8e549b79a350bca53c454 =>
373    core_rpc_server_commands_defs.h => 1369..=1417,
374
375    GetPeerList (restricted),
376
377    #[doc = serde_doc_test!(
378        GET_PEER_LIST_REQUEST => GetPeerListRequest {
379            public_only: true,
380            include_blocked: false,
381        }
382    )]
383    Request {
384        public_only: bool = default_true(), "default_true",
385        include_blocked: bool = default_false(), "default_false",
386    },
387
388    #[doc = serde_doc_test!(
389        GET_PEER_LIST_RESPONSE => GetPeerListResponse {
390            base: ResponseBase::OK,
391            gray_list: vec![
392                Peer {
393                    host: "161.97.193.0".into(),
394                    id: 18269586253849566614,
395                    ip: 12673441,
396                    last_seen: 0,
397                    port: 18080,
398                    rpc_port: 0,
399                    rpc_credits_per_hash: 0,
400                    pruning_seed: 0,
401                },
402                Peer {
403                    host: "193.142.4.2".into(),
404                    id: 10865563782170056467,
405                    ip: 33853121,
406                    last_seen: 0,
407                    port: 18085,
408                    pruning_seed: 387,
409                    rpc_port: 19085,
410                    rpc_credits_per_hash: 0,
411                }
412            ],
413            white_list: vec![
414                Peer {
415                    host: "78.27.98.0".into(),
416                    id: 11368279936682035606,
417                    ip: 6429518,
418                    last_seen: 1721246387,
419                    port: 18080,
420                    pruning_seed: 384,
421                    rpc_port: 0,
422                    rpc_credits_per_hash: 0,
423                },
424                Peer {
425                    host: "67.4.163.2".into(),
426                    id: 16545113262826842499,
427                    ip: 44237891,
428                    last_seen: 1721246387,
429                    port: 18080,
430                    rpc_port: 0,
431                    rpc_credits_per_hash: 0,
432                    pruning_seed: 0,
433                },
434                Peer {
435                    host: "70.52.75.3".into(),
436                    id: 3863337548778177169,
437                    ip: 55260230,
438                    last_seen: 1721246387,
439                    port: 18080,
440                    rpc_port: 18081,
441                    rpc_credits_per_hash: 0,
442                    pruning_seed: 0,
443                }
444            ]
445        }
446    )]
447    ResponseBase {
448        white_list: Vec<Peer>,
449        gray_list: Vec<Peer>,
450    }
451}
452
453define_request_and_response! {
454    set_log_hash_rate,
455    cc73fe71162d564ffda8e549b79a350bca53c454 =>
456    core_rpc_server_commands_defs.h => 1450..=1470,
457
458    SetLogHashRate (restricted),
459
460    #[derive(Copy)]
461    #[doc = serde_doc_test!(
462        SET_LOG_HASH_RATE_REQUEST => SetLogHashRateRequest {
463            visible: true,
464        }
465    )]
466    Request {
467        visible: bool = default_false(), "default_false",
468    },
469
470    #[doc = serde_doc_test!(
471        SET_LOG_HASH_RATE_RESPONSE => SetLogHashRateResponse {
472            base: ResponseBase::OK,
473        }
474    )]
475    ResponseBase {}
476}
477
478define_request_and_response! {
479    set_log_level,
480    cc73fe71162d564ffda8e549b79a350bca53c454 =>
481    core_rpc_server_commands_defs.h => 1450..=1470,
482
483    SetLogLevel (restricted),
484
485    #[derive(Copy)]
486    #[doc = serde_doc_test!(
487        SET_LOG_LEVEL_REQUEST => SetLogLevelRequest {
488            level: 1
489        }
490    )]
491    Request {
492        level: u8,
493    },
494
495    #[doc = serde_doc_test!(
496        SET_LOG_LEVEL_RESPONSE => SetLogLevelResponse {
497            base: ResponseBase::OK,
498        }
499    )]
500    ResponseBase {}
501}
502
503define_request_and_response! {
504    set_log_categories,
505    cc73fe71162d564ffda8e549b79a350bca53c454 =>
506    core_rpc_server_commands_defs.h => 1494..=1517,
507
508    SetLogCategories (restricted),
509
510    #[doc = serde_doc_test!(
511        SET_LOG_CATEGORIES_REQUEST => SetLogCategoriesRequest {
512            categories: "*:INFO".into(),
513        }
514    )]
515    Request {
516        categories: String = default_string(), "default_string",
517    },
518
519    #[doc = serde_doc_test!(
520        SET_LOG_CATEGORIES_RESPONSE => SetLogCategoriesResponse {
521            base: ResponseBase::OK,
522            categories: "*:INFO".into(),
523        }
524    )]
525    ResponseBase {
526        categories: String,
527    }
528}
529
530define_request_and_response! {
531    set_bootstrap_daemon,
532    cc73fe71162d564ffda8e549b79a350bca53c454 =>
533    core_rpc_server_commands_defs.h => 1785..=1812,
534
535    SetBootstrapDaemon (restricted),
536
537    #[doc = serde_doc_test!(
538        SET_BOOTSTRAP_DAEMON_REQUEST => SetBootstrapDaemonRequest {
539            address: "http://getmonero.org:18081".into(),
540            username: String::new(),
541            password: String::new(),
542            proxy: String::new(),
543        }
544    )]
545    Request {
546        address: String,
547        username: String = default_string(), "default_string",
548        password: String = default_string(), "default_string",
549        proxy: String = default_string(), "default_string",
550    },
551
552    #[doc = serde_doc_test!(
553        SET_BOOTSTRAP_DAEMON_RESPONSE => SetBootstrapDaemonResponse {
554            status: Status::Ok,
555        }
556    )]
557    Response {
558        status: Status,
559    }
560}
561
562define_request_and_response! {
563    get_transaction_pool,
564    cc73fe71162d564ffda8e549b79a350bca53c454 =>
565    core_rpc_server_commands_defs.h => 1569..=1591,
566
567    GetTransactionPool (empty),
568    Request {},
569
570    #[doc = serde_doc_test!(GET_TRANSACTION_POOL_RESPONSE)]
571    AccessResponseBase {
572        transactions: Vec<TxInfo>,
573        spent_key_images: Vec<SpentKeyImageInfo>,
574    }
575}
576
577define_request_and_response! {
578    get_transaction_pool_stats,
579    cc73fe71162d564ffda8e549b79a350bca53c454 =>
580    core_rpc_server_commands_defs.h => 1712..=1732,
581
582    GetTransactionPoolStats (empty),
583    Request {},
584
585    #[doc = serde_doc_test!(
586        GET_TRANSACTION_POOL_STATS_RESPONSE => GetTransactionPoolStatsResponse {
587            base: AccessResponseBase::OK,
588            pool_stats: TxpoolStats {
589                bytes_max: 11843,
590                bytes_med: 2219,
591                bytes_min: 1528,
592                bytes_total: 144192,
593                fee_total: 7018100000,
594                histo: vec![
595                    TxpoolHisto { bytes: 11219, txs: 4 },
596                    TxpoolHisto { bytes: 9737, txs: 5 },
597                    TxpoolHisto { bytes: 8757, txs: 4 },
598                    TxpoolHisto { bytes: 14763, txs: 4 },
599                    TxpoolHisto { bytes: 15007, txs: 6 },
600                    TxpoolHisto { bytes: 15924, txs: 6 },
601                    TxpoolHisto { bytes: 17869, txs: 8 },
602                    TxpoolHisto { bytes: 10894, txs: 5 },
603                    TxpoolHisto { bytes: 38485, txs: 10 },
604                    TxpoolHisto { bytes: 1537, txs: 1 },
605                ],
606                histo_98pc: 186,
607                num_10m: 0,
608                num_double_spends: 0,
609                num_failing: 0,
610                num_not_relayed: 0,
611                oldest: 1721261651,
612                txs_total: 53
613            }
614        }
615    )]
616    AccessResponseBase {
617        pool_stats: TxpoolStats,
618    }
619}
620
621define_request_and_response! {
622    stop_daemon,
623    cc73fe71162d564ffda8e549b79a350bca53c454 =>
624    core_rpc_server_commands_defs.h => 1814..=1831,
625
626    StopDaemon (restricted, empty),
627    Request {},
628
629    #[doc = serde_doc_test!(
630        STOP_DAEMON_RESPONSE => StopDaemonResponse {
631            status: Status::Ok,
632        }
633    )]
634    Response {
635        status: Status,
636    }
637}
638
639define_request_and_response! {
640    get_limit,
641    cc73fe71162d564ffda8e549b79a350bca53c454 =>
642    core_rpc_server_commands_defs.h => 1852..=1874,
643
644    GetLimit (empty),
645    Request {},
646
647    #[doc = serde_doc_test!(
648        GET_LIMIT_RESPONSE => GetLimitResponse {
649            base: ResponseBase::OK,
650            limit_down: 1280000,
651            limit_up: 1280000,
652        }
653    )]
654    ResponseBase {
655        limit_down: u64,
656        limit_up: u64,
657    }
658}
659
660define_request_and_response! {
661    set_limit,
662    cc73fe71162d564ffda8e549b79a350bca53c454 =>
663    core_rpc_server_commands_defs.h => 1876..=1903,
664
665    SetLimit (restricted),
666
667    #[doc = serde_doc_test!(
668        SET_LIMIT_REQUEST => SetLimitRequest {
669            limit_down: 1024,
670            limit_up: 0,
671        }
672    )]
673    Request {
674        // FIXME: These may need to be `Option<i64>`.
675        limit_down: i64 = default_zero::<i64>(), "default_zero",
676        limit_up: i64 = default_zero::<i64>(), "default_zero",
677    },
678
679    #[doc = serde_doc_test!(
680        SET_LIMIT_RESPONSE => SetLimitResponse {
681            base: ResponseBase::OK,
682            limit_down: 1024,
683            limit_up: 128,
684        }
685    )]
686    ResponseBase {
687        limit_down: i64,
688        limit_up: i64,
689    }
690}
691
692define_request_and_response! {
693    out_peers,
694    cc73fe71162d564ffda8e549b79a350bca53c454 =>
695    core_rpc_server_commands_defs.h => 1876..=1903,
696
697    OutPeers (restricted),
698
699    #[doc = serde_doc_test!(
700        OUT_PEERS_REQUEST => OutPeersRequest {
701            out_peers: 3232235535,
702            set: true,
703        }
704    )]
705    Request {
706        set: bool = default_true(), "default_true",
707        out_peers: u32,
708    },
709
710    #[doc = serde_doc_test!(
711        OUT_PEERS_RESPONSE => OutPeersResponse {
712            base: ResponseBase::OK,
713            out_peers: 3232235535,
714        }
715    )]
716    ResponseBase {
717        out_peers: u32,
718    }
719}
720
721define_request_and_response! {
722    in_peers,
723    cc73fe71162d564ffda8e549b79a350bca53c454 =>
724    core_rpc_server_commands_defs.h => 1932..=1956,
725    InPeers (restricted),
726    Request {
727        set: bool = default_true(), "default_true",
728        in_peers: u32,
729    },
730    ResponseBase {
731        in_peers: u32,
732    }
733}
734
735define_request_and_response! {
736    get_net_stats,
737    cc73fe71162d564ffda8e549b79a350bca53c454 =>
738    core_rpc_server_commands_defs.h => 793..=822,
739
740    GetNetStats (restricted, empty),
741    Request {},
742
743    #[doc = serde_doc_test!(
744        GET_NET_STATS_RESPONSE => GetNetStatsResponse {
745            base: ResponseBase::OK,
746            start_time: 1721251858,
747            total_bytes_in: 16283817214,
748            total_bytes_out: 34225244079,
749            total_packets_in: 5981922,
750            total_packets_out: 3627107,
751        }
752    )]
753    ResponseBase {
754        start_time: u64,
755        total_packets_in: u64,
756        total_bytes_in: u64,
757        total_packets_out: u64,
758        total_bytes_out: u64,
759    }
760}
761
762define_request_and_response! {
763    get_outs,
764    cc73fe71162d564ffda8e549b79a350bca53c454 =>
765    core_rpc_server_commands_defs.h => 567..=609,
766
767    GetOuts,
768    #[doc = serde_doc_test!(
769        GET_OUTS_REQUEST => GetOutsRequest {
770            outputs: vec![
771                GetOutputsOut { amount: 1, index: 0 },
772                GetOutputsOut { amount: 1, index: 1 },
773            ],
774            get_txid: true
775        }
776    )]
777    Request {
778        outputs: Vec<GetOutputsOut>,
779        get_txid: bool,
780    },
781
782    #[doc = serde_doc_test!(
783        GET_OUTS_RESPONSE => GetOutsResponse {
784            base: ResponseBase::OK,
785            outs: vec![
786                OutKey {
787                    height: 51941,
788                    key: "08980d939ec297dd597119f498ad69fed9ca55e3a68f29f2782aae887ef0cf8e".into(),
789                    mask: "1738eb7a677c6149228a2beaa21bea9e3370802d72a3eec790119580e02bd522".into(),
790                    txid: "9d651903b80fb70b9935b72081cd967f543662149aed3839222511acd9100601".into(),
791                    unlocked: true
792                },
793                OutKey {
794                    height: 51945,
795                    key: "454fe46c405be77625fa7e3389a04d3be392346983f27603561ac3a3a74f4a75".into(),
796                    mask: "1738eb7a677c6149228a2beaa21bea9e3370802d72a3eec790119580e02bd522".into(),
797                    txid: "230bff732dc5f225df14fff82aadd1bf11b3fb7ad3a03413c396a617e843f7d0".into(),
798                    unlocked: true
799                },
800            ]
801        }
802    )]
803    ResponseBase {
804        outs: Vec<OutKey>,
805    }
806}
807
808define_request_and_response! {
809    update,
810    cc73fe71162d564ffda8e549b79a350bca53c454 =>
811    core_rpc_server_commands_defs.h => 2324..=2359,
812
813    Update (restricted),
814
815    #[doc = serde_doc_test!(
816        UPDATE_REQUEST => UpdateRequest {
817            command: "check".into(),
818            path: "".into(),
819        }
820    )]
821    Request {
822        command: String,
823        path: String = default_string(), "default_string",
824    },
825
826    #[doc = serde_doc_test!(
827        UPDATE_RESPONSE => UpdateResponse {
828            base: ResponseBase::OK,
829            auto_uri: "".into(),
830            hash: "".into(),
831            path: "".into(),
832            update: false,
833            user_uri: "".into(),
834            version: "".into(),
835        }
836    )]
837    ResponseBase {
838        auto_uri: String,
839        hash: String,
840        path: String,
841        update: bool,
842        user_uri: String,
843        version: String,
844    }
845}
846
847define_request_and_response! {
848    pop_blocks,
849    cc73fe71162d564ffda8e549b79a350bca53c454 =>
850    core_rpc_server_commands_defs.h => 2722..=2745,
851
852    PopBlocks (restricted),
853
854    #[doc = serde_doc_test!(
855        POP_BLOCKS_REQUEST => PopBlocksRequest {
856            nblocks: 6
857        }
858    )]
859    Request {
860        nblocks: u64,
861    },
862
863    #[doc = serde_doc_test!(
864        POP_BLOCKS_RESPONSE => PopBlocksResponse {
865            base: ResponseBase::OK,
866            height: 76482,
867        }
868    )]
869    ResponseBase {
870        height: u64,
871    }
872}
873
874define_request_and_response! {
875    UNDOCUMENTED_ENDPOINT,
876    cc73fe71162d564ffda8e549b79a350bca53c454 =>
877    core_rpc_server_commands_defs.h => 1615..=1635,
878
879    GetTransactionPoolHashes (empty),
880    Request {},
881
882    #[doc = serde_doc_test!(
883        GET_TRANSACTION_POOL_HASHES_RESPONSE => GetTransactionPoolHashesResponse {
884            base: ResponseBase::OK,
885            tx_hashes: vec![
886                "aa928aed888acd6152c60194d50a4df29b0b851be6169acf11b6a8e304dd6c03".into(),
887                "794345f321a98f3135151f3056c0fdf8188646a8dab27de971428acf3551dd11".into(),
888                "1e9d2ae11f2168a228942077483e70940d34e8658c972bbc3e7f7693b90edf17".into(),
889                "7375c928f261d00f07197775eb0bfa756e5f23319819152faa0b3c670fe54c1b".into(),
890                "2e4d5f8c5a45498f37fb8b6ca4ebc1efa0c371c38c901c77e66b08c072287329".into(),
891                "eee6d596cf855adfb10e1597d2018e3a61897ac467ef1d4a5406b8d20bfbd52f".into(),
892                "59c574d7ba9bb4558470f74503c7518946a85ea22c60fccfbdec108ce7d8f236".into(),
893                "0d57bec1e1075a9e1ac45cf3b3ced1ad95ccdf2a50ce360190111282a0178655".into(),
894                "60d627b2369714a40009c07d6185ebe7fa4af324fdfa8d95a37a936eb878d062".into(),
895                "661d7e728a901a8cb4cf851447d9cd5752462687ed0b776b605ba706f06bdc7d".into(),
896                "b80e1f09442b00b3fffe6db5d263be6267c7586620afff8112d5a8775a6fc58e".into(),
897                "974063906d1ddfa914baf85176b0f689d616d23f3d71ed4798458c8b4f9b9d8f".into(),
898                "d2575ae152a180be4981a9d2fc009afcd073adaa5c6d8b022c540a62d6c905bb".into(),
899                "3d78aa80ee50f506683bab9f02855eb10257a08adceda7cbfbdfc26b10f6b1bb".into(),
900                "8b5bc125bdb73b708500f734501d55088c5ac381a0879e1141634eaa72b6a4da".into(),
901                "11c06f4d2f00c912ca07313ed2ea5366f3cae914a762bed258731d3d9e3706df".into(),
902                "b3644dc7c9a3a53465fe80ad3769e516edaaeb7835e16fdd493aac110d472ae1".into(),
903                "ed2478ad793b923dbf652c8612c40799d764e5468897021234a14a37346bc6ee".into()
904            ],
905        }
906    )]
907    ResponseBase {
908        tx_hashes: Vec<String>,
909    }
910}
911
912define_request_and_response! {
913    UNDOCUMENTED_ENDPOINT,
914    cc73fe71162d564ffda8e549b79a350bca53c454 =>
915    core_rpc_server_commands_defs.h => 1419..=1448,
916
917    GetPublicNodes (restricted),
918
919    #[doc = serde_doc_test!(
920        GET_PUBLIC_NODES_REQUEST => GetPublicNodesRequest {
921            gray: false,
922            white: true,
923            include_blocked: false,
924        }
925    )]
926    Request {
927        gray: bool = default_false(), "default_false",
928        white: bool = default_true(), "default_true",
929        include_blocked: bool = default_false(), "default_false",
930    },
931
932    #[doc = serde_doc_test!(
933        GET_PUBLIC_NODES_RESPONSE => GetPublicNodesResponse {
934            base: ResponseBase::OK,
935            gray: vec![],
936            white: vec![
937                PublicNode {
938                    host: "70.52.75.3".into(),
939                    last_seen: 1721246387,
940                    rpc_credits_per_hash: 0,
941                    rpc_port: 18081,
942                },
943                PublicNode {
944                    host: "zbjkbsxc5munw3qusl7j2hpcmikhqocdf4pqhnhtpzw5nt5jrmofptid.onion:18083".into(),
945                    last_seen: 1720186288,
946                    rpc_credits_per_hash: 0,
947                    rpc_port: 18089,
948                }
949            ]
950        }
951    )]
952    ResponseBase {
953        gray: Vec<PublicNode> = default_vec::<PublicNode>(), "default_vec",
954        white: Vec<PublicNode> = default_vec::<PublicNode>(), "default_vec",
955    }
956}
957
958//---------------------------------------------------------------------------------------------------- Request
959/// Other JSON requests.
960///
961/// This enum contains all [`crate::other`] requests.
962///
963/// See also: [`OtherResponse`].
964///
965/// # (De)serialization
966/// The `serde` implementation will (de)serialize from
967/// the inner variant itself, e.g. [`OtherRequest::SetLogLevel`]
968/// has the same (de)serialization as [`SetLogLevelRequest`].
969///
970/// ```rust
971/// use cuprate_rpc_types::other::*;
972///
973/// let request = OtherRequest::SetLogLevel(Default::default());
974/// let json = serde_json::to_string(&request).unwrap();
975/// assert_eq!(json, r#"{"level":0}"#);
976/// ```
977#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
978#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
979#[cfg_attr(feature = "serde", serde(untagged))]
980pub enum OtherRequest {
981    GetHeight(GetHeightRequest),
982    GetTransactions(GetTransactionsRequest),
983    GetAltBlocksHashes(GetAltBlocksHashesRequest),
984    IsKeyImageSpent(IsKeyImageSpentRequest),
985    SendRawTransaction(SendRawTransactionRequest),
986    StartMining(StartMiningRequest),
987    StopMining(StopMiningRequest),
988    MiningStatus(MiningStatusRequest),
989    SaveBc(SaveBcRequest),
990    GetPeerList(GetPeerListRequest),
991    SetLogHashRate(SetLogHashRateRequest),
992    SetLogLevel(SetLogLevelRequest),
993    SetLogCategories(SetLogCategoriesRequest),
994    SetBootstrapDaemon(SetBootstrapDaemonRequest),
995    GetTransactionPool(GetTransactionPoolRequest),
996    GetTransactionPoolStats(GetTransactionPoolStatsRequest),
997    StopDaemon(StopDaemonRequest),
998    GetLimit(GetLimitRequest),
999    SetLimit(SetLimitRequest),
1000    OutPeers(OutPeersRequest),
1001    InPeers(InPeersRequest),
1002    GetNetStats(GetNetStatsRequest),
1003    GetOuts(GetOutsRequest),
1004    Update(UpdateRequest),
1005    PopBlocks(PopBlocksRequest),
1006    GetTransactionPoolHashes(GetTransactionPoolHashesRequest),
1007    GetPublicNodes(GetPublicNodesRequest),
1008}
1009
1010impl RpcCallValue for OtherRequest {
1011    fn is_restricted(&self) -> bool {
1012        match self {
1013            Self::GetHeight(x) => x.is_restricted(),
1014            Self::GetTransactions(x) => x.is_restricted(),
1015            Self::GetAltBlocksHashes(x) => x.is_restricted(),
1016            Self::IsKeyImageSpent(x) => x.is_restricted(),
1017            Self::SendRawTransaction(x) => x.is_restricted(),
1018            Self::StartMining(x) => x.is_restricted(),
1019            Self::StopMining(x) => x.is_restricted(),
1020            Self::MiningStatus(x) => x.is_restricted(),
1021            Self::SaveBc(x) => x.is_restricted(),
1022            Self::GetPeerList(x) => x.is_restricted(),
1023            Self::SetLogHashRate(x) => x.is_restricted(),
1024            Self::SetLogLevel(x) => x.is_restricted(),
1025            Self::SetLogCategories(x) => x.is_restricted(),
1026            Self::SetBootstrapDaemon(x) => x.is_restricted(),
1027            Self::GetTransactionPool(x) => x.is_restricted(),
1028            Self::GetTransactionPoolStats(x) => x.is_restricted(),
1029            Self::StopDaemon(x) => x.is_restricted(),
1030            Self::GetLimit(x) => x.is_restricted(),
1031            Self::SetLimit(x) => x.is_restricted(),
1032            Self::OutPeers(x) => x.is_restricted(),
1033            Self::InPeers(x) => x.is_restricted(),
1034            Self::GetNetStats(x) => x.is_restricted(),
1035            Self::GetOuts(x) => x.is_restricted(),
1036            Self::Update(x) => x.is_restricted(),
1037            Self::PopBlocks(x) => x.is_restricted(),
1038            Self::GetTransactionPoolHashes(x) => x.is_restricted(),
1039            Self::GetPublicNodes(x) => x.is_restricted(),
1040        }
1041    }
1042
1043    fn is_empty(&self) -> bool {
1044        match self {
1045            Self::GetHeight(x) => x.is_empty(),
1046            Self::GetTransactions(x) => x.is_empty(),
1047            Self::GetAltBlocksHashes(x) => x.is_empty(),
1048            Self::IsKeyImageSpent(x) => x.is_empty(),
1049            Self::SendRawTransaction(x) => x.is_empty(),
1050            Self::StartMining(x) => x.is_empty(),
1051            Self::StopMining(x) => x.is_empty(),
1052            Self::MiningStatus(x) => x.is_empty(),
1053            Self::SaveBc(x) => x.is_empty(),
1054            Self::GetPeerList(x) => x.is_empty(),
1055            Self::SetLogHashRate(x) => x.is_empty(),
1056            Self::SetLogLevel(x) => x.is_empty(),
1057            Self::SetLogCategories(x) => x.is_empty(),
1058            Self::SetBootstrapDaemon(x) => x.is_empty(),
1059            Self::GetTransactionPool(x) => x.is_empty(),
1060            Self::GetTransactionPoolStats(x) => x.is_empty(),
1061            Self::StopDaemon(x) => x.is_empty(),
1062            Self::GetLimit(x) => x.is_empty(),
1063            Self::SetLimit(x) => x.is_empty(),
1064            Self::OutPeers(x) => x.is_empty(),
1065            Self::InPeers(x) => x.is_empty(),
1066            Self::GetNetStats(x) => x.is_empty(),
1067            Self::GetOuts(x) => x.is_empty(),
1068            Self::Update(x) => x.is_empty(),
1069            Self::PopBlocks(x) => x.is_empty(),
1070            Self::GetTransactionPoolHashes(x) => x.is_empty(),
1071            Self::GetPublicNodes(x) => x.is_empty(),
1072        }
1073    }
1074}
1075
1076//---------------------------------------------------------------------------------------------------- Response
1077/// Other JSON responses.
1078///
1079/// This enum contains all [`crate::other`] responses.
1080///
1081/// See also: [`OtherRequest`].
1082///
1083/// # (De)serialization
1084/// The `serde` implementation will (de)serialize from
1085/// the inner variant itself, e.g. [`OtherRequest::SetBootstrapDaemon`]
1086/// has the same (de)serialization as [`SetBootstrapDaemonResponse`].
1087///
1088/// ```rust
1089/// use cuprate_rpc_types::other::*;
1090///
1091/// let response = OtherResponse::SetBootstrapDaemon(Default::default());
1092/// let json = serde_json::to_string(&response).unwrap();
1093/// assert_eq!(json, r#"{"status":"OK"}"#);
1094/// ```
1095#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1096#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1097#[cfg_attr(feature = "serde", serde(untagged))]
1098pub enum OtherResponse {
1099    GetHeight(GetHeightResponse),
1100    GetTransactions(GetTransactionsResponse),
1101    GetAltBlocksHashes(GetAltBlocksHashesResponse),
1102    IsKeyImageSpent(IsKeyImageSpentResponse),
1103    SendRawTransaction(SendRawTransactionResponse),
1104    StartMining(StartMiningResponse),
1105    StopMining(StopMiningResponse),
1106    MiningStatus(MiningStatusResponse),
1107    SaveBc(SaveBcResponse),
1108    GetPeerList(GetPeerListResponse),
1109    SetLogHashRate(SetLogHashRateResponse),
1110    SetLogLevel(SetLogLevelResponse),
1111    SetLogCategories(SetLogCategoriesResponse),
1112    SetBootstrapDaemon(SetBootstrapDaemonResponse),
1113    GetTransactionPool(GetTransactionPoolResponse),
1114    GetTransactionPoolStats(GetTransactionPoolStatsResponse),
1115    StopDaemon(StopDaemonResponse),
1116    GetLimit(GetLimitResponse),
1117    SetLimit(SetLimitResponse),
1118    OutPeers(OutPeersResponse),
1119    InPeers(InPeersResponse),
1120    GetNetStats(GetNetStatsResponse),
1121    GetOuts(GetOutsResponse),
1122    Update(UpdateResponse),
1123    PopBlocks(PopBlocksResponse),
1124    GetTransactionPoolHashes(GetTransactionPoolHashesResponse),
1125    GetPublicNodes(GetPublicNodesResponse),
1126}
1127
1128//---------------------------------------------------------------------------------------------------- Tests
1129#[cfg(test)]
1130mod test {
1131    // use super::*;
1132}