hiero_sdk/hooks/
hook_store_transaction.rs1use hiero_sdk_proto::services;
2use hiero_sdk_proto::services::smart_contract_service_client::SmartContractServiceClient;
3use tonic::transport::Channel;
4
5use crate::hooks::{
6 EvmHookStorageUpdate,
7 HookId,
8};
9use crate::ledger_id::RefLedgerId;
10use crate::protobuf::ToProtobuf;
11use crate::transaction::{
12 ChunkInfo,
13 ToTransactionDataProtobuf,
14 Transaction,
15 TransactionData,
16 TransactionExecute,
17};
18use crate::{
19 BoxGrpcFuture,
20 ValidateChecksums,
21};
22
23pub type HookStoreTransaction = Transaction<HookStoreTransactionData>;
25
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct HookStoreTransactionData {
28 hook_id: Option<HookId>,
30 storage_updates: Vec<EvmHookStorageUpdate>,
32}
33
34impl Default for HookStoreTransactionData {
35 fn default() -> Self {
36 Self { hook_id: None, storage_updates: Vec::new() }
37 }
38}
39
40impl HookStoreTransaction {
41 pub fn set_hook_id(&mut self, hook_id: HookId) -> &mut Self {
43 self.data_mut().hook_id = Some(hook_id);
44 self
45 }
46
47 pub fn set_storage_updates(&mut self, storage_updates: Vec<EvmHookStorageUpdate>) -> &mut Self {
49 self.data_mut().storage_updates = storage_updates;
50 self
51 }
52
53 pub fn add_storage_update(&mut self, storage_update: EvmHookStorageUpdate) -> &mut Self {
55 self.data_mut().storage_updates.push(storage_update);
56 self
57 }
58
59 pub fn get_hook_id(&self) -> Option<&HookId> {
61 self.data().hook_id.as_ref()
62 }
63
64 pub fn get_storage_updates(&self) -> &[EvmHookStorageUpdate] {
66 &self.data().storage_updates
67 }
68}
69
70impl HookStoreTransactionData {
71 pub fn new() -> Self {
73 Self::default()
74 }
75}
76
77impl TransactionData for HookStoreTransactionData {
78 fn default_max_transaction_fee(&self) -> crate::Hbar {
80 crate::Hbar::new(2)
81 }
82}
83
84impl ValidateChecksums for HookStoreTransactionData {
85 fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), crate::Error> {
86 if let Some(hook_id) = &self.hook_id {
87 hook_id.entity_id.validate_checksums(ledger_id)?;
88 }
89 Ok(())
90 }
91}
92
93impl TransactionExecute for HookStoreTransactionData {
94 fn execute(
95 &self,
96 channel: Channel,
97 request: services::Transaction,
98 ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
99 Box::pin(async { SmartContractServiceClient::new(channel).hook_store(request).await })
100 }
101}
102
103impl ToTransactionDataProtobuf for HookStoreTransactionData {
104 fn to_transaction_data_protobuf(
105 &self,
106 chunk_info: &ChunkInfo,
107 ) -> services::transaction_body::Data {
108 let _ = chunk_info.assert_single_transaction();
109 services::transaction_body::Data::HookStore(self.to_protobuf())
110 }
111}
112
113impl crate::protobuf::ToProtobuf for HookStoreTransactionData {
114 type Protobuf = services::HookStoreTransactionBody;
115
116 fn to_protobuf(&self) -> Self::Protobuf {
117 services::HookStoreTransactionBody {
118 hook_id: self.hook_id.as_ref().map(|id| id.to_protobuf()),
119 storage_updates: self
120 .storage_updates
121 .iter()
122 .map(|update| update.to_protobuf())
123 .collect(),
124 }
125 }
126}
127
128impl crate::protobuf::FromProtobuf<services::HookStoreTransactionBody>
129 for HookStoreTransactionData
130{
131 fn from_protobuf(pb: services::HookStoreTransactionBody) -> crate::Result<Self> {
132 let hook_id = pb.hook_id.map(HookId::from_protobuf).transpose()?;
133
134 let storage_updates = pb
135 .storage_updates
136 .into_iter()
137 .map(EvmHookStorageUpdate::from_protobuf)
138 .collect::<Result<Vec<_>, _>>()?;
139
140 Ok(Self { hook_id, storage_updates })
141 }
142}
143
144impl From<HookStoreTransactionData> for crate::transaction::AnyTransactionData {
145 fn from(transaction: HookStoreTransactionData) -> Self {
146 Self::HookStore(transaction)
147 }
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153 use crate::hooks::{
154 EvmHookStorageSlot,
155 EvmHookStorageUpdate,
156 HookId,
157 };
158
159 #[test]
160 fn test_hook_store_transaction_creation() {
161 let hook_id = HookId::new(None, 123);
162 let storage_slot = EvmHookStorageSlot::new(vec![1, 2, 3], vec![4, 5, 6]);
163 let storage_update = EvmHookStorageUpdate::StorageSlot(storage_slot);
164
165 let mut transaction = HookStoreTransaction::new();
166 transaction.set_hook_id(hook_id.clone()).add_storage_update(storage_update);
167
168 assert_eq!(transaction.get_hook_id(), Some(&hook_id));
169 assert_eq!(transaction.get_storage_updates().len(), 1);
170 }
171
172 #[test]
173 fn test_hook_store_transaction_default() {
174 let transaction = HookStoreTransaction::new();
175 assert_eq!(transaction.get_hook_id(), None);
176 assert_eq!(transaction.get_storage_updates().len(), 0);
177 }
178}