use crate::codec::short_vec::write_shortvec_len;
use crate::models::instruction::Instruction;
use crate::models::message::{Message, MessageLegacy, MessageV0};
use crate::models::{HashBase58, PubkeyBase58, Transaction};
const VERSION_PREFIX: u8 = 0x80;
const VERSION_0: u8 = 0;
pub fn serialize_transaction(tx: &Transaction) -> Vec<u8> {
let mut buf = Vec::new();
write_shortvec_len(tx.signatures.len(), &mut buf);
for sig in &tx.signatures {
buf.extend_from_slice(&sig.to_bytes());
}
buf.extend_from_slice(&serialize_message(&tx.message));
buf
}
pub fn serialize_message(msg: &Message) -> Vec<u8> {
match msg {
Message::Legacy(legacy_msg) => serialize_message_legacy(legacy_msg),
Message::V0(v0_msg) => serialize_message_v0(v0_msg),
}
}
pub fn serialize_message_legacy(msg: &MessageLegacy) -> Vec<u8> {
let mut buf = Vec::new();
buf.push(msg.header.num_required_signatures);
buf.push(msg.header.num_readonly_signed_accounts);
buf.push(msg.header.num_readonly_unsigned_accounts);
write_shortvec_len(msg.account_keys.len(), &mut buf);
for PubkeyBase58(pk) in &msg.account_keys {
buf.extend_from_slice(pk);
}
let HashBase58(bh) = &msg.recent_blockhash;
buf.extend_from_slice(bh);
write_shortvec_len(msg.instructions.len(), &mut buf);
for instr in &msg.instructions {
buf.extend_from_slice(&serialize_instruction(instr));
}
buf
}
pub fn serialize_message_v0(msg: &MessageV0) -> Vec<u8> {
let mut buf = Vec::new();
buf.push(VERSION_PREFIX | VERSION_0);
buf.push(msg.header.num_required_signatures);
buf.push(msg.header.num_readonly_signed_accounts);
buf.push(msg.header.num_readonly_unsigned_accounts);
write_shortvec_len(msg.account_keys.len(), &mut buf);
for PubkeyBase58(pk) in &msg.account_keys {
buf.extend_from_slice(pk);
}
let HashBase58(bh) = &msg.recent_blockhash;
buf.extend_from_slice(bh);
write_shortvec_len(msg.instructions.len(), &mut buf);
for instr in &msg.instructions {
buf.extend_from_slice(&serialize_instruction(instr));
}
write_shortvec_len(msg.address_table_lookups.len(), &mut buf);
for lut in &msg.address_table_lookups {
buf.extend_from_slice(&lut.account_key.0);
write_shortvec_len(lut.writable_indexes.len(), &mut buf);
buf.extend_from_slice(&lut.writable_indexes);
write_shortvec_len(lut.readonly_indexes.len(), &mut buf);
buf.extend_from_slice(&lut.readonly_indexes);
}
buf
}
pub fn serialize_instruction(instr: &Instruction) -> Vec<u8> {
let mut buf = Vec::new();
buf.push(instr.program_id_index);
write_shortvec_len(instr.accounts.len(), &mut buf);
buf.extend_from_slice(&instr.accounts);
write_shortvec_len(instr.data.len(), &mut buf);
buf.extend_from_slice(&instr.data);
buf
}