muta_protocol/codec/
transaction.rs1use std::convert::TryFrom;
2
3use bytes::Bytes;
4use prost::Message;
5
6use crate::{
7 codec::{primitive::Hash, CodecError, ProtocolCodecSync},
8 field, impl_default_bytes_codec_for,
9 types::primitive as protocol_primitive,
10 ProtocolError, ProtocolResult,
11};
12
13#[derive(Clone, Message)]
14pub struct TransactionRequest {
15 #[prost(bytes, tag = "1")]
16 pub service_name: Vec<u8>,
17
18 #[prost(bytes, tag = "2")]
19 pub method: Vec<u8>,
20
21 #[prost(bytes, tag = "3")]
22 pub payload: Vec<u8>,
23}
24
25#[derive(Clone, Message)]
26pub struct RawTransaction {
27 #[prost(message, tag = "1")]
28 pub chain_id: Option<Hash>,
29
30 #[prost(message, tag = "2")]
31 pub nonce: Option<Hash>,
32
33 #[prost(uint64, tag = "3")]
34 pub timeout: u64,
35
36 #[prost(uint64, tag = "4")]
37 pub cycles_price: u64,
38
39 #[prost(uint64, tag = "5")]
40 pub cycles_limit: u64,
41
42 #[prost(message, tag = "6")]
43 pub request: Option<TransactionRequest>,
44}
45
46#[derive(Clone, Message)]
47pub struct SignedTransaction {
48 #[prost(message, tag = "1")]
49 pub raw: Option<RawTransaction>,
50
51 #[prost(message, tag = "2")]
52 pub tx_hash: Option<Hash>,
53
54 #[prost(bytes, tag = "3")]
55 pub pubkey: Vec<u8>,
56
57 #[prost(bytes, tag = "4")]
58 pub signature: Vec<u8>,
59}
60
61impl From<transaction::TransactionRequest> for TransactionRequest {
68 fn from(request: transaction::TransactionRequest) -> TransactionRequest {
69 TransactionRequest {
70 service_name: request.service_name.as_bytes().to_vec(),
71 method: request.method.as_bytes().to_vec(),
72 payload: request.payload.as_bytes().to_vec(),
73 }
74 }
75}
76
77impl TryFrom<TransactionRequest> for transaction::TransactionRequest {
78 type Error = ProtocolError;
79
80 fn try_from(
81 request: TransactionRequest,
82 ) -> Result<transaction::TransactionRequest, Self::Error> {
83 Ok(transaction::TransactionRequest {
84 service_name: String::from_utf8(request.service_name)
85 .map_err(CodecError::FromStringUtf8)?,
86 method: String::from_utf8(request.method).map_err(CodecError::FromStringUtf8)?,
87 payload: String::from_utf8(request.payload).map_err(CodecError::FromStringUtf8)?,
88 })
89 }
90}
91
92impl From<transaction::RawTransaction> for RawTransaction {
95 fn from(raw: transaction::RawTransaction) -> RawTransaction {
96 let chain_id = Some(Hash::from(raw.chain_id));
97 let nonce = Some(Hash::from(raw.nonce));
98 let request = Some(TransactionRequest::from(raw.request));
99
100 RawTransaction {
101 chain_id,
102 nonce,
103 cycles_price: raw.cycles_price,
104 timeout: raw.timeout,
105 cycles_limit: raw.cycles_limit,
106 request,
107 }
108 }
109}
110
111impl TryFrom<RawTransaction> for transaction::RawTransaction {
112 type Error = ProtocolError;
113
114 fn try_from(raw: RawTransaction) -> Result<transaction::RawTransaction, Self::Error> {
115 let chain_id = field!(raw.chain_id, "RawTransaction", "chain_id")?;
116 let nonce = field!(raw.nonce, "RawTransaction", "nonce")?;
117 let request = field!(raw.request, "RawTransaction", "request")?;
118
119 let raw_tx = transaction::RawTransaction {
120 chain_id: protocol_primitive::Hash::try_from(chain_id)?,
121 nonce: protocol_primitive::Hash::try_from(nonce)?,
122 timeout: raw.timeout,
123 cycles_price: raw.cycles_price,
124 cycles_limit: raw.cycles_limit,
125 request: transaction::TransactionRequest::try_from(request)?,
126 };
127
128 Ok(raw_tx)
129 }
130}
131
132impl From<transaction::SignedTransaction> for SignedTransaction {
135 fn from(stx: transaction::SignedTransaction) -> SignedTransaction {
136 let raw = RawTransaction::from(stx.raw);
137 let tx_hash = Hash::from(stx.tx_hash);
138
139 SignedTransaction {
140 raw: Some(raw),
141 tx_hash: Some(tx_hash),
142 pubkey: stx.pubkey.to_vec(),
143 signature: stx.signature.to_vec(),
144 }
145 }
146}
147
148impl TryFrom<SignedTransaction> for transaction::SignedTransaction {
149 type Error = ProtocolError;
150
151 fn try_from(stx: SignedTransaction) -> Result<transaction::SignedTransaction, Self::Error> {
152 let raw = field!(stx.raw, "SignedTransaction", "raw")?;
153 let tx_hash = field!(stx.tx_hash, "SignedTransaction", "tx_hash")?;
154
155 let stx = transaction::SignedTransaction {
156 raw: transaction::RawTransaction::try_from(raw)?,
157 tx_hash: protocol_primitive::Hash::try_from(tx_hash)?,
158 pubkey: Bytes::from(stx.pubkey),
159 signature: Bytes::from(stx.signature),
160 };
161
162 Ok(stx)
163 }
164}
165
166impl_default_bytes_codec_for!(transaction, [RawTransaction, SignedTransaction]);