Skip to main content

hiero_sdk/topic/
topic_delete_transaction.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use hiero_sdk_proto::services;
4use hiero_sdk_proto::services::consensus_service_client::ConsensusServiceClient;
5use tonic::transport::Channel;
6
7use crate::ledger_id::RefLedgerId;
8use crate::protobuf::{
9    FromProtobuf,
10    ToProtobuf,
11};
12use crate::transaction::{
13    AnyTransactionData,
14    ChunkInfo,
15    ToSchedulableTransactionDataProtobuf,
16    ToTransactionDataProtobuf,
17    TransactionData,
18    TransactionExecute,
19};
20use crate::{
21    BoxGrpcFuture,
22    Error,
23    TopicId,
24    Transaction,
25    ValidateChecksums,
26};
27
28/// Delete a topic.
29///
30/// No more transactions or queries on the topic will succeed.
31///
32/// If an `admin_key` is set, this transaction must be signed by that key.
33/// If there is no `admin_key`, this transaction will fail `UNAUTHORIZED`.
34///
35pub type TopicDeleteTransaction = Transaction<TopicDeleteTransactionData>;
36
37#[derive(Debug, Clone, Default)]
38pub struct TopicDeleteTransactionData {
39    /// The topic ID which is being deleted in this transaction.
40    topic_id: Option<TopicId>,
41}
42
43impl TopicDeleteTransaction {
44    /// Returns the ID of the topic which is being deleted in this transaction.
45    #[must_use]
46    pub fn get_topic_id(&self) -> Option<TopicId> {
47        self.data().topic_id
48    }
49
50    /// Sets the topic ID which is being deleted in this transaction.
51    pub fn topic_id(&mut self, id: impl Into<TopicId>) -> &mut Self {
52        self.data_mut().topic_id = Some(id.into());
53        self
54    }
55}
56
57impl TransactionData for TopicDeleteTransactionData {}
58
59impl TransactionExecute for TopicDeleteTransactionData {
60    fn execute(
61        &self,
62        channel: Channel,
63        request: services::Transaction,
64    ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
65        Box::pin(async { ConsensusServiceClient::new(channel).delete_topic(request).await })
66    }
67}
68
69impl ValidateChecksums for TopicDeleteTransactionData {
70    fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), Error> {
71        self.topic_id.validate_checksums(ledger_id)
72    }
73}
74
75impl ToTransactionDataProtobuf for TopicDeleteTransactionData {
76    fn to_transaction_data_protobuf(
77        &self,
78        chunk_info: &ChunkInfo,
79    ) -> services::transaction_body::Data {
80        let _ = chunk_info.assert_single_transaction();
81
82        services::transaction_body::Data::ConsensusDeleteTopic(self.to_protobuf())
83    }
84}
85
86impl ToSchedulableTransactionDataProtobuf for TopicDeleteTransactionData {
87    fn to_schedulable_transaction_data_protobuf(
88        &self,
89    ) -> services::schedulable_transaction_body::Data {
90        services::schedulable_transaction_body::Data::ConsensusDeleteTopic(self.to_protobuf())
91    }
92}
93
94impl From<TopicDeleteTransactionData> for AnyTransactionData {
95    fn from(transaction: TopicDeleteTransactionData) -> Self {
96        Self::TopicDelete(transaction)
97    }
98}
99
100impl FromProtobuf<services::ConsensusDeleteTopicTransactionBody> for TopicDeleteTransactionData {
101    fn from_protobuf(pb: services::ConsensusDeleteTopicTransactionBody) -> crate::Result<Self> {
102        Ok(Self { topic_id: Option::from_protobuf(pb.topic_id)? })
103    }
104}
105
106impl ToProtobuf for TopicDeleteTransactionData {
107    type Protobuf = services::ConsensusDeleteTopicTransactionBody;
108
109    fn to_protobuf(&self) -> Self::Protobuf {
110        services::ConsensusDeleteTopicTransactionBody { topic_id: self.topic_id.to_protobuf() }
111    }
112}
113
114#[cfg(test)]
115mod tests {
116    use expect_test::expect;
117
118    use crate::transaction::test_helpers::{
119        check_body,
120        transaction_body,
121    };
122    use crate::{
123        AnyTransaction,
124        TopicDeleteTransaction,
125        TopicId,
126    };
127
128    fn make_transaction() -> TopicDeleteTransaction {
129        let mut tx = TopicDeleteTransaction::new_for_tests();
130
131        tx.topic_id("0.0.5007".parse::<TopicId>().unwrap()).freeze().unwrap();
132
133        tx
134    }
135
136    #[test]
137    fn serialize() {
138        let tx = make_transaction();
139
140        let tx = transaction_body(tx);
141
142        let tx = check_body(tx);
143
144        expect![[r#"
145            ConsensusDeleteTopic(
146                ConsensusDeleteTopicTransactionBody {
147                    topic_id: Some(
148                        TopicId {
149                            shard_num: 0,
150                            realm_num: 0,
151                            topic_num: 5007,
152                        },
153                    ),
154                },
155            )
156        "#]]
157        .assert_debug_eq(&tx)
158    }
159
160    #[test]
161    fn to_from_bytes() {
162        let tx = make_transaction();
163
164        let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
165
166        let tx = transaction_body(tx);
167
168        let tx2 = transaction_body(tx2);
169
170        assert_eq!(tx, tx2);
171    }
172}