Skip to main content

muta_protocol/fixed_codec/
transaction.rs

1use bytes::BytesMut;
2
3use crate::fixed_codec::{FixedCodec, FixedCodecError};
4use crate::types::primitive::Hash;
5use crate::types::transaction::{RawTransaction, SignedTransaction, TransactionRequest};
6use crate::{impl_default_fixed_codec_for, ProtocolResult};
7
8// Impl FixedCodec trait for types
9impl_default_fixed_codec_for!(transaction, [RawTransaction, SignedTransaction]);
10
11impl rlp::Encodable for RawTransaction {
12    fn rlp_append(&self, s: &mut rlp::RlpStream) {
13        s.begin_list(8);
14        s.append(&self.chain_id.as_bytes().to_vec());
15        s.append(&self.cycles_limit);
16        s.append(&self.cycles_price);
17        s.append(&self.nonce.as_bytes().to_vec());
18        s.append(&self.request.method);
19        s.append(&self.request.service_name);
20        s.append(&self.request.payload);
21        s.append(&self.timeout);
22    }
23}
24
25impl rlp::Decodable for RawTransaction {
26    fn decode(r: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
27        let chain_id = Hash::from_bytes(BytesMut::from(r.at(0)?.data()?).freeze())
28            .map_err(|_| rlp::DecoderError::RlpInvalidLength)?;
29
30        let cycles_limit: u64 = r.at(1)?.as_val()?;
31        let cycles_price: u64 = r.at(2)?.as_val()?;
32
33        let nonce = Hash::from_bytes(BytesMut::from(r.at(3)?.data()?).freeze())
34            .map_err(|_| rlp::DecoderError::RlpInvalidLength)?;
35
36        let request = TransactionRequest {
37            method:       r.at(4)?.as_val()?,
38            service_name: r.at(5)?.as_val()?,
39            payload:      r.at(6)?.as_val()?,
40        };
41        let timeout = r.at(7)?.as_val()?;
42
43        Ok(Self {
44            chain_id,
45            cycles_price,
46            cycles_limit,
47            nonce,
48            request,
49            timeout,
50        })
51    }
52}
53
54impl rlp::Encodable for SignedTransaction {
55    fn rlp_append(&self, s: &mut rlp::RlpStream) {
56        s.begin_list(4)
57            .append(&self.pubkey.to_vec())
58            .append(&self.raw)
59            .append(&self.signature.to_vec())
60            .append(&self.tx_hash);
61    }
62}
63
64impl rlp::Decodable for SignedTransaction {
65    fn decode(r: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
66        if !r.is_list() && r.size() != 4 {
67            return Err(rlp::DecoderError::RlpIncorrectListLen);
68        }
69
70        let pubkey = BytesMut::from(r.at(0)?.data()?).freeze();
71        let raw: RawTransaction = rlp::decode(r.at(1)?.as_raw())?;
72        let signature = BytesMut::from(r.at(2)?.data()?).freeze();
73        let tx_hash = rlp::decode(r.at(3)?.as_raw())?;
74
75        Ok(SignedTransaction {
76            raw,
77            tx_hash,
78            pubkey,
79            signature,
80        })
81    }
82}