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;
7use crate::{NamespaceId, SeqTypes, 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 From<i64> for NamespaceId {
22 fn from(value: i64) -> Self {
23 Self(value as u64)
24 }
25}
26
27impl From<NamespaceId> for i64 {
28 fn from(value: NamespaceId) -> Self {
29 value.0 as Self
30 }
31}
32
33impl<'de> Deserialize<'de> for NamespaceId {
34 fn deserialize<D>(deserializer: D) -> Result<NamespaceId, D::Error>
35 where
36 D: Deserializer<'de>,
37 {
38 use serde::de::Unexpected;
39
40 let ns_id = <u64 as Deserialize>::deserialize(deserializer)?;
41 if ns_id > u32::MAX as u64 {
42 Err(D::Error::invalid_value(
43 Unexpected::Unsigned(ns_id),
44 &"at most u32::MAX",
45 ))
46 } else {
47 Ok(NamespaceId(ns_id))
48 }
49 }
50}
51
52impl NamespaceId {
53 #[cfg(any(test, feature = "testing"))]
54 pub fn random(rng: &mut dyn rand::RngCore) -> Self {
55 Self(rng.next_u32() as u64)
56 }
57}
58
59impl Transaction {
60 pub fn new(namespace: NamespaceId, payload: Vec<u8>) -> Self {
61 Self { namespace, payload }
62 }
63
64 pub fn namespace(&self) -> NamespaceId {
65 self.namespace
66 }
67
68 pub fn payload(&self) -> &[u8] {
69 &self.payload
70 }
71
72 pub fn into_payload(self) -> Vec<u8> {
73 self.payload
74 }
75
76 pub fn size_in_block(&self, new_ns: bool) -> u64 {
77 if new_ns {
78 self.minimum_block_size()
80 } else {
81 (self.payload().len() + NsPayloadBuilder::tx_table_entry_byte_len()) as u64
82 }
83 }
84
85 #[cfg(any(test, feature = "testing"))]
86 pub fn random(rng: &mut dyn rand::RngCore) -> Self {
87 use rand::Rng;
88 let len = rng.gen_range(0..100);
89 Self::new(
90 NamespaceId::random(rng),
91 (0..len).map(|_| rand::random::<u8>()).collect::<Vec<_>>(),
92 )
93 }
94 #[cfg(any(test, feature = "testing"))]
95 pub fn of_size(len: usize) -> Self {
97 Self::new(
98 NamespaceId(1),
99 (0..len).map(|_| rand::random::<u8>()).collect::<Vec<_>>(),
100 )
101 }
102}
103
104impl HotShotTransaction for Transaction {
105 fn minimum_block_size(&self) -> u64 {
106 let len =
108 self.payload().len()
110 + NsPayloadBuilder::tx_table_entry_byte_len()
112 + NsPayloadBuilder::tx_table_header_byte_len();
114 len as u64
119 }
120}
121
122impl Committable for Transaction {
123 fn commit(&self) -> Commitment<Self> {
124 committable::RawCommitmentBuilder::new("Transaction")
125 .u64_field("namespace", self.namespace.0)
126 .var_size_bytes(&self.payload)
127 .finalize()
128 }
129
130 fn tag() -> String {
131 "TX".into()
132 }
133}
134
135impl ExplorerTransaction<SeqTypes> for Transaction {
136 fn namespace_id(&self) -> NamespaceId {
137 self.namespace
138 }
139
140 fn payload_size(&self) -> u64 {
141 self.payload.len() as u64
142 }
143}