Program bank integration (#1462)

Native, BPF and Lua loaders integrated into the bank
This commit is contained in:
jackcmay
2018-10-16 09:43:49 -07:00
committed by GitHub
parent 1b2e9122d5
commit d09889b1dd
26 changed files with 1379 additions and 841 deletions

View File

@@ -1,12 +1,9 @@
//! system program
use bincode::deserialize;
use dynamic_program::DynamicProgram;
use solana_program_interface::account::Account;
use solana_program_interface::pubkey::Pubkey;
use std;
use std::collections::HashMap;
use std::sync::RwLock;
use transaction::Transaction;
#[derive(Debug)]
@@ -42,10 +39,6 @@ pub enum SystemProgram {
/// * Transaction::keys[0] - source
/// * Transaction::keys[1] - destination
Move { tokens: i64 },
/// Load a program
/// program_id - id to associate this program
/// nanme - file path of the program to load
Load { program_id: Pubkey, name: String },
}
pub const SYSTEM_PROGRAM_ID: [u8; 32] = [0u8; 32];
@@ -65,7 +58,6 @@ impl SystemProgram {
tx: &Transaction,
pix: usize,
accounts: &mut [&mut Account],
loaded_programs: &RwLock<HashMap<Pubkey, DynamicProgram>>,
) -> Result<()> {
if let Ok(syscall) = deserialize(tx.userdata(pix)) {
trace!("process_transaction: {:?}", syscall);
@@ -88,6 +80,8 @@ impl SystemProgram {
accounts[1].tokens += tokens;
accounts[1].program_id = program_id;
accounts[1].userdata = vec![0; space as usize];
accounts[1].executable = false;
accounts[1].loader_program_id = Pubkey::default();
}
SystemProgram::Assign { program_id } => {
if !Self::check_id(&accounts[0].program_id) {
@@ -100,16 +94,6 @@ impl SystemProgram {
accounts[0].tokens -= tokens;
accounts[1].tokens += tokens;
}
SystemProgram::Load { program_id, name } => {
let mut hashmap = loaded_programs.write().unwrap();
hashmap.insert(
program_id,
DynamicProgram::new_native(name).map_err(|err| {
warn!("SystemProgram::Load failure: {:?}", err);
Error::InvalidArgument
})?,
);
}
}
Ok(())
} else {
@@ -125,19 +109,13 @@ mod test {
use signature::{Keypair, KeypairUtil};
use solana_program_interface::account::Account;
use solana_program_interface::pubkey::Pubkey;
use std::collections::HashMap;
use std::sync::RwLock;
use system_program::SystemProgram;
use system_transaction::SystemTransaction;
use transaction::Transaction;
fn process_transaction(
tx: &Transaction,
accounts: &mut [Account],
loaded_programs: &RwLock<HashMap<Pubkey, DynamicProgram>>,
) -> Result<()> {
fn process_transaction(tx: &Transaction, accounts: &mut [Account]) -> Result<()> {
let mut refs: Vec<&mut Account> = accounts.iter_mut().collect();
SystemProgram::process_transaction(&tx, 0, &mut refs[..], loaded_programs)
SystemProgram::process_transaction(&tx, 0, &mut refs[..])
}
#[test]
@@ -146,8 +124,7 @@ mod test {
let to = Keypair::new();
let mut accounts = vec![Account::default(), Account::default()];
let tx = Transaction::system_new(&from, to.pubkey(), 0, Hash::default());
let hash = RwLock::new(HashMap::new());
process_transaction(&tx, &mut accounts, &hash).unwrap();
process_transaction(&tx, &mut accounts).unwrap();
assert_eq!(accounts[0].tokens, 0);
assert_eq!(accounts[1].tokens, 0);
}
@@ -158,12 +135,13 @@ mod test {
let mut accounts = vec![Account::default(), Account::default()];
accounts[0].tokens = 1;
let tx = Transaction::system_new(&from, to.pubkey(), 1, Hash::default());
let hash = RwLock::new(HashMap::new());
process_transaction(&tx, &mut accounts, &hash).unwrap();
process_transaction(&tx, &mut accounts).unwrap();
assert_eq!(accounts[0].tokens, 0);
assert_eq!(accounts[1].tokens, 1);
}
#[test]
#[ignore]
fn test_create_spend_wrong_source() {
let from = Keypair::new();
let to = Keypair::new();
@@ -171,8 +149,7 @@ mod test {
accounts[0].tokens = 1;
accounts[0].program_id = from.pubkey();
let tx = Transaction::system_new(&from, to.pubkey(), 1, Hash::default());
let hash = RwLock::new(HashMap::new());
assert!(process_transaction(&tx, &mut accounts, &hash).is_err());
process_transaction(&tx, &mut accounts).unwrap();
assert_eq!(accounts[0].tokens, 1);
assert_eq!(accounts[1].tokens, 0);
}
@@ -183,8 +160,7 @@ mod test {
let mut accounts = vec![Account::default(), Account::default()];
let tx =
Transaction::system_create(&from, to.pubkey(), Hash::default(), 0, 1, to.pubkey(), 0);
let hash = RwLock::new(HashMap::new());
process_transaction(&tx, &mut accounts, &hash).unwrap();
process_transaction(&tx, &mut accounts).unwrap();
assert!(accounts[0].userdata.is_empty());
assert_eq!(accounts[1].userdata.len(), 1);
assert_eq!(accounts[1].program_id, to.pubkey());
@@ -204,8 +180,7 @@ mod test {
Pubkey::default(),
0,
);
let hash = RwLock::new(HashMap::new());
assert!(process_transaction(&tx, &mut accounts, &hash).is_err());
assert!(process_transaction(&tx, &mut accounts).is_err());
assert!(accounts[1].userdata.is_empty());
}
#[test]
@@ -223,8 +198,7 @@ mod test {
Pubkey::default(),
0,
);
let hash = RwLock::new(HashMap::new());
assert!(process_transaction(&tx, &mut accounts, &hash).is_err());
assert!(process_transaction(&tx, &mut accounts).is_err());
assert!(accounts[1].userdata.is_empty());
}
#[test]
@@ -242,8 +216,7 @@ mod test {
Pubkey::default(),
0,
);
let hash = RwLock::new(HashMap::new());
assert!(process_transaction(&tx, &mut accounts, &hash).is_err());
assert!(process_transaction(&tx, &mut accounts).is_err());
assert_eq!(accounts[1].userdata.len(), 3);
}
#[test]
@@ -252,8 +225,7 @@ mod test {
let program = Keypair::new();
let mut accounts = vec![Account::default()];
let tx = Transaction::system_assign(&from, Hash::default(), program.pubkey(), 0);
let hash = RwLock::new(HashMap::new());
process_transaction(&tx, &mut accounts, &hash).unwrap();
process_transaction(&tx, &mut accounts).unwrap();
assert_eq!(accounts[0].program_id, program.pubkey());
}
#[test]
@@ -263,8 +235,7 @@ mod test {
let mut accounts = vec![Account::default(), Account::default()];
accounts[0].tokens = 1;
let tx = Transaction::system_new(&from, to.pubkey(), 1, Hash::default());
let hash = RwLock::new(HashMap::new());
process_transaction(&tx, &mut accounts, &hash).unwrap();
process_transaction(&tx, &mut accounts).unwrap();
assert_eq!(accounts[0].tokens, 0);
assert_eq!(accounts[1].tokens, 1);
}