cuprate_types/
block_complete_entry.rs1use 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#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
26#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
27pub struct BlockCompleteEntry {
28 pub pruned: bool,
30 pub block: Bytes,
32 pub block_weight: u64,
34 pub txs: TransactionBlobs,
36}
37
38#[cfg(feature = "epee")]
39epee_object!(
40 BlockCompleteEntry,
41 pruned: bool = false,
42 block: Bytes,
43 block_weight: u64 = 0_u64,
44 txs: TransactionBlobs = TransactionBlobs::None =>
45 TransactionBlobs::tx_blob_read,
46 TransactionBlobs::tx_blob_write,
47 TransactionBlobs::should_write_tx_blobs,
48);
49
50#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
53#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
54pub enum TransactionBlobs {
55 Pruned(Vec<PrunedTxBlobEntry>),
57 Normal(Vec<Bytes>),
59 #[default]
60 None,
62}
63
64impl TransactionBlobs {
65 pub fn take_pruned(self) -> Option<Vec<PrunedTxBlobEntry>> {
67 match self {
68 Self::Normal(_) => None,
69 Self::Pruned(txs) => Some(txs),
70 Self::None => Some(vec![]),
71 }
72 }
73
74 pub fn take_normal(self) -> Option<Vec<Bytes>> {
76 match self {
77 Self::Normal(txs) => Some(txs),
78 Self::Pruned(_) => None,
79 Self::None => Some(vec![]),
80 }
81 }
82
83 pub const fn len(&self) -> usize {
85 match self {
86 Self::Normal(txs) => txs.len(),
87 Self::Pruned(txs) => txs.len(),
88 Self::None => 0,
89 }
90 }
91
92 pub const fn is_empty(&self) -> bool {
94 self.len() == 0
95 }
96
97 #[cfg(feature = "epee")]
99 fn tx_blob_read<B: Buf>(
100 b: &mut B,
101 _: cuprate_epee_encoding::EpeeValueLimits,
102 ) -> cuprate_epee_encoding::Result<Self> {
103 let limits = cuprate_epee_encoding::EpeeValueLimits {
104 min_element_size: 32,
107 max_sequence_len: usize::MAX,
109 };
110
111 let marker = cuprate_epee_encoding::read_marker(b)?;
112 match marker.inner_marker {
113 InnerMarker::Object => Ok(Self::Pruned(Vec::read(b, &marker, limits)?)),
114 InnerMarker::String => Ok(Self::Normal(Vec::read(b, &marker, limits)?)),
115 InnerMarker::I64
116 | InnerMarker::I32
117 | InnerMarker::I16
118 | InnerMarker::I8
119 | InnerMarker::U64
120 | InnerMarker::U32
121 | InnerMarker::U16
122 | InnerMarker::U8
123 | InnerMarker::F64
124 | InnerMarker::Bool => Err(cuprate_epee_encoding::Error::Value(
125 "Invalid marker for tx blobs".to_string(),
126 )),
127 }
128 }
129
130 #[cfg(feature = "epee")]
132 fn tx_blob_write<B: BufMut>(
133 self,
134 field_name: &str,
135 w: &mut B,
136 ) -> cuprate_epee_encoding::Result<()> {
137 if self.should_write_tx_blobs() {
138 match self {
139 Self::Normal(bytes) => {
140 cuprate_epee_encoding::write_field(bytes, field_name, w)?;
141 }
142 Self::Pruned(obj) => {
143 cuprate_epee_encoding::write_field(obj, field_name, w)?;
144 }
145 Self::None => (),
146 }
147 }
148 Ok(())
149 }
150
151 #[cfg(feature = "epee")]
153 const fn should_write_tx_blobs(&self) -> bool {
154 !self.is_empty()
155 }
156}
157
158#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
161#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
162pub struct PrunedTxBlobEntry {
163 pub blob: Bytes,
165 pub prunable_hash: ByteArray<32>,
167}
168
169#[cfg(feature = "epee")]
170epee_object!(
171 PrunedTxBlobEntry,
172 blob: Bytes,
173 prunable_hash: ByteArray<32>,
174);
175
176#[cfg(test)]
178mod tests {}