Remove keypairs from BankClient
Bring its interface closer to the other clients.
This commit is contained in:
parent
cecdb7061e
commit
3fc09fb23f
|
@ -28,6 +28,7 @@ mod bpf {
|
|||
mod bpf_c {
|
||||
use super::*;
|
||||
use solana_sdk::bpf_loader;
|
||||
use solana_sdk::signature::KeypairUtil;
|
||||
use std::io::Read;
|
||||
|
||||
#[test]
|
||||
|
@ -38,14 +39,16 @@ mod bpf {
|
|||
let mut elf = Vec::new();
|
||||
file.read_to_end(&mut elf).unwrap();
|
||||
|
||||
let (genesis_block, mint_keypair) = GenesisBlock::new(50);
|
||||
let (genesis_block, alice_keypair) = GenesisBlock::new(50);
|
||||
let bank = Bank::new(&genesis_block);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
|
||||
// Call user program
|
||||
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();
|
||||
let program_id = load_program(&bank_client, &alice_keypair, &bpf_loader::id(), elf);
|
||||
let instruction = create_invoke_instruction(alice_keypair.pubkey(), program_id, &1u8);
|
||||
bank_client
|
||||
.process_instruction(&alice_keypair, instruction)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -67,22 +70,24 @@ mod bpf {
|
|||
let mut elf = Vec::new();
|
||||
file.read_to_end(&mut elf).unwrap();
|
||||
|
||||
let (genesis_block, mint_keypair) = GenesisBlock::new(50);
|
||||
let (genesis_block, alice_keypair) = GenesisBlock::new(50);
|
||||
let bank = Bank::new(&genesis_block);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
|
||||
let loader_id = load_program(
|
||||
&bank,
|
||||
&alice_client,
|
||||
&bank_client,
|
||||
&alice_keypair,
|
||||
&native_loader::id(),
|
||||
"solana_bpf_loader".as_bytes().to_vec(),
|
||||
);
|
||||
|
||||
// Call user program
|
||||
let program_id = load_program(&bank, &alice_client, &loader_id, elf);
|
||||
let program_id = load_program(&bank_client, &alice_keypair, &loader_id, elf);
|
||||
let instruction =
|
||||
create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
|
||||
alice_client.process_instruction(instruction).unwrap();
|
||||
create_invoke_instruction(alice_keypair.pubkey(), program_id, &1u8);
|
||||
bank_client
|
||||
.process_instruction(&alice_keypair, instruction)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,6 +99,7 @@ mod bpf {
|
|||
#[cfg(feature = "bpf_rust")]
|
||||
mod bpf_rust {
|
||||
use super::*;
|
||||
use solana_sdk::signature::KeypairUtil;
|
||||
use std::io::Read;
|
||||
|
||||
#[test]
|
||||
|
@ -108,22 +114,24 @@ mod bpf {
|
|||
let mut elf = Vec::new();
|
||||
file.read_to_end(&mut elf).unwrap();
|
||||
|
||||
let (genesis_block, mint_keypair) = GenesisBlock::new(50);
|
||||
let (genesis_block, alice_keypair) = GenesisBlock::new(50);
|
||||
let bank = Bank::new(&genesis_block);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
|
||||
let loader_id = load_program(
|
||||
&bank,
|
||||
&alice_client,
|
||||
&bank_client,
|
||||
&alice_keypair,
|
||||
&native_loader::id(),
|
||||
"solana_bpf_loader".as_bytes().to_vec(),
|
||||
);
|
||||
|
||||
// Call user program
|
||||
let program_id = load_program(&bank, &alice_client, &loader_id, elf);
|
||||
let program_id = load_program(&bank_client, &alice_keypair, &loader_id, elf);
|
||||
let instruction =
|
||||
create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
|
||||
alice_client.process_instruction(instruction).unwrap();
|
||||
create_invoke_instruction(alice_keypair.pubkey(), program_id, &1u8);
|
||||
bank_client
|
||||
.process_instruction(&alice_keypair, instruction)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,21 +162,23 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_budget_payment() {
|
||||
let (bank, mint_keypair) = create_bank(10_000);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let alice_pubkey = alice_client.pubkey();
|
||||
let (bank, alice_keypair) = create_bank(10_000);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
let alice_pubkey = alice_keypair.pubkey();
|
||||
let bob_pubkey = Keypair::new().pubkey();
|
||||
let instructions = BudgetInstruction::new_payment(&alice_pubkey, &bob_pubkey, 100);
|
||||
let message = Message::new(instructions);
|
||||
alice_client.process_message(message).unwrap();
|
||||
bank_client
|
||||
.process_message(&[&alice_keypair], message)
|
||||
.unwrap();
|
||||
assert_eq!(bank.get_balance(&bob_pubkey), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsigned_witness_key() {
|
||||
let (bank, mint_keypair) = create_bank(10_000);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let alice_pubkey = alice_client.pubkey();
|
||||
let (bank, alice_keypair) = create_bank(10_000);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
let alice_pubkey = alice_keypair.pubkey();
|
||||
|
||||
// Initialize BudgetState
|
||||
let budget_pubkey = Keypair::new().pubkey();
|
||||
|
@ -191,12 +193,16 @@ mod tests {
|
|||
1,
|
||||
);
|
||||
let message = Message::new(instructions);
|
||||
alice_client.process_message(message).unwrap();
|
||||
bank_client
|
||||
.process_message(&[&alice_keypair], message)
|
||||
.unwrap();
|
||||
|
||||
// Attack! Part 1: Sign a witness transaction with a random key.
|
||||
let mallory_client = BankClient::new(&bank, Keypair::new());
|
||||
let mallory_pubkey = mallory_client.pubkey();
|
||||
alice_client.transfer(1, &mallory_pubkey).unwrap();
|
||||
let mallory_keypair = Keypair::new();
|
||||
let mallory_pubkey = mallory_keypair.pubkey();
|
||||
bank_client
|
||||
.transfer(1, &alice_keypair, &mallory_pubkey)
|
||||
.unwrap();
|
||||
let instruction =
|
||||
BudgetInstruction::new_apply_signature(&mallory_pubkey, &budget_pubkey, &bob_pubkey);
|
||||
let mut message = Message::new(vec![instruction]);
|
||||
|
@ -207,7 +213,7 @@ mod tests {
|
|||
|
||||
// Ensure the transaction fails because of the unsigned key.
|
||||
assert_eq!(
|
||||
mallory_client.process_message(message),
|
||||
bank_client.process_message(&[&mallory_keypair], message),
|
||||
Err(TransactionError::InstructionError(
|
||||
0,
|
||||
InstructionError::MissingRequiredSignature
|
||||
|
@ -217,9 +223,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_unsigned_timestamp() {
|
||||
let (bank, mint_keypair) = create_bank(10_000);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let alice_pubkey = alice_client.pubkey();
|
||||
let (bank, alice_keypair) = create_bank(10_000);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
let alice_pubkey = alice_keypair.pubkey();
|
||||
|
||||
// Initialize BudgetState
|
||||
let budget_pubkey = Keypair::new().pubkey();
|
||||
|
@ -235,12 +241,16 @@ mod tests {
|
|||
1,
|
||||
);
|
||||
let message = Message::new(instructions);
|
||||
alice_client.process_message(message).unwrap();
|
||||
bank_client
|
||||
.process_message(&[&alice_keypair], message)
|
||||
.unwrap();
|
||||
|
||||
// Attack! Part 1: Sign a timestamp transaction with a random key.
|
||||
let mallory_client = BankClient::new(&bank, Keypair::new());
|
||||
let mallory_pubkey = mallory_client.pubkey();
|
||||
alice_client.transfer(1, &mallory_pubkey).unwrap();
|
||||
let mallory_keypair = Keypair::new();
|
||||
let mallory_pubkey = mallory_keypair.pubkey();
|
||||
bank_client
|
||||
.transfer(1, &alice_keypair, &mallory_pubkey)
|
||||
.unwrap();
|
||||
let instruction = BudgetInstruction::new_apply_timestamp(
|
||||
&mallory_pubkey,
|
||||
&budget_pubkey,
|
||||
|
@ -255,7 +265,7 @@ mod tests {
|
|||
|
||||
// Ensure the transaction fails because of the unsigned key.
|
||||
assert_eq!(
|
||||
mallory_client.process_message(message),
|
||||
bank_client.process_message(&[&mallory_keypair], message),
|
||||
Err(TransactionError::InstructionError(
|
||||
0,
|
||||
InstructionError::MissingRequiredSignature
|
||||
|
@ -265,9 +275,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_pay_on_date() {
|
||||
let (bank, mint_keypair) = create_bank(2);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let alice_pubkey = alice_client.pubkey();
|
||||
let (bank, alice_keypair) = create_bank(2);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
let alice_pubkey = alice_keypair.pubkey();
|
||||
let budget_pubkey = Keypair::new().pubkey();
|
||||
let bob_pubkey = Keypair::new().pubkey();
|
||||
let mallory_pubkey = Keypair::new().pubkey();
|
||||
|
@ -282,7 +292,9 @@ mod tests {
|
|||
1,
|
||||
);
|
||||
let message = Message::new(instructions);
|
||||
alice_client.process_message(message).unwrap();
|
||||
bank_client
|
||||
.process_message(&[&alice_keypair], message)
|
||||
.unwrap();
|
||||
assert_eq!(bank.get_balance(&alice_pubkey), 1);
|
||||
assert_eq!(bank.get_balance(&budget_pubkey), 1);
|
||||
|
||||
|
@ -298,7 +310,9 @@ mod tests {
|
|||
dt,
|
||||
);
|
||||
assert_eq!(
|
||||
alice_client.process_instruction(instruction).unwrap_err(),
|
||||
bank_client
|
||||
.process_instruction(&alice_keypair, instruction)
|
||||
.unwrap_err(),
|
||||
TransactionError::InstructionError(
|
||||
0,
|
||||
InstructionError::CustomError(serialize(&BudgetError::DestinationMissing).unwrap())
|
||||
|
@ -316,7 +330,9 @@ mod tests {
|
|||
// that pubkey's funds are now available.
|
||||
let instruction =
|
||||
BudgetInstruction::new_apply_timestamp(&alice_pubkey, &budget_pubkey, &bob_pubkey, dt);
|
||||
alice_client.process_instruction(instruction).unwrap();
|
||||
bank_client
|
||||
.process_instruction(&alice_keypair, instruction)
|
||||
.unwrap();
|
||||
assert_eq!(bank.get_balance(&alice_pubkey), 1);
|
||||
assert_eq!(bank.get_balance(&budget_pubkey), 0);
|
||||
assert_eq!(bank.get_balance(&bob_pubkey), 1);
|
||||
|
@ -325,9 +341,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_cancel_payment() {
|
||||
let (bank, mint_keypair) = create_bank(3);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let alice_pubkey = alice_client.pubkey();
|
||||
let (bank, alice_keypair) = create_bank(3);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
let alice_pubkey = alice_keypair.pubkey();
|
||||
let budget_pubkey = Keypair::new().pubkey();
|
||||
let bob_pubkey = Keypair::new().pubkey();
|
||||
let dt = Utc::now();
|
||||
|
@ -342,7 +358,9 @@ mod tests {
|
|||
1,
|
||||
);
|
||||
let message = Message::new(instructions);
|
||||
alice_client.process_message(message).unwrap();
|
||||
bank_client
|
||||
.process_message(&[&alice_keypair], message)
|
||||
.unwrap();
|
||||
assert_eq!(bank.get_balance(&alice_pubkey), 2);
|
||||
assert_eq!(bank.get_balance(&budget_pubkey), 1);
|
||||
|
||||
|
@ -351,14 +369,18 @@ mod tests {
|
|||
assert!(budget_state.is_pending());
|
||||
|
||||
// Attack! try to put the lamports into the wrong account with cancel
|
||||
let mallory_client = BankClient::new(&bank, Keypair::new());
|
||||
let mallory_pubkey = mallory_client.pubkey();
|
||||
alice_client.transfer(1, &mallory_pubkey).unwrap();
|
||||
let mallory_keypair = Keypair::new();
|
||||
let mallory_pubkey = mallory_keypair.pubkey();
|
||||
bank_client
|
||||
.transfer(1, &alice_keypair, &mallory_pubkey)
|
||||
.unwrap();
|
||||
assert_eq!(bank.get_balance(&alice_pubkey), 1);
|
||||
|
||||
let instruction =
|
||||
BudgetInstruction::new_apply_signature(&mallory_pubkey, &budget_pubkey, &bob_pubkey);
|
||||
mallory_client.process_instruction(instruction).unwrap();
|
||||
bank_client
|
||||
.process_instruction(&mallory_keypair, instruction)
|
||||
.unwrap();
|
||||
// nothing should be changed because apply witness didn't finalize a payment
|
||||
assert_eq!(bank.get_balance(&alice_pubkey), 1);
|
||||
assert_eq!(bank.get_balance(&budget_pubkey), 1);
|
||||
|
@ -367,7 +389,9 @@ mod tests {
|
|||
// Now, cancel the transaction. mint gets her funds back
|
||||
let instruction =
|
||||
BudgetInstruction::new_apply_signature(&alice_pubkey, &budget_pubkey, &alice_pubkey);
|
||||
alice_client.process_instruction(instruction).unwrap();
|
||||
bank_client
|
||||
.process_instruction(&alice_keypair, instruction)
|
||||
.unwrap();
|
||||
assert_eq!(bank.get_balance(&alice_pubkey), 2);
|
||||
assert_eq!(bank.get_account(&budget_pubkey), None);
|
||||
assert_eq!(bank.get_account(&bob_pubkey), None);
|
||||
|
|
|
@ -64,39 +64,37 @@ mod tests {
|
|||
(bank, mint_keypair)
|
||||
}
|
||||
|
||||
fn create_config_client(bank: &Bank, mint_keypair: Keypair) -> (BankClient, Pubkey, Pubkey) {
|
||||
let config_client =
|
||||
BankClient::new_with_keypairs(&bank, vec![Keypair::new(), Keypair::new()]);
|
||||
fn create_config_client(bank: &Bank, mint_keypair: Keypair) -> (BankClient, Keypair, Keypair) {
|
||||
let from_keypair = Keypair::new();
|
||||
let from_pubkey = from_keypair.pubkey();
|
||||
let config_keypair = Keypair::new();
|
||||
let config_pubkey = config_keypair.pubkey();
|
||||
|
||||
let from_pubkey = config_client.pubkeys()[0];
|
||||
let config_pubkey = config_client.pubkeys()[1];
|
||||
let bank_client = BankClient::new(&bank);
|
||||
bank_client
|
||||
.transfer(42, &mint_keypair, &from_pubkey)
|
||||
.unwrap();
|
||||
|
||||
let mint_client = BankClient::new(&bank, mint_keypair);
|
||||
mint_client
|
||||
.process_instruction(SystemInstruction::new_move(
|
||||
&mint_client.pubkey(),
|
||||
&from_pubkey,
|
||||
42,
|
||||
))
|
||||
.expect("new_move");
|
||||
|
||||
mint_client
|
||||
.process_instruction(ConfigInstruction::new_account::<MyConfig>(
|
||||
&mint_client.pubkey(),
|
||||
&config_pubkey,
|
||||
1,
|
||||
))
|
||||
bank_client
|
||||
.process_instruction(
|
||||
&mint_keypair,
|
||||
ConfigInstruction::new_account::<MyConfig>(
|
||||
&mint_keypair.pubkey(),
|
||||
&config_pubkey,
|
||||
1,
|
||||
),
|
||||
)
|
||||
.expect("new_account");
|
||||
|
||||
(config_client, from_pubkey, config_pubkey)
|
||||
(bank_client, from_keypair, config_keypair)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_process_create_ok() {
|
||||
solana_logger::setup();
|
||||
let (bank, from_keypair) = create_bank(10_000);
|
||||
let (config_client, _, _) = create_config_client(&bank, from_keypair);
|
||||
let config_account = bank.get_account(&config_client.pubkeys()[1]).unwrap();
|
||||
let (_bank_client, _, config_keypair) = create_config_client(&bank, from_keypair);
|
||||
let config_account = bank.get_account(&config_keypair.pubkey()).unwrap();
|
||||
assert_eq!(id(), config_account.owner);
|
||||
assert_eq!(
|
||||
MyConfig::default(),
|
||||
|
@ -108,11 +106,16 @@ mod tests {
|
|||
fn test_process_store_ok() {
|
||||
solana_logger::setup();
|
||||
let (bank, mint_keypair) = create_bank(10_000);
|
||||
let (config_client, from_pubkey, config_pubkey) = create_config_client(&bank, mint_keypair);
|
||||
let (bank_client, from_keypair, config_keypair) = create_config_client(&bank, mint_keypair);
|
||||
let config_pubkey = config_keypair.pubkey();
|
||||
|
||||
let my_config = MyConfig::new(42);
|
||||
let instruction = ConfigInstruction::new_store(&from_pubkey, &config_pubkey, &my_config);
|
||||
config_client.process_instruction(instruction).unwrap();
|
||||
let instruction =
|
||||
ConfigInstruction::new_store(&from_keypair.pubkey(), &config_pubkey, &my_config);
|
||||
let message = Message::new(vec![instruction]);
|
||||
bank_client
|
||||
.process_message(&[&from_keypair, &config_keypair], message)
|
||||
.unwrap();
|
||||
|
||||
let config_account = bank.get_account(&config_pubkey).unwrap();
|
||||
assert_eq!(
|
||||
|
@ -125,15 +128,22 @@ mod tests {
|
|||
fn test_process_store_fail_instruction_data_too_large() {
|
||||
solana_logger::setup();
|
||||
let (bank, mint_keypair) = create_bank(10_000);
|
||||
let (config_client, from_pubkey, config_pubkey) = create_config_client(&bank, mint_keypair);
|
||||
let (bank_client, from_keypair, config_keypair) = create_config_client(&bank, mint_keypair);
|
||||
|
||||
let my_config = MyConfig::new(42);
|
||||
let instruction = ConfigInstruction::new_store(&from_pubkey, &config_pubkey, &my_config);
|
||||
|
||||
// Replace instruction data with a vector that's too large
|
||||
let mut message = Message::new(vec![instruction]);
|
||||
message.instructions[0].data = vec![0; 123];
|
||||
config_client.process_message(message).unwrap_err();
|
||||
let mut instruction = ConfigInstruction::new_store(
|
||||
&from_keypair.pubkey(),
|
||||
&config_keypair.pubkey(),
|
||||
&my_config,
|
||||
);
|
||||
instruction.data = vec![0; 123];
|
||||
|
||||
let message = Message::new(vec![instruction]);
|
||||
bank_client
|
||||
.process_message(&[&from_keypair, &config_keypair], message)
|
||||
.unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -143,19 +153,22 @@ mod tests {
|
|||
let system_keypair = Keypair::new();
|
||||
let system_pubkey = system_keypair.pubkey();
|
||||
bank.transfer(42, &mint_keypair, &system_pubkey).unwrap();
|
||||
let (_config_client, from_pubkey, config_pubkey) =
|
||||
create_config_client(&bank, mint_keypair);
|
||||
let (bank_client, from_keypair, config_keypair) = create_config_client(&bank, mint_keypair);
|
||||
|
||||
let move_instruction = SystemInstruction::new_move(&system_pubkey, &Pubkey::default(), 42);
|
||||
let my_config = MyConfig::new(42);
|
||||
let mut store_instruction =
|
||||
ConfigInstruction::new_store(&from_pubkey, &config_pubkey, &my_config);
|
||||
let mut store_instruction = ConfigInstruction::new_store(
|
||||
&from_keypair.pubkey(),
|
||||
&config_keypair.pubkey(),
|
||||
&my_config,
|
||||
);
|
||||
store_instruction.accounts[0].is_signer = false;
|
||||
store_instruction.accounts[1].is_signer = false;
|
||||
|
||||
// Don't sign the transaction with `config_client`
|
||||
let message = Message::new(vec![move_instruction, store_instruction]);
|
||||
let system_client = BankClient::new(&bank, system_keypair);
|
||||
system_client.process_message(message).unwrap_err();
|
||||
bank_client
|
||||
.process_message(&[&system_keypair], message)
|
||||
.unwrap_err();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -509,68 +509,61 @@ mod test {
|
|||
(bank, mint_keypair)
|
||||
}
|
||||
|
||||
fn create_client(bank: &Bank, mint_keypair: Keypair) -> (BankClient, Pubkey) {
|
||||
fn create_client(bank: &Bank, mint_keypair: Keypair) -> (BankClient, Keypair) {
|
||||
let owner = Keypair::new();
|
||||
let pubkey = owner.pubkey();
|
||||
let mint_client = BankClient::new(&bank, mint_keypair);
|
||||
mint_client
|
||||
.process_instruction(SystemInstruction::new_move(
|
||||
&mint_client.pubkey(),
|
||||
&owner.pubkey(),
|
||||
42,
|
||||
))
|
||||
.expect("new_move");
|
||||
let bank_client = BankClient::new(&bank);
|
||||
bank_client
|
||||
.transfer(42, &mint_keypair, &owner.pubkey())
|
||||
.unwrap();
|
||||
|
||||
let client = BankClient::new(&bank, owner);
|
||||
|
||||
(client, pubkey)
|
||||
(bank_client, owner)
|
||||
}
|
||||
|
||||
fn create_account(client: &BankClient, owner: &Pubkey) -> Pubkey {
|
||||
fn create_account(client: &BankClient, owner: &Keypair) -> Pubkey {
|
||||
let new = Keypair::new().pubkey();
|
||||
let instruction = SystemInstruction::new_program_account(
|
||||
&owner,
|
||||
&owner.pubkey(),
|
||||
&new,
|
||||
1,
|
||||
mem::size_of::<ExchangeState>() as u64,
|
||||
&id(),
|
||||
);
|
||||
client
|
||||
.process_instruction(instruction)
|
||||
.process_instruction(&owner, instruction)
|
||||
.expect(&format!("{}:{}", line!(), file!()));
|
||||
new
|
||||
}
|
||||
|
||||
fn create_token_account(client: &BankClient, owner: &Pubkey) -> Pubkey {
|
||||
fn create_token_account(client: &BankClient, owner: &Keypair) -> Pubkey {
|
||||
let new = Keypair::new().pubkey();
|
||||
let instruction = SystemInstruction::new_program_account(
|
||||
&owner,
|
||||
&owner.pubkey(),
|
||||
&new,
|
||||
1,
|
||||
mem::size_of::<ExchangeState>() as u64,
|
||||
&id(),
|
||||
);
|
||||
client
|
||||
.process_instruction(instruction)
|
||||
.process_instruction(owner, instruction)
|
||||
.expect(&format!("{}:{}", line!(), file!()));
|
||||
let instruction = ExchangeInstruction::new_account_request(&owner, &new);
|
||||
let instruction = ExchangeInstruction::new_account_request(&owner.pubkey(), &new);
|
||||
client
|
||||
.process_instruction(instruction)
|
||||
.process_instruction(owner, instruction)
|
||||
.expect(&format!("{}:{}", line!(), file!()));
|
||||
new
|
||||
}
|
||||
|
||||
fn transfer(client: &BankClient, owner: &Pubkey, to: &Pubkey, token: Token, tokens: u64) {
|
||||
fn transfer(client: &BankClient, owner: &Keypair, to: &Pubkey, token: Token, tokens: u64) {
|
||||
let instruction =
|
||||
ExchangeInstruction::new_transfer_request(owner, to, &id(), token, tokens);
|
||||
ExchangeInstruction::new_transfer_request(&owner.pubkey(), to, &id(), token, tokens);
|
||||
client
|
||||
.process_instruction(instruction)
|
||||
.process_instruction(owner, instruction)
|
||||
.expect(&format!("{}:{}", line!(), file!()));
|
||||
}
|
||||
|
||||
fn trade(
|
||||
client: &BankClient,
|
||||
owner: &Pubkey,
|
||||
owner: &Keypair,
|
||||
direction: Direction,
|
||||
pair: TokenPair,
|
||||
from_token: Token,
|
||||
|
@ -584,7 +577,7 @@ mod test {
|
|||
transfer(&client, &owner, &src, from_token, src_tokens);
|
||||
|
||||
let instruction = ExchangeInstruction::new_trade_request(
|
||||
owner,
|
||||
&owner.pubkey(),
|
||||
&trade,
|
||||
direction,
|
||||
pair,
|
||||
|
@ -594,7 +587,7 @@ mod test {
|
|||
&dst,
|
||||
);
|
||||
client
|
||||
.process_instruction(instruction)
|
||||
.process_instruction(owner, instruction)
|
||||
.expect(&format!("{}:{}", line!(), file!()));
|
||||
(trade, src, dst)
|
||||
}
|
||||
|
@ -620,7 +613,7 @@ mod test {
|
|||
// Check results
|
||||
|
||||
assert_eq!(
|
||||
TokenAccountInfo::default().owner(&owner),
|
||||
TokenAccountInfo::default().owner(&owner.pubkey()),
|
||||
ExchangeProcessor::deserialize_account(&new_account.data[..]).unwrap()
|
||||
);
|
||||
}
|
||||
|
@ -632,9 +625,9 @@ mod test {
|
|||
let (client, owner) = create_client(&bank, mint_keypair);
|
||||
|
||||
let new = create_token_account(&client, &owner);
|
||||
let instruction = ExchangeInstruction::new_account_request(&owner, &new);
|
||||
let instruction = ExchangeInstruction::new_account_request(&owner.pubkey(), &new);
|
||||
client
|
||||
.process_instruction(instruction)
|
||||
.process_instruction(&owner, instruction)
|
||||
.expect_err(&format!("{}:{}", line!(), file!()));
|
||||
}
|
||||
|
||||
|
@ -647,9 +640,9 @@ mod test {
|
|||
let new = create_token_account(&client, &owner);
|
||||
|
||||
let instruction =
|
||||
ExchangeInstruction::new_transfer_request(&owner, &new, &id(), Token::A, 42);
|
||||
ExchangeInstruction::new_transfer_request(&owner.pubkey(), &new, &id(), Token::A, 42);
|
||||
client
|
||||
.process_instruction(instruction)
|
||||
.process_instruction(&owner, instruction)
|
||||
.expect(&format!("{}:{}", line!(), file!()));
|
||||
|
||||
let new_account = bank.get_account(&new).unwrap();
|
||||
|
@ -658,7 +651,7 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
TokenAccountInfo::default()
|
||||
.owner(&owner)
|
||||
.owner(&owner.pubkey())
|
||||
.tokens(42, 0, 0, 0),
|
||||
ExchangeProcessor::deserialize_account(&new_account.data[..]).unwrap()
|
||||
);
|
||||
|
@ -689,7 +682,7 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
TradeOrderInfo {
|
||||
owner: owner,
|
||||
owner: owner.pubkey(),
|
||||
direction: Direction::To,
|
||||
pair: TokenPair::AB,
|
||||
tokens: 2,
|
||||
|
@ -701,12 +694,14 @@ mod test {
|
|||
);
|
||||
assert_eq!(
|
||||
TokenAccountInfo::default()
|
||||
.owner(&owner)
|
||||
.owner(&owner.pubkey())
|
||||
.tokens(40, 0, 0, 0),
|
||||
ExchangeProcessor::deserialize_account(&src_account.data[..]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TokenAccountInfo::default().owner(&owner).tokens(0, 0, 0, 0),
|
||||
TokenAccountInfo::default()
|
||||
.owner(&owner.pubkey())
|
||||
.tokens(0, 0, 0, 0),
|
||||
ExchangeProcessor::deserialize_account(&dst_account.data[..]).unwrap()
|
||||
);
|
||||
}
|
||||
|
@ -741,7 +736,7 @@ mod test {
|
|||
);
|
||||
|
||||
let instruction = ExchangeInstruction::new_swap_request(
|
||||
&owner,
|
||||
&owner.pubkey(),
|
||||
&swap,
|
||||
&to_trade,
|
||||
&from_trade,
|
||||
|
@ -750,7 +745,7 @@ mod test {
|
|||
&profit,
|
||||
);
|
||||
client
|
||||
.process_instruction(instruction)
|
||||
.process_instruction(&owner, instruction)
|
||||
.expect(&format!("{}:{}", line!(), file!()));
|
||||
|
||||
let to_trade_account = bank.get_account(&to_trade).unwrap();
|
||||
|
@ -766,7 +761,7 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
TradeOrderInfo {
|
||||
owner: owner,
|
||||
owner: owner.pubkey(),
|
||||
direction: Direction::To,
|
||||
pair: TokenPair::AB,
|
||||
tokens: 1,
|
||||
|
@ -777,16 +772,20 @@ mod test {
|
|||
ExchangeProcessor::deserialize_trade(&to_trade_account.data[..]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TokenAccountInfo::default().owner(&owner).tokens(0, 0, 0, 0),
|
||||
TokenAccountInfo::default()
|
||||
.owner(&owner.pubkey())
|
||||
.tokens(0, 0, 0, 0),
|
||||
ExchangeProcessor::deserialize_account(&to_src_account.data[..]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TokenAccountInfo::default().owner(&owner).tokens(0, 2, 0, 0),
|
||||
TokenAccountInfo::default()
|
||||
.owner(&owner.pubkey())
|
||||
.tokens(0, 2, 0, 0),
|
||||
ExchangeProcessor::deserialize_account(&to_dst_account.data[..]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TradeOrderInfo {
|
||||
owner: owner,
|
||||
owner: owner.pubkey(),
|
||||
direction: Direction::From,
|
||||
pair: TokenPair::AB,
|
||||
tokens: 0,
|
||||
|
@ -797,15 +796,21 @@ mod test {
|
|||
ExchangeProcessor::deserialize_trade(&from_trade_account.data[..]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TokenAccountInfo::default().owner(&owner).tokens(0, 0, 0, 0),
|
||||
TokenAccountInfo::default()
|
||||
.owner(&owner.pubkey())
|
||||
.tokens(0, 0, 0, 0),
|
||||
ExchangeProcessor::deserialize_account(&from_src_account.data[..]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TokenAccountInfo::default().owner(&owner).tokens(1, 0, 0, 0),
|
||||
TokenAccountInfo::default()
|
||||
.owner(&owner.pubkey())
|
||||
.tokens(1, 0, 0, 0),
|
||||
ExchangeProcessor::deserialize_account(&from_dst_account.data[..]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
TokenAccountInfo::default().owner(&owner).tokens(0, 1, 0, 0),
|
||||
TokenAccountInfo::default()
|
||||
.owner(&owner.pubkey())
|
||||
.tokens(0, 1, 0, 0),
|
||||
ExchangeProcessor::deserialize_account(&profit_account.data[..]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
|
|
|
@ -4,21 +4,22 @@ use solana_runtime::loader_utils::{create_invoke_instruction, load_program};
|
|||
use solana_sdk::genesis_block::GenesisBlock;
|
||||
use solana_sdk::instruction::InstructionError;
|
||||
use solana_sdk::native_loader;
|
||||
use solana_sdk::signature::KeypairUtil;
|
||||
use solana_sdk::transaction::TransactionError;
|
||||
|
||||
#[test]
|
||||
fn test_program_native_failure() {
|
||||
let (genesis_block, mint_keypair) = GenesisBlock::new(50);
|
||||
let (genesis_block, alice_keypair) = GenesisBlock::new(50);
|
||||
let bank = Bank::new(&genesis_block);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
|
||||
let program = "failure".as_bytes().to_vec();
|
||||
let program_id = load_program(&bank, &alice_client, &native_loader::id(), program);
|
||||
let program_id = load_program(&bank_client, &alice_keypair, &native_loader::id(), program);
|
||||
|
||||
// Call user program
|
||||
let instruction = create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
|
||||
let instruction = create_invoke_instruction(alice_keypair.pubkey(), program_id, &1u8);
|
||||
assert_eq!(
|
||||
alice_client.process_instruction(instruction),
|
||||
bank_client.process_instruction(&alice_keypair, instruction),
|
||||
Err(TransactionError::InstructionError(
|
||||
0,
|
||||
InstructionError::GenericError
|
||||
|
|
|
@ -3,19 +3,22 @@ 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::signature::KeypairUtil;
|
||||
|
||||
#[test]
|
||||
fn test_program_native_noop() {
|
||||
solana_logger::setup();
|
||||
|
||||
let (genesis_block, mint_keypair) = GenesisBlock::new(50);
|
||||
let (genesis_block, alice_keypair) = GenesisBlock::new(50);
|
||||
let bank = Bank::new(&genesis_block);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
|
||||
let program = "noop".as_bytes().to_vec();
|
||||
let program_id = load_program(&bank, &alice_client, &native_loader::id(), program);
|
||||
let program_id = load_program(&bank_client, &alice_keypair, &native_loader::id(), program);
|
||||
|
||||
// Call user program
|
||||
let instruction = create_invoke_instruction(alice_client.pubkey(), program_id, &1u8);
|
||||
alice_client.process_instruction(instruction).unwrap();
|
||||
let instruction = create_invoke_instruction(alice_keypair.pubkey(), program_id, &1u8);
|
||||
bank_client
|
||||
.process_instruction(&alice_keypair, instruction)
|
||||
.unwrap();
|
||||
}
|
||||
|
|
|
@ -358,19 +358,19 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_bank_storage() {
|
||||
let (mut genesis_block, mint_keypair) = GenesisBlock::new(1000);
|
||||
let (mut genesis_block, alice_keypair) = GenesisBlock::new(1000);
|
||||
genesis_block
|
||||
.native_programs
|
||||
.push(("solana_storage_program".to_string(), id()));
|
||||
let bank = Bank::new(&genesis_block);
|
||||
let alice_client = BankClient::new(&bank, mint_keypair);
|
||||
let alice_pubkey = alice_client.pubkey();
|
||||
let alice_pubkey = alice_keypair.pubkey();
|
||||
let bob_keypair = Keypair::new();
|
||||
let bob_client = BankClient::new(&bank, bob_keypair);
|
||||
let bob_pubkey = bob_client.pubkey();
|
||||
let bob_pubkey = bob_keypair.pubkey();
|
||||
let jack_pubkey = Keypair::new().pubkey();
|
||||
let jill_pubkey = Keypair::new().pubkey();
|
||||
|
||||
let bank = Bank::new(&genesis_block);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
|
||||
let x = 42;
|
||||
let blockhash = genesis_block.hash();
|
||||
let x2 = x * 2;
|
||||
|
@ -378,14 +378,20 @@ mod tests {
|
|||
|
||||
bank.register_tick(&blockhash);
|
||||
|
||||
alice_client.transfer(10, &jill_pubkey).unwrap();
|
||||
alice_client.transfer(10, &bob_pubkey).unwrap();
|
||||
alice_client.transfer(10, &jack_pubkey).unwrap();
|
||||
bank_client
|
||||
.transfer(10, &alice_keypair, &jill_pubkey)
|
||||
.unwrap();
|
||||
bank_client
|
||||
.transfer(10, &alice_keypair, &bob_pubkey)
|
||||
.unwrap();
|
||||
bank_client
|
||||
.transfer(10, &alice_keypair, &jack_pubkey)
|
||||
.unwrap();
|
||||
|
||||
let ix =
|
||||
SystemInstruction::new_program_account(&alice_pubkey, &bob_pubkey, 1, 4 * 1024, &id());
|
||||
|
||||
alice_client.process_instruction(ix).unwrap();
|
||||
bank_client.process_instruction(&alice_keypair, ix).unwrap();
|
||||
|
||||
let ix = StorageInstruction::new_advertise_recent_blockhash(
|
||||
&bob_pubkey,
|
||||
|
@ -393,7 +399,7 @@ mod tests {
|
|||
ENTRIES_PER_SEGMENT,
|
||||
);
|
||||
|
||||
bob_client.process_instruction(ix).unwrap();
|
||||
bank_client.process_instruction(&bob_keypair, ix).unwrap();
|
||||
|
||||
let entry_height = 0;
|
||||
let ix = StorageInstruction::new_mining_proof(
|
||||
|
@ -402,7 +408,7 @@ mod tests {
|
|||
entry_height,
|
||||
Signature::default(),
|
||||
);
|
||||
let _result = bob_client.process_instruction(ix).unwrap();
|
||||
let _result = bank_client.process_instruction(&bob_keypair, ix).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
get_storage_entry_height(&bank, &bob_pubkey),
|
||||
|
|
|
@ -50,7 +50,7 @@ mod tests {
|
|||
use solana_runtime::bank::{Bank, Result};
|
||||
use solana_runtime::bank_client::BankClient;
|
||||
use solana_sdk::genesis_block::GenesisBlock;
|
||||
use solana_sdk::instruction::{AccountMeta, Instruction, InstructionError};
|
||||
use solana_sdk::instruction::InstructionError;
|
||||
use solana_sdk::message::Message;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||
|
@ -66,49 +66,51 @@ mod tests {
|
|||
|
||||
fn create_vote_account(
|
||||
bank_client: &BankClient,
|
||||
from_keypair: &Keypair,
|
||||
vote_id: &Pubkey,
|
||||
lamports: u64,
|
||||
) -> Result<()> {
|
||||
let ixs = VoteInstruction::new_account(&bank_client.pubkey(), vote_id, lamports);
|
||||
let ixs = VoteInstruction::new_account(&from_keypair.pubkey(), vote_id, lamports);
|
||||
let message = Message::new(ixs);
|
||||
bank_client.process_message(message)
|
||||
bank_client.process_message(&[from_keypair], message)
|
||||
}
|
||||
|
||||
fn create_vote_account_with_delegate(
|
||||
bank_client: &BankClient,
|
||||
from_keypair: &Keypair,
|
||||
vote_keypair: &Keypair,
|
||||
delegate_id: &Pubkey,
|
||||
lamports: u64,
|
||||
) -> Result<()> {
|
||||
let vote_id = bank_client.pubkeys()[1];
|
||||
let mut ixs = VoteInstruction::new_account(&bank_client.pubkey(), &vote_id, lamports);
|
||||
let vote_id = vote_keypair.pubkey();
|
||||
let mut ixs = VoteInstruction::new_account(&from_keypair.pubkey(), &vote_id, lamports);
|
||||
let delegate_ix = VoteInstruction::new_delegate_stake(&vote_id, delegate_id);
|
||||
ixs.push(delegate_ix);
|
||||
let message = Message::new(ixs);
|
||||
bank_client.process_message(message)
|
||||
bank_client.process_message(&[&from_keypair, vote_keypair], message)
|
||||
}
|
||||
|
||||
fn submit_vote(
|
||||
bank_client: &BankClient,
|
||||
staking_account: &Pubkey,
|
||||
vote_keypair: &Keypair,
|
||||
tick_height: u64,
|
||||
) -> Result<()> {
|
||||
let vote_ix = VoteInstruction::new_vote(staking_account, Vote::new(tick_height));
|
||||
bank_client.process_instruction(vote_ix)
|
||||
let vote_ix = VoteInstruction::new_vote(&vote_keypair.pubkey(), Vote::new(tick_height));
|
||||
bank_client.process_instruction(&vote_keypair, vote_ix)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vote_bank_basic() {
|
||||
let (bank, from_keypair) = create_bank(10_000);
|
||||
let alice_client = BankClient::new(&bank, from_keypair);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
|
||||
let vote_keypair = Keypair::new();
|
||||
let vote_client = BankClient::new(&bank, vote_keypair);
|
||||
let vote_id = vote_client.pubkey();
|
||||
let vote_id = vote_keypair.pubkey();
|
||||
|
||||
create_vote_account(&alice_client, &vote_id, 100).unwrap();
|
||||
submit_vote(&vote_client, &vote_id, 0).unwrap();
|
||||
create_vote_account(&bank_client, &from_keypair, &vote_id, 100).unwrap();
|
||||
submit_vote(&bank_client, &vote_keypair, 0).unwrap();
|
||||
|
||||
let vote_account = bank.get_account(&vote_client.pubkey()).unwrap();
|
||||
let vote_account = bank.get_account(&vote_id).unwrap();
|
||||
let vote_state = VoteState::deserialize(&vote_account.data).unwrap();
|
||||
assert_eq!(vote_state.votes.len(), 1);
|
||||
}
|
||||
|
@ -117,36 +119,38 @@ mod tests {
|
|||
fn test_vote_bank_delegate() {
|
||||
let (bank, from_keypair) = create_bank(10_000);
|
||||
let vote_keypair = Keypair::new();
|
||||
let alice_and_vote_client =
|
||||
BankClient::new_with_keypairs(&bank, vec![from_keypair, vote_keypair]);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
let delegate_id = Keypair::new().pubkey();
|
||||
create_vote_account_with_delegate(&alice_and_vote_client, &delegate_id, 100).unwrap();
|
||||
create_vote_account_with_delegate(
|
||||
&bank_client,
|
||||
&from_keypair,
|
||||
&vote_keypair,
|
||||
&delegate_id,
|
||||
100,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vote_via_bank_with_no_signature() {
|
||||
let (bank, from_keypair) = create_bank(10_000);
|
||||
let mallory_client = BankClient::new(&bank, from_keypair);
|
||||
let (bank, mallory_keypair) = create_bank(10_000);
|
||||
let bank_client = BankClient::new(&bank);
|
||||
|
||||
let vote_keypair = Keypair::new();
|
||||
let vote_client = BankClient::new(&bank, vote_keypair);
|
||||
let vote_id = vote_client.pubkey();
|
||||
let vote_id = vote_keypair.pubkey();
|
||||
|
||||
create_vote_account(&mallory_client, &vote_id, 100).unwrap();
|
||||
create_vote_account(&bank_client, &mallory_keypair, &vote_id, 100).unwrap();
|
||||
|
||||
let mallory_id = mallory_client.pubkey();
|
||||
let vote_ix = Instruction::new(
|
||||
id(),
|
||||
&VoteInstruction::Vote(Vote::new(0)),
|
||||
vec![AccountMeta::new(vote_id, false)], // <--- attack!! No signer required.
|
||||
);
|
||||
let mallory_id = mallory_keypair.pubkey();
|
||||
let mut vote_ix = VoteInstruction::new_vote(&vote_id, Vote::new(0));
|
||||
vote_ix.accounts[0].is_signer = false; // <--- attack!! No signer required.
|
||||
|
||||
// Sneak in an instruction so that the transaction is signed but
|
||||
// the 0th account in the second instruction is not! The program
|
||||
// needs to check that it's signed.
|
||||
let move_ix = SystemInstruction::new_move(&mallory_id, &vote_id, 1);
|
||||
let message = Message::new(vec![move_ix, vote_ix]);
|
||||
let result = mallory_client.process_message(message);
|
||||
let result = bank_client.process_message(&[&mallory_keypair], message);
|
||||
|
||||
// And ensure there's no vote.
|
||||
let vote_account = bank.get_account(&vote_id).unwrap();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue