solana/sdk/src/system_instruction.rs

117 lines
3.7 KiB
Rust
Raw Normal View History

2019-03-23 21:12:27 -06:00
use crate::instruction::{AccountMeta, Instruction};
2018-12-14 20:39:10 -08:00
use crate::pubkey::Pubkey;
2019-02-28 04:48:44 -07:00
use crate::system_program;
2018-11-16 08:04:46 -08:00
2019-03-13 14:37:24 -06:00
#[derive(Serialize, Debug, Clone, PartialEq)]
pub enum SystemError {
AccountAlreadyInUse,
ResultWithNegativeLamports,
SourceNotSystemAccount,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
2018-11-16 08:04:46 -08:00
pub enum SystemInstruction {
/// Create a new account
/// * Transaction::keys[0] - source
/// * Transaction::keys[1] - new account key
2019-03-05 16:28:14 -08:00
/// * lamports - number of lamports to transfer to the new account
2018-11-16 08:04:46 -08:00
/// * space - memory to allocate if greater then zero
/// * program_id - the program id of the new account
CreateAccount {
2019-03-05 16:28:14 -08:00
lamports: u64,
2018-11-16 08:04:46 -08:00
space: u64,
program_id: Pubkey,
},
/// Assign account to a program
/// * Transaction::keys[0] - account to assign
Assign { program_id: Pubkey },
2019-03-05 16:28:14 -08:00
/// Move lamports
2018-11-16 08:04:46 -08:00
/// * Transaction::keys[0] - source
/// * Transaction::keys[1] - destination
2019-03-05 16:28:14 -08:00
Move { lamports: u64 },
2018-11-16 08:04:46 -08:00
}
2019-02-28 04:48:44 -07:00
impl SystemInstruction {
2019-03-03 15:43:51 -07:00
pub fn new_program_account(
from_id: &Pubkey,
to_id: &Pubkey,
2019-03-05 16:28:14 -08:00
lamports: u64,
2019-03-03 15:43:51 -07:00
space: u64,
program_id: &Pubkey,
) -> Instruction {
let account_metas = vec![
AccountMeta::new(*from_id, true),
AccountMeta::new(*to_id, false),
];
Instruction::new(
2019-03-03 15:43:51 -07:00
system_program::id(),
&SystemInstruction::CreateAccount {
2019-03-05 16:28:14 -08:00
lamports,
2019-03-03 15:43:51 -07:00
space,
program_id: *program_id,
2019-03-03 15:43:51 -07:00
},
account_metas,
2019-03-03 15:43:51 -07:00
)
}
2019-03-25 20:57:25 -06:00
/// Create and sign a transaction to create a system account
pub fn new_account(from_id: &Pubkey, to_id: &Pubkey, lamports: u64) -> Instruction {
let program_id = system_program::id();
Self::new_program_account(from_id, to_id, lamports, 0, &program_id)
}
2019-03-21 10:03:50 -06:00
pub fn new_assign(from_id: &Pubkey, program_id: &Pubkey) -> Instruction {
let account_metas = vec![AccountMeta::new(*from_id, true)];
Instruction::new(
system_program::id(),
&SystemInstruction::Assign {
program_id: *program_id,
},
account_metas,
)
}
pub fn new_move(from_id: &Pubkey, to_id: &Pubkey, lamports: u64) -> Instruction {
let account_metas = vec![
AccountMeta::new(*from_id, true),
AccountMeta::new(*to_id, false),
];
Instruction::new(
2019-02-28 04:48:44 -07:00
system_program::id(),
2019-03-05 16:28:14 -08:00
&SystemInstruction::Move { lamports },
account_metas,
2019-02-28 04:48:44 -07:00
)
}
/// 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]);
}
2019-02-28 04:48:44 -07:00
}