diff --git a/programs/budget_api/src/budget_expr.rs b/programs/budget_api/src/budget_expr.rs index 0bfc690aac..1e45ae82e0 100644 --- a/programs/budget_api/src/budget_expr.rs +++ b/programs/budget_api/src/budget_expr.rs @@ -70,16 +70,20 @@ impl BudgetExpr { witness: &Pubkey, lamports: u64, to: &Pubkey, - from: &Pubkey, + from: Option, ) -> Self { + if from.is_none() { + return Self::new_authorized_payment(witness, lamports, to); + } + let from = from.unwrap(); BudgetExpr::Or( ( Condition::Signature(*witness), Box::new(BudgetExpr::new_payment(lamports, to)), ), ( - Condition::Signature(*from), - Box::new(BudgetExpr::new_payment(lamports, from)), + Condition::Signature(from), + Box::new(BudgetExpr::new_payment(lamports, &from)), ), ) } @@ -119,16 +123,20 @@ impl BudgetExpr { dt_pubkey: &Pubkey, lamports: u64, to: &Pubkey, - from: &Pubkey, + from: Option, ) -> Self { + if from.is_none() { + return Self::new_future_payment(dt, dt_pubkey, lamports, to); + } + let from = from.unwrap(); BudgetExpr::Or( ( Condition::Timestamp(dt, *dt_pubkey), Box::new(Self::new_payment(lamports, to)), ), ( - Condition::Signature(*from), - Box::new(Self::new_payment(lamports, from)), + Condition::Signature(from), + Box::new(Self::new_payment(lamports, &from)), ), ) } @@ -213,7 +221,9 @@ mod tests { assert!(BudgetExpr::new_payment(42, &to).verify(42)); assert!(BudgetExpr::new_authorized_payment(&from, 42, &to).verify(42)); assert!(BudgetExpr::new_future_payment(dt, &from, 42, &to).verify(42)); - assert!(BudgetExpr::new_cancelable_future_payment(dt, &from, 42, &to, &from).verify(42)); + assert!( + BudgetExpr::new_cancelable_future_payment(dt, &from, 42, &to, Some(from)).verify(42) + ); } #[test] @@ -257,11 +267,11 @@ mod tests { let from = Pubkey::default(); let to = Pubkey::default(); - let mut expr = BudgetExpr::new_cancelable_future_payment(dt, &from, 42, &to, &from); + let mut expr = BudgetExpr::new_cancelable_future_payment(dt, &from, 42, &to, Some(from)); expr.apply_witness(&Witness::Timestamp(dt), &from); assert_eq!(expr, BudgetExpr::new_payment(42, &to)); - let mut expr = BudgetExpr::new_cancelable_future_payment(dt, &from, 42, &to, &from); + let mut expr = BudgetExpr::new_cancelable_future_payment(dt, &from, 42, &to, Some(from)); expr.apply_witness(&Witness::Signature, &from); assert_eq!(expr, BudgetExpr::new_payment(42, &from)); } diff --git a/programs/budget_api/src/budget_instruction.rs b/programs/budget_api/src/budget_instruction.rs index 5be7b38121..562c61b504 100644 --- a/programs/budget_api/src/budget_instruction.rs +++ b/programs/budget_api/src/budget_instruction.rs @@ -1,9 +1,13 @@ use crate::budget_expr::BudgetExpr; +use crate::budget_state::BudgetState; use crate::id; +use bincode::serialized_size; use chrono::prelude::{DateTime, Utc}; use serde_derive::{Deserialize, Serialize}; use solana_sdk::instruction::{AccountMeta, Instruction}; use solana_sdk::pubkey::Pubkey; +use solana_sdk::signature::{Keypair, KeypairUtil}; +use solana_sdk::system_instruction::SystemInstruction; /// A smart contract. #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] @@ -63,4 +67,88 @@ impl BudgetInstruction { } Instruction::new(id(), &BudgetInstruction::ApplySignature, account_metas) } + + pub fn new_account( + from: &Pubkey, + contract: &Pubkey, + lamports: u64, + expr: BudgetExpr, + ) -> Vec { + if !expr.verify(lamports) { + panic!("invalid budget expression"); + } + let space = serialized_size(&BudgetState::new(expr.clone())).unwrap(); + vec![ + SystemInstruction::new_program_account(&from, contract, lamports, space, &id()), + BudgetInstruction::new_initialize_account(contract, expr), + ] + } + + /// Create a new payment script. + pub fn new_payment(from: &Pubkey, to: &Pubkey, lamports: u64) -> Vec { + let contract = Keypair::new().pubkey(); + let expr = BudgetExpr::new_payment(lamports, to); + Self::new_account(from, &contract, lamports, expr) + } + + /// Create a future payment script. + pub fn new_on_date( + from: &Pubkey, + to: &Pubkey, + contract: &Pubkey, + dt: DateTime, + dt_pubkey: &Pubkey, + cancelable: Option, + lamports: u64, + ) -> Vec { + let expr = + BudgetExpr::new_cancelable_future_payment(dt, dt_pubkey, lamports, to, cancelable); + Self::new_account(from, contract, lamports, expr) + } + + /// Create a multisig payment script. + pub fn new_when_signed( + from: &Pubkey, + to: &Pubkey, + contract: &Pubkey, + witness: &Pubkey, + cancelable: Option, + lamports: u64, + ) -> Vec { + let expr = BudgetExpr::new_cancelable_authorized_payment(witness, lamports, to, cancelable); + Self::new_account(from, contract, lamports, expr) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::budget_expr::BudgetExpr; + + #[test] + fn test_budget_instruction_verify() { + let alice_pubkey = Keypair::new().pubkey(); + let bob_pubkey = Keypair::new().pubkey(); + BudgetInstruction::new_payment(&alice_pubkey, &bob_pubkey, 1); // No panic! indicates success. + } + + #[test] + #[should_panic] + fn test_budget_instruction_overspend() { + let alice_pubkey = Keypair::new().pubkey(); + let bob_pubkey = Keypair::new().pubkey(); + let budget_pubkey = Keypair::new().pubkey(); + let expr = BudgetExpr::new_payment(2, &bob_pubkey); + BudgetInstruction::new_account(&alice_pubkey, &budget_pubkey, 1, expr); + } + + #[test] + #[should_panic] + fn test_budget_instruction_underspend() { + let alice_pubkey = Keypair::new().pubkey(); + let bob_pubkey = Keypair::new().pubkey(); + let budget_pubkey = Keypair::new().pubkey(); + let expr = BudgetExpr::new_payment(1, &bob_pubkey); + BudgetInstruction::new_account(&alice_pubkey, &budget_pubkey, 2, expr); + } } diff --git a/programs/budget_api/src/budget_processor.rs b/programs/budget_api/src/budget_processor.rs index 48a24e0f54..f0edfdb4f0 100644 --- a/programs/budget_api/src/budget_processor.rs +++ b/programs/budget_api/src/budget_processor.rs @@ -144,7 +144,6 @@ pub fn process_instruction( mod tests { use super::*; use crate::budget_instruction::BudgetInstruction; - use crate::budget_script::BudgetScript; use crate::id; use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; @@ -166,8 +165,8 @@ mod tests { let alice_client = BankClient::new(&bank, mint_keypair); let alice_pubkey = alice_client.pubkey(); let bob_pubkey = Keypair::new().pubkey(); - let script = BudgetScript::pay(&alice_pubkey, &bob_pubkey, 100); - alice_client.process_script(script).unwrap(); + let instructions = BudgetInstruction::new_payment(&alice_pubkey, &bob_pubkey, 100); + alice_client.process_instructions(instructions).unwrap(); assert_eq!(bank.get_balance(&bob_pubkey), 100); } @@ -181,7 +180,7 @@ mod tests { let budget_pubkey = Keypair::new().pubkey(); let bob_pubkey = Keypair::new().pubkey(); let witness = Keypair::new().pubkey(); - let script = BudgetScript::pay_on_signature( + let instructions = BudgetInstruction::new_when_signed( &alice_pubkey, &bob_pubkey, &budget_pubkey, @@ -189,7 +188,7 @@ mod tests { None, 1, ); - alice_client.process_script(script).unwrap(); + alice_client.process_instructions(instructions).unwrap(); // Attack! Part 1: Sign a witness transaction with a random key. let mallory_client = BankClient::new(&bank, Keypair::new()); @@ -223,7 +222,7 @@ mod tests { let budget_pubkey = Keypair::new().pubkey(); let bob_pubkey = Keypair::new().pubkey(); let dt = Utc::now(); - let script = BudgetScript::pay_on_date( + let instructions = BudgetInstruction::new_on_date( &alice_pubkey, &bob_pubkey, &budget_pubkey, @@ -232,7 +231,7 @@ mod tests { None, 1, ); - alice_client.process_script(script).unwrap(); + alice_client.process_instructions(instructions).unwrap(); // Attack! Part 1: Sign a timestamp transaction with a random key. let mallory_client = BankClient::new(&bank, Keypair::new()); @@ -269,7 +268,7 @@ mod tests { let bob_pubkey = Keypair::new().pubkey(); let mallory_pubkey = Keypair::new().pubkey(); let dt = Utc::now(); - let script = BudgetScript::pay_on_date( + let instructions = BudgetInstruction::new_on_date( &alice_pubkey, &bob_pubkey, &budget_pubkey, @@ -278,7 +277,7 @@ mod tests { None, 1, ); - alice_client.process_script(script).unwrap(); + alice_client.process_instructions(instructions).unwrap(); assert_eq!(bank.get_balance(&alice_pubkey), 1); assert_eq!(bank.get_balance(&budget_pubkey), 1); @@ -328,7 +327,7 @@ mod tests { let bob_pubkey = Keypair::new().pubkey(); let dt = Utc::now(); - let script = BudgetScript::pay_on_date( + let instructions = BudgetInstruction::new_on_date( &alice_pubkey, &bob_pubkey, &budget_pubkey, @@ -337,7 +336,7 @@ mod tests { Some(alice_pubkey), 1, ); - alice_client.process_script(script).unwrap(); + alice_client.process_instructions(instructions).unwrap(); assert_eq!(bank.get_balance(&alice_pubkey), 2); assert_eq!(bank.get_balance(&budget_pubkey), 1); diff --git a/programs/budget_api/src/budget_script.rs b/programs/budget_api/src/budget_script.rs deleted file mode 100644 index f4a0220ccb..0000000000 --- a/programs/budget_api/src/budget_script.rs +++ /dev/null @@ -1,108 +0,0 @@ -use crate::budget_expr::BudgetExpr; -use crate::budget_instruction::BudgetInstruction; -use crate::budget_state::BudgetState; -use crate::id; -use bincode::serialized_size; -use chrono::prelude::{DateTime, Utc}; -use solana_sdk::pubkey::Pubkey; -use solana_sdk::script::Script; -use solana_sdk::signature::{Keypair, KeypairUtil}; -use solana_sdk::system_instruction::SystemInstruction; - -pub struct BudgetScript {} - -impl BudgetScript { - pub fn new_account( - from: &Pubkey, - contract: &Pubkey, - lamports: u64, - expr: BudgetExpr, - ) -> Script { - if !expr.verify(lamports) { - panic!("invalid budget expression"); - } - let space = serialized_size(&BudgetState::new(expr.clone())).unwrap(); - let instructions = vec![ - SystemInstruction::new_program_account(&from, contract, lamports, space, &id()), - BudgetInstruction::new_initialize_account(contract, expr), - ]; - Script::new(instructions) - } - - /// Create a new payment script. - pub fn pay(from: &Pubkey, to: &Pubkey, lamports: u64) -> Script { - let contract = Keypair::new().pubkey(); - let expr = BudgetExpr::new_payment(lamports, to); - Self::new_account(from, &contract, lamports, expr) - } - - /// Create a future payment script. - pub fn pay_on_date( - from: &Pubkey, - to: &Pubkey, - contract: &Pubkey, - dt: DateTime, - dt_pubkey: &Pubkey, - cancelable: Option, - lamports: u64, - ) -> Script { - let expr = if let Some(from) = &cancelable { - BudgetExpr::new_cancelable_future_payment(dt, dt_pubkey, lamports, to, from) - } else { - BudgetExpr::new_future_payment(dt, dt_pubkey, lamports, to) - }; - - Self::new_account(from, contract, lamports, expr) - } - - /// Create a multisig payment script. - pub fn pay_on_signature( - from: &Pubkey, - to: &Pubkey, - contract: &Pubkey, - witness: &Pubkey, - cancelable: Option, - lamports: u64, - ) -> Script { - let expr = if let Some(from) = &cancelable { - BudgetExpr::new_cancelable_authorized_payment(witness, lamports, to, from) - } else { - BudgetExpr::new_authorized_payment(witness, lamports, to) - }; - - Self::new_account(from, contract, lamports, expr) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::budget_expr::BudgetExpr; - - #[test] - fn test_budget_script_verify() { - let alice_pubkey = Keypair::new().pubkey(); - let bob_pubkey = Keypair::new().pubkey(); - BudgetScript::pay(&alice_pubkey, &bob_pubkey, 1); // No panic! indicates success. - } - - #[test] - #[should_panic] - fn test_budget_script_overspend() { - let alice_pubkey = Keypair::new().pubkey(); - let bob_pubkey = Keypair::new().pubkey(); - let budget_pubkey = Keypair::new().pubkey(); - let expr = BudgetExpr::new_payment(2, &bob_pubkey); - BudgetScript::new_account(&alice_pubkey, &budget_pubkey, 1, expr); - } - - #[test] - #[should_panic] - fn test_budget_script_underspend() { - let alice_pubkey = Keypair::new().pubkey(); - let bob_pubkey = Keypair::new().pubkey(); - let budget_pubkey = Keypair::new().pubkey(); - let expr = BudgetExpr::new_payment(1, &bob_pubkey); - BudgetScript::new_account(&alice_pubkey, &budget_pubkey, 2, expr); - } -} diff --git a/programs/budget_api/src/budget_transaction.rs b/programs/budget_api/src/budget_transaction.rs index c08a7ff494..643ffa94a4 100644 --- a/programs/budget_api/src/budget_transaction.rs +++ b/programs/budget_api/src/budget_transaction.rs @@ -1,29 +1,15 @@ //! The `budget_transaction` module provides functionality for creating Budget transactions. use crate::budget_instruction::BudgetInstruction; -use crate::budget_script::BudgetScript; use chrono::prelude::*; use solana_sdk::hash::Hash; use solana_sdk::pubkey::Pubkey; -use solana_sdk::script::Script; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::transaction::Transaction; pub struct BudgetTransaction {} impl BudgetTransaction { - fn new_signed( - from_keypair: &Keypair, - script: Script, - recent_blockhash: Hash, - fee: u64, - ) -> Transaction { - let mut tx = script.compile(); - tx.fee = fee; - tx.sign(&[from_keypair], recent_blockhash); - tx - } - /// Create and sign a new Transaction. Used for unit-testing. pub fn new_payment( from_keypair: &Keypair, @@ -32,8 +18,8 @@ impl BudgetTransaction { recent_blockhash: Hash, fee: u64, ) -> Transaction { - let script = BudgetScript::pay(&from_keypair.pubkey(), to, lamports); - Self::new_signed(from_keypair, script, recent_blockhash, fee) + let ixs = BudgetInstruction::new_payment(&from_keypair.pubkey(), to, lamports); + Transaction::new_signed_instructions(&[from_keypair], ixs, recent_blockhash, fee) } /// Create and sign a new Witness Timestamp. Used for unit-testing. @@ -46,9 +32,7 @@ impl BudgetTransaction { ) -> Transaction { let from = from_keypair.pubkey(); let ix = BudgetInstruction::new_apply_timestamp(&from, contract, to, dt); - let mut tx = Transaction::new(vec![ix]); - tx.sign(&[from_keypair], recent_blockhash); - tx + Transaction::new_signed_instructions(&[from_keypair], vec![ix], recent_blockhash, 0) } /// Create and sign a new Witness Signature. Used for unit-testing. @@ -60,9 +44,7 @@ impl BudgetTransaction { ) -> Transaction { let from = from_keypair.pubkey(); let ix = BudgetInstruction::new_apply_signature(&from, contract, to); - let mut tx = Transaction::new(vec![ix]); - tx.sign(&[from_keypair], recent_blockhash); - tx + Transaction::new_signed_instructions(&[from_keypair], vec![ix], recent_blockhash, 0) } /// Create and sign a postdated Transaction. Used for unit-testing. @@ -76,7 +58,7 @@ impl BudgetTransaction { lamports: u64, recent_blockhash: Hash, ) -> Transaction { - let script = BudgetScript::pay_on_date( + let ixs = BudgetInstruction::new_on_date( &from_keypair.pubkey(), to, contract, @@ -85,7 +67,7 @@ impl BudgetTransaction { cancelable, lamports, ); - Self::new_signed(from_keypair, script, recent_blockhash, 0) + Transaction::new_signed_instructions(&[from_keypair], ixs, recent_blockhash, 0) } /// Create and sign a multisig Transaction. @@ -98,7 +80,7 @@ impl BudgetTransaction { lamports: u64, recent_blockhash: Hash, ) -> Transaction { - let script = BudgetScript::pay_on_signature( + let ixs = BudgetInstruction::new_when_signed( &from_keypair.pubkey(), to, contract, @@ -106,6 +88,6 @@ impl BudgetTransaction { cancelable, lamports, ); - Self::new_signed(from_keypair, script, recent_blockhash, 0) + Transaction::new_signed_instructions(&[from_keypair], ixs, recent_blockhash, 0) } } diff --git a/programs/budget_api/src/lib.rs b/programs/budget_api/src/lib.rs index 034f2f3d4a..59a66e87e2 100644 --- a/programs/budget_api/src/lib.rs +++ b/programs/budget_api/src/lib.rs @@ -1,7 +1,6 @@ pub mod budget_expr; pub mod budget_instruction; pub mod budget_processor; -pub mod budget_script; pub mod budget_state; pub mod budget_transaction; pub mod payment_plan; diff --git a/programs/config_api/src/config_processor.rs b/programs/config_api/src/config_processor.rs index 8bece35eea..ba22e5ba7a 100644 --- a/programs/config_api/src/config_processor.rs +++ b/programs/config_api/src/config_processor.rs @@ -34,9 +34,9 @@ mod tests { use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; use solana_sdk::genesis_block::GenesisBlock; - use solana_sdk::script::Script; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction::SystemInstruction; + use solana_sdk::transaction::Transaction; #[derive(Serialize, Deserialize, Default, Debug, PartialEq)] struct MyConfig { @@ -131,8 +131,7 @@ mod tests { let instruction = ConfigInstruction::new_store(&from_pubkey, &config_pubkey, &my_config); // Replace instruction data with a vector that's too large - let script = Script::new(vec![instruction]); - let mut transaction = script.compile(); + let mut transaction = Transaction::new(vec![instruction]); transaction.instructions[0].data = vec![0; 123]; config_client.process_transaction(transaction).unwrap_err(); } @@ -154,8 +153,7 @@ mod tests { ConfigInstruction::new_store(&from_pubkey, &config_pubkey, &my_config); // Don't sign the transaction with `config_client` - let script = Script::new(vec![move_instruction, store_instruction]); - let mut transaction = script.compile(); + let mut transaction = Transaction::new(vec![move_instruction, store_instruction]); transaction.sign_unchecked(&[&system_keypair], bank.last_blockhash()); let system_client = BankClient::new(&bank, system_keypair); system_client.process_transaction(transaction).unwrap_err(); diff --git a/programs/vote_api/src/lib.rs b/programs/vote_api/src/lib.rs index 254c41d129..06b43641aa 100644 --- a/programs/vote_api/src/lib.rs +++ b/programs/vote_api/src/lib.rs @@ -1,6 +1,5 @@ pub mod vote_instruction; pub mod vote_processor; -pub mod vote_script; pub mod vote_state; pub mod vote_transaction; diff --git a/programs/vote_api/src/vote_instruction.rs b/programs/vote_api/src/vote_instruction.rs index 5e1c23cc93..82c73a6cc3 100644 --- a/programs/vote_api/src/vote_instruction.rs +++ b/programs/vote_api/src/vote_instruction.rs @@ -1,7 +1,10 @@ use crate::id; +use crate::vote_state::VoteState; use serde_derive::{Deserialize, Serialize}; use solana_sdk::instruction::{AccountMeta, Instruction}; use solana_sdk::pubkey::Pubkey; +use solana_sdk::system_instruction::SystemInstruction; +use solana_sdk::transaction::{AccountMeta, Instruction}; #[derive(Serialize, Default, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct Vote { @@ -32,6 +35,13 @@ pub enum VoteInstruction { } impl VoteInstruction { + pub fn new_account(from_id: &Pubkey, staker_id: &Pubkey, lamports: u64) -> Vec { + let space = VoteState::max_size() as u64; + let create_ix = + SystemInstruction::new_program_account(&from_id, staker_id, lamports, space, &id()); + let init_ix = VoteInstruction::new_initialize_account(staker_id); + vec![create_ix, init_ix] + } pub fn new_clear_credits(vote_id: &Pubkey) -> Instruction { let account_metas = vec![AccountMeta::new(*vote_id, true)]; Instruction::new(id(), &VoteInstruction::ClearCredits, account_metas) diff --git a/programs/vote_api/src/vote_processor.rs b/programs/vote_api/src/vote_processor.rs index ea586522b0..03bf660086 100644 --- a/programs/vote_api/src/vote_processor.rs +++ b/programs/vote_api/src/vote_processor.rs @@ -46,7 +46,6 @@ mod tests { use super::*; use crate::id; use crate::vote_instruction::{Vote, VoteInstruction}; - use crate::vote_script::VoteScript; use crate::vote_state::VoteState; use solana_runtime::bank::{Bank, Result}; use solana_runtime::bank_client::BankClient; @@ -69,8 +68,8 @@ mod tests { vote_id: &Pubkey, lamports: u64, ) -> Result<()> { - let script = VoteScript::new_account(&bank_client.pubkey(), vote_id, lamports); - bank_client.process_script(script) + let ixs = VoteInstruction::new_account(&bank_client.pubkey(), vote_id, lamports); + bank_client.process_instructions(ixs) } fn create_vote_account_with_delegate( @@ -79,10 +78,10 @@ mod tests { lamports: u64, ) -> Result<()> { let vote_id = bank_client.pubkeys()[1]; - let mut script = VoteScript::new_account(&bank_client.pubkey(), &vote_id, lamports); + let mut ixs = VoteInstruction::new_account(&bank_client.pubkey(), &vote_id, lamports); let delegate_ix = VoteInstruction::new_delegate_stake(&vote_id, delegate_id); - script.push(delegate_ix); - bank_client.process_script(script) + ixs.push(delegate_ix); + bank_client.process_instructions(ixs) } fn submit_vote( diff --git a/programs/vote_api/src/vote_script.rs b/programs/vote_api/src/vote_script.rs deleted file mode 100644 index 2bcca48102..0000000000 --- a/programs/vote_api/src/vote_script.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! The `vote_script` module provides functionality for creating vote scripts. - -use crate::id; -use crate::vote_instruction::VoteInstruction; -use crate::vote_state::VoteState; -use solana_sdk::pubkey::Pubkey; -use solana_sdk::script::Script; -use solana_sdk::system_instruction::SystemInstruction; - -pub struct VoteScript; - -impl VoteScript { - /// Fund or create the staking account with lamports - pub fn new_account(from_id: &Pubkey, staker_id: &Pubkey, lamports: u64) -> Script { - let space = VoteState::max_size() as u64; - let create_ix = - SystemInstruction::new_program_account(&from_id, staker_id, lamports, space, &id()); - let init_ix = VoteInstruction::new_initialize_account(staker_id); - Script::new(vec![create_ix, init_ix]) - } -} diff --git a/programs/vote_api/src/vote_transaction.rs b/programs/vote_api/src/vote_transaction.rs index 78b5338436..02f65c8fc1 100644 --- a/programs/vote_api/src/vote_transaction.rs +++ b/programs/vote_api/src/vote_transaction.rs @@ -1,7 +1,6 @@ //! The `vote_transaction` module provides functionality for creating vote transactions. use crate::vote_instruction::{Vote, VoteInstruction}; -use crate::vote_script::VoteScript; use crate::vote_state::VoteState; use crate::{check_id, id}; use bincode::deserialize; @@ -38,7 +37,8 @@ impl VoteTransaction { fee: u64, ) -> Transaction { let from_id = from_keypair.pubkey(); - let mut tx = VoteScript::new_account(&from_id, staker_id, lamports).compile(); + let ixs = VoteInstruction::new_account(&from_id, staker_id, lamports); + let mut tx = Transaction::new(ixs); tx.fee = fee; tx.sign(&[from_keypair], recent_blockhash); tx diff --git a/runtime/src/bank_client.rs b/runtime/src/bank_client.rs index 2a4ef1c5f0..d1c32c8e34 100644 --- a/runtime/src/bank_client.rs +++ b/runtime/src/bank_client.rs @@ -1,7 +1,6 @@ use crate::bank::Bank; use solana_sdk::instruction::Instruction; use solana_sdk::pubkey::Pubkey; -use solana_sdk::script::Script; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::transaction::{Transaction, TransactionError}; @@ -39,17 +38,12 @@ impl<'a> BankClient<'a> { self.bank.process_transaction(&tx) } - /// Create and process a transaction. - pub fn process_script(&self, script: Script) -> Result<(), TransactionError> { - self.process_transaction(script.compile()) - } - /// Create and process a transaction from a list of instructions. pub fn process_instructions( &self, instructions: Vec, ) -> Result<(), TransactionError> { - self.process_script(Script::new(instructions)) + self.process_transaction(Transaction::new(instructions)) } /// Create and process a transaction from a single instruction. diff --git a/runtime/src/system_program.rs b/runtime/src/system_program.rs index 435d18db55..ff591fa0e5 100644 --- a/runtime/src/system_program.rs +++ b/runtime/src/system_program.rs @@ -109,7 +109,6 @@ mod tests { use solana_sdk::account::Account; use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::instruction::{AccountMeta, Instruction, InstructionError}; - use solana_sdk::script::Script; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::system_program; @@ -296,13 +295,13 @@ mod tests { AccountMeta::new(alice_pubkey, false), AccountMeta::new(mallory_pubkey, true), ]; - let malicious_script = Script::new(vec![Instruction::new( + let malicious_instruction = Instruction::new( system_program::id(), &SystemInstruction::Move { lamports: 10 }, account_metas, - )]); + ); assert_eq!( - mallory_client.process_script(malicious_script), + mallory_client.process_instruction(malicious_instruction), Err(TransactionError::InstructionError( 0, InstructionError::MissingRequiredSignature diff --git a/sdk/src/script.rs b/sdk/src/instruction_compiler.rs similarity index 91% rename from sdk/src/script.rs rename to sdk/src/instruction_compiler.rs index 2301ca8666..87a6843313 100644 --- a/sdk/src/script.rs +++ b/sdk/src/instruction_compiler.rs @@ -1,4 +1,4 @@ -//! A library for building scripts and compiling them into transactions. +//! A library for compiling instructions use crate::hash::Hash; use crate::instruction::{CompiledInstruction, Instruction}; @@ -39,20 +39,16 @@ fn compile_instructions( } /// A utility for constructing transactions -pub struct Script { +pub struct InstructionCompiler { instructions: Vec, } -impl Script { +impl InstructionCompiler { /// Create a new unsigned transaction from a single instruction pub fn new(instructions: Vec) -> Self { Self { instructions } } - pub fn push(&mut self, instruction: Instruction) { - self.instructions.push(instruction); - } - /// Return pubkeys referenced by all instructions, with the ones needing signatures first. /// No duplicates and order is preserved. fn keys(&self) -> (Vec, Vec) { @@ -111,7 +107,7 @@ mod tests { #[test] fn test_transaction_builder_unique_program_ids() { let program_id0 = Pubkey::default(); - let program_ids = Script::new(vec![ + let program_ids = InstructionCompiler::new(vec![ Instruction::new(program_id0, &0, vec![]), Instruction::new(program_id0, &0, vec![]), ]) @@ -123,7 +119,7 @@ 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 = Script::new(vec![ + let program_ids = InstructionCompiler::new(vec![ Instruction::new(program_id0, &0, vec![]), Instruction::new(program_id1, &0, vec![]), Instruction::new(program_id0, &0, vec![]), @@ -136,7 +132,7 @@ 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 = Script::new(vec![ + let program_ids = InstructionCompiler::new(vec![ Instruction::new(program_id0, &0, vec![]), Instruction::new(program_id1, &0, vec![]), Instruction::new(program_id0, &0, vec![]), @@ -149,7 +145,7 @@ mod tests { fn test_transaction_builder_unique_keys_both_signed() { let program_id = Pubkey::default(); let id0 = Pubkey::default(); - let keys = Script::new(vec![ + let keys = InstructionCompiler::new(vec![ Instruction::new(program_id, &0, vec![AccountMeta::new(id0, true)]), Instruction::new(program_id, &0, vec![AccountMeta::new(id0, true)]), ]) @@ -161,7 +157,7 @@ mod tests { fn test_transaction_builder_unique_keys_one_signed() { let program_id = Pubkey::default(); let id0 = Pubkey::default(); - let keys = Script::new(vec![ + let keys = InstructionCompiler::new(vec![ Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]), Instruction::new(program_id, &0, vec![AccountMeta::new(id0, true)]), ]) @@ -174,7 +170,7 @@ mod tests { let program_id = Pubkey::default(); let id0 = Keypair::new().pubkey(); let id1 = Pubkey::default(); // Key less than id0 - let keys = Script::new(vec![ + let keys = InstructionCompiler::new(vec![ Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]), Instruction::new(program_id, &0, vec![AccountMeta::new(id1, false)]), ]) @@ -187,7 +183,7 @@ mod tests { let program_id = Pubkey::default(); let id0 = Pubkey::default(); let id1 = Keypair::new().pubkey(); - let keys = Script::new(vec![ + let keys = InstructionCompiler::new(vec![ Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]), Instruction::new(program_id, &0, vec![AccountMeta::new(id1, false)]), Instruction::new(program_id, &0, vec![AccountMeta::new(id0, true)]), @@ -201,7 +197,7 @@ mod tests { let program_id = Pubkey::default(); let id0 = Pubkey::default(); let id1 = Keypair::new().pubkey(); - let keys = Script::new(vec![ + let keys = InstructionCompiler::new(vec![ Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]), Instruction::new(program_id, &0, vec![AccountMeta::new(id1, true)]), ]) @@ -215,11 +211,11 @@ mod tests { let program_id = Pubkey::default(); let id0 = Pubkey::default(); let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, false)]); - let tx = Script::new(vec![ix]).compile(); + let tx = InstructionCompiler::new(vec![ix]).compile(); assert_eq!(tx.signatures.capacity(), 0); let ix = Instruction::new(program_id, &0, vec![AccountMeta::new(id0, true)]); - let tx = Script::new(vec![ix]).compile(); + let tx = InstructionCompiler::new(vec![ix]).compile(); assert_eq!(tx.signatures.capacity(), 1); } @@ -230,7 +226,7 @@ mod tests { let id0 = Pubkey::default(); let keypair1 = Keypair::new(); let id1 = keypair1.pubkey(); - let tx = Script::new(vec![ + let tx = InstructionCompiler::new(vec![ Instruction::new(program_id0, &0, vec![AccountMeta::new(id0, false)]), Instruction::new(program_id1, &0, vec![AccountMeta::new(id1, true)]), Instruction::new(program_id0, &0, vec![AccountMeta::new(id1, false)]), diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 725213a497..af5242de21 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -3,13 +3,13 @@ pub mod bpf_loader; pub mod genesis_block; pub mod hash; pub mod instruction; +mod instruction_compiler; pub mod loader_instruction; pub mod native_loader; pub mod native_program; pub mod packet; pub mod pubkey; pub mod rpc_port; -pub mod script; pub mod shortvec; pub mod signature; pub mod system_instruction; diff --git a/sdk/src/transaction.rs b/sdk/src/transaction.rs index 11b86ecc43..35f77d73e5 100644 --- a/sdk/src/transaction.rs +++ b/sdk/src/transaction.rs @@ -2,9 +2,9 @@ use crate::hash::{Hash, Hasher}; use crate::instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError}; +use crate::instruction_compiler::InstructionCompiler; use crate::packet::PACKET_DATA_SIZE; use crate::pubkey::Pubkey; -use crate::script::Script; use crate::shortvec::{deserialize_vec_with, encode_len, serialize_vec_with}; use crate::signature::{KeypairUtil, Signature}; use bincode::Error; @@ -73,7 +73,7 @@ pub struct Transaction { impl Transaction { pub fn new(instructions: Vec) -> Self { - Script::new(instructions).compile() + InstructionCompiler::new(instructions).compile() } pub fn new_signed_instructions(