use super::cosignature_builder::*;
use super::embedded_transaction_builder::*;
use super::embedded_transaction_helper::*;
use super::generator_utils::*;
use super::hash256_dto::*;
#[derive(Debug, Clone)]
pub struct AggregateTransactionBodyBuilder {
pub transactions_hash: Hash256Dto,
pub transactions: Vec<Box<dyn EmbeddedTransactionHelper + 'static>>,
pub cosignatures: Vec<CosignatureBuilder>,
}
impl AggregateTransactionBodyBuilder {
fn load_embedded_transactions(transactions: &mut Vec<Box<dyn EmbeddedTransactionHelper + 'static>>, mut payload: Vec<u8>, payload_size: u32) -> Vec<u8> {
let mut remaining_byte_sizes = payload_size as usize;
while remaining_byte_sizes > 0 {
let item = load_from_binary(&payload);
transactions.push(item.clone());
let size = item.get_size();
let item_size = size + Self::get_padding_size(item.get_size(), 8);
remaining_byte_sizes -= item_size;
payload = (&payload[item_size..]).to_vec();
}
payload
}
fn load_cosignatures(transactions: &mut Vec<CosignatureBuilder>, mut payload: Vec<u8>, payload_size: usize) -> Vec<u8> {
let mut remaining_byte_sizes = payload_size;
while remaining_byte_sizes > 0 {
let item = CosignatureBuilder::from_binary(&payload);
transactions.push(item.clone());
let size = item.get_size();
let item_size = size + Self::get_padding_size(item.get_size(), 8);
remaining_byte_sizes -= item_size;
payload = (&payload[item_size..]).to_vec();
}
payload
}
pub fn from_binary(payload: &[u8]) -> Self {
let mut _bytes = payload.to_vec();
let transactions_hash = Hash256Dto::from_binary(&_bytes); _bytes = _bytes[transactions_hash.get_size()..].to_vec();
let buf = fixed_bytes::<4>(&_bytes);
let payload_size = u32::from_le_bytes(buf); _bytes = (&_bytes[4..]).to_vec();
let buf = fixed_bytes::<4>(&_bytes);
let _ = u32::from_le_bytes(buf); _bytes = (&_bytes[4..]).to_vec();
let mut transactions: Vec<Box<dyn EmbeddedTransactionHelper + 'static>> = vec![];
_bytes = AggregateTransactionBodyBuilder::load_embedded_transactions(&mut transactions, _bytes, payload_size);
let mut cosignatures: Vec<CosignatureBuilder> = vec![];
let _ = Self::load_cosignatures(&mut cosignatures, _bytes.clone(), _bytes.clone().len());
AggregateTransactionBodyBuilder { transactions_hash, transactions, cosignatures } }
pub fn serialize_aligned(transaction: &Box<dyn EmbeddedTransactionHelper>) -> Vec<u8> {
let txn_bytes = transaction.serializer();
let padding = vec![0u8; Self::get_padding_size(txn_bytes.len(), 8)];
[txn_bytes, padding].concat()
}
pub fn size_aligned(transaction: &Box<dyn EmbeddedTransactionHelper>) -> usize {
let txn_size = transaction.get_size();
let padding_size = Self::get_padding_size(txn_size, 8);
txn_size + padding_size
}
fn get_padding_size(size: usize, alignment: usize) -> usize {
if alignment == 0 {
return 0;
}
if size % alignment == 0 {
return 0;
}
alignment - size % alignment
}
pub fn get_size(&self) -> usize {
let mut size = 0;
size += self.transactions_hash.get_size(); size += 4; size += 4; for i in &self.transactions {
size += Self::size_aligned(i); };
for i in &self.cosignatures {
size += i.get_size(); };
size
}
pub fn serializer(&self) -> Vec<u8> {
let mut buf: Vec<u8> = vec![];
buf.append(&mut self.transactions_hash.serializer()); let mut size_value: u32 = 0;
for i in &self.transactions {
size_value += Self::size_aligned(i) as u32;
};
buf.append(&mut size_value.to_le_bytes().to_vec()); buf.append(&mut [0u8; 4].to_vec()); for i in &self.transactions {
buf.append(&mut Self::serialize_aligned(i)); }
for i in &self.cosignatures {
buf.append(&mut i.serializer()); }
buf
}
}