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 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 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            _ => Err(cuprate_epee_encoding::Error::Value(
100                "Invalid marker for tx blobs".to_string(),
101            )),
102        }
103    }
104
105    /// Epee write function.
106    #[cfg(feature = "epee")]
107    fn tx_blob_write<B: BufMut>(
108        self,
109        field_name: &str,
110        w: &mut B,
111    ) -> cuprate_epee_encoding::Result<()> {
112        if self.should_write_tx_blobs() {
113            match self {
114                Self::Normal(bytes) => {
115                    cuprate_epee_encoding::write_field(bytes, field_name, w)?;
116                }
117                Self::Pruned(obj) => {
118                    cuprate_epee_encoding::write_field(obj, field_name, w)?;
119                }
120                Self::None => (),
121            }
122        }
123        Ok(())
124    }
125
126    /// Epee should write function.
127    #[cfg(feature = "epee")]
128    fn should_write_tx_blobs(&self) -> bool {
129        !self.is_empty()
130    }
131}
132
133//---------------------------------------------------------------------------------------------------- PrunedTxBlobEntry
134/// A pruned transaction with the hash of the missing prunable data
135#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
136#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
137pub struct PrunedTxBlobEntry {
138    /// The transaction.
139    pub blob: Bytes,
140    /// The prunable transaction hash.
141    pub prunable_hash: ByteArray<32>,
142}
143
144#[cfg(feature = "epee")]
145epee_object!(
146    PrunedTxBlobEntry,
147    blob: Bytes,
148    prunable_hash: ByteArray<32>,
149);
150
151//---------------------------------------------------------------------------------------------------- Import
152#[cfg(test)]
153mod tests {}