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

View File

@ -1,28 +1,23 @@
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::native_loader;
use solana_sdk::transaction::{InstructionError, Transaction, TransactionError};
use solana_sdk::transaction::{InstructionError, TransactionError};
#[test]
fn test_program_native_failure() {
let (genesis_block, mint_keypair) = GenesisBlock::new(50);
let bank = Bank::new(&genesis_block);
let alice_client = BankClient::new(&bank, mint_keypair);
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
let tx = Transaction::new_signed(
&mint_keypair,
&[],
&program_id,
&1u8,
bank.last_blockhash(),
0,
);
let instruction = create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
assert_eq!(
bank.process_transaction(&tx),
alice_client.process_instruction(instruction),
Err(TransactionError::InstructionError(
0,
InstructionError::GenericError

View File

@ -1,8 +1,8 @@
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::native_loader;
use solana_sdk::transaction::Transaction;
#[test]
fn test_program_native_noop() {
@ -10,19 +10,12 @@ fn test_program_native_noop() {
let (genesis_block, mint_keypair) = GenesisBlock::new(50);
let bank = Bank::new(&genesis_block);
let alice_client = BankClient::new(&bank, mint_keypair);
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
let tx = Transaction::new_signed(
&mint_keypair,
&[],
&program_id,
&1u8,
bank.last_blockhash(),
0,
);
bank.process_transaction(&tx).unwrap();
assert_eq!(bank.get_signature_status(&tx.signatures[0]), Some(Ok(())));
let instruction = create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
alice_client.process_instruction(instruction).unwrap();
}

View File

@ -1,42 +1,54 @@
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::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 {
let program_account = Keypair::new();
pub fn load_program(
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(
from,
&program_account.pubkey(),
bank.last_blockhash(),
let instruction = SystemInstruction::new_program_account(
&from_client.pubkey(),
&program_pubkey,
1,
program.len() as u64,
loader_id,
0,
);
bank.process_transaction(&tx).unwrap();
assert_eq!(bank.get_signature_status(&tx.signatures[0]), Some(Ok(())));
from_client.process_instruction(instruction).unwrap();
let program_client = BankClient::new(bank, program_keypair);
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 tx = LoaderTransaction::new_write(
&program_account,
loader_id,
offset,
chunk.to_vec(),
bank.last_blockhash(),
0,
);
bank.process_transaction(&tx).unwrap();
let instruction =
LoaderInstruction::new_write(&program_pubkey, loader_id, offset, chunk.to_vec());
program_client.process_instruction(instruction).unwrap();
offset += chunk_size as u32;
}
let tx = LoaderTransaction::new_finalize(&program_account, loader_id, bank.last_blockhash(), 0);
bank.process_transaction(&tx).unwrap();
assert_eq!(bank.get_signature_status(&tx.signatures[0]), Some(Ok(())));
let instruction = LoaderInstruction::new_finalize(&program_pubkey, loader_id);
program_client.process_instruction(instruction).unwrap();
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 hash;
pub mod loader_instruction;
pub mod loader_transaction;
pub mod native_loader;
pub mod native_program;
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_sdk::bpf_loader;
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::rpc_port::DEFAULT_RPC_PORT;
use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
@ -408,20 +408,21 @@ fn process_deploy(
.chunks(USERDATA_CHUNK_SIZE)
.zip(0..)
.map(|(chunk, i)| {
LoaderTransaction::new_write(
&program_id,
let instruction = LoaderInstruction::new_write(
&program_id.pubkey(),
&bpf_loader::id(),
(i * USERDATA_CHUNK_SIZE) as u32,
chunk.to_vec(),
blockhash,
0,
)
);
Transaction::new_signed_instructions(&[&program_id], vec![instruction], blockhash, 0)
})
.collect();
rpc_client.send_and_confirm_transactions(write_transactions, &program_id)?;
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
.send_and_confirm_transaction(&mut tx, &program_id)
.map_err(|_| {