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::packet::to_packets;
use crate::poh_recorder::WorkingBank; use crate::poh_recorder::WorkingBank;
use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::instruction::InstructionError;
use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::system_transaction::SystemTransaction;
use solana_sdk::transaction::InstructionError;
use std::sync::mpsc::channel; use std::sync::mpsc::channel;
use std::thread::sleep; use std::thread::sleep;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,8 +5,8 @@
use crate::*; use crate::*;
use log::*; use log::*;
use solana_sdk::account::KeyedAccount; use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
pub const TOTAL_VALIDATOR_REWARDS: u64 = 1000; pub const TOTAL_VALIDATOR_REWARDS: u64 = 1000;
pub const TOTAL_REPLICATOR_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::account::{create_keyed_accounts, Account};
use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::hash::{hash, Hash}; use solana_sdk::hash::{hash, Hash};
use solana_sdk::instruction::CompiledInstruction;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil, Signature}; use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::system_transaction::SystemTransaction;
use solana_sdk::transaction::{CompiledInstruction, Transaction}; use solana_sdk::transaction::Transaction;
fn test_transaction( fn test_transaction(
tx: &Transaction, tx: &Transaction,

View File

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

View File

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

View File

@ -6,8 +6,8 @@ use crate::vote_state;
use bincode::deserialize; use bincode::deserialize;
use log::*; use log::*;
use solana_sdk::account::KeyedAccount; use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
pub fn process_instruction( pub fn process_instruction(
_program_id: &Pubkey, _program_id: &Pubkey,
@ -51,10 +51,11 @@ mod tests {
use solana_runtime::bank::{Bank, Result}; use solana_runtime::bank::{Bank, Result};
use solana_runtime::bank_client::BankClient; use solana_runtime::bank_client::BankClient;
use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::instruction::{AccountMeta, Instruction, InstructionError};
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction; 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) { fn create_bank(lamports: u64) -> (Bank, Keypair) {
let (genesis_block, mint_keypair) = GenesisBlock::new(lamports); 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 log::*;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use solana_sdk::account::{Account, KeyedAccount}; use solana_sdk::account::{Account, KeyedAccount};
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction::InstructionError;
use std::collections::VecDeque; use std::collections::VecDeque;
// Maximum number of votes to keep around // Maximum number of votes to keep around

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
use crate::instruction::{AccountMeta, Instruction};
use crate::pubkey::Pubkey; use crate::pubkey::Pubkey;
use crate::system_program; use crate::system_program;
use crate::transaction::{AccountMeta, Instruction};
#[derive(Serialize, Debug, Clone, PartialEq)] #[derive(Serialize, Debug, Clone, PartialEq)]
pub enum SystemError { 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::hash::{Hash, Hasher};
use crate::instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError};
use crate::packet::PACKET_DATA_SIZE; use crate::packet::PACKET_DATA_SIZE;
use crate::pubkey::Pubkey; use crate::pubkey::Pubkey;
use crate::script::Script; use crate::script::Script;
use crate::shortvec::{ use crate::shortvec::{deserialize_vec_with, encode_len, serialize_vec_with};
deserialize_vec_bytes, deserialize_vec_with, encode_len, serialize_vec_bytes,
serialize_vec_with,
};
use crate::signature::{KeypairUtil, Signature}; use crate::signature::{KeypairUtil, Signature};
use crate::system_instruction::SystemError; use bincode::Error;
use bincode::{serialize, Error};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use serde::{Deserialize, Serialize, Serializer}; use serde::{Deserialize, Serialize, Serializer};
use std::fmt; use std::fmt;
use std::io::{Cursor, Read, Write}; use std::io::{Cursor, Read, Write};
use std::mem::size_of; 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. /// Reasons a transaction might be rejected.
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub enum TransactionError { pub enum TransactionError {
@ -553,7 +410,7 @@ impl<'de> Deserialize<'de> for Transaction {
mod tests { mod tests {
use super::*; use super::*;
use crate::signature::Keypair; use crate::signature::Keypair;
use bincode::deserialize; use bincode::{deserialize, serialize};
#[test] #[test]
fn test_refs() { fn test_refs() {