espresso_types/v0/impls/
transaction.rs1use committable::{Commitment, Committable};
2use hotshot_query_service::explorer::ExplorerTransaction;
3use hotshot_types::traits::block_contents::Transaction as HotShotTransaction;
4use serde::{de::Error, Deserialize, Deserializer};
5
6use super::{NsPayloadBuilder, NsTableBuilder};
7use crate::{NamespaceId, Transaction};
8
9impl From<u32> for NamespaceId {
10 fn from(value: u32) -> Self {
11 Self(value as u64)
12 }
13}
14
15impl From<NamespaceId> for u32 {
16 fn from(value: NamespaceId) -> Self {
17 value.0 as Self
18 }
19}
20
21impl<'de> Deserialize<'de> for NamespaceId {
22 fn deserialize<D>(deserializer: D) -> Result<NamespaceId, D::Error>
23 where
24 D: Deserializer<'de>,
25 {
26 use serde::de::Unexpected;
27
28 let ns_id = <u64 as Deserialize>::deserialize(deserializer)?;
29 if ns_id > u32::MAX as u64 {
30 Err(D::Error::invalid_value(
31 Unexpected::Unsigned(ns_id),
32 &"at most u32::MAX",
33 ))
34 } else {
35 Ok(NamespaceId(ns_id))
36 }
37 }
38}
39
40impl NamespaceId {
41 #[cfg(any(test, feature = "testing"))]
42 pub fn random(rng: &mut dyn rand::RngCore) -> Self {
43 Self(rng.next_u32() as u64)
44 }
45}
46
47impl Transaction {
48 pub fn new(namespace: NamespaceId, payload: Vec<u8>) -> Self {
49 Self { namespace, payload }
50 }
51
52 pub fn namespace(&self) -> NamespaceId {
53 self.namespace
54 }
55
56 pub fn payload(&self) -> &[u8] {
57 &self.payload
58 }
59
60 pub fn into_payload(self) -> Vec<u8> {
61 self.payload
62 }
63
64 pub fn size_in_block(&self, new_ns: bool) -> u64 {
65 if new_ns {
66 self.minimum_block_size()
69 } else {
70 (self.payload().len() + NsPayloadBuilder::tx_table_entry_byte_len()) as u64
71 }
72 }
73
74 #[cfg(any(test, feature = "testing"))]
75 pub fn random(rng: &mut dyn rand::RngCore) -> Self {
76 use rand::Rng;
77 let len = rng.gen_range(0..100);
78 Self::new(
79 NamespaceId::random(rng),
80 (0..len).map(|_| rand::random::<u8>()).collect::<Vec<_>>(),
81 )
82 }
83 #[cfg(any(test, feature = "testing"))]
84 pub fn of_size(len: usize) -> Self {
86 Self::new(
87 NamespaceId(1),
88 (0..len).map(|_| rand::random::<u8>()).collect::<Vec<_>>(),
89 )
90 }
91}
92
93impl HotShotTransaction for Transaction {
94 fn minimum_block_size(&self) -> u64 {
95 let len = self.payload().len()
96 + NsPayloadBuilder::tx_table_entry_byte_len()
97 + NsTableBuilder::entry_byte_len()
98 + NsPayloadBuilder::tx_table_header_byte_len();
99 len as u64
100 }
101}
102
103impl Committable for Transaction {
104 fn commit(&self) -> Commitment<Self> {
105 committable::RawCommitmentBuilder::new("Transaction")
106 .u64_field("namespace", self.namespace.0)
107 .var_size_bytes(&self.payload)
108 .finalize()
109 }
110
111 fn tag() -> String {
112 "TX".into()
113 }
114}
115
116impl ExplorerTransaction for Transaction {
117 type NamespaceId = NamespaceId;
118 fn namespace_id(&self) -> Self::NamespaceId {
119 self.namespace
120 }
121
122 fn payload_size(&self) -> u64 {
123 self.payload.len() as u64
124 }
125}