cuprate_types/rpc/
pool_info.rs

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