cuprate_rpc_types/misc/
pool_info.rs

1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4#[cfg(feature = "epee")]
5use crate::misc::PoolInfoExtent;
6#[cfg(feature = "epee")]
7use cuprate_epee_encoding::{
8    epee_object, error,
9    macros::bytes::{Buf, BufMut},
10    read_epee_value, write_field, EpeeObject, EpeeObjectBuilder,
11};
12
13use cuprate_fixed_bytes::ByteArrayVec;
14
15use crate::misc::PoolTxInfo;
16
17//---------------------------------------------------------------------------------------------------- PoolInfo
18#[doc = crate::macros::monero_definition_link!(
19    cc73fe71162d564ffda8e549b79a350bca53c454,
20    "rpc/core_rpc_server_commands_defs.h",
21    223..=228
22)]
23/// Used in [`crate::bin::GetBlocksResponse`].
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
26#[repr(u8)]
27pub enum PoolInfo {
28    #[default]
29    None,
30    Incremental(PoolInfoIncremental),
31    Full(PoolInfoFull),
32}
33
34//---------------------------------------------------------------------------------------------------- Internal data
35/// Data within [`PoolInfo::Incremental`].
36#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
37#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
38pub struct PoolInfoIncremental {
39    pub added_pool_txs: Vec<PoolTxInfo>,
40    pub remaining_added_pool_txids: ByteArrayVec<32>,
41    pub removed_pool_txids: ByteArrayVec<32>,
42}
43
44#[cfg(feature = "epee")]
45epee_object! {
46    PoolInfoIncremental,
47    added_pool_txs: Vec<PoolTxInfo>,
48    remaining_added_pool_txids: ByteArrayVec<32>,
49    removed_pool_txids: ByteArrayVec<32>,
50}
51
52/// Data within [`PoolInfo::Full`].
53#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
54#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
55pub struct PoolInfoFull {
56    pub added_pool_txs: Vec<PoolTxInfo>,
57    pub remaining_added_pool_txids: ByteArrayVec<32>,
58}
59
60#[cfg(feature = "epee")]
61epee_object! {
62    PoolInfoFull,
63    added_pool_txs: Vec<PoolTxInfo>,
64    remaining_added_pool_txids: ByteArrayVec<32>,
65}
66
67//---------------------------------------------------------------------------------------------------- PoolInfo epee impl
68#[cfg(feature = "epee")]
69/// [`EpeeObjectBuilder`] for [`GetBlocksResponse`].
70///
71/// Not for public usage.
72#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
73#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
74pub struct __PoolInfoEpeeBuilder {
75    /// This is a distinct field in `monerod`,
76    /// which as represented in this library with [`PoolInfo`]'s `u8` tag.
77    pub pool_info_extent: Option<PoolInfoExtent>,
78
79    pub added_pool_txs: Option<Vec<PoolTxInfo>>,
80    pub remaining_added_pool_txids: Option<ByteArrayVec<32>>,
81    pub removed_pool_txids: Option<ByteArrayVec<32>>,
82}
83
84// Custom epee implementation.
85//
86// HACK/INVARIANT:
87// If any data within [`PoolInfo`] changes, the below code should be changed as well.
88#[cfg(feature = "epee")]
89impl EpeeObjectBuilder<PoolInfo> for __PoolInfoEpeeBuilder {
90    fn add_field<B: Buf>(&mut self, name: &str, r: &mut B) -> error::Result<bool> {
91        macro_rules! read_epee_field {
92            ($($field:ident),*) => {
93                match name {
94                    $(
95                        stringify!($field) => { self.$field = Some(read_epee_value(r)?); },
96                    )*
97                    _ => return Ok(false),
98                }
99            };
100        }
101
102        read_epee_field! {
103            pool_info_extent,
104            added_pool_txs,
105            remaining_added_pool_txids,
106            removed_pool_txids
107        }
108
109        Ok(true)
110    }
111
112    fn finish(self) -> error::Result<PoolInfo> {
113        // INVARIANT:
114        // `monerod` omits serializing the field itself when a container is empty,
115        // `unwrap_or_default()` is used over `error()` in these cases.
116        // Some of the uses are when values have default fallbacks: `pool_info_extent`.
117
118        let pool_info_extent = self.pool_info_extent.unwrap_or_default();
119        let this = match pool_info_extent {
120            PoolInfoExtent::None => PoolInfo::None,
121            PoolInfoExtent::Incremental => PoolInfo::Incremental(PoolInfoIncremental {
122                added_pool_txs: self.added_pool_txs.unwrap_or_default(),
123                remaining_added_pool_txids: self.remaining_added_pool_txids.unwrap_or_default(),
124                removed_pool_txids: self.removed_pool_txids.unwrap_or_default(),
125            }),
126            PoolInfoExtent::Full => PoolInfo::Full(PoolInfoFull {
127                added_pool_txs: self.added_pool_txs.unwrap_or_default(),
128                remaining_added_pool_txids: self.remaining_added_pool_txids.unwrap_or_default(),
129            }),
130        };
131
132        Ok(this)
133    }
134}
135
136#[cfg(feature = "epee")]
137impl EpeeObject for PoolInfo {
138    type Builder = __PoolInfoEpeeBuilder;
139
140    fn number_of_fields(&self) -> u64 {
141        // Inner struct fields.
142        let inner_fields = match self {
143            Self::None => 0,
144            Self::Incremental(s) => s.number_of_fields(),
145            Self::Full(s) => s.number_of_fields(),
146        };
147
148        // [`PoolInfoExtent`] + inner struct fields
149        1 + inner_fields
150    }
151
152    fn write_fields<B: BufMut>(self, w: &mut B) -> error::Result<()> {
153        const FIELD: &str = "pool_info_extent";
154
155        match self {
156            Self::None => {
157                write_field(PoolInfoExtent::None.to_u8(), FIELD, w)?;
158            }
159            Self::Incremental(s) => {
160                s.write_fields(w)?;
161                write_field(PoolInfoExtent::Incremental.to_u8(), FIELD, w)?;
162            }
163            Self::Full(s) => {
164                s.write_fields(w)?;
165                write_field(PoolInfoExtent::Full.to_u8(), FIELD, w)?;
166            }
167        }
168
169        Ok(())
170    }
171}