Abandon Builder pattern

This commit is contained in:
Greg Fitzgerald
2019-03-15 10:54:56 -06:00
parent aca739b800
commit 24d9138067
10 changed files with 108 additions and 114 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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(),

View File

@ -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(

View File

@ -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;

View File

@ -167,26 +167,11 @@ pub struct Transaction {
}
impl Transaction {
pub fn new_signed<S: Serialize, T: KeypairUtil>(
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<Instruction>) -> Self {
TransactionBuilder::new(instructions).compile()
}
pub fn new_unsigned<T: Serialize>(
pub fn new_with_blockhash_and_fee<T: Serialize>(
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<S: Serialize, T: KeypairUtil>(
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]));
}

View File

@ -33,7 +33,6 @@ fn compile_instructions(
}
/// A utility for constructing transactions
#[derive(Default)]
pub struct TransactionBuilder {
instructions: Vec<Instruction>,
}
@ -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<Pubkey>, Vec<Pubkey>) {
@ -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]));

View File

@ -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<Pubkey>,
) -> 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())