Remove custom serialization
This commit is contained in:
parent
981e057363
commit
857dc2ba47
|
@ -4,7 +4,7 @@
|
||||||
//! unstable and may change in future releases.
|
//! unstable and may change in future releases.
|
||||||
|
|
||||||
use crate::rpc_client::RpcClient;
|
use crate::rpc_client::RpcClient;
|
||||||
use bincode::serialize_into;
|
use bincode::{serialize_into, serialized_size};
|
||||||
use log::*;
|
use log::*;
|
||||||
use solana_sdk::hash::Hash;
|
use solana_sdk::hash::Hash;
|
||||||
use solana_sdk::packet::PACKET_DATA_SIZE;
|
use solana_sdk::packet::PACKET_DATA_SIZE;
|
||||||
|
@ -63,7 +63,7 @@ impl ThinClient {
|
||||||
/// Send a signed Transaction to the server for processing. This method
|
/// Send a signed Transaction to the server for processing. This method
|
||||||
/// does not wait for a response.
|
/// does not wait for a response.
|
||||||
pub fn transfer_signed(&self, transaction: &Transaction) -> io::Result<Signature> {
|
pub fn transfer_signed(&self, transaction: &Transaction) -> io::Result<Signature> {
|
||||||
let mut buf = vec![0; transaction.serialized_size().unwrap() as usize];
|
let mut buf = vec![0; serialized_size(&transaction).unwrap() as usize];
|
||||||
let mut wr = std::io::Cursor::new(&mut buf[..]);
|
let mut wr = std::io::Cursor::new(&mut buf[..]);
|
||||||
serialize_into(&mut wr, &transaction)
|
serialize_into(&mut wr, &transaction)
|
||||||
.expect("serialize Transaction in pub fn transfer_signed");
|
.expect("serialize Transaction in pub fn transfer_signed");
|
||||||
|
@ -83,7 +83,7 @@ impl ThinClient {
|
||||||
) -> io::Result<Signature> {
|
) -> io::Result<Signature> {
|
||||||
for x in 0..tries {
|
for x in 0..tries {
|
||||||
transaction.sign(&[keypair], self.get_recent_blockhash()?);
|
transaction.sign(&[keypair], self.get_recent_blockhash()?);
|
||||||
let mut buf = vec![0; transaction.serialized_size().unwrap() as usize];
|
let mut buf = vec![0; serialized_size(&transaction).unwrap() as usize];
|
||||||
let mut wr = std::io::Cursor::new(&mut buf[..]);
|
let mut wr = std::io::Cursor::new(&mut buf[..]);
|
||||||
serialize_into(&mut wr, &transaction)
|
serialize_into(&mut wr, &transaction)
|
||||||
.expect("serialize Transaction in pub fn transfer_signed");
|
.expect("serialize Transaction in pub fn transfer_signed");
|
||||||
|
@ -112,7 +112,7 @@ impl ThinClient {
|
||||||
) -> io::Result<Signature> {
|
) -> io::Result<Signature> {
|
||||||
for x in 0..tries {
|
for x in 0..tries {
|
||||||
transaction.sign(&[keypair], self.get_recent_blockhash()?);
|
transaction.sign(&[keypair], self.get_recent_blockhash()?);
|
||||||
let mut buf = vec![0; transaction.serialized_size().unwrap() as usize];
|
let mut buf = vec![0; serialized_size(&transaction).unwrap() as usize];
|
||||||
let mut wr = std::io::Cursor::new(&mut buf[..]);
|
let mut wr = std::io::Cursor::new(&mut buf[..]);
|
||||||
serialize_into(&mut wr, &transaction)
|
serialize_into(&mut wr, &transaction)
|
||||||
.expect("serialize Transaction in pub fn transfer_signed");
|
.expect("serialize Transaction in pub fn transfer_signed");
|
||||||
|
|
|
@ -105,7 +105,7 @@ impl Entry {
|
||||||
pub fn serialized_size(transactions: &[Transaction]) -> u64 {
|
pub fn serialized_size(transactions: &[Transaction]) -> u64 {
|
||||||
let txs_size: u64 = transactions
|
let txs_size: u64 = transactions
|
||||||
.iter()
|
.iter()
|
||||||
.map(|tx| tx.serialized_size().unwrap())
|
.map(|tx| serialized_size(tx).unwrap())
|
||||||
.sum();
|
.sum();
|
||||||
// num_hashes + hash + txs
|
// num_hashes + hash + txs
|
||||||
(2 * size_of::<u64>() + size_of::<Hash>()) as u64 + txs_size
|
(2 * size_of::<u64>() + size_of::<Hash>()) as u64 + txs_size
|
||||||
|
@ -402,7 +402,7 @@ pub fn make_large_test_entries(num_entries: usize) -> Vec<Entry> {
|
||||||
let ix = BudgetInstruction::new_apply_timestamp(&pubkey, &pubkey, &pubkey, Utc::now());
|
let ix = BudgetInstruction::new_apply_timestamp(&pubkey, &pubkey, &pubkey, Utc::now());
|
||||||
let tx = Transaction::new_signed_instructions(&[&keypair], vec![ix], one, 0);
|
let tx = Transaction::new_signed_instructions(&[&keypair], vec![ix], one, 0);
|
||||||
|
|
||||||
let serialized_size = tx.serialized_size().unwrap();
|
let serialized_size = serialized_size(&tx).unwrap();
|
||||||
let num_txs = BLOB_DATA_SIZE / serialized_size as usize;
|
let num_txs = BLOB_DATA_SIZE / serialized_size as usize;
|
||||||
let txs = vec![tx; num_txs];
|
let txs = vec![tx; num_txs];
|
||||||
let entry = next_entries(&one, 1, txs)[0].clone();
|
let entry = next_entries(&one, 1, txs)[0].clone();
|
||||||
|
@ -643,8 +643,8 @@ mod tests {
|
||||||
let tx_small = create_sample_vote(&vote_account, next_hash);
|
let tx_small = create_sample_vote(&vote_account, next_hash);
|
||||||
let tx_large = create_sample_payment(&keypair, next_hash);
|
let tx_large = create_sample_payment(&keypair, next_hash);
|
||||||
|
|
||||||
let tx_small_size = tx_small.serialized_size().unwrap() as usize;
|
let tx_small_size = serialized_size(&tx_small).unwrap() as usize;
|
||||||
let tx_large_size = tx_large.serialized_size().unwrap() as usize;
|
let tx_large_size = serialized_size(&tx_large).unwrap() as usize;
|
||||||
let entry_size = serialized_size(&Entry {
|
let entry_size = serialized_size(&Entry {
|
||||||
num_hashes: 0,
|
num_hashes: 0,
|
||||||
hash: Hash::default(),
|
hash: Hash::default(),
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
use crate::packet::{Packet, SharedPackets};
|
use crate::packet::{Packet, SharedPackets};
|
||||||
use crate::result::Result;
|
use crate::result::Result;
|
||||||
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
use solana_metrics::counter::Counter;
|
use solana_metrics::counter::Counter;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::shortvec::decode_len;
|
|
||||||
use solana_sdk::signature::Signature;
|
use solana_sdk::signature::Signature;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::Transaction;
|
||||||
|
@ -124,25 +124,17 @@ pub fn ed25519_verify(batches: &[SharedPackets]) -> Vec<Vec<u8>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_packet_offsets(packet: &Packet, current_offset: u32) -> (u32, u32, u32, u32) {
|
pub fn get_packet_offsets(packet: &Packet, current_offset: u32) -> (u32, u32, u32, u32) {
|
||||||
// Read in the size of signatures array
|
// Read in u64 as the size of signatures array
|
||||||
let start_offset = TX_OFFSET + size_of::<u64>();
|
let mut rdr = Cursor::new(&packet.data[TX_OFFSET..size_of::<u64>()]);
|
||||||
let mut rd = Cursor::new(&packet.data[start_offset..]);
|
let sig_len = rdr.read_u64::<LittleEndian>().unwrap() as u32;
|
||||||
let sig_len = decode_len(&mut rd).unwrap();
|
|
||||||
let sig_size = rd.position() as usize;
|
|
||||||
let msg_start_offset = start_offset + sig_size + sig_len * size_of::<Signature>();
|
|
||||||
let mut rd = Cursor::new(&packet.data[msg_start_offset..]);
|
|
||||||
let _ = decode_len(&mut rd).unwrap();
|
|
||||||
let pubkey_size = rd.position() as usize;
|
|
||||||
let pubkey_offset = current_offset as usize + msg_start_offset + pubkey_size;
|
|
||||||
|
|
||||||
let sig_start = start_offset + current_offset as usize + sig_size;
|
let msg_start_offset =
|
||||||
|
current_offset + size_of::<u64>() as u32 + sig_len * size_of::<Signature>() as u32;
|
||||||
|
let pubkey_offset = msg_start_offset + size_of::<u64>() as u32;
|
||||||
|
|
||||||
(
|
let sig_start = TX_OFFSET as u32 + size_of::<u64>() as u32;
|
||||||
sig_len as u32,
|
|
||||||
sig_start as u32,
|
(sig_len, sig_start, msg_start_offset, pubkey_offset)
|
||||||
current_offset + msg_start_offset as u32,
|
|
||||||
pubkey_offset as u32,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_offsets(batches: &[SharedPackets]) -> Result<TxOffsets> {
|
pub fn generate_offsets(batches: &[SharedPackets]) -> Result<TxOffsets> {
|
||||||
|
@ -157,14 +149,14 @@ pub fn generate_offsets(batches: &[SharedPackets]) -> Result<TxOffsets> {
|
||||||
p.read().unwrap().packets.iter().for_each(|packet| {
|
p.read().unwrap().packets.iter().for_each(|packet| {
|
||||||
let current_offset = current_packet as u32 * size_of::<Packet>() as u32;
|
let current_offset = current_packet as u32 * size_of::<Packet>() as u32;
|
||||||
|
|
||||||
let (sig_len, sig_start, msg_start_offset, pubkey_offset) =
|
let (sig_len, _sig_start, msg_start_offset, pubkey_offset) =
|
||||||
get_packet_offsets(packet, current_offset);
|
get_packet_offsets(packet, current_offset);
|
||||||
let mut pubkey_offset = pubkey_offset;
|
let mut pubkey_offset = pubkey_offset;
|
||||||
|
|
||||||
sig_lens.push(sig_len);
|
sig_lens.push(sig_len);
|
||||||
|
|
||||||
trace!("pubkey_offset: {}", pubkey_offset);
|
trace!("pubkey_offset: {}", pubkey_offset);
|
||||||
let mut sig_offset = sig_start;
|
let mut sig_offset = current_offset + size_of::<u64>() as u32;
|
||||||
for _ in 0..sig_len {
|
for _ in 0..sig_len {
|
||||||
signature_offsets.push(sig_offset);
|
signature_offsets.push(sig_offset);
|
||||||
sig_offset += size_of::<Signature>() as u32;
|
sig_offset += size_of::<Signature>() as u32;
|
||||||
|
@ -337,7 +329,7 @@ mod tests {
|
||||||
use bincode::{deserialize, serialize};
|
use bincode::{deserialize, serialize};
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::Transaction;
|
||||||
|
|
||||||
const SIG_OFFSET: usize = std::mem::size_of::<u64>() + 1;
|
const SIG_OFFSET: usize = std::mem::size_of::<u64>();
|
||||||
|
|
||||||
pub fn memfind<A: Eq>(a: &[A], b: &[A]) -> Option<usize> {
|
pub fn memfind<A: Eq>(a: &[A], b: &[A]) -> Option<usize> {
|
||||||
assert!(a.len() >= b.len());
|
assert!(a.len() >= b.len());
|
||||||
|
@ -424,11 +416,11 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_packet_offsets() {
|
fn test_get_packet_offsets() {
|
||||||
assert_eq!(get_packet_offsets_from_tx(test_tx(), 0), (1, 9, 64, 1));
|
assert_eq!(get_packet_offsets_from_tx(test_tx(), 0), (1, 8, 64, 8));
|
||||||
assert_eq!(get_packet_offsets_from_tx(test_tx(), 100), (1, 9, 64, 1));
|
assert_eq!(get_packet_offsets_from_tx(test_tx(), 100), (1, 8, 64, 8));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
get_packet_offsets_from_tx(test_multisig_tx(), 0),
|
get_packet_offsets_from_tx(test_multisig_tx(), 0),
|
||||||
(2, 9, 128, 1)
|
(2, 8, 128, 8)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
//! Defines a composable Instruction type and a memory-efficient CompiledInstruction.
|
//! Defines a composable Instruction type and a memory-efficient CompiledInstruction.
|
||||||
|
|
||||||
use crate::pubkey::Pubkey;
|
use crate::pubkey::Pubkey;
|
||||||
use crate::shortvec::{deserialize_vec_bytes, encode_len, serialize_vec_bytes};
|
|
||||||
use crate::system_instruction::SystemError;
|
use crate::system_instruction::SystemError;
|
||||||
use bincode::{serialize, Error};
|
use bincode::serialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::io::{Cursor, Read, Write};
|
|
||||||
use std::mem::size_of;
|
|
||||||
|
|
||||||
/// Reasons the runtime might have rejected an instruction.
|
/// Reasons the runtime might have rejected an instruction.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
@ -129,41 +126,4 @@ impl CompiledInstruction {
|
||||||
accounts,
|
accounts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize_with(mut writer: &mut Cursor<&mut [u8]>, ix: &Self) -> Result<(), Error> {
|
|
||||||
writer.write_all(&[ix.program_ids_index])?;
|
|
||||||
serialize_vec_bytes(&mut writer, &ix.accounts[..])?;
|
|
||||||
serialize_vec_bytes(&mut writer, &ix.data[..])?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deserialize_from(mut reader: &mut Cursor<&[u8]>) -> Result<Self, Error> {
|
|
||||||
let mut buf = [0];
|
|
||||||
reader.read_exact(&mut buf)?;
|
|
||||||
let program_ids_index = buf[0];
|
|
||||||
let accounts = deserialize_vec_bytes(&mut reader)?;
|
|
||||||
let data = deserialize_vec_bytes(&mut reader)?;
|
|
||||||
Ok(CompiledInstruction {
|
|
||||||
program_ids_index,
|
|
||||||
accounts,
|
|
||||||
data,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn serialized_size(&self) -> Result<u64, Error> {
|
|
||||||
let mut buf = [0; size_of::<u64>() + 1];
|
|
||||||
let mut wr = Cursor::new(&mut buf[..]);
|
|
||||||
let mut size = size_of::<u8>();
|
|
||||||
|
|
||||||
let len = self.accounts.len();
|
|
||||||
encode_len(&mut wr, len)?;
|
|
||||||
size += wr.position() as usize + (len * size_of::<u8>());
|
|
||||||
|
|
||||||
let len = self.data.len();
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, len)?;
|
|
||||||
size += wr.position() as usize + (len * size_of::<u8>());
|
|
||||||
|
|
||||||
Ok(size as u64)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ pub mod native_program;
|
||||||
pub mod packet;
|
pub mod packet;
|
||||||
pub mod pubkey;
|
pub mod pubkey;
|
||||||
pub mod rpc_port;
|
pub mod rpc_port;
|
||||||
pub mod shortvec;
|
|
||||||
pub mod signature;
|
pub mod signature;
|
||||||
pub mod system_instruction;
|
pub mod system_instruction;
|
||||||
pub mod system_program;
|
pub mod system_program;
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
/// Maximum over-the-wire size of a Transaction
|
/// Maximum over-the-wire size of a Transaction
|
||||||
pub const PACKET_DATA_SIZE: usize = 512;
|
// TODO: Set this back to 512 after shortvec optimization is reinstated.
|
||||||
|
pub const PACKET_DATA_SIZE: usize = 522;
|
||||||
|
|
|
@ -1,373 +0,0 @@
|
||||||
use bincode::{deserialize_from, serialize_into, Error};
|
|
||||||
use serde::Serialize;
|
|
||||||
use std::io::{Cursor, Read, Write};
|
|
||||||
use std::mem::size_of;
|
|
||||||
|
|
||||||
pub fn encode_len<W: Write>(writer: &mut W, len: usize) -> Result<(), Error> {
|
|
||||||
let mut rem_len = len;
|
|
||||||
loop {
|
|
||||||
let mut elem = (rem_len & 0x7f) as u8;
|
|
||||||
rem_len >>= 7;
|
|
||||||
if rem_len == 0 {
|
|
||||||
writer.write_all(&[elem])?;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
elem |= 0x80;
|
|
||||||
writer.write_all(&[elem])?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decode_len<R: Read>(reader: &mut R) -> Result<usize, Error> {
|
|
||||||
let mut len: usize = 0;
|
|
||||||
let mut size: usize = 0;
|
|
||||||
loop {
|
|
||||||
let mut elem = [0u8; 1];
|
|
||||||
reader.read_exact(&mut elem)?;
|
|
||||||
len |= (elem[0] as usize & 0x7f) << (size * 7);
|
|
||||||
size += 1;
|
|
||||||
if elem[0] as usize & 0x80 == 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert!(size <= size_of::<usize>() + 1);
|
|
||||||
}
|
|
||||||
Ok(len)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn serialize_vec_with<T>(
|
|
||||||
mut writer: &mut Cursor<&mut [u8]>,
|
|
||||||
input: &[T],
|
|
||||||
ser_fn: fn(&mut Cursor<&mut [u8]>, &T) -> Result<(), Error>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
encode_len(&mut writer, input.len())?;
|
|
||||||
input.iter().for_each(|e| ser_fn(&mut writer, &e).unwrap());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn serialize_vec_bytes<W: Write>(mut writer: W, input: &[u8]) -> Result<(), Error> {
|
|
||||||
let len = input.len();
|
|
||||||
encode_len(&mut writer, len)?;
|
|
||||||
writer.write_all(input)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn serialize_vec<W: Write, T>(mut writer: W, input: &[T]) -> Result<(), Error>
|
|
||||||
where
|
|
||||||
T: Serialize,
|
|
||||||
{
|
|
||||||
let len = input.len();
|
|
||||||
encode_len(&mut writer, len)?;
|
|
||||||
input
|
|
||||||
.iter()
|
|
||||||
.for_each(|e| serialize_into(&mut writer, &e).unwrap());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deserialize_vec_bytes<R: Read>(mut reader: &mut R) -> Result<Vec<u8>, Error> {
|
|
||||||
let vec_len = decode_len(&mut reader)?;
|
|
||||||
let mut buf = vec![0; vec_len];
|
|
||||||
reader.read_exact(&mut buf[..])?;
|
|
||||||
Ok(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deserialize_vec<R: Read, T>(mut reader: &mut R) -> Result<Vec<T>, Error>
|
|
||||||
where
|
|
||||||
T: serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
let vec_len = decode_len(&mut reader)?;
|
|
||||||
let mut vec: Vec<T> = Vec::with_capacity(vec_len);
|
|
||||||
for _ in 0..vec_len {
|
|
||||||
let t: T = deserialize_from(&mut reader)?;
|
|
||||||
vec.push(t);
|
|
||||||
}
|
|
||||||
Ok(vec)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deserialize_vec_with<T>(
|
|
||||||
mut reader: &mut Cursor<&[u8]>,
|
|
||||||
deser_fn: fn(&mut Cursor<&[u8]>) -> Result<T, Error>,
|
|
||||||
) -> Result<Vec<T>, Error> {
|
|
||||||
let vec_len = decode_len(&mut reader)?;
|
|
||||||
let mut vec: Vec<T> = Vec::with_capacity(vec_len);
|
|
||||||
for _ in 0..vec_len {
|
|
||||||
let t: T = deser_fn(&mut reader)?;
|
|
||||||
vec.push(t);
|
|
||||||
}
|
|
||||||
Ok(vec)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use bincode::{deserialize, serialize, serialized_size};
|
|
||||||
use serde::ser::Serializer;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use std::fmt;
|
|
||||||
use std::io::Cursor;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_shortvec_encode_len() {
|
|
||||||
let mut buf = vec![0u8; size_of::<u64>() + 1];
|
|
||||||
let mut wr = Cursor::new(&mut buf[..]);
|
|
||||||
encode_len(&mut wr, 0x0).unwrap();
|
|
||||||
let vec = wr.get_ref()[..wr.position() as usize].to_vec();
|
|
||||||
assert_eq!(vec, vec![0u8]);
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, 0x5).unwrap();
|
|
||||||
let vec = wr.get_ref()[..wr.position() as usize].to_vec();
|
|
||||||
assert_eq!(vec, vec![0x5u8]);
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, 0x7f).unwrap();
|
|
||||||
let vec = wr.get_ref()[..wr.position() as usize].to_vec();
|
|
||||||
assert_eq!(vec, vec![0x7fu8]);
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, 0x80).unwrap();
|
|
||||||
let vec = wr.get_ref()[..wr.position() as usize].to_vec();
|
|
||||||
assert_eq!(vec, vec![0x80u8, 0x01u8]);
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, 0xff).unwrap();
|
|
||||||
let vec = wr.get_ref()[..wr.position() as usize].to_vec();
|
|
||||||
assert_eq!(vec, vec![0xffu8, 0x01u8]);
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, 0x100).unwrap();
|
|
||||||
let vec = wr.get_ref()[..wr.position() as usize].to_vec();
|
|
||||||
assert_eq!(vec, vec![0x80u8, 0x02u8]);
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, 0x7fff).unwrap();
|
|
||||||
let vec = wr.get_ref()[..wr.position() as usize].to_vec();
|
|
||||||
assert_eq!(vec, vec![0xffu8, 0xffu8, 0x01u8]);
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, 0x200000).unwrap();
|
|
||||||
let vec = wr.get_ref()[..wr.position() as usize].to_vec();
|
|
||||||
assert_eq!(vec, vec![0x80u8, 0x80u8, 0x80u8, 0x01u8]);
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, 0x7ffffffff).unwrap();
|
|
||||||
let vec = wr.get_ref()[..wr.position() as usize].to_vec();
|
|
||||||
assert_eq!(vec, vec![0xffu8, 0xffu8, 0xffu8, 0xffu8, 0x7fu8]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn test_shortvec_decode_zero_len() {
|
|
||||||
let mut buf = vec![];
|
|
||||||
let mut rd = Cursor::new(&mut buf[..]);
|
|
||||||
assert_eq!(decode_len(&mut rd).unwrap(), 0);
|
|
||||||
assert_eq!(rd.position(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_shortvec_decode_len() {
|
|
||||||
let mut buf = vec![0u8];
|
|
||||||
let mut rd = Cursor::new(&mut buf[..]);
|
|
||||||
assert_eq!(decode_len(&mut rd).unwrap(), 0);
|
|
||||||
assert_eq!(rd.position(), 1);
|
|
||||||
let mut buf = vec![5u8];
|
|
||||||
let mut rd = Cursor::new(&mut buf[..]);
|
|
||||||
assert_eq!(decode_len(&mut rd).unwrap(), 5);
|
|
||||||
assert_eq!(rd.position(), 1);
|
|
||||||
let mut buf = vec![0x7fu8];
|
|
||||||
let mut rd = Cursor::new(&mut buf[..]);
|
|
||||||
assert_eq!(decode_len(&mut rd).unwrap(), 0x7f);
|
|
||||||
assert_eq!(rd.position(), 1);
|
|
||||||
let mut buf = vec![0x80u8, 0x01u8];
|
|
||||||
let mut rd = Cursor::new(&mut buf[..]);
|
|
||||||
assert_eq!(decode_len(&mut rd).unwrap(), 0x80);
|
|
||||||
assert_eq!(rd.position(), 2);
|
|
||||||
let mut buf = vec![0xffu8, 0x01u8];
|
|
||||||
let mut rd = Cursor::new(&mut buf[..]);
|
|
||||||
assert_eq!(decode_len(&mut rd).unwrap(), 0xff);
|
|
||||||
assert_eq!(rd.position(), 2);
|
|
||||||
let mut buf = vec![0x80u8, 0x02u8];
|
|
||||||
let mut rd = Cursor::new(&mut buf[..]);
|
|
||||||
assert_eq!(decode_len(&mut rd).unwrap(), 0x100);
|
|
||||||
assert_eq!(rd.position(), 2);
|
|
||||||
let mut buf = vec![0xffu8, 0xffu8, 0x01u8];
|
|
||||||
let mut rd = Cursor::new(&mut buf[..]);
|
|
||||||
assert_eq!(decode_len(&mut rd).unwrap(), 0x7fff);
|
|
||||||
assert_eq!(rd.position(), 3);
|
|
||||||
let mut buf = vec![0x80u8, 0x80u8, 0x80u8, 0x01u8];
|
|
||||||
let mut rd = Cursor::new(&mut buf[..]);
|
|
||||||
assert_eq!(decode_len(&mut rd).unwrap(), 0x200000);
|
|
||||||
assert_eq!(rd.position(), 4);
|
|
||||||
let mut buf = vec![0xffu8, 0xffu8, 0xffu8, 0xffu8, 0x7fu8];
|
|
||||||
let mut rd = Cursor::new(&mut buf[..]);
|
|
||||||
assert_eq!(decode_len(&mut rd).unwrap(), 0x7ffffffff);
|
|
||||||
assert_eq!(rd.position(), 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_shortvec_u8() {
|
|
||||||
let vec: Vec<u8> = vec![4; 32];
|
|
||||||
let mut buf = vec![0u8; serialized_size(&vec).unwrap() as usize + 1];
|
|
||||||
let mut wr = Cursor::new(&mut buf[..]);
|
|
||||||
serialize_vec_bytes(&mut wr, &vec).unwrap();
|
|
||||||
let size = wr.position() as usize;
|
|
||||||
let ser = &wr.into_inner()[..size];
|
|
||||||
assert_eq!(ser.len(), vec.len() + 1);
|
|
||||||
let mut rd = Cursor::new(&ser[..]);
|
|
||||||
let deser: Vec<u8> = deserialize_vec_bytes(&mut rd).unwrap();
|
|
||||||
assert_eq!(vec, deser);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
|
||||||
struct TestVec {
|
|
||||||
vec_u8: Vec<u8>,
|
|
||||||
id: u8,
|
|
||||||
vec_u32: Vec<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TestVec {
|
|
||||||
pub fn serialize_with(
|
|
||||||
mut writer: &mut Cursor<&mut [u8]>,
|
|
||||||
tv: &TestVec,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
serialize_vec(&mut writer, &tv.vec_u8).unwrap();
|
|
||||||
serialize_into(&mut writer, &tv.id).unwrap();
|
|
||||||
serialize_vec(&mut writer, &tv.vec_u32).unwrap();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
pub fn from_bytes(mut reader: &mut Cursor<&[u8]>) -> Result<Self, Error> {
|
|
||||||
let vec_u8: Vec<u8> = deserialize_vec(&mut reader).unwrap();
|
|
||||||
let id: u8 = deserialize_from(&mut reader).unwrap();
|
|
||||||
let vec_u32: Vec<u32> = deserialize_vec(&mut reader).unwrap();
|
|
||||||
Ok(TestVec {
|
|
||||||
vec_u8,
|
|
||||||
id,
|
|
||||||
vec_u32,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
pub fn serialized_size(&self) -> u64 {
|
|
||||||
let mut buf = vec![0u8; size_of::<u64>() + 1];
|
|
||||||
let mut size = size_of::<u64>();
|
|
||||||
let mut wr = Cursor::new(&mut buf[..]);
|
|
||||||
encode_len(&mut wr, self.vec_u8.len()).unwrap();
|
|
||||||
size += wr.position() as usize + self.vec_u8.len() * size_of::<u8>();
|
|
||||||
size += size_of::<u8>();
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, self.vec_u32.len()).unwrap();
|
|
||||||
size += wr.position() as usize + self.vec_u32.len() * size_of::<u32>();
|
|
||||||
size as u64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for TestVec {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
use serde::ser::Error;
|
|
||||||
let mut buf = vec![0u8; self.serialized_size() as usize];
|
|
||||||
let mut wr = Cursor::new(&mut buf[..]);
|
|
||||||
serialize_vec(&mut wr, &self.vec_u8).map_err(Error::custom)?;
|
|
||||||
serialize_into(&mut wr, &self.id).map_err(Error::custom)?;
|
|
||||||
serialize_vec(&mut wr, &self.vec_u32).map_err(Error::custom)?;
|
|
||||||
let len = wr.position() as usize;
|
|
||||||
serializer.serialize_bytes(&wr.into_inner()[..len])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TestVecVisitor;
|
|
||||||
impl<'a> serde::de::Visitor<'a> for TestVecVisitor {
|
|
||||||
type Value = TestVec;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str("Expecting TestVec")
|
|
||||||
}
|
|
||||||
fn visit_bytes<E>(self, data: &[u8]) -> Result<TestVec, E>
|
|
||||||
where
|
|
||||||
E: serde::de::Error,
|
|
||||||
{
|
|
||||||
use serde::de::Error;
|
|
||||||
let mut rd = Cursor::new(&data[..]);
|
|
||||||
let v1: Vec<u8> = deserialize_vec(&mut rd).map_err(Error::custom)?;
|
|
||||||
let id: u8 = deserialize_from(&mut rd).map_err(Error::custom)?;
|
|
||||||
let v2: Vec<u32> = deserialize_vec(&mut rd).map_err(Error::custom)?;
|
|
||||||
Ok(TestVec {
|
|
||||||
vec_u8: v1,
|
|
||||||
id,
|
|
||||||
vec_u32: v2,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'de> Deserialize<'de> for TestVec {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: ::serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
deserializer.deserialize_bytes(TestVecVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_shortvec_testvec() {
|
|
||||||
let tvec: TestVec = TestVec {
|
|
||||||
vec_u8: vec![4; 32],
|
|
||||||
id: 5,
|
|
||||||
vec_u32: vec![6; 32],
|
|
||||||
};
|
|
||||||
let size = tvec.serialized_size() as usize;
|
|
||||||
assert_eq!(
|
|
||||||
size,
|
|
||||||
tvec.vec_u8.len() + 1 + 1 + (tvec.vec_u32.len() * 4) + 1 + 8
|
|
||||||
);
|
|
||||||
let ser = serialize(&tvec).unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
ser.len(),
|
|
||||||
tvec.vec_u8.len() + 1 + 1 + (tvec.vec_u32.len() * 4) + 1 + 8
|
|
||||||
);
|
|
||||||
let deser = deserialize(&ser).unwrap();
|
|
||||||
assert_eq!(tvec, deser);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
|
|
||||||
struct TestVecArr {
|
|
||||||
data: Vec<TestVec>,
|
|
||||||
}
|
|
||||||
impl TestVecArr {
|
|
||||||
fn new() -> Self {
|
|
||||||
TestVecArr { data: vec![] }
|
|
||||||
}
|
|
||||||
fn serialized_size(tvec: &TestVecArr) -> u64 {
|
|
||||||
let mut buf = vec![0u8; size_of::<u64>() + 1];
|
|
||||||
let mut wr = Cursor::new(&mut buf[..]);
|
|
||||||
encode_len(&mut wr, tvec.data.len()).unwrap();
|
|
||||||
let size: u64 = tvec
|
|
||||||
.data
|
|
||||||
.iter()
|
|
||||||
.map(|tv| TestVec::serialized_size(&tv))
|
|
||||||
.sum();
|
|
||||||
size_of::<u64>() as u64 + size + wr.position()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_shortvec_testvec_with() {
|
|
||||||
let tvec1 = TestVec {
|
|
||||||
vec_u8: vec![4; 32],
|
|
||||||
id: 5,
|
|
||||||
vec_u32: vec![6; 32],
|
|
||||||
};
|
|
||||||
let tvec2 = TestVec {
|
|
||||||
vec_u8: vec![7; 32],
|
|
||||||
id: 8,
|
|
||||||
vec_u32: vec![9; 32],
|
|
||||||
};
|
|
||||||
let tvec3 = TestVec {
|
|
||||||
vec_u8: vec![],
|
|
||||||
id: 10,
|
|
||||||
vec_u32: vec![11; 32],
|
|
||||||
};
|
|
||||||
let mut tvecarr: TestVecArr = TestVecArr::new();
|
|
||||||
tvecarr.data.push(tvec1);
|
|
||||||
tvecarr.data.push(tvec2);
|
|
||||||
tvecarr.data.push(tvec3);
|
|
||||||
let mut buf = vec![0u8; TestVecArr::serialized_size(&tvecarr) as usize];
|
|
||||||
let mut wr = Cursor::new(&mut buf[..]);
|
|
||||||
serialize_vec_with(&mut wr, &tvecarr.data, TestVec::serialize_with).unwrap();
|
|
||||||
let size = wr.position() as usize;
|
|
||||||
let ser = &wr.into_inner()[..size];
|
|
||||||
let mut rd = Cursor::new(&ser[..]);
|
|
||||||
let deser = deserialize_vec_with(&mut rd, TestVec::from_bytes).unwrap();
|
|
||||||
assert_eq!(tvecarr.data, deser);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,16 +3,10 @@
|
||||||
use crate::hash::Hash;
|
use crate::hash::Hash;
|
||||||
use crate::instruction::{CompiledInstruction, Instruction, InstructionError};
|
use crate::instruction::{CompiledInstruction, Instruction, InstructionError};
|
||||||
use crate::message::Message;
|
use crate::message::Message;
|
||||||
use crate::packet::PACKET_DATA_SIZE;
|
|
||||||
use crate::pubkey::Pubkey;
|
use crate::pubkey::Pubkey;
|
||||||
use crate::shortvec::{deserialize_vec_with, encode_len, serialize_vec_with};
|
|
||||||
use crate::signature::{KeypairUtil, Signature};
|
use crate::signature::{KeypairUtil, Signature};
|
||||||
use bincode::Error;
|
use bincode::serialize;
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use serde::Serialize;
|
||||||
use serde::{Deserialize, Serialize, Serializer};
|
|
||||||
use std::fmt;
|
|
||||||
use std::io::{Cursor, Read, Write};
|
|
||||||
use std::mem::size_of;
|
|
||||||
|
|
||||||
/// Reasons a transaction might be rejected.
|
/// Reasons a transaction might be rejected.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
@ -53,7 +47,7 @@ pub enum TransactionError {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An atomic transaction
|
/// An atomic transaction
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
||||||
pub struct Transaction {
|
pub struct Transaction {
|
||||||
/// A set of digital signatures of `account_keys`, `program_ids`, `recent_blockhash`, `fee` and `instructions`, signed by the first
|
/// A set of digital signatures of `account_keys`, `program_ids`, `recent_blockhash`, `fee` and `instructions`, signed by the first
|
||||||
/// signatures.len() keys of account_keys
|
/// signatures.len() keys of account_keys
|
||||||
|
@ -173,24 +167,16 @@ impl Transaction {
|
||||||
}
|
}
|
||||||
/// Get the transaction data to sign.
|
/// Get the transaction data to sign.
|
||||||
pub fn message(&self) -> Vec<u8> {
|
pub fn message(&self) -> Vec<u8> {
|
||||||
let mut buf = vec![0u8; PACKET_DATA_SIZE];
|
let mut data = serialize(&self.account_keys).expect("serialize account_keys");
|
||||||
let mut wr = Cursor::new(&mut buf[..]);
|
let blockhash = serialize(&self.recent_blockhash).expect("serialize recent_blockhash");
|
||||||
serialize_vec_with(&mut wr, &self.account_keys, Transaction::serialize_pubkey)
|
data.extend_from_slice(&blockhash);
|
||||||
.expect("serialize account_keys");
|
let fee_data = serialize(&self.fee).expect("serialize fee");
|
||||||
wr.write_all(self.recent_blockhash.as_ref())
|
data.extend_from_slice(&fee_data);
|
||||||
.expect("serialize recent_blockhash");
|
let program_ids = serialize(&self.program_ids).expect("serialize program_ids");
|
||||||
wr.write_u64::<LittleEndian>(self.fee)
|
data.extend_from_slice(&program_ids);
|
||||||
.expect("serialize fee");
|
let instructions = serialize(&self.instructions).expect("serialize instructions");
|
||||||
serialize_vec_with(&mut wr, &self.program_ids, Transaction::serialize_pubkey)
|
data.extend_from_slice(&instructions);
|
||||||
.expect("serialize program_ids");
|
data
|
||||||
serialize_vec_with(
|
|
||||||
&mut wr,
|
|
||||||
&self.instructions,
|
|
||||||
CompiledInstruction::serialize_with,
|
|
||||||
)
|
|
||||||
.expect("serialize instructions");
|
|
||||||
let len = wr.position() as usize;
|
|
||||||
wr.into_inner()[..len].to_vec()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sign this transaction.
|
/// Sign this transaction.
|
||||||
|
@ -229,141 +215,6 @@ impl Transaction {
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialized_size(&self) -> Result<u64, Error> {
|
|
||||||
let mut buf = [0u8; size_of::<u64>() + 1];
|
|
||||||
let mut wr = Cursor::new(&mut buf[..]);
|
|
||||||
let mut size = size_of::<u64>();
|
|
||||||
|
|
||||||
let len = self.signatures.len();
|
|
||||||
encode_len(&mut wr, len)?;
|
|
||||||
size += wr.position() as usize + (len * size_of::<Signature>());
|
|
||||||
|
|
||||||
let len = self.account_keys.len();
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, len)?;
|
|
||||||
size += wr.position() as usize + (len * size_of::<Pubkey>());
|
|
||||||
|
|
||||||
size += size_of::<Hash>();
|
|
||||||
|
|
||||||
size += size_of::<u64>();
|
|
||||||
|
|
||||||
let len = self.program_ids.len();
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, len)?;
|
|
||||||
size += wr.position() as usize + (len * size_of::<Pubkey>());
|
|
||||||
|
|
||||||
let len = self.instructions.len();
|
|
||||||
wr.set_position(0);
|
|
||||||
encode_len(&mut wr, len)?;
|
|
||||||
size += wr.position() as usize;
|
|
||||||
let inst_size: u64 = self
|
|
||||||
.instructions
|
|
||||||
.iter()
|
|
||||||
.map(|ix| ix.serialized_size().unwrap())
|
|
||||||
.sum();
|
|
||||||
Ok(size as u64 + inst_size)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_signature(writer: &mut Cursor<&mut [u8]>, sig: &Signature) -> Result<(), Error> {
|
|
||||||
writer.write_all(sig.as_ref())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_pubkey(writer: &mut Cursor<&mut [u8]>, key: &Pubkey) -> Result<(), Error> {
|
|
||||||
writer.write_all(key.as_ref())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_signature(reader: &mut Cursor<&[u8]>) -> Result<Signature, Error> {
|
|
||||||
let mut buf = [0; size_of::<Signature>()];
|
|
||||||
reader.read_exact(&mut buf)?;
|
|
||||||
Ok(Signature::new(&buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_pubkey(reader: &mut Cursor<&[u8]>) -> Result<Pubkey, Error> {
|
|
||||||
let mut buf = [0; size_of::<Pubkey>()];
|
|
||||||
reader.read_exact(&mut buf)?;
|
|
||||||
Ok(Pubkey::new(&buf))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for Transaction {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
use serde::ser::Error;
|
|
||||||
let mut buf = vec![0u8; self.serialized_size().unwrap() as usize];
|
|
||||||
let mut wr = Cursor::new(&mut buf[..]);
|
|
||||||
serialize_vec_with(&mut wr, &self.signatures, Transaction::serialize_signature)
|
|
||||||
.map_err(Error::custom)?;
|
|
||||||
serialize_vec_with(&mut wr, &self.account_keys, Transaction::serialize_pubkey)
|
|
||||||
.map_err(Error::custom)?;
|
|
||||||
wr.write_all(self.recent_blockhash.as_ref())
|
|
||||||
.map_err(Error::custom)?;
|
|
||||||
wr.write_u64::<LittleEndian>(self.fee)
|
|
||||||
.map_err(Error::custom)?;
|
|
||||||
serialize_vec_with(&mut wr, &self.program_ids, Transaction::serialize_pubkey)
|
|
||||||
.map_err(Error::custom)?;
|
|
||||||
serialize_vec_with(
|
|
||||||
&mut wr,
|
|
||||||
&self.instructions,
|
|
||||||
CompiledInstruction::serialize_with,
|
|
||||||
)
|
|
||||||
.map_err(Error::custom)?;
|
|
||||||
let size = wr.position() as usize;
|
|
||||||
serializer.serialize_bytes(&wr.into_inner()[..size])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TransactionVisitor;
|
|
||||||
impl<'a> serde::de::Visitor<'a> for TransactionVisitor {
|
|
||||||
type Value = Transaction;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str("Expecting Instruction")
|
|
||||||
}
|
|
||||||
fn visit_bytes<E>(self, data: &[u8]) -> Result<Transaction, E>
|
|
||||||
where
|
|
||||||
E: serde::de::Error,
|
|
||||||
{
|
|
||||||
use serde::de::Error;
|
|
||||||
let mut rd = Cursor::new(&data[..]);
|
|
||||||
let signatures: Vec<Signature> =
|
|
||||||
deserialize_vec_with(&mut rd, Transaction::deserialize_signature)
|
|
||||||
.map_err(Error::custom)?;
|
|
||||||
let account_keys: Vec<Pubkey> =
|
|
||||||
deserialize_vec_with(&mut rd, Transaction::deserialize_pubkey)
|
|
||||||
.map_err(Error::custom)?;
|
|
||||||
let mut buf = [0; size_of::<Hash>()];
|
|
||||||
rd.read_exact(&mut buf).map_err(Error::custom)?;
|
|
||||||
let recent_blockhash: Hash = Hash::new(&buf);
|
|
||||||
let fee = rd.read_u64::<LittleEndian>().map_err(Error::custom)?;
|
|
||||||
let program_ids: Vec<Pubkey> =
|
|
||||||
deserialize_vec_with(&mut rd, Transaction::deserialize_pubkey)
|
|
||||||
.map_err(Error::custom)?;
|
|
||||||
let instructions: Vec<CompiledInstruction> =
|
|
||||||
deserialize_vec_with(&mut rd, CompiledInstruction::deserialize_from)
|
|
||||||
.map_err(Error::custom)?;
|
|
||||||
Ok(Transaction {
|
|
||||||
signatures,
|
|
||||||
account_keys,
|
|
||||||
recent_blockhash,
|
|
||||||
fee,
|
|
||||||
program_ids,
|
|
||||||
instructions,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Transaction {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: ::serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
deserializer.deserialize_bytes(TransactionVisitor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -550,16 +401,18 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
serialize(&create_sample_transaction()).unwrap(),
|
serialize(&create_sample_transaction()).unwrap(),
|
||||||
vec![
|
vec![
|
||||||
212, 0, 0, 0, 0, 0, 0, 0, 1, 107, 231, 179, 42, 11, 220, 153, 173, 229, 29, 51,
|
1, 0, 0, 0, 0, 0, 0, 0, 60, 2, 97, 229, 100, 48, 42, 208, 222, 192, 129, 29, 142,
|
||||||
218, 98, 26, 46, 164, 248, 228, 118, 244, 191, 192, 198, 228, 190, 119, 21, 52, 66,
|
187, 4, 174, 210, 77, 78, 162, 101, 146, 144, 241, 159, 44, 89, 89, 10, 103, 229,
|
||||||
25, 124, 247, 192, 73, 48, 231, 2, 70, 34, 82, 133, 137, 148, 66, 73, 231, 72, 195,
|
94, 92, 240, 124, 0, 83, 22, 216, 2, 112, 193, 158, 93, 210, 144, 222, 144, 13,
|
||||||
100, 133, 214, 2, 168, 108, 252, 200, 83, 99, 105, 51, 216, 145, 30, 14, 2, 36,
|
138, 209, 246, 89, 156, 195, 234, 186, 215, 92, 250, 125, 210, 24, 10, 2, 0, 0, 0,
|
||||||
100, 158, 252, 33, 161, 97, 185, 62, 89, 99, 195, 250, 249, 187, 189, 171, 118,
|
0, 0, 0, 0, 36, 100, 158, 252, 33, 161, 97, 185, 62, 89, 99, 195, 250, 249, 187,
|
||||||
241, 90, 248, 14, 68, 219, 231, 62, 157, 5, 142, 27, 210, 117, 1, 1, 1, 4, 5, 6, 7,
|
189, 171, 118, 241, 90, 248, 14, 68, 219, 231, 62, 157, 5, 142, 27, 210, 117, 1, 1,
|
||||||
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4, 1, 1, 1, 0, 0, 0,
|
1, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 99, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1,
|
0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4, 5,
|
||||||
1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4, 2, 2, 2, 1, 0, 2, 0, 1, 3, 1, 2, 3
|
6, 7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4, 2, 2, 2, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2,
|
||||||
|
3
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue