Migrate loader tests to BankClient

This commit is contained in:
Greg Fitzgerald 2019-03-21 08:14:14 -06:00
parent 58f071b7a0
commit d2415613de
7 changed files with 76 additions and 130 deletions

View File

@ -1,10 +1,10 @@
#[cfg(any(feature = "bpf_c", feature = "bpf_rust"))] #[cfg(any(feature = "bpf_c", feature = "bpf_rust"))]
mod bpf { mod bpf {
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_runtime::loader_utils::load_program; use solana_runtime::bank_client::BankClient;
use solana_runtime::loader_utils::{create_invoke_instruction, load_program};
use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::native_loader; use solana_sdk::native_loader;
use solana_sdk::transaction::Transaction;
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::path::PathBuf; use std::path::PathBuf;
@ -40,19 +40,12 @@ mod bpf {
let (genesis_block, mint_keypair) = GenesisBlock::new(50); let (genesis_block, mint_keypair) = GenesisBlock::new(50);
let bank = Bank::new(&genesis_block); let bank = Bank::new(&genesis_block);
let alice_client = BankClient::new(&bank, mint_keypair);
// Call user program // Call user program
let program_id = load_program(&bank, &mint_keypair, &bpf_loader::id(), elf); let program_id = load_program(&bank, &alice_client, &bpf_loader::id(), elf);
let tx = Transaction::new_signed( let instruction = create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
&mint_keypair, alice_client.process_instruction(instruction).unwrap();
&[],
&program_id,
&vec![1u8],
bank.last_blockhash(),
0,
);
bank.process_transaction(&tx).unwrap();
assert_eq!(bank.get_signature_status(&tx.signatures[0]), Some(Ok(())));
} }
#[test] #[test]
@ -76,26 +69,20 @@ mod bpf {
let (genesis_block, mint_keypair) = GenesisBlock::new(50); let (genesis_block, mint_keypair) = GenesisBlock::new(50);
let bank = Bank::new(&genesis_block); let bank = Bank::new(&genesis_block);
let alice_client = BankClient::new(&bank, mint_keypair);
let loader_id = load_program( let loader_id = load_program(
&bank, &bank,
&mint_keypair, &alice_client,
&native_loader::id(), &native_loader::id(),
"solana_bpf_loader".as_bytes().to_vec(), "solana_bpf_loader".as_bytes().to_vec(),
); );
// Call user program // Call user program
let program_id = load_program(&bank, &mint_keypair, &loader_id, elf); let program_id = load_program(&bank, &alice_client, &loader_id, elf);
let tx = Transaction::new_signed( let instruction =
&mint_keypair, create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
&[], alice_client.process_instruction(instruction).unwrap();
&program_id,
&vec![1u8],
bank.last_blockhash(),
0,
);
bank.process_transaction(&tx).unwrap();
assert_eq!(bank.get_signature_status(&tx.signatures[0]), Some(Ok(())));
} }
} }
} }
@ -123,25 +110,20 @@ mod bpf {
let (genesis_block, mint_keypair) = GenesisBlock::new(50); let (genesis_block, mint_keypair) = GenesisBlock::new(50);
let bank = Bank::new(&genesis_block); let bank = Bank::new(&genesis_block);
let alice_client = BankClient::new(&bank, mint_keypair);
let loader_id = load_program( let loader_id = load_program(
&bank, &bank,
&mint_keypair, &alice_client,
&native_loader::id(), &native_loader::id(),
"solana_bpf_loader".as_bytes().to_vec(), "solana_bpf_loader".as_bytes().to_vec(),
); );
// Call user program // Call user program
let program_id = load_program(&bank, &mint_keypair, &loader_id, elf); let program_id = load_program(&bank, &alice_client, &loader_id, elf);
let tx = Transaction::new_signed( let instruction =
&mint_keypair, create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
&[], alice_client.process_instruction(instruction).unwrap();
&program_id,
&vec![1u8],
bank.last_blockhash(),
0,
);
bank.process_transaction(&tx).unwrap();
assert_eq!(bank.get_signature_status(&tx.signatures[0]), Some(Ok(())));
} }
} }
} }

View File

@ -1,28 +1,23 @@
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_runtime::loader_utils::load_program; use solana_runtime::bank_client::BankClient;
use solana_runtime::loader_utils::{create_invoke_instruction, load_program};
use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::native_loader; use solana_sdk::native_loader;
use solana_sdk::transaction::{InstructionError, Transaction, TransactionError}; use solana_sdk::transaction::{InstructionError, TransactionError};
#[test] #[test]
fn test_program_native_failure() { fn test_program_native_failure() {
let (genesis_block, mint_keypair) = GenesisBlock::new(50); let (genesis_block, mint_keypair) = GenesisBlock::new(50);
let bank = Bank::new(&genesis_block); let bank = Bank::new(&genesis_block);
let alice_client = BankClient::new(&bank, mint_keypair);
let program = "failure".as_bytes().to_vec(); let program = "failure".as_bytes().to_vec();
let program_id = load_program(&bank, &mint_keypair, &native_loader::id(), program); let program_id = load_program(&bank, &alice_client, &native_loader::id(), program);
// Call user program // Call user program
let tx = Transaction::new_signed( let instruction = create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
&mint_keypair,
&[],
&program_id,
&1u8,
bank.last_blockhash(),
0,
);
assert_eq!( assert_eq!(
bank.process_transaction(&tx), alice_client.process_instruction(instruction),
Err(TransactionError::InstructionError( Err(TransactionError::InstructionError(
0, 0,
InstructionError::GenericError InstructionError::GenericError

View File

@ -1,8 +1,8 @@
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_runtime::loader_utils::load_program; use solana_runtime::bank_client::BankClient;
use solana_runtime::loader_utils::{create_invoke_instruction, load_program};
use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::native_loader; use solana_sdk::native_loader;
use solana_sdk::transaction::Transaction;
#[test] #[test]
fn test_program_native_noop() { fn test_program_native_noop() {
@ -10,19 +10,12 @@ fn test_program_native_noop() {
let (genesis_block, mint_keypair) = GenesisBlock::new(50); let (genesis_block, mint_keypair) = GenesisBlock::new(50);
let bank = Bank::new(&genesis_block); let bank = Bank::new(&genesis_block);
let alice_client = BankClient::new(&bank, mint_keypair);
let program = "noop".as_bytes().to_vec(); let program = "noop".as_bytes().to_vec();
let program_id = load_program(&bank, &mint_keypair, &native_loader::id(), program); let program_id = load_program(&bank, &alice_client, &native_loader::id(), program);
// Call user program // Call user program
let tx = Transaction::new_signed( let instruction = create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
&mint_keypair, alice_client.process_instruction(instruction).unwrap();
&[],
&program_id,
&1u8,
bank.last_blockhash(),
0,
);
bank.process_transaction(&tx).unwrap();
assert_eq!(bank.get_signature_status(&tx.signatures[0]), Some(Ok(())));
} }

View File

@ -1,42 +1,54 @@
use crate::bank::Bank; use crate::bank::Bank;
use solana_sdk::loader_transaction::LoaderTransaction; use crate::bank_client::BankClient;
use serde::Serialize;
use solana_sdk::loader_instruction::LoaderInstruction;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::transaction::{AccountMeta, Instruction};
pub fn load_program(bank: &Bank, from: &Keypair, loader_id: &Pubkey, program: Vec<u8>) -> Pubkey { pub fn load_program(
let program_account = Keypair::new(); bank: &Bank,
from_client: &BankClient,
loader_id: &Pubkey,
program: Vec<u8>,
) -> Pubkey {
let program_keypair = Keypair::new();
let program_pubkey = program_keypair.pubkey();
let tx = SystemTransaction::new_program_account( let instruction = SystemInstruction::new_program_account(
from, &from_client.pubkey(),
&program_account.pubkey(), &program_pubkey,
bank.last_blockhash(),
1, 1,
program.len() as u64, program.len() as u64,
loader_id, loader_id,
0,
); );
bank.process_transaction(&tx).unwrap(); from_client.process_instruction(instruction).unwrap();
assert_eq!(bank.get_signature_status(&tx.signatures[0]), Some(Ok(())));
let program_client = BankClient::new(bank, program_keypair);
let chunk_size = 256; // Size of chunk just needs to fit into tx let chunk_size = 256; // Size of chunk just needs to fit into tx
let mut offset = 0; let mut offset = 0;
for chunk in program.chunks(chunk_size) { for chunk in program.chunks(chunk_size) {
let tx = LoaderTransaction::new_write( let instruction =
&program_account, LoaderInstruction::new_write(&program_pubkey, loader_id, offset, chunk.to_vec());
loader_id, program_client.process_instruction(instruction).unwrap();
offset,
chunk.to_vec(),
bank.last_blockhash(),
0,
);
bank.process_transaction(&tx).unwrap();
offset += chunk_size as u32; offset += chunk_size as u32;
} }
let tx = LoaderTransaction::new_finalize(&program_account, loader_id, bank.last_blockhash(), 0); let instruction = LoaderInstruction::new_finalize(&program_pubkey, loader_id);
bank.process_transaction(&tx).unwrap(); program_client.process_instruction(instruction).unwrap();
assert_eq!(bank.get_signature_status(&tx.signatures[0]), Some(Ok(())));
program_account.pubkey() program_pubkey
}
// Return an Instruction that invokes `program_id` with `data` and required
// a signature from `from_pubkey`.
pub fn create_invoke_instruction<T: Serialize>(
from_pubkey: Pubkey,
program_id: Pubkey,
data: &T,
) -> Instruction {
let account_metas = vec![AccountMeta::new(from_pubkey, true)];
Instruction::new(program_id, data, account_metas)
} }

View File

@ -3,7 +3,6 @@ pub mod bpf_loader;
pub mod genesis_block; pub mod genesis_block;
pub mod hash; pub mod hash;
pub mod loader_instruction; pub mod loader_instruction;
pub mod loader_transaction;
pub mod native_loader; pub mod native_loader;
pub mod native_program; pub mod native_program;
pub mod packet; pub mod packet;

View File

@ -1,36 +0,0 @@
//! The `loader_transaction` module provides functionality for loading and calling a program
use crate::hash::Hash;
use crate::loader_instruction::LoaderInstruction;
use crate::pubkey::Pubkey;
use crate::signature::{Keypair, KeypairUtil};
use crate::transaction::Transaction;
pub struct LoaderTransaction {}
impl LoaderTransaction {
pub fn new_write(
from_keypair: &Keypair,
loader: &Pubkey,
offset: u32,
bytes: Vec<u8>,
recent_blockhash: Hash,
fee: u64,
) -> Transaction {
let write_instruction =
LoaderInstruction::new_write(&from_keypair.pubkey(), loader, offset, bytes);
let instructions = vec![write_instruction];
Transaction::new_signed_instructions(&[from_keypair], instructions, recent_blockhash, fee)
}
pub fn new_finalize(
from_keypair: &Keypair,
loader: &Pubkey,
recent_blockhash: Hash,
fee: u64,
) -> Transaction {
let finalize_instruction = LoaderInstruction::new_finalize(&from_keypair.pubkey(), loader);
let instructions = vec![finalize_instruction];
Transaction::new_signed_instructions(&[from_keypair], instructions, recent_blockhash, fee)
}
}

View File

@ -14,7 +14,7 @@ use solana_drone::drone::DRONE_PORT;
use solana_drone::drone_mock::request_airdrop_transaction; use solana_drone::drone_mock::request_airdrop_transaction;
use solana_sdk::bpf_loader; use solana_sdk::bpf_loader;
use solana_sdk::hash::Hash; use solana_sdk::hash::Hash;
use solana_sdk::loader_transaction::LoaderTransaction; use solana_sdk::loader_instruction::LoaderInstruction;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::rpc_port::DEFAULT_RPC_PORT; use solana_sdk::rpc_port::DEFAULT_RPC_PORT;
use solana_sdk::signature::{Keypair, KeypairUtil, Signature}; use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
@ -408,20 +408,21 @@ fn process_deploy(
.chunks(USERDATA_CHUNK_SIZE) .chunks(USERDATA_CHUNK_SIZE)
.zip(0..) .zip(0..)
.map(|(chunk, i)| { .map(|(chunk, i)| {
LoaderTransaction::new_write( let instruction = LoaderInstruction::new_write(
&program_id, &program_id.pubkey(),
&bpf_loader::id(), &bpf_loader::id(),
(i * USERDATA_CHUNK_SIZE) as u32, (i * USERDATA_CHUNK_SIZE) as u32,
chunk.to_vec(), chunk.to_vec(),
blockhash, );
0, Transaction::new_signed_instructions(&[&program_id], vec![instruction], blockhash, 0)
)
}) })
.collect(); .collect();
rpc_client.send_and_confirm_transactions(write_transactions, &program_id)?; rpc_client.send_and_confirm_transactions(write_transactions, &program_id)?;
trace!("Finalizing program account"); trace!("Finalizing program account");
let mut tx = LoaderTransaction::new_finalize(&program_id, &bpf_loader::id(), blockhash, 0); let instruction = LoaderInstruction::new_finalize(&program_id.pubkey(), &bpf_loader::id());
let mut tx =
Transaction::new_signed_instructions(&[&program_id], vec![instruction], blockhash, 0);
rpc_client rpc_client
.send_and_confirm_transaction(&mut tx, &program_id) .send_and_confirm_transaction(&mut tx, &program_id)
.map_err(|_| { .map_err(|_| {