cuprate_types/
block_complete_entry.rs

1//! Contains [`BlockCompleteEntry`] and the related types.
2
3//---------------------------------------------------------------------------------------------------- Import
4use bytes::Bytes;
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use cuprate_fixed_bytes::ByteArray;
10
11#[cfg(feature = "epee")]
12use cuprate_epee_encoding::{
13    epee_object,
14    macros::bytes::{Buf, BufMut},
15    EpeeValue, InnerMarker,
16};
17
18//---------------------------------------------------------------------------------------------------- BlockCompleteEntry
19/// A block that can contain transactions.
20#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
22pub struct BlockCompleteEntry {
23    /// `true` if transaction data is pruned.
24    pub pruned: bool,
25    /// The block.
26    pub block: Bytes,
27    /// The block weight/size.
28    pub block_weight: u64,
29    /// The block's transactions.
30    pub txs: TransactionBlobs,
31}
32
33#[cfg(feature = "epee")]
34epee_object!(
35    BlockCompleteEntry,
36    pruned: bool = false,
37    block: Bytes,
38    block_weight: u64 = 0_u64,
39    txs: TransactionBlobs = TransactionBlobs::None =>
40        TransactionBlobs::tx_blob_read,
41        TransactionBlobs::tx_blob_write,
42        TransactionBlobs::should_write_tx_blobs,
43);
44
45//---------------------------------------------------------------------------------------------------- TransactionBlobs
46/// Transaction blobs within [`BlockCompleteEntry`].
47#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
48#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
49pub enum TransactionBlobs {
50    /// Pruned transaction blobs.
51    Pruned(Vec<PrunedTxBlobEntry>),
52    /// Normal transaction blobs.
53    Normal(Vec<Bytes>),
54    #[default]
55    /// No transactions.
56    None,
57}
58
59impl TransactionBlobs {
60    /// Returns [`Some`] if `self` is [`Self::Pruned`].
61    pub fn take_pruned(self) -> Option<Vec<PrunedTxBlobEntry>> {
62        match self {
63            Self::Normal(_) => None,
64            Self::Pruned(txs) => Some(txs),
65            Self::None => Some(vec![]),
66        }
67    }
68
69    /// Returns [`Some`] if `self` is [`Self::Normal`].
70    pub fn take_normal(self) -> Option<Vec<Bytes>> {
71        match self {
72            Self::Normal(txs) => Some(txs),
73            Self::Pruned(_) => None,
74            Self::None => Some(vec![]),
75        }
76    }
77
78    /// Returns the byte length of the blob.
79    pub const fn len(&self) -> usize {
80        match self {
81            Self::Normal(txs) => txs.len(),
82            Self::Pruned(txs) => txs.len(),
83            Self::None => 0,
84        }
85    }
86
87    /// Returns `true` if the byte length of the blob is `0`.
88    pub const fn is_empty(&self) -> bool {
89        self.len() == 0
90    }
91
92    /// Epee read function.
93    #[cfg(feature = "epee")]
94    fn tx_blob_read<B: Buf>(b: &mut B) -> cuprate_epee_encoding::Result<Self> {
95        let marker = cuprate_epee_encoding::read_marker(b)?;
96        match marker.inner_marker {
97            InnerMarker::Object => Ok(Self::Pruned(Vec::read(b, &marker)?)),
98            InnerMarker::String => Ok(Self::Normal(Vec::read(b, &marker)?)),
99            InnerMarker::I64
100            | InnerMarker::I32
101            | InnerMarker::I16
102            | InnerMarker::I8
103            | InnerMarker::U64
104            | InnerMarker::U32
105            | InnerMarker::U16
106            | InnerMarker::U8
107            | InnerMarker::F64
108            | InnerMarker::Bool => Err(cuprate_epee_encoding::Error::Value(
109                "Invalid marker for tx blobs".to_string(),
110            )),
111        }
112    }
113
114    /// Epee write function.
115    #[cfg(feature = "epee")]
116    fn tx_blob_write<B: BufMut>(
117        self,
118        field_name: &str,
119        w: &mut B,
120    ) -> cuprate_epee_encoding::Result<()> {
121        if self.should_write_tx_blobs() {
122            match self {
123                Self::Normal(bytes) => {
124                    cuprate_epee_encoding::write_field(bytes, field_name, w)?;
125                }
126                Self::Pruned(obj) => {
127                    cuprate_epee_encoding::write_field(obj, field_name, w)?;
128                }
129                Self::None => (),
130            }
131        }
132        Ok(())
133    }
134
135    /// Epee should write function.
136    #[cfg(feature = "epee")]
137    const fn should_write_tx_blobs(&self) -> bool {
138        !self.is_empty()
139    }
140}
141
142//---------------------------------------------------------------------------------------------------- PrunedTxBlobEntry
143/// A pruned transaction with the hash of the missing prunable data
144#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
145#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
146pub struct PrunedTxBlobEntry {
147    /// The transaction.
148    pub blob: Bytes,
149    /// The prunable transaction hash.
150    pub prunable_hash: ByteArray<32>,
151}
152
153#[cfg(feature = "epee")]
154epee_object!(
155    PrunedTxBlobEntry,
156    blob: Bytes,
157    prunable_hash: ByteArray<32>,
158);
159
160//---------------------------------------------------------------------------------------------------- Import
161#[cfg(test)]
162mod tests {}