Move Instruction into its own module

This commit is contained in:
Greg Fitzgerald 2019-03-23 21:12:27 -06:00 committed by Grimes
parent 68c35bfde6
commit acedf4ca5a
32 changed files with 202 additions and 187 deletions

View File

@ -503,9 +503,9 @@ mod tests {
use crate::packet::to_packets;
use crate::poh_recorder::WorkingBank;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::instruction::InstructionError;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_transaction::SystemTransaction;
use solana_sdk::transaction::InstructionError;
use std::sync::mpsc::channel;
use std::thread::sleep;

View File

@ -337,10 +337,11 @@ mod tests {
use bincode::{deserialize, serialize};
use solana_budget_api;
use solana_sdk::hash::Hash;
use solana_sdk::instruction::CompiledInstruction;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::system_program;
use solana_sdk::transaction::{CompiledInstruction, Transaction};
use solana_sdk::transaction::Transaction;
const SIG_OFFSET: usize = std::mem::size_of::<u64>() + 1;

View File

@ -5,10 +5,10 @@ use libc::c_char;
use log::*;
use solana_rbpf::{EbpfVmRaw, MemoryRegion};
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::loader_instruction::LoaderInstruction;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::solana_entrypoint;
use solana_sdk::transaction::InstructionError;
use std::ffi::CStr;
use std::io::prelude::*;
use std::io::{Error, ErrorKind};

View File

@ -2,8 +2,8 @@ use crate::budget_expr::BudgetExpr;
use crate::id;
use chrono::prelude::{DateTime, Utc};
use serde_derive::{Deserialize, Serialize};
use solana_sdk::instruction::{AccountMeta, Instruction};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::{AccountMeta, Instruction};
/// A smart contract.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]

View File

@ -6,8 +6,8 @@ use bincode::{deserialize, serialize};
use chrono::prelude::{DateTime, Utc};
use log::*;
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
/// Process a Witness Signature. Any payment plans waiting on this signature
/// will progress one step.
@ -149,8 +149,9 @@ mod tests {
use solana_runtime::bank::Bank;
use solana_runtime::bank_client::BankClient;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::instruction::InstructionError;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::transaction::{InstructionError, Transaction, TransactionError};
use solana_sdk::transaction::{Transaction, TransactionError};
fn create_bank(lamports: u64) -> (Bank, Keypair) {
let (genesis_block, mint_keypair) = GenesisBlock::new(lamports);

View File

@ -2,7 +2,7 @@
use crate::budget_expr::BudgetExpr;
use bincode::{self, deserialize, serialize_into};
use serde_derive::{Deserialize, Serialize};
use solana_sdk::transaction::InstructionError;
use solana_sdk::instruction::InstructionError;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum BudgetError {

View File

@ -1,8 +1,8 @@
use crate::id;
use crate::ConfigState;
use solana_sdk::instruction::{AccountMeta, Instruction};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::transaction::{AccountMeta, Instruction};
pub struct ConfigInstruction {}

View File

@ -2,8 +2,8 @@
use log::*;
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
pub fn process_instruction(
_program_id: &Pubkey,

View File

@ -3,8 +3,8 @@
use crate::exchange_state::*;
use crate::id;
use serde_derive::{Deserialize, Serialize};
use solana_sdk::instruction::{AccountMeta, Instruction};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::{AccountMeta, Instruction};
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct TradeRequestInfo {

View File

@ -5,8 +5,8 @@ use crate::exchange_state::*;
use crate::id;
use log::*;
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
use std::cmp;
pub struct ExchangeProcessor {}

View File

@ -1,7 +1,7 @@
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::solana_entrypoint;
use solana_sdk::transaction::InstructionError;
solana_entrypoint!(entrypoint);
fn entrypoint(

View File

@ -2,8 +2,9 @@ use solana_runtime::bank::Bank;
use solana_runtime::bank_client::BankClient;
use solana_runtime::loader_utils::{create_invoke_instruction, load_program};
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::instruction::InstructionError;
use solana_sdk::native_loader;
use solana_sdk::transaction::{InstructionError, TransactionError};
use solana_sdk::transaction::TransactionError;
#[test]
fn test_program_native_failure() {

View File

@ -1,8 +1,8 @@
use log::*;
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::solana_entrypoint;
use solana_sdk::transaction::InstructionError;
solana_entrypoint!(entrypoint);
fn entrypoint(

View File

@ -5,8 +5,8 @@
use crate::*;
use log::*;
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
pub const TOTAL_VALIDATOR_REWARDS: u64 = 1000;
pub const TOTAL_REPLICATOR_REWARDS: u64 = 1000;
@ -179,10 +179,11 @@ mod tests {
use solana_sdk::account::{create_keyed_accounts, Account};
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::hash::{hash, Hash};
use solana_sdk::instruction::CompiledInstruction;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
use solana_sdk::system_transaction::SystemTransaction;
use solana_sdk::transaction::{CompiledInstruction, Transaction};
use solana_sdk::transaction::Transaction;
fn test_transaction(
tx: &Transaction,

View File

@ -2,8 +2,8 @@ use crate::token_state::TokenState;
use bincode::serialize;
use log::*;
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
pub fn process_instruction(
program_id: &Pubkey,

View File

@ -1,7 +1,7 @@
use crate::id;
use serde_derive::{Deserialize, Serialize};
use solana_sdk::instruction::{AccountMeta, Instruction};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::{AccountMeta, Instruction};
#[derive(Serialize, Default, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Vote {

View File

@ -6,8 +6,8 @@ use crate::vote_state;
use bincode::deserialize;
use log::*;
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
pub fn process_instruction(
_program_id: &Pubkey,
@ -51,10 +51,11 @@ mod tests {
use solana_runtime::bank::{Bank, Result};
use solana_runtime::bank_client::BankClient;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::instruction::{AccountMeta, Instruction, InstructionError};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::transaction::{AccountMeta, Instruction, InstructionError, TransactionError};
use solana_sdk::transaction::TransactionError;
fn create_bank(lamports: u64) -> (Bank, Keypair) {
let (genesis_block, mint_keypair) = GenesisBlock::new(lamports);

View File

@ -7,8 +7,8 @@ use bincode::{deserialize, serialize_into, serialized_size, ErrorKind};
use log::*;
use serde_derive::{Deserialize, Serialize};
use solana_sdk::account::{Account, KeyedAccount};
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
use std::collections::VecDeque;
// Maximum number of votes to keep around

View File

@ -991,9 +991,8 @@ mod tests {
use rand::{thread_rng, Rng};
use solana_sdk::account::Account;
use solana_sdk::hash::Hash;
use solana_sdk::signature::Keypair;
use solana_sdk::signature::KeypairUtil;
use solana_sdk::transaction::CompiledInstruction;
use solana_sdk::instruction::CompiledInstruction;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::transaction::Transaction;
fn cleanup_paths(paths: &str) {

View File

@ -928,11 +928,11 @@ mod tests {
use bincode::serialize;
use solana_sdk::genesis_block::{GenesisBlock, BOOTSTRAP_LEADER_LAMPORTS};
use solana_sdk::hash;
use solana_sdk::instruction::{CompiledInstruction, InstructionError};
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::system_program;
use solana_sdk::system_transaction::SystemTransaction;
use solana_sdk::transaction::{CompiledInstruction, InstructionError};
#[test]
fn test_bank_new() {

View File

@ -1,9 +1,10 @@
use crate::bank::Bank;
use solana_sdk::instruction::Instruction;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::script::Script;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::transaction::{Instruction, Transaction, TransactionError};
use solana_sdk::transaction::{Transaction, TransactionError};
pub struct BankClient<'a> {
bank: &'a Bank,
@ -67,7 +68,7 @@ impl<'a> BankClient<'a> {
mod tests {
use super::*;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::transaction::AccountMeta;
use solana_sdk::instruction::AccountMeta;
#[test]
fn test_bank_client_new_with_keypairs() {

View File

@ -1,11 +1,11 @@
use crate::bank::Bank;
use crate::bank_client::BankClient;
use serde::Serialize;
use solana_sdk::instruction::{AccountMeta, Instruction};
use solana_sdk::loader_instruction::LoaderInstruction;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::transaction::{AccountMeta, Instruction};
pub fn load_program(
bank: &Bank,

View File

@ -6,10 +6,10 @@ use libloading::os::unix::*;
use libloading::os::windows::*;
use log::*;
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::loader_instruction::LoaderInstruction;
use solana_sdk::native_program;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
use std::env;
use std::path::PathBuf;
use std::str;

View File

@ -1,8 +1,9 @@
use crate::native_loader;
use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount};
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::system_program;
use solana_sdk::transaction::{InstructionError, Transaction, TransactionError};
use solana_sdk::transaction::{Transaction, TransactionError};
/// Return true if the slice has any duplicate elements
pub fn has_duplicates<T: PartialEq>(xs: &[T]) -> bool {

View File

@ -1,10 +1,10 @@
use bincode::serialize;
use log::*;
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::system_instruction::{SystemError, SystemInstruction};
use solana_sdk::system_program;
use solana_sdk::transaction::InstructionError;
const FROM_ACCOUNT_INDEX: usize = 0;
const TO_ACCOUNT_INDEX: usize = 1;
@ -108,11 +108,12 @@ mod tests {
use crate::bank_client::BankClient;
use solana_sdk::account::Account;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::instruction::{AccountMeta, Instruction, InstructionError};
use solana_sdk::script::Script;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::system_program;
use solana_sdk::transaction::{AccountMeta, Instruction, InstructionError, TransactionError};
use solana_sdk::transaction::TransactionError;
#[test]
fn test_create_system_account() {

149
sdk/src/instruction.rs Normal file
View File

@ -0,0 +1,149 @@
//! Defines a composable Instruction type and a memory-efficient CompiledInstruction.
use crate::pubkey::Pubkey;
use crate::shortvec::{deserialize_vec_bytes, encode_len, serialize_vec_bytes};
use crate::system_instruction::SystemError;
use bincode::{serialize, Error};
use serde::Serialize;
use std::io::{Cursor, Read, Write};
use std::mem::size_of;
/// Reasons the runtime might have rejected an instruction.
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum InstructionError {
/// Deprecated! Use CustomError instead!
/// The program instruction returned an error
GenericError,
/// The arguments provided to a program instruction where invalid
InvalidArgument,
/// An instruction's data contents was invalid
InvalidInstructionData,
/// An account's data contents was invalid
InvalidAccountData,
/// An account's data was too small
AccountDataTooSmall,
/// The account did not have the expected program id
IncorrectProgramId,
/// A signature was required but not found
MissingRequiredSignature,
/// An initialize instruction was sent to an account that has already been initialized.
AccountAlreadyInitialized,
/// An attempt to operate on an account that hasn't been initialized.
UninitializedAccount,
/// Program's instruction lamport balance does not equal the balance after the instruction
UnbalancedInstruction,
/// Program modified an account's program id
ModifiedProgramId,
/// Program spent the lamports of an account that doesn't belong to it
ExternalAccountLamportSpend,
/// Program modified the data of an account that doesn't belong to it
ExternalAccountDataModified,
/// An account was referenced more than once in a single instruction
DuplicateAccountIndex,
/// CustomError allows on-chain programs to implement program-specific error types and see
/// them returned by the Solana runtime. A CustomError may be any type that is serialized
/// to a Vec of bytes, max length 32 bytes. Any CustomError Vec greater than this length will
/// be truncated by the runtime.
CustomError(Vec<u8>),
}
impl InstructionError {
pub fn new_result_with_negative_lamports() -> Self {
let serialized_error =
bincode::serialize(&SystemError::ResultWithNegativeLamports).unwrap();
InstructionError::CustomError(serialized_error)
}
}
/// An instruction to execute a program
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct GenericInstruction<P, Q> {
/// Index into the transaction program ids array indicating the program account that executes this instruction
pub program_ids_index: P,
/// Ordered indices into the transaction keys array indicating which accounts to pass to the program
pub accounts: Vec<Q>,
/// The program input data
pub data: Vec<u8>,
}
impl<P, Q> GenericInstruction<P, Q> {
pub fn new<T: Serialize>(program_ids_index: P, data: &T, accounts: Vec<Q>) -> Self {
let data = serialize(data).unwrap();
Self {
program_ids_index,
data,
accounts,
}
}
}
/// Account metadata used to define Instructions
#[derive(Debug)]
pub struct AccountMeta {
/// An account's public key
pub pubkey: Pubkey,
/// True if an Instruciton requires a Transaction signature matching `pubkey`.
pub is_signer: bool,
}
impl AccountMeta {
pub fn new(pubkey: Pubkey, is_signer: bool) -> Self {
Self { pubkey, is_signer }
}
}
pub type Instruction = GenericInstruction<Pubkey, AccountMeta>;
pub type CompiledInstruction = GenericInstruction<u8, u8>;
impl CompiledInstruction {
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)
}
}

View File

@ -2,6 +2,7 @@ pub mod account;
pub mod bpf_loader;
pub mod genesis_block;
pub mod hash;
pub mod instruction;
pub mod loader_instruction;
pub mod native_loader;
pub mod native_program;

View File

@ -1,5 +1,5 @@
use crate::instruction::{AccountMeta, Instruction};
use crate::pubkey::Pubkey;
use crate::transaction::{AccountMeta, Instruction};
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum LoaderInstruction {

View File

@ -1,6 +1,6 @@
use crate::account::KeyedAccount;
use crate::instruction::InstructionError;
use crate::pubkey::Pubkey;
use crate::transaction::InstructionError;
// All native programs export a symbol named process()
pub const ENTRYPOINT: &str = "process";
@ -24,7 +24,7 @@ macro_rules! solana_entrypoint(
keyed_accounts: &mut [solana_sdk::account::KeyedAccount],
data: &[u8],
tick_height: u64
) -> Result<(), solana_sdk::transaction::InstructionError> {
) -> Result<(), solana_sdk::instruction::InstructionError> {
$entrypoint(program_id, keyed_accounts, data, tick_height)
}
)
@ -40,7 +40,7 @@ macro_rules! process_instruction_entrypoint(
keyed_accounts: &mut [solana_sdk::account::KeyedAccount],
data: &[u8],
tick_height: u64,
) -> Result<(), solana_sdk::transaction::InstructionError> {
) -> Result<(), solana_sdk::instruction::InstructionError> {
solana_logger::setup();
log::trace!("process_instruction: {:?}", data);

View File

@ -1,8 +1,9 @@
//! A library for building scripts and compiling them into transactions.
use crate::hash::Hash;
use crate::instruction::{CompiledInstruction, Instruction};
use crate::pubkey::Pubkey;
use crate::transaction::{CompiledInstruction, Instruction, Transaction};
use crate::transaction::Transaction;
use itertools::Itertools;
fn position(keys: &[Pubkey], key: &Pubkey) -> u8 {
@ -104,8 +105,8 @@ impl Script {
#[cfg(test)]
mod tests {
use super::*;
use crate::instruction::AccountMeta;
use crate::signature::{Keypair, KeypairUtil};
use crate::transaction::AccountMeta;
#[test]
fn test_transaction_builder_unique_program_ids() {

View File

@ -1,6 +1,6 @@
use crate::instruction::{AccountMeta, Instruction};
use crate::pubkey::Pubkey;
use crate::system_program;
use crate::transaction::{AccountMeta, Instruction};
#[derive(Serialize, Debug, Clone, PartialEq)]
pub enum SystemError {

View File

@ -1,162 +1,19 @@
//! The `transaction` module provides functionality for creating log transactions.
//! Defines a Transaction type to package an atomic sequence of instructions.
use crate::hash::{Hash, Hasher};
use crate::instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError};
use crate::packet::PACKET_DATA_SIZE;
use crate::pubkey::Pubkey;
use crate::script::Script;
use crate::shortvec::{
deserialize_vec_bytes, deserialize_vec_with, encode_len, serialize_vec_bytes,
serialize_vec_with,
};
use crate::shortvec::{deserialize_vec_with, encode_len, serialize_vec_with};
use crate::signature::{KeypairUtil, Signature};
use crate::system_instruction::SystemError;
use bincode::{serialize, Error};
use bincode::Error;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use serde::{Deserialize, Serialize, Serializer};
use std::fmt;
use std::io::{Cursor, Read, Write};
use std::mem::size_of;
/// Reasons the runtime might have rejected an instruction.
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum InstructionError {
/// Deprecated! Use CustomError instead!
/// The program instruction returned an error
GenericError,
/// The arguments provided to a program instruction where invalid
InvalidArgument,
/// An instruction's data contents was invalid
InvalidInstructionData,
/// An account's data contents was invalid
InvalidAccountData,
/// An account's data was too small
AccountDataTooSmall,
/// The account did not have the expected program id
IncorrectProgramId,
/// A signature was required but not found
MissingRequiredSignature,
/// An initialize instruction was sent to an account that has already been initialized.
AccountAlreadyInitialized,
/// An attempt to operate on an account that hasn't been initialized.
UninitializedAccount,
/// Program's instruction lamport balance does not equal the balance after the instruction
UnbalancedInstruction,
/// Program modified an account's program id
ModifiedProgramId,
/// Program spent the lamports of an account that doesn't belong to it
ExternalAccountLamportSpend,
/// Program modified the data of an account that doesn't belong to it
ExternalAccountDataModified,
/// An account was referenced more than once in a single instruction
DuplicateAccountIndex,
/// CustomError allows on-chain programs to implement program-specific error types and see
/// them returned by the Solana runtime. A CustomError may be any type that is serialized
/// to a Vec of bytes, max length 32 bytes. Any CustomError Vec greater than this length will
/// be truncated by the runtime.
CustomError(Vec<u8>),
}
impl InstructionError {
pub fn new_result_with_negative_lamports() -> Self {
let serialized_error =
bincode::serialize(&SystemError::ResultWithNegativeLamports).unwrap();
InstructionError::CustomError(serialized_error)
}
}
/// An instruction to execute a program
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct GenericInstruction<P, Q> {
/// Index into the transaction program ids array indicating the program account that executes this instruction
pub program_ids_index: P,
/// Ordered indices into the transaction keys array indicating which accounts to pass to the program
pub accounts: Vec<Q>,
/// The program input data
pub data: Vec<u8>,
}
impl<P, Q> GenericInstruction<P, Q> {
pub fn new<T: Serialize>(program_ids_index: P, data: &T, accounts: Vec<Q>) -> Self {
let data = serialize(data).unwrap();
Self {
program_ids_index,
data,
accounts,
}
}
}
/// Account metadata used to define Instructions
#[derive(Debug)]
pub struct AccountMeta {
/// An account's public key
pub pubkey: Pubkey,
/// True if an Instruciton requires a Transaction signature matching `pubkey`.
pub is_signer: bool,
}
impl AccountMeta {
pub fn new(pubkey: Pubkey, is_signer: bool) -> Self {
Self { pubkey, is_signer }
}
}
pub type Instruction = GenericInstruction<Pubkey, AccountMeta>;
pub type CompiledInstruction = GenericInstruction<u8, u8>;
impl CompiledInstruction {
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)
}
}
/// Reasons a transaction might be rejected.
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum TransactionError {
@ -553,7 +410,7 @@ impl<'de> Deserialize<'de> for Transaction {
mod tests {
use super::*;
use crate::signature::Keypair;
use bincode::deserialize;
use bincode::{deserialize, serialize};
#[test]
fn test_refs() {