Remove keypairs from BankClient

Bring its interface closer to the other clients.
This commit is contained in:
Greg Fitzgerald
2019-03-27 07:34:01 -06:00
parent cecdb7061e
commit 3fc09fb23f
11 changed files with 303 additions and 237 deletions

View File

@ -8,44 +8,42 @@ use solana_sdk::transaction::{Transaction, TransactionError};
pub struct BankClient<'a> {
bank: &'a Bank,
keypairs: Vec<Keypair>,
}
impl<'a> BankClient<'a> {
pub fn new_with_keypairs(bank: &'a Bank, keypairs: Vec<Keypair>) -> Self {
assert!(!keypairs.is_empty());
Self { bank, keypairs }
pub fn new(bank: &'a Bank) -> Self {
Self { bank }
}
pub fn new(bank: &'a Bank, keypair: Keypair) -> Self {
Self::new_with_keypairs(bank, vec![keypair])
}
pub fn pubkey(&self) -> Pubkey {
self.keypairs[0].pubkey()
}
pub fn pubkeys(&self) -> Vec<Pubkey> {
self.keypairs.iter().map(|x| x.pubkey()).collect()
}
pub fn process_message(&self, message: Message) -> Result<(), TransactionError> {
let keypairs: Vec<_> = self.keypairs.iter().collect();
pub fn process_message(
&self,
keypairs: &[&Keypair],
message: Message,
) -> Result<(), TransactionError> {
let blockhash = self.bank.last_blockhash();
let transaction = Transaction::new(&keypairs, message, blockhash);
self.bank.process_transaction(&transaction)
}
/// Create and process a transaction from a single instruction.
pub fn process_instruction(&self, instruction: Instruction) -> Result<(), TransactionError> {
pub fn process_instruction(
&self,
keypair: &Keypair,
instruction: Instruction,
) -> Result<(), TransactionError> {
let message = Message::new(vec![instruction]);
self.process_message(message)
self.process_message(&[keypair], message)
}
/// Transfer lamports to pubkey
pub fn transfer(&self, lamports: u64, pubkey: &Pubkey) -> Result<(), TransactionError> {
let move_instruction = SystemInstruction::new_move(&self.pubkey(), pubkey, lamports);
self.process_instruction(move_instruction)
/// Transfer `lamports` from `keypair` to `pubkey`
pub fn transfer(
&self,
lamports: u64,
keypair: &Keypair,
pubkey: &Pubkey,
) -> Result<(), TransactionError> {
let move_instruction = SystemInstruction::new_move(&keypair.pubkey(), pubkey, lamports);
self.process_instruction(keypair, move_instruction)
}
}
@ -58,21 +56,22 @@ mod tests {
#[test]
fn test_bank_client_new_with_keypairs() {
let (genesis_block, john_doe_keypair) = GenesisBlock::new(10_000);
let john_pubkey = john_doe_keypair.pubkey();
let jane_doe_keypair = Keypair::new();
let doe_keypairs = vec![john_doe_keypair, jane_doe_keypair];
let jane_pubkey = jane_doe_keypair.pubkey();
let doe_keypairs = vec![&john_doe_keypair, &jane_doe_keypair];
let bank = Bank::new(&genesis_block);
let doe_client = BankClient::new_with_keypairs(&bank, doe_keypairs);
let jane_pubkey = doe_client.pubkeys()[1];
let bank_client = BankClient::new(&bank);
// Create 2-2 Multisig Move instruction.
let bob_pubkey = Keypair::new().pubkey();
let mut move_instruction =
SystemInstruction::new_move(&doe_client.pubkey(), &bob_pubkey, 42);
let mut move_instruction = SystemInstruction::new_move(&john_pubkey, &bob_pubkey, 42);
move_instruction
.accounts
.push(AccountMeta::new(jane_pubkey, true));
doe_client.process_instruction(move_instruction).unwrap();
let message = Message::new(vec![move_instruction]);
bank_client.process_message(&doe_keypairs, message).unwrap();
assert_eq!(bank.get_balance(&bob_pubkey), 42);
}
}

View File

@ -1,4 +1,3 @@
use crate::bank::Bank;
use crate::bank_client::BankClient;
use serde::Serialize;
use solana_sdk::instruction::{AccountMeta, Instruction};
@ -8,8 +7,8 @@ use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
pub fn load_program(
bank: &Bank,
from_client: &BankClient,
bank_client: &BankClient,
from_keypair: &Keypair,
loader_id: &Pubkey,
program: Vec<u8>,
) -> Pubkey {
@ -17,27 +16,31 @@ pub fn load_program(
let program_pubkey = program_keypair.pubkey();
let instruction = SystemInstruction::new_program_account(
&from_client.pubkey(),
&from_keypair.pubkey(),
&program_pubkey,
1,
program.len() as u64,
loader_id,
);
from_client.process_instruction(instruction).unwrap();
let program_client = BankClient::new(bank, program_keypair);
bank_client
.process_instruction(&from_keypair, instruction)
.unwrap();
let chunk_size = 256; // Size of chunk just needs to fit into tx
let mut offset = 0;
for chunk in program.chunks(chunk_size) {
let instruction =
LoaderInstruction::new_write(&program_pubkey, loader_id, offset, chunk.to_vec());
program_client.process_instruction(instruction).unwrap();
bank_client
.process_instruction(&program_keypair, instruction)
.unwrap();
offset += chunk_size as u32;
}
let instruction = LoaderInstruction::new_finalize(&program_pubkey, loader_id);
program_client.process_instruction(instruction).unwrap();
bank_client
.process_instruction(&program_keypair, instruction)
.unwrap();
program_pubkey
}

View File

@ -277,17 +277,17 @@ mod tests {
#[test]
fn test_system_unsigned_transaction() {
let (genesis_block, mint_keypair) = GenesisBlock::new(100);
let bank = Bank::new(&genesis_block);
let alice_client = BankClient::new(&bank, mint_keypair);
let alice_pubkey = alice_client.pubkey();
let mallory_client = BankClient::new(&bank, Keypair::new());
let mallory_pubkey = mallory_client.pubkey();
let (genesis_block, alice_keypair) = GenesisBlock::new(100);
let alice_pubkey = alice_keypair.pubkey();
let mallory_keypair = Keypair::new();
let mallory_pubkey = mallory_keypair.pubkey();
// Fund to account to bypass AccountNotFound error
alice_client.transfer(50, &mallory_pubkey).unwrap();
let bank = Bank::new(&genesis_block);
let bank_client = BankClient::new(&bank);
bank_client
.transfer(50, &alice_keypair, &mallory_pubkey)
.unwrap();
// Erroneously sign transaction with recipient account key
// No signature case is tested by bank `test_zero_signatures()`
@ -301,7 +301,7 @@ mod tests {
account_metas,
);
assert_eq!(
mallory_client.process_instruction(malicious_instruction),
bank_client.process_instruction(&mallory_keypair, malicious_instruction),
Err(TransactionError::InstructionError(
0,
InstructionError::MissingRequiredSignature