Instruction name swap

* Instruction -> GenericInstruction
* Instruction<u8, u8> -> CompiledInstruction
* Instruction<Pubkey, (Pubkey, bool)> -> Instruction
This commit is contained in:
Greg Fitzgerald 2019-03-15 09:47:25 -06:00
parent 66fb1bbb2e
commit 968022a1b0
13 changed files with 97 additions and 94 deletions

View File

@ -340,7 +340,7 @@ mod tests {
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::{Instruction, Transaction}; use solana_sdk::transaction::{CompiledInstruction, Transaction};
const SIG_OFFSET: usize = std::mem::size_of::<u64>() + 1; const SIG_OFFSET: usize = std::mem::size_of::<u64>() + 1;
@ -501,7 +501,7 @@ mod tests {
let program_ids = vec![system_program::id(), solana_budget_api::id()]; let program_ids = vec![system_program::id(), solana_budget_api::id()];
let instructions = vec![Instruction::new(0, &system_instruction, vec![0, 1])]; let instructions = vec![CompiledInstruction::new(0, &system_instruction, vec![0, 1])];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&keypairs, &keypairs,

View File

@ -3,7 +3,7 @@ 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::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction_builder::BuilderInstruction; use solana_sdk::transaction::Instruction;
/// A smart contract. /// A smart contract.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
@ -28,13 +28,13 @@ pub enum BudgetInstruction {
} }
impl BudgetInstruction { impl BudgetInstruction {
pub fn new_initialize_account(contract: &Pubkey, expr: BudgetExpr) -> BuilderInstruction { pub fn new_initialize_account(contract: &Pubkey, expr: BudgetExpr) -> Instruction {
let mut keys = vec![]; let mut keys = vec![];
if let BudgetExpr::Pay(payment) = &expr { if let BudgetExpr::Pay(payment) = &expr {
keys.push((payment.to, false)); keys.push((payment.to, false));
} }
keys.push((*contract, false)); keys.push((*contract, false));
BuilderInstruction::new(id(), &BudgetInstruction::InitializeAccount(expr), keys) Instruction::new(id(), &BudgetInstruction::InitializeAccount(expr), keys)
} }
pub fn new_apply_timestamp( pub fn new_apply_timestamp(
@ -42,23 +42,19 @@ impl BudgetInstruction {
contract: &Pubkey, contract: &Pubkey,
to: &Pubkey, to: &Pubkey,
dt: DateTime<Utc>, dt: DateTime<Utc>,
) -> BuilderInstruction { ) -> Instruction {
let mut keys = vec![(*from, true), (*contract, false)]; let mut keys = vec![(*from, true), (*contract, false)];
if from != to { if from != to {
keys.push((*to, false)); keys.push((*to, false));
} }
BuilderInstruction::new(id(), &BudgetInstruction::ApplyTimestamp(dt), keys) Instruction::new(id(), &BudgetInstruction::ApplyTimestamp(dt), keys)
} }
pub fn new_apply_signature( pub fn new_apply_signature(from: &Pubkey, contract: &Pubkey, to: &Pubkey) -> Instruction {
from: &Pubkey,
contract: &Pubkey,
to: &Pubkey,
) -> BuilderInstruction {
let mut keys = vec![(*from, true), (*contract, false)]; let mut keys = vec![(*from, true), (*contract, false)];
if from != to { if from != to {
keys.push((*to, false)); keys.push((*to, false));
} }
BuilderInstruction::new(id(), &BudgetInstruction::ApplySignature, keys) Instruction::new(id(), &BudgetInstruction::ApplySignature, keys)
} }
} }

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::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction_builder::BuilderInstruction; use solana_sdk::transaction::Instruction;
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum RewardsInstruction { pub enum RewardsInstruction {
@ -9,8 +9,8 @@ pub enum RewardsInstruction {
} }
impl RewardsInstruction { impl RewardsInstruction {
pub fn new_redeem_vote_credits(vote_id: &Pubkey, rewards_id: &Pubkey) -> BuilderInstruction { pub fn new_redeem_vote_credits(vote_id: &Pubkey, rewards_id: &Pubkey) -> Instruction {
BuilderInstruction::new( Instruction::new(
id(), id(),
&RewardsInstruction::RedeemVoteCredits, &RewardsInstruction::RedeemVoteCredits,
vec![(*vote_id, true), (*rewards_id, false)], vec![(*vote_id, true), (*rewards_id, false)],

View File

@ -180,7 +180,7 @@ mod test {
use solana_sdk::account::{create_keyed_accounts, Account}; use solana_sdk::account::{create_keyed_accounts, Account};
use solana_sdk::hash::Hash; use solana_sdk::hash::Hash;
use solana_sdk::signature::{Keypair, KeypairUtil, Signature}; use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
use solana_sdk::transaction::{Instruction, Transaction}; use solana_sdk::transaction::{CompiledInstruction, Transaction};
use solana_storage_api::{ProofStatus, StorageTransaction}; use solana_storage_api::{ProofStatus, StorageTransaction};
fn test_transaction( fn test_transaction(
@ -188,7 +188,7 @@ mod test {
program_accounts: &mut [Account], program_accounts: &mut [Account],
) -> Result<(), ProgramError> { ) -> Result<(), ProgramError> {
assert_eq!(tx.instructions.len(), 1); assert_eq!(tx.instructions.len(), 1);
let Instruction { let CompiledInstruction {
ref accounts, ref accounts,
ref data, ref data,
.. ..

View File

@ -5,8 +5,8 @@ use solana_sdk::native_program::ProgramError;
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::{InstructionError, TransactionError}; use solana_sdk::transaction::{Instruction, InstructionError, TransactionError};
use solana_sdk::transaction_builder::{BuilderInstruction, TransactionBuilder}; use solana_sdk::transaction_builder::TransactionBuilder;
use solana_vote_api::vote_instruction::{Vote, VoteInstruction}; use solana_vote_api::vote_instruction::{Vote, VoteInstruction};
use solana_vote_api::vote_state::VoteState; use solana_vote_api::vote_state::VoteState;
use solana_vote_api::vote_transaction::VoteTransaction; use solana_vote_api::vote_transaction::VoteTransaction;
@ -111,7 +111,7 @@ fn test_vote_via_bank_with_no_signature() {
let mallory_id = mallory_keypair.pubkey(); let mallory_id = mallory_keypair.pubkey();
let blockhash = bank.last_blockhash(); let blockhash = bank.last_blockhash();
let vote_ix = BuilderInstruction::new( let vote_ix = Instruction::new(
solana_vote_api::id(), solana_vote_api::id(),
&VoteInstruction::Vote(Vote::new(0)), &VoteInstruction::Vote(Vote::new(0)),
vec![(vote_id, false)], // <--- attack!! No signature. vec![(vote_id, false)], // <--- attack!! No signature.

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::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::transaction_builder::BuilderInstruction; use solana_sdk::transaction::Instruction;
#[derive(Serialize, Default, Deserialize, Debug, PartialEq, Eq, Clone)] #[derive(Serialize, Default, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Vote { pub struct Vote {
@ -32,34 +32,31 @@ pub enum VoteInstruction {
} }
impl VoteInstruction { impl VoteInstruction {
pub fn new_clear_credits(vote_id: &Pubkey) -> BuilderInstruction { pub fn new_clear_credits(vote_id: &Pubkey) -> Instruction {
BuilderInstruction::new(id(), &VoteInstruction::ClearCredits, vec![(*vote_id, true)]) Instruction::new(id(), &VoteInstruction::ClearCredits, vec![(*vote_id, true)])
} }
pub fn new_delegate_stake(vote_id: &Pubkey, delegate_id: &Pubkey) -> BuilderInstruction { pub fn new_delegate_stake(vote_id: &Pubkey, delegate_id: &Pubkey) -> Instruction {
BuilderInstruction::new( Instruction::new(
id(), id(),
&VoteInstruction::DelegateStake(*delegate_id), &VoteInstruction::DelegateStake(*delegate_id),
vec![(*vote_id, true)], vec![(*vote_id, true)],
) )
} }
pub fn new_authorize_voter( pub fn new_authorize_voter(vote_id: &Pubkey, authorized_voter_id: &Pubkey) -> Instruction {
vote_id: &Pubkey, Instruction::new(
authorized_voter_id: &Pubkey,
) -> BuilderInstruction {
BuilderInstruction::new(
id(), id(),
&VoteInstruction::AuthorizeVoter(*authorized_voter_id), &VoteInstruction::AuthorizeVoter(*authorized_voter_id),
vec![(*vote_id, true)], vec![(*vote_id, true)],
) )
} }
pub fn new_initialize_account(vote_id: &Pubkey) -> BuilderInstruction { pub fn new_initialize_account(vote_id: &Pubkey) -> Instruction {
BuilderInstruction::new( Instruction::new(
id(), id(),
&VoteInstruction::InitializeAccount, &VoteInstruction::InitializeAccount,
vec![(*vote_id, false)], vec![(*vote_id, false)],
) )
} }
pub fn new_vote(vote_id: &Pubkey, vote: Vote) -> BuilderInstruction { pub fn new_vote(vote_id: &Pubkey, vote: Vote) -> Instruction {
BuilderInstruction::new(id(), &VoteInstruction::Vote(vote), vec![(*vote_id, true)]) Instruction::new(id(), &VoteInstruction::Vote(vote), vec![(*vote_id, true)])
} }
} }

View File

@ -1017,7 +1017,7 @@ mod tests {
use solana_sdk::hash::Hash; use solana_sdk::hash::Hash;
use solana_sdk::signature::Keypair; use solana_sdk::signature::Keypair;
use solana_sdk::signature::KeypairUtil; use solana_sdk::signature::KeypairUtil;
use solana_sdk::transaction::Instruction; 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) {
@ -1046,7 +1046,7 @@ mod tests {
let accounts: Vec<(Pubkey, Account)> = Vec::new(); let accounts: Vec<(Pubkey, Account)> = Vec::new();
let mut error_counters = ErrorCounters::default(); let mut error_counters = ErrorCounters::default();
let instructions = vec![Instruction::new(1, &(), vec![0])]; let instructions = vec![CompiledInstruction::new(1, &(), vec![0])];
let tx = Transaction::new_with_instructions::<Keypair>( let tx = Transaction::new_with_instructions::<Keypair>(
&[], &[],
&[], &[],
@ -1070,7 +1070,7 @@ mod tests {
let keypair = Keypair::new(); let keypair = Keypair::new();
let instructions = vec![Instruction::new(1, &(), vec![0])]; let instructions = vec![CompiledInstruction::new(1, &(), vec![0])];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&keypair], &[&keypair],
&[], &[],
@ -1102,7 +1102,7 @@ mod tests {
let account = Account::new(2, 1, &Pubkey::default()); let account = Account::new(2, 1, &Pubkey::default());
accounts.push((key1, account)); accounts.push((key1, account));
let instructions = vec![Instruction::new(1, &(), vec![0])]; let instructions = vec![CompiledInstruction::new(1, &(), vec![0])];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&keypair], &[&keypair],
&[], &[],
@ -1130,7 +1130,7 @@ mod tests {
let account = Account::new(1, 1, &Pubkey::default()); let account = Account::new(1, 1, &Pubkey::default());
accounts.push((key0, account)); accounts.push((key0, account));
let instructions = vec![Instruction::new(1, &(), vec![0])]; let instructions = vec![CompiledInstruction::new(1, &(), vec![0])];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&keypair], &[&keypair],
&[], &[],
@ -1165,7 +1165,7 @@ mod tests {
let account = Account::new(2, 1, &Pubkey::default()); let account = Account::new(2, 1, &Pubkey::default());
accounts.push((key1, account)); accounts.push((key1, account));
let instructions = vec![Instruction::new(0, &(), vec![0, 1])]; let instructions = vec![CompiledInstruction::new(0, &(), vec![0, 1])];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&keypair], &[&keypair],
&[key1], &[key1],
@ -1237,7 +1237,7 @@ mod tests {
account.owner = key5; account.owner = key5;
accounts.push((key6, account)); accounts.push((key6, account));
let instructions = vec![Instruction::new(0, &(), vec![0])]; let instructions = vec![CompiledInstruction::new(0, &(), vec![0])];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&keypair], &[&keypair],
&[], &[],
@ -1271,7 +1271,7 @@ mod tests {
account.owner = Pubkey::default(); account.owner = Pubkey::default();
accounts.push((key1, account)); accounts.push((key1, account));
let instructions = vec![Instruction::new(0, &(), vec![0])]; let instructions = vec![CompiledInstruction::new(0, &(), vec![0])];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&keypair], &[&keypair],
&[], &[],
@ -1304,7 +1304,7 @@ mod tests {
account.owner = native_loader::id(); account.owner = native_loader::id();
accounts.push((key1, account)); accounts.push((key1, account));
let instructions = vec![Instruction::new(0, &(), vec![0])]; let instructions = vec![CompiledInstruction::new(0, &(), vec![0])];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&keypair], &[&keypair],
&[], &[],
@ -1351,8 +1351,8 @@ mod tests {
accounts.push((key3, account)); accounts.push((key3, account));
let instructions = vec![ let instructions = vec![
Instruction::new(0, &(), vec![0]), CompiledInstruction::new(0, &(), vec![0]),
Instruction::new(1, &(), vec![0]), CompiledInstruction::new(1, &(), vec![0]),
]; ];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&keypair], &[&keypair],
@ -1396,7 +1396,7 @@ mod tests {
let account = Account::new(10, 1, &Pubkey::default()); let account = Account::new(10, 1, &Pubkey::default());
accounts.push((pubkey, account)); accounts.push((pubkey, account));
let instructions = vec![Instruction::new(0, &(), vec![0, 1])]; let instructions = vec![CompiledInstruction::new(0, &(), vec![0, 1])];
// Simulate pay-to-self transaction, which loads the same account twice // Simulate pay-to-self transaction, which loads the same account twice
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&keypair], &[&keypair],

View File

@ -847,7 +847,7 @@ mod tests {
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::{Instruction, InstructionError}; use solana_sdk::transaction::{CompiledInstruction, InstructionError};
#[test] #[test]
fn test_bank_new() { fn test_bank_new() {
@ -927,12 +927,12 @@ mod tests {
let bank = Bank::new(&genesis_block); let bank = Bank::new(&genesis_block);
let spend = SystemInstruction::Move { lamports: 1 }; let spend = SystemInstruction::Move { lamports: 1 };
let instructions = vec![ let instructions = vec![
Instruction { CompiledInstruction {
program_ids_index: 0, program_ids_index: 0,
data: serialize(&spend).unwrap(), data: serialize(&spend).unwrap(),
accounts: vec![0, 1], accounts: vec![0, 1],
}, },
Instruction { CompiledInstruction {
program_ids_index: 0, program_ids_index: 0,
data: serialize(&spend).unwrap(), data: serialize(&spend).unwrap(),
accounts: vec![0, 2], accounts: vec![0, 2],

View File

@ -5,8 +5,8 @@ use solana_sdk::native_program::ProgramError;
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::{InstructionError, TransactionError}; use solana_sdk::transaction::{Instruction, InstructionError, TransactionError};
use solana_sdk::transaction_builder::{BuilderInstruction, TransactionBuilder}; use solana_sdk::transaction_builder::TransactionBuilder;
#[test] #[test]
fn test_system_unsigned_transaction() { fn test_system_unsigned_transaction() {
@ -26,7 +26,7 @@ fn test_system_unsigned_transaction() {
// Erroneously sign transaction with recipient account key // Erroneously sign transaction with recipient account key
// No signature case is tested by bank `test_zero_signatures()` // No signature case is tested by bank `test_zero_signatures()`
let ix = BuilderInstruction::new( let ix = Instruction::new(
system_program::id(), system_program::id(),
&SystemInstruction::Move { lamports: 10 }, &SystemInstruction::Move { lamports: 10 },
vec![(from_pubkey, false), (to_pubkey, true)], vec![(from_pubkey, false), (to_pubkey, true)],

View File

@ -1,6 +1,6 @@
use crate::pubkey::Pubkey; use crate::pubkey::Pubkey;
use crate::system_program; use crate::system_program;
use crate::transaction_builder::BuilderInstruction; use crate::transaction::Instruction;
#[derive(Serialize, Debug, Clone, PartialEq)] #[derive(Serialize, Debug, Clone, PartialEq)]
pub enum SystemError { pub enum SystemError {
@ -38,8 +38,8 @@ impl SystemInstruction {
lamports: u64, lamports: u64,
space: u64, space: u64,
program_id: &Pubkey, program_id: &Pubkey,
) -> BuilderInstruction { ) -> Instruction {
BuilderInstruction::new( Instruction::new(
system_program::id(), system_program::id(),
&SystemInstruction::CreateAccount { &SystemInstruction::CreateAccount {
lamports, lamports,
@ -50,8 +50,8 @@ impl SystemInstruction {
) )
} }
pub fn new_move(from_id: &Pubkey, to_id: &Pubkey, lamports: u64) -> BuilderInstruction { pub fn new_move(from_id: &Pubkey, to_id: &Pubkey, lamports: u64) -> Instruction {
BuilderInstruction::new( Instruction::new(
system_program::id(), system_program::id(),
&SystemInstruction::Move { lamports }, &SystemInstruction::Move { lamports },
vec![(*from_id, true), (*to_id, false)], vec![(*from_id, true), (*to_id, false)],

View File

@ -5,7 +5,7 @@ use crate::pubkey::Pubkey;
use crate::signature::Keypair; use crate::signature::Keypair;
use crate::system_instruction::SystemInstruction; use crate::system_instruction::SystemInstruction;
use crate::system_program; use crate::system_program;
use crate::transaction::{Instruction, Transaction}; use crate::transaction::{CompiledInstruction, Transaction};
pub struct SystemTransaction {} pub struct SystemTransaction {}
@ -103,7 +103,7 @@ impl SystemTransaction {
.enumerate() .enumerate()
.map(|(i, (_, amount))| { .map(|(i, (_, amount))| {
let spend = SystemInstruction::Move { lamports: *amount }; let spend = SystemInstruction::Move { lamports: *amount };
Instruction::new(0, &spend, vec![0, i as u8 + 1]) CompiledInstruction::new(0, &spend, vec![0, i as u8 + 1])
}) })
.collect(); .collect();
let to_keys: Vec<_> = moves.iter().map(|(to_key, _)| *to_key).collect(); let to_keys: Vec<_> = moves.iter().map(|(to_key, _)| *to_key).collect();

View File

@ -10,7 +10,7 @@ use crate::shortvec::{
}; };
use crate::signature::{KeypairUtil, Signature}; use crate::signature::{KeypairUtil, Signature};
use crate::system_instruction::SystemError; use crate::system_instruction::SystemError;
use crate::transaction_builder::{BuilderInstruction, TransactionBuilder}; use crate::transaction_builder::TransactionBuilder;
use bincode::{serialize, 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};
@ -50,7 +50,7 @@ impl InstructionError {
/// An instruction to execute a program /// An instruction to execute a program
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Instruction<P, Q> { pub struct GenericInstruction<P, Q> {
/// Index into the transaction program ids array indicating the program account that executes this instruction /// Index into the transaction program ids array indicating the program account that executes this instruction
pub program_ids_index: P, pub program_ids_index: P,
/// Ordered indices into the transaction keys array indicating which accounts to pass to the program /// Ordered indices into the transaction keys array indicating which accounts to pass to the program
@ -59,7 +59,7 @@ pub struct Instruction<P, Q> {
pub data: Vec<u8>, pub data: Vec<u8>,
} }
impl<P, Q> Instruction<P, Q> { impl<P, Q> GenericInstruction<P, Q> {
pub fn new<T: Serialize>(program_ids_index: P, data: &T, accounts: Vec<Q>) -> Self { pub fn new<T: Serialize>(program_ids_index: P, data: &T, accounts: Vec<Q>) -> Self {
let data = serialize(data).unwrap(); let data = serialize(data).unwrap();
Self { Self {
@ -70,7 +70,10 @@ impl<P, Q> Instruction<P, Q> {
} }
} }
impl Instruction<u8, u8> { pub type Instruction = GenericInstruction<Pubkey, (Pubkey, bool)>;
pub type CompiledInstruction = GenericInstruction<u8, u8>;
impl CompiledInstruction {
pub fn serialize_with(mut writer: &mut Cursor<&mut [u8]>, ix: &Self) -> Result<(), Error> { pub fn serialize_with(mut writer: &mut Cursor<&mut [u8]>, ix: &Self) -> Result<(), Error> {
writer.write_all(&[ix.program_ids_index])?; writer.write_all(&[ix.program_ids_index])?;
serialize_vec_bytes(&mut writer, &ix.accounts[..])?; serialize_vec_bytes(&mut writer, &ix.accounts[..])?;
@ -84,7 +87,7 @@ impl Instruction<u8, u8> {
let program_ids_index = buf[0]; let program_ids_index = buf[0];
let accounts = deserialize_vec_bytes(&mut reader)?; let accounts = deserialize_vec_bytes(&mut reader)?;
let data = deserialize_vec_bytes(&mut reader)?; let data = deserialize_vec_bytes(&mut reader)?;
Ok(Instruction { Ok(CompiledInstruction {
program_ids_index, program_ids_index,
accounts, accounts,
data, data,
@ -160,7 +163,7 @@ pub struct Transaction {
pub program_ids: Vec<Pubkey>, pub program_ids: Vec<Pubkey>,
/// Programs that will be executed in sequence and committed in one atomic transaction if all /// Programs that will be executed in sequence and committed in one atomic transaction if all
/// succeed. /// succeed.
pub instructions: Vec<Instruction<u8, u8>>, pub instructions: Vec<CompiledInstruction>,
} }
impl Transaction { impl Transaction {
@ -195,7 +198,7 @@ impl Transaction {
for pubkey in transaction_keys { for pubkey in transaction_keys {
account_keys.push((*pubkey, false)); account_keys.push((*pubkey, false));
} }
let instruction = BuilderInstruction::new(*program_id, data, account_keys); let instruction = Instruction::new(*program_id, data, account_keys);
let mut transaction = TransactionBuilder::new(fee).push(instruction).compile(); let mut transaction = TransactionBuilder::new(fee).push(instruction).compile();
transaction.recent_blockhash = recent_blockhash; transaction.recent_blockhash = recent_blockhash;
transaction transaction
@ -215,7 +218,7 @@ impl Transaction {
recent_blockhash: Hash, recent_blockhash: Hash,
fee: u64, fee: u64,
program_ids: Vec<Pubkey>, program_ids: Vec<Pubkey>,
instructions: Vec<Instruction<u8, u8>>, instructions: Vec<CompiledInstruction>,
) -> Self { ) -> Self {
let mut account_keys: Vec<_> = from_keypairs let mut account_keys: Vec<_> = from_keypairs
.iter() .iter()
@ -275,8 +278,12 @@ impl Transaction {
.expect("serialize fee"); .expect("serialize fee");
serialize_vec_with(&mut wr, &self.program_ids, Transaction::serialize_pubkey) serialize_vec_with(&mut wr, &self.program_ids, Transaction::serialize_pubkey)
.expect("serialize program_ids"); .expect("serialize program_ids");
serialize_vec_with(&mut wr, &self.instructions, Instruction::serialize_with) serialize_vec_with(
.expect("serialize instructions"); &mut wr,
&self.instructions,
CompiledInstruction::serialize_with,
)
.expect("serialize instructions");
let len = wr.position() as usize; let len = wr.position() as usize;
wr.into_inner()[..len].to_vec() wr.into_inner()[..len].to_vec()
} }
@ -416,8 +423,12 @@ impl Serialize for Transaction {
.map_err(Error::custom)?; .map_err(Error::custom)?;
serialize_vec_with(&mut wr, &self.program_ids, Transaction::serialize_pubkey) serialize_vec_with(&mut wr, &self.program_ids, Transaction::serialize_pubkey)
.map_err(Error::custom)?; .map_err(Error::custom)?;
serialize_vec_with(&mut wr, &self.instructions, Instruction::serialize_with) serialize_vec_with(
.map_err(Error::custom)?; &mut wr,
&self.instructions,
CompiledInstruction::serialize_with,
)
.map_err(Error::custom)?;
let size = wr.position() as usize; let size = wr.position() as usize;
serializer.serialize_bytes(&wr.into_inner()[..size]) serializer.serialize_bytes(&wr.into_inner()[..size])
} }
@ -449,8 +460,9 @@ impl<'a> serde::de::Visitor<'a> for TransactionVisitor {
let program_ids: Vec<Pubkey> = let program_ids: Vec<Pubkey> =
deserialize_vec_with(&mut rd, Transaction::deserialize_pubkey) deserialize_vec_with(&mut rd, Transaction::deserialize_pubkey)
.map_err(Error::custom)?; .map_err(Error::custom)?;
let instructions: Vec<Instruction<u8, u8>> = let instructions: Vec<CompiledInstruction> =
deserialize_vec_with(&mut rd, Instruction::deserialize_from).map_err(Error::custom)?; deserialize_vec_with(&mut rd, CompiledInstruction::deserialize_from)
.map_err(Error::custom)?;
Ok(Transaction { Ok(Transaction {
signatures, signatures,
account_keys, account_keys,
@ -485,8 +497,8 @@ mod tests {
let prog1 = Keypair::new().pubkey(); let prog1 = Keypair::new().pubkey();
let prog2 = Keypair::new().pubkey(); let prog2 = Keypair::new().pubkey();
let instructions = vec![ let instructions = vec![
Instruction::new(0, &(), vec![0, 1]), CompiledInstruction::new(0, &(), vec![0, 1]),
Instruction::new(1, &(), vec![0, 2]), CompiledInstruction::new(1, &(), vec![0, 2]),
]; ];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&key], &[&key],
@ -522,7 +534,7 @@ mod tests {
#[test] #[test]
fn test_refs_invalid_program_id() { fn test_refs_invalid_program_id() {
let key = Keypair::new(); let key = Keypair::new();
let instructions = vec![Instruction::new(1, &(), vec![])]; let instructions = vec![CompiledInstruction::new(1, &(), vec![])];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&key], &[&key],
&[], &[],
@ -536,7 +548,7 @@ mod tests {
#[test] #[test]
fn test_refs_invalid_account() { fn test_refs_invalid_account() {
let key = Keypair::new(); let key = Keypair::new();
let instructions = vec![Instruction::new(0, &(), vec![1])]; let instructions = vec![CompiledInstruction::new(0, &(), vec![1])];
let tx = Transaction::new_with_instructions( let tx = Transaction::new_with_instructions(
&[&key], &[&key],
&[], &[],
@ -686,6 +698,6 @@ mod tests {
.push(Instruction::new(program_id, &0, vec![(id0, true)])) .push(Instruction::new(program_id, &0, vec![(id0, true)]))
.compile(); .compile();
tx.sign(&[&keypair0], Hash::default()); tx.sign(&[&keypair0], Hash::default());
assert_eq!(tx.instructions[0], Instruction::new(0, &0, vec![0])); assert_eq!(tx.instructions[0], CompiledInstruction::new(0, &0, vec![0]));
} }
} }

View File

@ -2,22 +2,20 @@
use crate::hash::Hash; use crate::hash::Hash;
use crate::pubkey::Pubkey; use crate::pubkey::Pubkey;
use crate::transaction::{Instruction, Transaction}; use crate::transaction::{CompiledInstruction, Instruction, Transaction};
use itertools::Itertools; use itertools::Itertools;
pub type BuilderInstruction = Instruction<Pubkey, (Pubkey, bool)>;
fn position(keys: &[Pubkey], key: &Pubkey) -> u8 { fn position(keys: &[Pubkey], key: &Pubkey) -> u8 {
keys.iter().position(|k| k == key).unwrap() as u8 keys.iter().position(|k| k == key).unwrap() as u8
} }
fn compile_instruction( fn compile_instruction(
ix: &BuilderInstruction, ix: &Instruction,
keys: &[Pubkey], keys: &[Pubkey],
program_ids: &[Pubkey], program_ids: &[Pubkey],
) -> Instruction<u8, u8> { ) -> CompiledInstruction {
let accounts: Vec<_> = ix.accounts.iter().map(|(k, _)| position(keys, k)).collect(); let accounts: Vec<_> = ix.accounts.iter().map(|(k, _)| position(keys, k)).collect();
Instruction { CompiledInstruction {
program_ids_index: position(program_ids, &ix.program_ids_index), program_ids_index: position(program_ids, &ix.program_ids_index),
data: ix.data.clone(), data: ix.data.clone(),
accounts, accounts,
@ -25,10 +23,10 @@ fn compile_instruction(
} }
fn compile_instructions( fn compile_instructions(
ixs: &[BuilderInstruction], ixs: &[Instruction],
keys: &[Pubkey], keys: &[Pubkey],
program_ids: &[Pubkey], program_ids: &[Pubkey],
) -> Vec<Instruction<u8, u8>> { ) -> Vec<CompiledInstruction> {
ixs.iter() ixs.iter()
.map(|ix| compile_instruction(ix, keys, program_ids)) .map(|ix| compile_instruction(ix, keys, program_ids))
.collect() .collect()
@ -38,7 +36,7 @@ fn compile_instructions(
#[derive(Default)] #[derive(Default)]
pub struct TransactionBuilder { pub struct TransactionBuilder {
fee: u64, fee: u64,
instructions: Vec<BuilderInstruction>, instructions: Vec<Instruction>,
} }
impl TransactionBuilder { impl TransactionBuilder {
@ -51,18 +49,18 @@ impl TransactionBuilder {
} }
/// Create a new unsigned transaction from a single instruction /// Create a new unsigned transaction from a single instruction
pub fn new_with_instruction(instruction: BuilderInstruction) -> Transaction { pub fn new_with_instruction(instruction: Instruction) -> Transaction {
Self::new_with_instructions(vec![instruction]) Self::new_with_instructions(vec![instruction])
} }
/// Create a new unsigned transaction from a single instruction /// Create a new unsigned transaction from a single instruction
pub fn new_with_instructions(instructions: Vec<BuilderInstruction>) -> Transaction { pub fn new_with_instructions(instructions: Vec<Instruction>) -> Transaction {
let fee = 0; let fee = 0;
Self { fee, instructions }.compile() Self { fee, instructions }.compile()
} }
/// Add an instruction. /// Add an instruction.
pub fn push(&mut self, instruction: BuilderInstruction) -> &mut Self { pub fn push(&mut self, instruction: Instruction) -> &mut Self {
self.instructions.push(instruction); self.instructions.push(instruction);
self self
} }
@ -247,9 +245,9 @@ mod tests {
.push(Instruction::new(program_id1, &0, vec![(id1, true)])) .push(Instruction::new(program_id1, &0, vec![(id1, true)]))
.push(Instruction::new(program_id0, &0, vec![(id1, false)])) .push(Instruction::new(program_id0, &0, vec![(id1, false)]))
.compile(); .compile();
assert_eq!(tx.instructions[0], Instruction::new(0, &0, vec![1])); assert_eq!(tx.instructions[0], CompiledInstruction::new(0, &0, vec![1]));
assert_eq!(tx.instructions[1], Instruction::new(1, &0, vec![0])); assert_eq!(tx.instructions[1], CompiledInstruction::new(1, &0, vec![0]));
assert_eq!(tx.instructions[2], Instruction::new(0, &0, vec![0])); assert_eq!(tx.instructions[2], CompiledInstruction::new(0, &0, vec![0]));
} }
#[test] #[test]