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

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