Cleanup field names

This commit is contained in:
Greg Fitzgerald
2018-10-04 13:36:15 -07:00
parent 680f90df21
commit b508fdb62c
4 changed files with 81 additions and 72 deletions

View File

@ -412,7 +412,7 @@ impl Bank {
} }
pub fn verify_transaction( pub fn verify_transaction(
program_index: usize, instruction_index: usize,
tx_program_id: &Pubkey, tx_program_id: &Pubkey,
pre_program_id: &Pubkey, pre_program_id: &Pubkey,
pre_tokens: i64, pre_tokens: i64,
@ -425,14 +425,16 @@ impl Bank {
&& SystemProgram::check_id(&pre_program_id))) && SystemProgram::check_id(&pre_program_id)))
{ {
//TODO, this maybe redundant bpf should be able to guarantee this property //TODO, this maybe redundant bpf should be able to guarantee this property
return Err(BankError::ModifiedContractId(program_index as u8)); return Err(BankError::ModifiedContractId(instruction_index as u8));
} }
// For accounts unassigned to the contract, the individual balance of each accounts cannot decrease. // For accounts unassigned to the contract, the individual balance of each accounts cannot decrease.
if *tx_program_id != account.program_id && pre_tokens > account.tokens { if *tx_program_id != account.program_id && pre_tokens > account.tokens {
return Err(BankError::ExternalAccountTokenSpend(program_index as u8)); return Err(BankError::ExternalAccountTokenSpend(
instruction_index as u8,
));
} }
if account.tokens < 0 { if account.tokens < 0 {
return Err(BankError::ResultWithNegativeTokens(program_index as u8)); return Err(BankError::ResultWithNegativeTokens(instruction_index as u8));
} }
Ok(()) Ok(())
} }
@ -484,10 +486,10 @@ impl Bank {
fn execute_instruction( fn execute_instruction(
&self, &self,
tx: &Transaction, tx: &Transaction,
program_index: usize, instruction_index: usize,
program_accounts: &mut [&mut Account], program_accounts: &mut [&mut Account],
) -> Result<()> { ) -> Result<()> {
let tx_program_id = tx.program_id(program_index); let tx_program_id = tx.program_id(instruction_index);
// TODO: the runtime should be checking read/write access to memory // TODO: the runtime should be checking read/write access to memory
// we are trusting the hard coded contracts not to clobber or allocate // we are trusting the hard coded contracts not to clobber or allocate
let pre_total: i64 = program_accounts.iter().map(|a| a.tokens).sum(); let pre_total: i64 = program_accounts.iter().map(|a| a.tokens).sum();
@ -501,39 +503,45 @@ impl Bank {
if SystemProgram::check_id(&tx_program_id) { if SystemProgram::check_id(&tx_program_id) {
SystemProgram::process_transaction( SystemProgram::process_transaction(
&tx, &tx,
program_index, instruction_index,
program_accounts, program_accounts,
&self.loaded_contracts, &self.loaded_contracts,
) )
} else if BudgetState::check_id(&tx_program_id) { } else if BudgetState::check_id(&tx_program_id) {
if BudgetState::process_transaction(&tx, program_index, program_accounts).is_err() { if BudgetState::process_transaction(&tx, instruction_index, program_accounts).is_err() {
return Err(BankError::ProgramRuntimeError(program_index as u8)); return Err(BankError::ProgramRuntimeError(instruction_index as u8));
} }
} else if StorageProgram::check_id(&tx_program_id) { } else if StorageProgram::check_id(&tx_program_id) {
if StorageProgram::process_transaction(&tx, program_index, program_accounts).is_err() { if StorageProgram::process_transaction(&tx, instruction_index, program_accounts)
return Err(BankError::ProgramRuntimeError(program_index as u8));
}
} else if TicTacToeProgram::check_id(&tx_program_id) {
if TicTacToeProgram::process_transaction(&tx, program_index, program_accounts).is_err()
{
return Err(BankError::ProgramRuntimeError(program_index as u8));
}
} else if TicTacToeDashboardProgram::check_id(&tx_program_id) {
if TicTacToeDashboardProgram::process_transaction(&tx, program_index, program_accounts)
.is_err() .is_err()
{ {
return Err(BankError::ProgramRuntimeError(program_index as u8)); return Err(BankError::ProgramRuntimeError(instruction_index as u8));
} }
} else if self.loaded_contract(tx_program_id, tx, program_index, program_accounts) { } else if TicTacToeProgram::check_id(&tx_program_id) {
if TicTacToeProgram::process_transaction(&tx, instruction_index, program_accounts)
.is_err()
{
return Err(BankError::ProgramRuntimeError(instruction_index as u8));
}
} else if TicTacToeDashboardProgram::check_id(&tx_program_id) {
if TicTacToeDashboardProgram::process_transaction(
&tx,
instruction_index,
program_accounts,
).is_err()
{
return Err(BankError::ProgramRuntimeError(instruction_index as u8));
}
} else if self.loaded_contract(tx_program_id, tx, instruction_index, program_accounts) {
} else { } else {
return Err(BankError::UnknownContractId(program_index as u8)); return Err(BankError::UnknownContractId(instruction_index as u8));
} }
// Verify the transaction // Verify the transaction
for ((pre_program_id, pre_tokens), post_account) in for ((pre_program_id, pre_tokens), post_account) in
pre_data.iter().zip(program_accounts.iter()) pre_data.iter().zip(program_accounts.iter())
{ {
Self::verify_transaction( Self::verify_transaction(
program_index, instruction_index,
&tx_program_id, &tx_program_id,
pre_program_id, pre_program_id,
*pre_tokens, *pre_tokens,
@ -543,7 +551,7 @@ impl Bank {
// The total sum of all the tokens in all the pages cannot change. // The total sum of all the tokens in all the pages cannot change.
let post_total: i64 = program_accounts.iter().map(|a| a.tokens).sum(); let post_total: i64 = program_accounts.iter().map(|a| a.tokens).sum();
if pre_total != post_total { if pre_total != post_total {
Err(BankError::UnbalancedTransaction(program_index as u8)) Err(BankError::UnbalancedTransaction(instruction_index as u8))
} else { } else {
Ok(()) Ok(())
} }
@ -552,9 +560,9 @@ impl Bank {
/// This method calls each instruction in the transaction over the set of loaded Accounts /// This method calls each instruction in the transaction over the set of loaded Accounts
/// The accounts are committed back to the bank only if every instruction succeeds /// The accounts are committed back to the bank only if every instruction succeeds
fn execute_transaction(&self, tx: &Transaction, tx_accounts: &mut [Account]) -> Result<()> { fn execute_transaction(&self, tx: &Transaction, tx_accounts: &mut [Account]) -> Result<()> {
for (program_index, prog) in tx.instructions.iter().enumerate() { for (instruction_index, prog) in tx.instructions.iter().enumerate() {
Self::with_subset(tx_accounts, &prog.accounts, |program_accounts| { Self::with_subset(tx_accounts, &prog.accounts, |program_accounts| {
self.execute_instruction(tx, program_index, program_accounts) self.execute_instruction(tx, instruction_index, program_accounts)
})?; })?;
} }
Ok(()) Ok(())
@ -1005,12 +1013,12 @@ mod tests {
let spend = SystemProgram::Move { tokens: 1 }; let spend = SystemProgram::Move { tokens: 1 };
let instructions = vec![ let instructions = vec![
Instruction { Instruction {
program_id: 0, program_ids_index: 0,
userdata: serialize(&spend).unwrap(), userdata: serialize(&spend).unwrap(),
accounts: vec![0, 1], accounts: vec![0, 1],
}, },
Instruction { Instruction {
program_id: 0, program_ids_index: 0,
userdata: serialize(&spend).unwrap(), userdata: serialize(&spend).unwrap(),
accounts: vec![0, 2], accounts: vec![0, 2],
}, },
@ -1045,12 +1053,12 @@ mod tests {
let spend = SystemProgram::Move { tokens: 1 }; let spend = SystemProgram::Move { tokens: 1 };
let instructions = vec![ let instructions = vec![
Instruction { Instruction {
program_id: 0, program_ids_index: 0,
userdata: serialize(&spend).unwrap(), userdata: serialize(&spend).unwrap(),
accounts: vec![0, 1], accounts: vec![0, 1],
}, },
Instruction { Instruction {
program_id: 0, program_ids_index: 0,
userdata: serialize(&spend).unwrap(), userdata: serialize(&spend).unwrap(),
accounts: vec![0, 2], accounts: vec![0, 2],
}, },

View File

@ -48,18 +48,18 @@ impl BudgetState {
fn apply_signature( fn apply_signature(
&mut self, &mut self,
tx: &Transaction, tx: &Transaction,
program_index: usize, instruction_index: usize,
account: &mut [&mut Account], account: &mut [&mut Account],
) -> Result<(), BudgetError> { ) -> Result<(), BudgetError> {
let mut final_payment = None; let mut final_payment = None;
if let Some(ref mut budget) = self.pending_budget { if let Some(ref mut budget) = self.pending_budget {
let key = tx.key(program_index, 0).unwrap(); let key = tx.key(instruction_index, 0).unwrap();
budget.apply_witness(&Witness::Signature, key); budget.apply_witness(&Witness::Signature, key);
final_payment = budget.final_payment(); final_payment = budget.final_payment();
} }
if let Some(payment) = final_payment { if let Some(payment) = final_payment {
if Some(&payment.to) != tx.key(program_index, 2) { if Some(&payment.to) != tx.key(instruction_index, 2) {
trace!("destination missing"); trace!("destination missing");
return Err(BudgetError::DestinationMissing); return Err(BudgetError::DestinationMissing);
} }
@ -75,7 +75,7 @@ impl BudgetState {
fn apply_timestamp( fn apply_timestamp(
&mut self, &mut self,
tx: &Transaction, tx: &Transaction,
program_index: usize, instruction_index: usize,
accounts: &mut [&mut Account], accounts: &mut [&mut Account],
dt: DateTime<Utc>, dt: DateTime<Utc>,
) -> Result<(), BudgetError> { ) -> Result<(), BudgetError> {
@ -83,13 +83,13 @@ impl BudgetState {
let mut final_payment = None; let mut final_payment = None;
if let Some(ref mut budget) = self.pending_budget { if let Some(ref mut budget) = self.pending_budget {
let key = tx.key(program_index, 0).unwrap(); let key = tx.key(instruction_index, 0).unwrap();
budget.apply_witness(&Witness::Timestamp(dt), key); budget.apply_witness(&Witness::Timestamp(dt), key);
final_payment = budget.final_payment(); final_payment = budget.final_payment();
} }
if let Some(payment) = final_payment { if let Some(payment) = final_payment {
if Some(&payment.to) != tx.key(program_index, 2) { if Some(&payment.to) != tx.key(instruction_index, 2) {
trace!("destination missing"); trace!("destination missing");
return Err(BudgetError::DestinationMissing); return Err(BudgetError::DestinationMissing);
} }
@ -133,7 +133,7 @@ impl BudgetState {
/// Note: It is safe to apply credits from multiple transactions in parallel. /// Note: It is safe to apply credits from multiple transactions in parallel.
fn apply_credits_to_budget_state( fn apply_credits_to_budget_state(
tx: &Transaction, tx: &Transaction,
program_index: usize, instruction_index: usize,
accounts: &mut [&mut Account], accounts: &mut [&mut Account],
instruction: &Instruction, instruction: &Instruction,
) -> Result<(), BudgetError> { ) -> Result<(), BudgetError> {
@ -166,7 +166,7 @@ impl BudgetState {
Err(BudgetError::UninitializedContract) Err(BudgetError::UninitializedContract)
} else { } else {
trace!("apply timestamp"); trace!("apply timestamp");
state.apply_timestamp(tx, program_index, accounts, *dt)?; state.apply_timestamp(tx, instruction_index, accounts, *dt)?;
trace!("apply timestamp committed"); trace!("apply timestamp committed");
state.serialize(&mut accounts[1].userdata) state.serialize(&mut accounts[1].userdata)
} }
@ -183,7 +183,7 @@ impl BudgetState {
Err(BudgetError::UninitializedContract) Err(BudgetError::UninitializedContract)
} else { } else {
trace!("apply signature"); trace!("apply signature");
state.apply_signature(tx, program_index, accounts)?; state.apply_signature(tx, instruction_index, accounts)?;
trace!("apply signature committed"); trace!("apply signature committed");
state.serialize(&mut accounts[1].userdata) state.serialize(&mut accounts[1].userdata)
} }
@ -241,18 +241,18 @@ impl BudgetState {
/// be spent from this account . /// be spent from this account .
pub fn process_transaction( pub fn process_transaction(
tx: &Transaction, tx: &Transaction,
program_index: usize, instruction_index: usize,
accounts: &mut [&mut Account], accounts: &mut [&mut Account],
) -> Result<(), BudgetError> { ) -> Result<(), BudgetError> {
if let Ok(instruction) = deserialize(tx.userdata(program_index)) { if let Ok(instruction) = deserialize(tx.userdata(instruction_index)) {
trace!("process_transaction: {:?}", instruction); trace!("process_transaction: {:?}", instruction);
Self::apply_debits_to_budget_state(accounts, &instruction).and_then(|_| { Self::apply_debits_to_budget_state(accounts, &instruction).and_then(|_| {
Self::apply_credits_to_budget_state(tx, program_index, accounts, &instruction) Self::apply_credits_to_budget_state(tx, instruction_index, accounts, &instruction)
}) })
} else { } else {
info!( info!(
"Invalid transaction userdata: {:?}", "Invalid transaction userdata: {:?}",
tx.userdata(program_index) tx.userdata(instruction_index)
); );
Err(BudgetError::UserdataDeserializeFailure) Err(BudgetError::UserdataDeserializeFailure)
} }

View File

@ -278,7 +278,7 @@ mod tests {
let instruction = Instruction::NewContract(Contract { budget, tokens: 0 }); let instruction = Instruction::NewContract(Contract { budget, tokens: 0 });
let userdata = serialize(&instruction).unwrap(); let userdata = serialize(&instruction).unwrap();
let instructions = vec![transaction::Instruction { let instructions = vec![transaction::Instruction {
program_id: 0, program_ids_index: 0,
userdata, userdata,
accounts: vec![], accounts: vec![],
}]; }];
@ -286,7 +286,7 @@ mod tests {
account_keys: vec![], account_keys: vec![],
last_id: Default::default(), last_id: Default::default(),
signature: Default::default(), signature: Default::default(),
program_keys: vec![], program_ids: vec![],
instructions, instructions,
fee: 0, fee: 0,
}; };

View File

@ -10,13 +10,13 @@ pub const SIGNED_DATA_OFFSET: usize = size_of::<Signature>();
pub const SIG_OFFSET: usize = 0; pub const SIG_OFFSET: usize = 0;
pub const PUB_KEY_OFFSET: usize = size_of::<Signature>() + size_of::<u64>(); pub const PUB_KEY_OFFSET: usize = size_of::<Signature>() + size_of::<u64>();
/// An instruction to execute a program under `program_id` with the /// An instruction to execute a program under the `program_id` of `program_ids_index` with the
/// specified accounts and userdata /// specified accounts and userdata
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Instruction { pub struct Instruction {
/// The program code that executes this transaction is identified by the program_id. /// The program code that executes this transaction is identified by the program_id.
/// this is an offset into the Transaction::program_keys field /// this is an offset into the Transaction::program_ids field
pub program_id: u8, pub program_ids_index: u8,
/// Indices into the keys array of which accounts to load /// Indices into the keys array of which accounts to load
pub accounts: Vec<u8>, pub accounts: Vec<u8>,
/// Userdata to be stored in the account /// Userdata to be stored in the account
@ -26,7 +26,7 @@ pub struct Instruction {
/// An atomic transaction /// An atomic transaction
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Transaction { pub struct Transaction {
/// A digital signature of `keys`, `program_id`, `last_id`, `fee` and `userdata`, signed by `Pubkey`. /// A digital signature of `account_keys`, `program_ids`, `last_id`, `fee` and `instructions`, signed by `Pubkey`.
pub signature: Signature, pub signature: Signature,
/// The `Pubkeys` that are executing this transaction userdata. The meaning of each key is /// The `Pubkeys` that are executing this transaction userdata. The meaning of each key is
@ -42,8 +42,8 @@ pub struct Transaction {
/// The number of tokens paid for processing and storage of this transaction. /// The number of tokens paid for processing and storage of this transaction.
pub fee: i64, pub fee: i64,
/// Keys indentifying programs in the instructions vector. /// Keys identifying programs in the instructions vector.
pub program_keys: Vec<Pubkey>, pub program_ids: Vec<Pubkey>,
/// Programs that will be executed in sequence and commited in one atomic transaction if all /// Programs that will be executed in sequence and commited in one atomic transaction if all
/// succeed. /// succeed.
pub instructions: Vec<Instruction>, pub instructions: Vec<Instruction>,
@ -58,9 +58,9 @@ impl Transaction {
last_id: Hash, last_id: Hash,
fee: i64, fee: i64,
) -> Self { ) -> Self {
let program_keys = vec![program_id]; let program_ids = vec![program_id];
let instructions = vec![Instruction { let instructions = vec![Instruction {
program_id: 0, program_ids_index: 0,
userdata, userdata,
accounts: (0..(transaction_keys.len() as u8 + 1)) accounts: (0..(transaction_keys.len() as u8 + 1))
.into_iter() .into_iter()
@ -71,7 +71,7 @@ impl Transaction {
transaction_keys, transaction_keys,
last_id, last_id,
fee, fee,
program_keys, program_ids,
instructions, instructions,
) )
} }
@ -81,14 +81,14 @@ impl Transaction {
/// instances or token recipient keys. /// instances or token recipient keys.
/// * `last_id` - The PoH hash. /// * `last_id` - The PoH hash.
/// * `fee` - The transaction fee. /// * `fee` - The transaction fee.
/// * `program_keys` - The keys that identify programs used in the `instruction` vector. /// * `program_ids` - The keys that identify programs used in the `instruction` vector.
/// * `instructions` - The programs and their arguments that the transaction will execute atomically /// * `instructions` - The programs and their arguments that the transaction will execute atomically
pub fn new_with_instructions( pub fn new_with_instructions(
from_keypair: &Keypair, from_keypair: &Keypair,
keys: &[Pubkey], keys: &[Pubkey],
last_id: Hash, last_id: Hash,
fee: i64, fee: i64,
program_keys: Vec<Pubkey>, program_ids: Vec<Pubkey>,
instructions: Vec<Instruction>, instructions: Vec<Instruction>,
) -> Self { ) -> Self {
let from = from_keypair.pubkey(); let from = from_keypair.pubkey();
@ -99,23 +99,24 @@ impl Transaction {
account_keys, account_keys,
last_id, last_id,
fee, fee,
program_keys, program_ids,
instructions, instructions,
}; };
tx.sign(from_keypair); tx.sign(from_keypair);
tx tx
} }
pub fn userdata(&self, program_index: usize) -> &[u8] { pub fn userdata(&self, instruction_index: usize) -> &[u8] {
&self.instructions[program_index].userdata &self.instructions[instruction_index].userdata
} }
pub fn key(&self, program_index: usize, kix: usize) -> Option<&Pubkey> { pub fn key(&self, instruction_index: usize, accounts_index: usize) -> Option<&Pubkey> {
self.instructions self.instructions
.get(program_index) .get(instruction_index)
.and_then(|p| p.accounts.get(kix)) .and_then(|instruction| instruction.accounts.get(accounts_index))
.and_then(|ai| self.account_keys.get(*ai as usize)) .and_then(|ai| self.account_keys.get(*ai as usize))
} }
pub fn program_id(&self, program_index: usize) -> &Pubkey { pub fn program_id(&self, instruction_index: usize) -> &Pubkey {
&self.program_keys[self.instructions[program_index].program_id as usize] let program_ids_index = self.instructions[instruction_index].program_ids_index;
&self.program_ids[program_ids_index as usize]
} }
/// Get the transaction data to sign. /// Get the transaction data to sign.
pub fn get_sign_data(&self) -> Vec<u8> { pub fn get_sign_data(&self) -> Vec<u8> {
@ -124,11 +125,11 @@ impl Transaction {
let last_id_data = serialize(&self.last_id).expect("serialize last_id"); let last_id_data = serialize(&self.last_id).expect("serialize last_id");
data.extend_from_slice(&last_id_data); data.extend_from_slice(&last_id_data);
let fee_data = serialize(&self.fee).expect("serialize last_id"); let fee_data = serialize(&self.fee).expect("serialize fee");
data.extend_from_slice(&fee_data); data.extend_from_slice(&fee_data);
let program_keys = serialize(&self.program_keys).expect("serialize program_keys"); let program_ids = serialize(&self.program_ids).expect("serialize program_ids");
data.extend_from_slice(&program_keys); data.extend_from_slice(&program_ids);
let instructions = serialize(&self.instructions).expect("serialize instructions"); let instructions = serialize(&self.instructions).expect("serialize instructions");
data.extend_from_slice(&instructions); data.extend_from_slice(&instructions);
@ -151,7 +152,7 @@ impl Transaction {
/// Verify that references in the instructions are valid /// Verify that references in the instructions are valid
pub fn verify_refs(&self) -> bool { pub fn verify_refs(&self) -> bool {
for instruction in &self.instructions { for instruction in &self.instructions {
if (instruction.program_id as usize) >= self.program_keys.len() { if (instruction.program_ids_index as usize) >= self.program_ids.len() {
return false; return false;
} }
for account_index in &instruction.accounts { for account_index in &instruction.accounts {
@ -192,12 +193,12 @@ mod tests {
let prog2 = Keypair::new().pubkey(); let prog2 = Keypair::new().pubkey();
let instructions = vec![ let instructions = vec![
Instruction { Instruction {
program_id: 0, program_ids_index: 0,
userdata: vec![], userdata: vec![],
accounts: vec![0, 1], accounts: vec![0, 1],
}, },
Instruction { Instruction {
program_id: 1, program_ids_index: 1,
userdata: vec![], userdata: vec![],
accounts: vec![0, 2], accounts: vec![0, 2],
}, },
@ -224,7 +225,7 @@ mod tests {
fn test_refs_invalid_program_id() { fn test_refs_invalid_program_id() {
let key = Keypair::new(); let key = Keypair::new();
let instructions = vec![Instruction { let instructions = vec![Instruction {
program_id: 1, program_ids_index: 1,
userdata: vec![], userdata: vec![],
accounts: vec![], accounts: vec![],
}]; }];
@ -242,7 +243,7 @@ mod tests {
fn test_refs_invalid_account() { fn test_refs_invalid_account() {
let key = Keypair::new(); let key = Keypair::new();
let instructions = vec![Instruction { let instructions = vec![Instruction {
program_id: 0, program_ids_index: 0,
userdata: vec![], userdata: vec![],
accounts: vec![1], accounts: vec![1],
}]; }];