diff --git a/programs/budget_api/src/budget_transaction.rs b/programs/budget_api/src/budget_transaction.rs index e103eb1583..e5f422e54a 100644 --- a/programs/budget_api/src/budget_transaction.rs +++ b/programs/budget_api/src/budget_transaction.rs @@ -11,7 +11,6 @@ use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::transaction::Transaction; -use solana_sdk::transaction_builder::TransactionBuilder; pub struct BudgetTransaction {} @@ -31,7 +30,7 @@ impl BudgetTransaction { let create_ix = SystemInstruction::new_program_account(&from, contract, lamports, space, &id()); let init_ix = BudgetInstruction::new_initialize_account(contract, expr); - let mut tx = TransactionBuilder::new(vec![create_ix, init_ix]).compile(); + let mut tx = Transaction::new(vec![create_ix, init_ix]); tx.fee = fee; tx.sign(&[from_keypair], recent_blockhash); tx @@ -67,7 +66,7 @@ impl BudgetTransaction { ) -> Transaction { let from = from_keypair.pubkey(); let ix = BudgetInstruction::new_apply_timestamp(&from, contract, to, dt); - let mut tx = TransactionBuilder::new(vec![ix]).compile(); + let mut tx = Transaction::new(vec![ix]); tx.sign(&[from_keypair], recent_blockhash); tx } @@ -81,7 +80,7 @@ impl BudgetTransaction { ) -> Transaction { let from = from_keypair.pubkey(); let ix = BudgetInstruction::new_apply_signature(&from, contract, to); - let mut tx = TransactionBuilder::new(vec![ix]).compile(); + let mut tx = Transaction::new(vec![ix]); tx.sign(&[from_keypair], recent_blockhash); tx } diff --git a/programs/rewards_api/src/rewards_transaction.rs b/programs/rewards_api/src/rewards_transaction.rs index 0cc817b052..9d7cb8f037 100644 --- a/programs/rewards_api/src/rewards_transaction.rs +++ b/programs/rewards_api/src/rewards_transaction.rs @@ -9,7 +9,6 @@ use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::transaction::Transaction; -use solana_sdk::transaction_builder::TransactionBuilder; use solana_vote_api::vote_instruction::VoteInstruction; pub struct RewardsTransaction {} @@ -42,7 +41,7 @@ impl RewardsTransaction { let vote_id = vote_keypair.pubkey(); let redeem_ix = RewardsInstruction::new_redeem_vote_credits(&vote_id, rewards_id); let clear_ix = VoteInstruction::new_clear_credits(&vote_id); - let mut tx = TransactionBuilder::new(vec![redeem_ix, clear_ix]).compile(); + let mut tx = Transaction::new(vec![redeem_ix, clear_ix]); tx.fee = fee; tx.sign(&[vote_keypair], blockhash); tx diff --git a/programs/vote/tests/vote.rs b/programs/vote/tests/vote.rs index ac343ccc84..2d61de3297 100644 --- a/programs/vote/tests/vote.rs +++ b/programs/vote/tests/vote.rs @@ -5,8 +5,7 @@ use solana_sdk::native_program::ProgramError; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction::SystemInstruction; -use solana_sdk::transaction::{Instruction, InstructionError, TransactionError}; -use solana_sdk::transaction_builder::TransactionBuilder; +use solana_sdk::transaction::{Instruction, InstructionError, Transaction, TransactionError}; use solana_vote_api::vote_instruction::{Vote, VoteInstruction}; use solana_vote_api::vote_state::VoteState; use solana_vote_api::vote_transaction::VoteTransaction; @@ -120,10 +119,8 @@ fn test_vote_via_bank_with_no_signature() { // Sneak in an instruction so that the transaction is signed but // the 0th account in the second instruction is not! The program // needs to check that it's signed. - let mut tx = TransactionBuilder::default() - .push(SystemInstruction::new_move(&mallory_id, &vote_id, 1)) - .push(vote_ix) - .compile(); + let move_ix = SystemInstruction::new_move(&mallory_id, &vote_id, 1); + let mut tx = Transaction::new(vec![move_ix, vote_ix]); tx.sign(&[&mallory_keypair], blockhash); let result = bank.process_transaction(&tx); diff --git a/programs/vote_api/src/vote_transaction.rs b/programs/vote_api/src/vote_transaction.rs index fc6712beec..46bd40db91 100644 --- a/programs/vote_api/src/vote_transaction.rs +++ b/programs/vote_api/src/vote_transaction.rs @@ -9,7 +9,6 @@ use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::transaction::Transaction; -use solana_sdk::transaction_builder::TransactionBuilder; pub struct VoteTransaction {} @@ -23,7 +22,7 @@ impl VoteTransaction { ) -> Transaction { let vote = Vote { slot }; let ix = VoteInstruction::new_vote(staking_account, vote); - let mut tx = TransactionBuilder::new(vec![ix]).compile(); + let mut tx = Transaction::new(vec![ix]); tx.fee = fee; tx.sign(&[authorized_voter_keypair], recent_blockhash); tx @@ -42,7 +41,7 @@ impl VoteTransaction { let create_ix = SystemInstruction::new_program_account(&from_id, staker_id, lamports, space, &id()); let init_ix = VoteInstruction::new_initialize_account(staker_id); - let mut tx = TransactionBuilder::new(vec![create_ix, init_ix]).compile(); + let mut tx = Transaction::new(vec![create_ix, init_ix]); tx.fee = fee; tx.sign(&[from_keypair], recent_blockhash); tx @@ -64,7 +63,7 @@ impl VoteTransaction { SystemInstruction::new_program_account(&from_id, &voter_id, lamports, space, &id()); let init_ix = VoteInstruction::new_initialize_account(&voter_id); let delegate_ix = VoteInstruction::new_delegate_stake(&voter_id, &delegate_id); - let mut tx = TransactionBuilder::new(vec![create_ix, init_ix, delegate_ix]).compile(); + let mut tx = Transaction::new(vec![create_ix, init_ix, delegate_ix]); tx.fee = fee; tx.sign(&[from_keypair, voter_keypair], recent_blockhash); tx @@ -78,7 +77,7 @@ impl VoteTransaction { fee: u64, ) -> Transaction { let ix = VoteInstruction::new_authorize_voter(&vote_keypair.pubkey(), authorized_voter_id); - let mut tx = TransactionBuilder::new(vec![ix]).compile(); + let mut tx = Transaction::new(vec![ix]); tx.fee = fee; tx.sign(&[vote_keypair], recent_blockhash); tx @@ -92,7 +91,7 @@ impl VoteTransaction { fee: u64, ) -> Transaction { let ix = VoteInstruction::new_delegate_stake(&vote_keypair.pubkey(), node_id); - let mut tx = TransactionBuilder::new(vec![ix]).compile(); + let mut tx = Transaction::new(vec![ix]); tx.fee = fee; tx.sign(&[vote_keypair], recent_blockhash); tx diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index c3a9fdd253..b59ec1b027 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -1484,7 +1484,7 @@ mod tests { let move_lamports = SystemInstruction::Move { lamports: 1 }; - let mut tx = Transaction::new_unsigned( + let mut tx = Transaction::new_with_blockhash_and_fee( &mint_keypair.pubkey(), &[key.pubkey()], &system_program::id(), diff --git a/runtime/tests/system.rs b/runtime/tests/system.rs index f839d9eacd..5716638063 100644 --- a/runtime/tests/system.rs +++ b/runtime/tests/system.rs @@ -5,8 +5,7 @@ use solana_sdk::native_program::ProgramError; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::system_program; -use solana_sdk::transaction::{Instruction, InstructionError, TransactionError}; -use solana_sdk::transaction_builder::TransactionBuilder; +use solana_sdk::transaction::{Instruction, InstructionError, Transaction, TransactionError}; #[test] fn test_system_unsigned_transaction() { @@ -21,7 +20,7 @@ fn test_system_unsigned_transaction() { // Fund to account to bypass AccountNotFound error let ix = SystemInstruction::new_move(&from_pubkey, &to_pubkey, 50); - let mut tx = TransactionBuilder::new(vec![ix]).compile(); + let mut tx = Transaction::new(vec![ix]); alice_client.process_transaction(&mut tx).unwrap(); // Erroneously sign transaction with recipient account key @@ -31,7 +30,7 @@ fn test_system_unsigned_transaction() { &SystemInstruction::Move { lamports: 10 }, vec![(from_pubkey, false), (to_pubkey, true)], ); - let mut tx = TransactionBuilder::new(vec![ix]).compile(); + let mut tx = Transaction::new(vec![ix]); assert_eq!( mallory_client.process_transaction(&mut tx), Err(TransactionError::InstructionError( diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index ba45edc72f..a37397c0c6 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -15,7 +15,7 @@ pub mod system_program; pub mod system_transaction; pub mod timing; pub mod transaction; -pub mod transaction_builder; +mod transaction_builder; #[macro_use] extern crate serde_derive; diff --git a/sdk/src/transaction.rs b/sdk/src/transaction.rs index 23d2135739..738d729b47 100644 --- a/sdk/src/transaction.rs +++ b/sdk/src/transaction.rs @@ -167,26 +167,11 @@ pub struct Transaction { } impl Transaction { - pub fn new_signed( - from_keypair: &T, - transaction_keys: &[Pubkey], - program_id: &Pubkey, - data: &S, - recent_blockhash: Hash, - fee: u64, - ) -> Self { - let mut transaction = Self::new_unsigned( - &from_keypair.pubkey(), - transaction_keys, - program_id, - data, - Hash::default(), - fee, - ); - transaction.sign(&[from_keypair], recent_blockhash); - transaction + pub fn new(instructions: Vec) -> Self { + TransactionBuilder::new(instructions).compile() } - pub fn new_unsigned( + + pub fn new_with_blockhash_and_fee( from_pubkey: &Pubkey, transaction_keys: &[Pubkey], program_id: &Pubkey, @@ -199,12 +184,32 @@ impl Transaction { account_keys.push((*pubkey, false)); } let instruction = Instruction::new(*program_id, data, account_keys); - let mut transaction = TransactionBuilder::new(vec![instruction]).compile(); + let mut transaction = Self::new(vec![instruction]); transaction.fee = fee; transaction.recent_blockhash = recent_blockhash; transaction } + pub fn new_signed( + from_keypair: &T, + transaction_keys: &[Pubkey], + program_id: &Pubkey, + data: &S, + recent_blockhash: Hash, + fee: u64, + ) -> Self { + let mut transaction = Self::new_with_blockhash_and_fee( + &from_keypair.pubkey(), + transaction_keys, + program_id, + data, + Hash::default(), + fee, + ); + transaction.sign(&[from_keypair], recent_blockhash); + transaction + } + /// Create a signed transaction /// * `from_keypairs` - The keys used to sign the transaction. /// * `account_keys` - The keys for the transaction. These are the program state @@ -661,9 +666,7 @@ mod tests { #[should_panic] fn test_transaction_missing_key() { let keypair = Keypair::new(); - TransactionBuilder::default() - .compile() - .sign(&[&keypair], Hash::default()); + Transaction::new(vec![]).sign(&[&keypair], Hash::default()); } #[test] @@ -672,9 +675,7 @@ mod tests { let program_id = Pubkey::default(); let keypair0 = Keypair::new(); let id0 = keypair0.pubkey(); - TransactionBuilder::default() - .push(Instruction::new(program_id, &0, vec![(id0, true)])) - .compile() + Transaction::new(vec![Instruction::new(program_id, &0, vec![(id0, true)])]) .sign(&Vec::<&Keypair>::new(), Hash::default()); } @@ -684,10 +685,12 @@ mod tests { let program_id = Pubkey::default(); let keypair0 = Keypair::new(); let wrong_id = Pubkey::default(); - TransactionBuilder::default() - .push(Instruction::new(program_id, &0, vec![(wrong_id, true)])) - .compile() - .sign(&[&keypair0], Hash::default()); + Transaction::new(vec![Instruction::new( + program_id, + &0, + vec![(wrong_id, true)], + )]) + .sign(&[&keypair0], Hash::default()); } #[test] @@ -695,9 +698,7 @@ mod tests { let program_id = Pubkey::default(); let keypair0 = Keypair::new(); let id0 = keypair0.pubkey(); - let mut tx = TransactionBuilder::default() - .push(Instruction::new(program_id, &0, vec![(id0, true)])) - .compile(); + let mut tx = Transaction::new(vec![Instruction::new(program_id, &0, vec![(id0, true)])]); tx.sign(&[&keypair0], Hash::default()); assert_eq!(tx.instructions[0], CompiledInstruction::new(0, &0, vec![0])); } diff --git a/sdk/src/transaction_builder.rs b/sdk/src/transaction_builder.rs index 81054dc93f..3bfba659b0 100644 --- a/sdk/src/transaction_builder.rs +++ b/sdk/src/transaction_builder.rs @@ -33,7 +33,6 @@ fn compile_instructions( } /// A utility for constructing transactions -#[derive(Default)] pub struct TransactionBuilder { instructions: Vec, } @@ -44,12 +43,6 @@ impl TransactionBuilder { Self { instructions } } - /// Add an instruction. - pub fn push(&mut self, instruction: Instruction) -> &mut Self { - self.instructions.push(instruction); - self - } - /// Return pubkeys referenced by all instructions, with the ones needing signatures first. /// No duplicates and order is preserved. fn keys(&self) -> (Vec, Vec) { @@ -107,10 +100,11 @@ mod tests { #[test] fn test_transaction_builder_unique_program_ids() { let program_id0 = Pubkey::default(); - let program_ids = TransactionBuilder::default() - .push(Instruction::new(program_id0, &0, vec![])) - .push(Instruction::new(program_id0, &0, vec![])) - .program_ids(); + let program_ids = TransactionBuilder::new(vec![ + Instruction::new(program_id0, &0, vec![]), + Instruction::new(program_id0, &0, vec![]), + ]) + .program_ids(); assert_eq!(program_ids, vec![program_id0]); } @@ -118,11 +112,12 @@ mod tests { fn test_transaction_builder_unique_program_ids_not_adjacent() { let program_id0 = Pubkey::default(); let program_id1 = Keypair::new().pubkey(); - let program_ids = TransactionBuilder::default() - .push(Instruction::new(program_id0, &0, vec![])) - .push(Instruction::new(program_id1, &0, vec![])) - .push(Instruction::new(program_id0, &0, vec![])) - .program_ids(); + let program_ids = TransactionBuilder::new(vec![ + Instruction::new(program_id0, &0, vec![]), + Instruction::new(program_id1, &0, vec![]), + Instruction::new(program_id0, &0, vec![]), + ]) + .program_ids(); assert_eq!(program_ids, vec![program_id0, program_id1]); } @@ -130,11 +125,12 @@ mod tests { fn test_transaction_builder_unique_program_ids_order_preserved() { let program_id0 = Keypair::new().pubkey(); let program_id1 = Pubkey::default(); // Key less than program_id0 - let program_ids = TransactionBuilder::default() - .push(Instruction::new(program_id0, &0, vec![])) - .push(Instruction::new(program_id1, &0, vec![])) - .push(Instruction::new(program_id0, &0, vec![])) - .program_ids(); + let program_ids = TransactionBuilder::new(vec![ + Instruction::new(program_id0, &0, vec![]), + Instruction::new(program_id1, &0, vec![]), + Instruction::new(program_id0, &0, vec![]), + ]) + .program_ids(); assert_eq!(program_ids, vec![program_id0, program_id1]); } @@ -142,10 +138,11 @@ mod tests { fn test_transaction_builder_unique_keys_both_signed() { let program_id = Pubkey::default(); let id0 = Pubkey::default(); - let keys = TransactionBuilder::default() - .push(Instruction::new(program_id, &0, vec![(id0, true)])) - .push(Instruction::new(program_id, &0, vec![(id0, true)])) - .keys(); + let keys = TransactionBuilder::new(vec![ + Instruction::new(program_id, &0, vec![(id0, true)]), + Instruction::new(program_id, &0, vec![(id0, true)]), + ]) + .keys(); assert_eq!(keys, (vec![id0], vec![])); } @@ -153,10 +150,11 @@ mod tests { fn test_transaction_builder_unique_keys_one_signed() { let program_id = Pubkey::default(); let id0 = Pubkey::default(); - let keys = TransactionBuilder::default() - .push(Instruction::new(program_id, &0, vec![(id0, false)])) - .push(Instruction::new(program_id, &0, vec![(id0, true)])) - .keys(); + let keys = TransactionBuilder::new(vec![ + Instruction::new(program_id, &0, vec![(id0, false)]), + Instruction::new(program_id, &0, vec![(id0, true)]), + ]) + .keys(); assert_eq!(keys, (vec![id0], vec![])); } @@ -165,10 +163,11 @@ mod tests { let program_id = Pubkey::default(); let id0 = Keypair::new().pubkey(); let id1 = Pubkey::default(); // Key less than id0 - let keys = TransactionBuilder::default() - .push(Instruction::new(program_id, &0, vec![(id0, false)])) - .push(Instruction::new(program_id, &0, vec![(id1, false)])) - .keys(); + let keys = TransactionBuilder::new(vec![ + Instruction::new(program_id, &0, vec![(id0, false)]), + Instruction::new(program_id, &0, vec![(id1, false)]), + ]) + .keys(); assert_eq!(keys, (vec![], vec![id0, id1])); } @@ -177,11 +176,12 @@ mod tests { let program_id = Pubkey::default(); let id0 = Pubkey::default(); let id1 = Keypair::new().pubkey(); - let keys = TransactionBuilder::default() - .push(Instruction::new(program_id, &0, vec![(id0, false)])) - .push(Instruction::new(program_id, &0, vec![(id1, false)])) - .push(Instruction::new(program_id, &0, vec![(id0, true)])) - .keys(); + let keys = TransactionBuilder::new(vec![ + Instruction::new(program_id, &0, vec![(id0, false)]), + Instruction::new(program_id, &0, vec![(id1, false)]), + Instruction::new(program_id, &0, vec![(id0, true)]), + ]) + .keys(); assert_eq!(keys, (vec![id0], vec![id1])); } @@ -190,10 +190,11 @@ mod tests { let program_id = Pubkey::default(); let id0 = Pubkey::default(); let id1 = Keypair::new().pubkey(); - let keys = TransactionBuilder::default() - .push(Instruction::new(program_id, &0, vec![(id0, false)])) - .push(Instruction::new(program_id, &0, vec![(id1, true)])) - .keys(); + let keys = TransactionBuilder::new(vec![ + Instruction::new(program_id, &0, vec![(id0, false)]), + Instruction::new(program_id, &0, vec![(id1, true)]), + ]) + .keys(); assert_eq!(keys, (vec![id1], vec![id0])); } @@ -202,13 +203,12 @@ mod tests { fn test_transaction_builder_signed_keys_len() { let program_id = Pubkey::default(); let id0 = Pubkey::default(); - let tx = TransactionBuilder::default() - .push(Instruction::new(program_id, &0, vec![(id0, false)])) - .compile(); + let tx = + TransactionBuilder::new(vec![Instruction::new(program_id, &0, vec![(id0, false)])]) + .compile(); assert_eq!(tx.signatures.capacity(), 0); - let tx = TransactionBuilder::default() - .push(Instruction::new(program_id, &0, vec![(id0, true)])) + let tx = TransactionBuilder::new(vec![Instruction::new(program_id, &0, vec![(id0, true)])]) .compile(); assert_eq!(tx.signatures.capacity(), 1); } @@ -220,11 +220,12 @@ mod tests { let id0 = Pubkey::default(); let keypair1 = Keypair::new(); let id1 = keypair1.pubkey(); - let tx = TransactionBuilder::default() - .push(Instruction::new(program_id0, &0, vec![(id0, false)])) - .push(Instruction::new(program_id1, &0, vec![(id1, true)])) - .push(Instruction::new(program_id0, &0, vec![(id1, false)])) - .compile(); + let tx = TransactionBuilder::new(vec![ + Instruction::new(program_id0, &0, vec![(id0, false)]), + Instruction::new(program_id1, &0, vec![(id1, true)]), + Instruction::new(program_id0, &0, vec![(id1, false)]), + ]) + .compile(); assert_eq!(tx.instructions[0], CompiledInstruction::new(0, &0, vec![1])); assert_eq!(tx.instructions[1], CompiledInstruction::new(1, &0, vec![0])); assert_eq!(tx.instructions[2], CompiledInstruction::new(0, &0, vec![0])); diff --git a/wallet/src/wallet.rs b/wallet/src/wallet.rs index dd3900b20b..3be1247c57 100644 --- a/wallet/src/wallet.rs +++ b/wallet/src/wallet.rs @@ -25,7 +25,6 @@ use solana_sdk::signature::{Keypair, KeypairUtil, Signature}; use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::timing::{DEFAULT_TICKS_PER_SLOT, NUM_TICKS_PER_SECOND}; use solana_sdk::transaction::Transaction; -use solana_sdk::transaction_builder::TransactionBuilder; use solana_vote_api::vote_instruction::VoteInstruction; use solana_vote_api::vote_transaction::VoteTransaction; use std::fs::File; @@ -442,20 +441,20 @@ fn process_configure_staking( authorized_voter_option: Option, ) -> ProcessResult { let recent_blockhash = get_recent_blockhash(&rpc_client)?; - let mut tx = TransactionBuilder::default(); + let mut ixs = vec![]; if let Some(delegate_id) = delegate_option { - tx.push(VoteInstruction::new_delegate_stake( + ixs.push(VoteInstruction::new_delegate_stake( &config.id.pubkey(), &delegate_id, )); } if let Some(authorized_voter_id) = authorized_voter_option { - tx.push(VoteInstruction::new_authorize_voter( + ixs.push(VoteInstruction::new_authorize_voter( &config.id.pubkey(), &authorized_voter_id, )); } - let mut tx = tx.compile(); + let mut tx = Transaction::new(ixs); tx.sign(&[&config.id], recent_blockhash); let signature_str = send_and_confirm_transaction(&rpc_client, &mut tx, &config.id)?; Ok(signature_str.to_string())