waves_rust/util/
binary_serializer.rs1use prost::Message;
2
3use TransactionData::{
4 Burn, CreateAlias, Ethereum, Genesis, Lease, LeaseCancel, MassTransfer, Payment, Reissue,
5 SetAssetScript, SetScript, SponsorFee, UpdateAssetInfo,
6};
7
8use crate::error::Error::UnsupportedOperation;
9use crate::error::Result;
10use crate::model::TransactionData::{Data, Exchange, InvokeScript, Issue, Transfer};
11use crate::model::{ByteString, Order, OrderType, Transaction, TransactionData};
12use crate::waves_proto::transaction::Data as ProtoData;
13use crate::waves_proto::{
14 Amount as ProtoAmount, Order as ProtoOrder, Transaction as ProtoTransaction,
15};
16
17use super::ByteWriter;
18
19pub struct BinarySerializer;
20
21impl BinarySerializer {
22 pub fn tx_body_bytes(transaction: &Transaction) -> Result<Vec<u8>> {
23 let proto_data = match transaction.data() {
24 Genesis(tx) => ProtoData::Genesis(tx.try_into()?),
25 Payment(tx) => ProtoData::Payment(tx.try_into()?),
26 Transfer(tx) => ProtoData::Transfer(tx.try_into()?),
27 Data(tx) => ProtoData::DataTransaction(tx.try_into()?),
28 Issue(tx) => ProtoData::Issue(tx.try_into()?),
29 InvokeScript(tx) => ProtoData::InvokeScript(tx.try_into()?),
30 Exchange(tx) => ProtoData::Exchange(tx.try_into()?),
31 Reissue(tx) => ProtoData::Reissue(tx.try_into()?),
32 Burn(tx) => ProtoData::Burn(tx.try_into()?),
33 Lease(tx) => ProtoData::Lease(tx.try_into()?),
34 LeaseCancel(tx) => ProtoData::LeaseCancel(tx.try_into()?),
35 CreateAlias(tx) => ProtoData::CreateAlias(tx.try_into()?),
36 MassTransfer(tx) => ProtoData::MassTransfer(tx.try_into()?),
37 SetScript(tx) => ProtoData::SetScript(tx.try_into()?),
38 SetAssetScript(tx) => ProtoData::SetAssetScript(tx.try_into()?),
39 SponsorFee(tx) => ProtoData::SponsorFee(tx.try_into()?),
40 UpdateAssetInfo(tx) => ProtoData::UpdateAssetInfo(tx.try_into()?),
41 Ethereum(_) => Err(UnsupportedOperation("ethereum transaction".to_owned()))?,
42 };
43
44 let fee_asset_id = match transaction.fee().asset_id() {
45 None => vec![],
46 Some(asset_id) => asset_id.bytes(),
47 };
48
49 let amount = ProtoAmount {
50 amount: transaction.fee().value() as i64,
51 asset_id: fee_asset_id,
52 };
53
54 let proto_tx = ProtoTransaction {
55 chain_id: transaction.chain_id() as i32,
56 data: Some(proto_data),
57 fee: Some(amount),
58 sender_public_key: transaction.public_key().bytes(),
59 timestamp: transaction.timestamp() as i64,
60 version: transaction.version() as i32,
61 };
62
63 let buf = Message::encode_to_vec(&proto_tx);
64 Ok(buf)
65 }
66
67 pub fn order_body_bytes(order: &Order) -> Result<Vec<u8>> {
68 match order {
69 Order::V3(order) => {
70 let mut bw = ByteWriter::new();
71
72 bw.push_byte(3);
74 bw.push_bytes(&mut order.sender().bytes());
75 bw.push_bytes(&mut order.matcher().bytes());
76 match order.amount().asset_id() {
77 Some(asset_id) => {
78 bw.push_byte(1);
79 bw.push_bytes(&mut asset_id.bytes());
80 }
81 None => {
82 bw.push_byte(0);
83 }
84 }
85 match order.price().asset_id() {
86 Some(asset_id) => {
87 bw.push_byte(1);
88 bw.push_bytes(&mut asset_id.bytes());
89 }
90 None => {
91 bw.push_byte(0);
92 }
93 }
94 match order.order_type() {
95 OrderType::Buy => {
96 bw.push_byte(0);
97 }
98 OrderType::Sell => {
99 bw.push_byte(1);
100 }
101 }
102 bw.push_bytes(&mut order.price().value().to_be_bytes().to_vec());
103 bw.push_bytes(&mut order.amount().value().to_be_bytes().to_vec());
104 bw.push_bytes(&mut order.timestamp().to_be_bytes().to_vec());
105 bw.push_bytes(&mut order.expiration().to_be_bytes().to_vec());
106 bw.push_bytes(&mut order.fee().value().to_be_bytes().to_vec());
107 match order.fee().asset_id() {
108 Some(asset_id) => {
109 bw.push_byte(1);
110 bw.push_bytes(&mut asset_id.bytes());
111 }
112 None => {
113 bw.push_byte(0);
114 }
115 }
116
117 Ok(bw.bytes())
118 }
119 Order::V4(_) => {
120 let proto_order: ProtoOrder = order.try_into()?;
121 let buf = Message::encode_to_vec(&proto_order);
122 Ok(buf)
123 }
124 }
125 }
126}