Move new_move_many to SystemInstruction

This commit is contained in:
Greg Fitzgerald 2019-03-26 10:03:12 -06:00 committed by Grimes
parent 9759ac2961
commit df333e8b6e
5 changed files with 52 additions and 75 deletions

View File

@ -13,6 +13,7 @@ use solana_metrics::influxdb;
use solana_sdk::hash::Hash;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::system_transaction::SystemTransaction;
use solana_sdk::timing::timestamp;
use solana_sdk::timing::{duration_as_ms, duration_as_s};
@ -563,7 +564,7 @@ fn fund_keys(client: &ThinClient, source: &Keypair, dests: &[Keypair], lamports:
.map(|(k, m)| {
(
k.clone(),
SystemTransaction::new_move_many(k, &m, Hash::default(), 0),
Transaction::new(SystemInstruction::new_move_many(&k.pubkey(), &m)),
)
})
.collect();

View File

@ -925,10 +925,9 @@ impl Drop for Bank {
#[cfg(test)]
mod tests {
use super::*;
use bincode::serialize;
use solana_sdk::genesis_block::{GenesisBlock, BOOTSTRAP_LEADER_LAMPORTS};
use solana_sdk::hash;
use solana_sdk::instruction::{CompiledInstruction, InstructionError};
use solana_sdk::instruction::InstructionError;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::system_program;
@ -1010,40 +1009,24 @@ mod tests {
let key1 = Keypair::new().pubkey();
let key2 = Keypair::new().pubkey();
let bank = Bank::new(&genesis_block);
let spend = SystemInstruction::Move { lamports: 1 };
let instructions = vec![
CompiledInstruction {
program_ids_index: 0,
data: serialize(&spend).unwrap(),
accounts: vec![0, 1],
},
CompiledInstruction {
program_ids_index: 0,
data: serialize(&spend).unwrap(),
accounts: vec![0, 2],
},
];
let t1 = Transaction::new_with_compiled_instructions(
let instructions =
SystemInstruction::new_move_many(&mint_keypair.pubkey(), &[(key1, 1), (key2, 1)]);
let tx = Transaction::new_signed_instructions(
&[&mint_keypair],
&[key1, key2],
instructions,
genesis_block.hash(),
0,
vec![system_program::id()],
instructions,
);
let res = bank.process_transactions(&vec![t1.clone()]);
assert_eq!(res.len(), 1);
assert_eq!(
bank.process_transaction(&tx).unwrap_err(),
TransactionError::InstructionError(
1,
InstructionError::new_result_with_negative_lamports(),
)
);
assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 1);
assert_eq!(bank.get_balance(&key1), 0);
assert_eq!(bank.get_balance(&key2), 0);
assert_eq!(
bank.get_signature_status(&t1.signatures[0]),
Some(Err(TransactionError::InstructionError(
1,
InstructionError::new_result_with_negative_lamports(),
)))
);
}
#[test]
@ -1052,19 +1035,18 @@ mod tests {
let key1 = Keypair::new().pubkey();
let key2 = Keypair::new().pubkey();
let bank = Bank::new(&genesis_block);
let t1 = SystemTransaction::new_move_many(
&mint_keypair,
&[(key1, 1), (key2, 1)],
let instructions =
SystemInstruction::new_move_many(&mint_keypair.pubkey(), &[(key1, 1), (key2, 1)]);
let tx = Transaction::new_signed_instructions(
&[&mint_keypair],
instructions,
genesis_block.hash(),
0,
);
let res = bank.process_transactions(&vec![t1.clone()]);
assert_eq!(res.len(), 1);
assert_eq!(res[0], Ok(()));
bank.process_transaction(&tx).unwrap();
assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 0);
assert_eq!(bank.get_balance(&key1), 1);
assert_eq!(bank.get_balance(&key2), 1);
assert_eq!(bank.get_signature_status(&t1.signatures[0]), Some(Ok(())));
}
// This test demonstrates that fees are paid even when a program fails.

View File

@ -92,7 +92,7 @@ impl<P, Q> GenericInstruction<P, Q> {
}
/// Account metadata used to define Instructions
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct AccountMeta {
/// An account's public key
pub pubkey: Pubkey,

View File

@ -82,4 +82,35 @@ impl SystemInstruction {
account_metas,
)
}
/// Create and sign new SystemInstruction::Move transaction to many destinations
pub fn new_move_many(from_id: &Pubkey, to_lamports: &[(Pubkey, u64)]) -> Vec<Instruction> {
to_lamports
.iter()
.map(|(to_id, lamports)| SystemInstruction::new_move(from_id, to_id, *lamports))
.collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::signature::{Keypair, KeypairUtil};
fn get_keys(instruction: &Instruction) -> Vec<Pubkey> {
instruction.accounts.iter().map(|x| x.pubkey).collect()
}
#[test]
fn test_move_many() {
let alice_pubkey = Keypair::new().pubkey();
let bob_pubkey = Keypair::new().pubkey();
let carol_pubkey = Keypair::new().pubkey();
let to_lamports = vec![(bob_pubkey, 1), (carol_pubkey, 2)];
let instructions = SystemInstruction::new_move_many(&alice_pubkey, &to_lamports);
assert_eq!(instructions.len(), 2);
assert_eq!(get_keys(&instructions[0]), vec![alice_pubkey, bob_pubkey]);
assert_eq!(get_keys(&instructions[1]), vec![alice_pubkey, carol_pubkey]);
}
}

View File

@ -73,41 +73,4 @@ impl SystemTransaction {
let instructions = vec![move_instruction];
Transaction::new_signed_instructions(&[from_keypair], instructions, recent_blockhash, fee)
}
/// Create and sign new SystemInstruction::Move transaction to many destinations
pub fn new_move_many(
from_keypair: &Keypair,
to_lamports: &[(Pubkey, u64)],
recent_blockhash: Hash,
fee: u64,
) -> Transaction {
let from_pubkey = from_keypair.pubkey();
let instructions: Vec<_> = to_lamports
.iter()
.map(|(pubkey, lamports)| SystemInstruction::new_move(&from_pubkey, pubkey, *lamports))
.collect();
Transaction::new_signed_instructions(&[from_keypair], instructions, recent_blockhash, fee)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::signature::KeypairUtil;
#[test]
fn test_move_many() {
let from = Keypair::new();
let t1 = Keypair::new();
let t2 = Keypair::new();
let moves = vec![(t1.pubkey(), 1), (t2.pubkey(), 2)];
let tx = SystemTransaction::new_move_many(&from, &moves, Hash::default(), 0);
assert_eq!(tx.account_keys[0], from.pubkey());
assert_eq!(tx.account_keys[1], t1.pubkey());
assert_eq!(tx.account_keys[2], t2.pubkey());
assert_eq!(tx.instructions.len(), 2);
assert_eq!(tx.instructions[0].accounts, vec![0, 1]);
assert_eq!(tx.instructions[1].accounts, vec![0, 2]);
}
}