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(
program_index: usize,
instruction_index: usize,
tx_program_id: &Pubkey,
pre_program_id: &Pubkey,
pre_tokens: i64,
@ -425,14 +425,16 @@ impl Bank {
&& SystemProgram::check_id(&pre_program_id)))
{
//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.
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 {
return Err(BankError::ResultWithNegativeTokens(program_index as u8));
return Err(BankError::ResultWithNegativeTokens(instruction_index as u8));
}
Ok(())
}
@ -484,10 +486,10 @@ impl Bank {
fn execute_instruction(
&self,
tx: &Transaction,
program_index: usize,
instruction_index: usize,
program_accounts: &mut [&mut Account],
) -> 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
// we are trusting the hard coded contracts not to clobber or allocate
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) {
SystemProgram::process_transaction(
&tx,
program_index,
instruction_index,
program_accounts,
&self.loaded_contracts,
)
} else if BudgetState::check_id(&tx_program_id) {
if BudgetState::process_transaction(&tx, program_index, program_accounts).is_err() {
return Err(BankError::ProgramRuntimeError(program_index as u8));
if BudgetState::process_transaction(&tx, instruction_index, program_accounts).is_err() {
return Err(BankError::ProgramRuntimeError(instruction_index as u8));
}
} else if StorageProgram::check_id(&tx_program_id) {
if StorageProgram::process_transaction(&tx, program_index, program_accounts).is_err() {
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)
if StorageProgram::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 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 {
return Err(BankError::UnknownContractId(program_index as u8));
return Err(BankError::UnknownContractId(instruction_index as u8));
}
// Verify the transaction
for ((pre_program_id, pre_tokens), post_account) in
pre_data.iter().zip(program_accounts.iter())
{
Self::verify_transaction(
program_index,
instruction_index,
&tx_program_id,
pre_program_id,
*pre_tokens,
@ -543,7 +551,7 @@ impl Bank {
// 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();
if pre_total != post_total {
Err(BankError::UnbalancedTransaction(program_index as u8))
Err(BankError::UnbalancedTransaction(instruction_index as u8))
} else {
Ok(())
}
@ -552,9 +560,9 @@ impl Bank {
/// 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
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.execute_instruction(tx, program_index, program_accounts)
self.execute_instruction(tx, instruction_index, program_accounts)
})?;
}
Ok(())
@ -1005,12 +1013,12 @@ mod tests {
let spend = SystemProgram::Move { tokens: 1 };
let instructions = vec![
Instruction {
program_id: 0,
program_ids_index: 0,
userdata: serialize(&spend).unwrap(),
accounts: vec![0, 1],
},
Instruction {
program_id: 0,
program_ids_index: 0,
userdata: serialize(&spend).unwrap(),
accounts: vec![0, 2],
},
@ -1045,12 +1053,12 @@ mod tests {
let spend = SystemProgram::Move { tokens: 1 };
let instructions = vec![
Instruction {
program_id: 0,
program_ids_index: 0,
userdata: serialize(&spend).unwrap(),
accounts: vec![0, 1],
},
Instruction {
program_id: 0,
program_ids_index: 0,
userdata: serialize(&spend).unwrap(),
accounts: vec![0, 2],
},

View File

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

View File

@ -278,7 +278,7 @@ mod tests {
let instruction = Instruction::NewContract(Contract { budget, tokens: 0 });
let userdata = serialize(&instruction).unwrap();
let instructions = vec![transaction::Instruction {
program_id: 0,
program_ids_index: 0,
userdata,
accounts: vec![],
}];
@ -286,7 +286,7 @@ mod tests {
account_keys: vec![],
last_id: Default::default(),
signature: Default::default(),
program_keys: vec![],
program_ids: vec![],
instructions,
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 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
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Instruction {
/// The program code that executes this transaction is identified by the program_id.
/// this is an offset into the Transaction::program_keys field
pub program_id: u8,
/// this is an offset into the Transaction::program_ids field
pub program_ids_index: u8,
/// Indices into the keys array of which accounts to load
pub accounts: Vec<u8>,
/// Userdata to be stored in the account
@ -26,7 +26,7 @@ pub struct Instruction {
/// An atomic transaction
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
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,
/// 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.
pub fee: i64,
/// Keys indentifying programs in the instructions vector.
pub program_keys: Vec<Pubkey>,
/// Keys identifying programs in the instructions vector.
pub program_ids: Vec<Pubkey>,
/// Programs that will be executed in sequence and commited in one atomic transaction if all
/// succeed.
pub instructions: Vec<Instruction>,
@ -58,9 +58,9 @@ impl Transaction {
last_id: Hash,
fee: i64,
) -> Self {
let program_keys = vec![program_id];
let program_ids = vec![program_id];
let instructions = vec![Instruction {
program_id: 0,
program_ids_index: 0,
userdata,
accounts: (0..(transaction_keys.len() as u8 + 1))
.into_iter()
@ -71,7 +71,7 @@ impl Transaction {
transaction_keys,
last_id,
fee,
program_keys,
program_ids,
instructions,
)
}
@ -81,14 +81,14 @@ impl Transaction {
/// instances or token recipient keys.
/// * `last_id` - The PoH hash.
/// * `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
pub fn new_with_instructions(
from_keypair: &Keypair,
keys: &[Pubkey],
last_id: Hash,
fee: i64,
program_keys: Vec<Pubkey>,
program_ids: Vec<Pubkey>,
instructions: Vec<Instruction>,
) -> Self {
let from = from_keypair.pubkey();
@ -99,23 +99,24 @@ impl Transaction {
account_keys,
last_id,
fee,
program_keys,
program_ids,
instructions,
};
tx.sign(from_keypair);
tx
}
pub fn userdata(&self, program_index: usize) -> &[u8] {
&self.instructions[program_index].userdata
pub fn userdata(&self, instruction_index: usize) -> &[u8] {
&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
.get(program_index)
.and_then(|p| p.accounts.get(kix))
.get(instruction_index)
.and_then(|instruction| instruction.accounts.get(accounts_index))
.and_then(|ai| self.account_keys.get(*ai as usize))
}
pub fn program_id(&self, program_index: usize) -> &Pubkey {
&self.program_keys[self.instructions[program_index].program_id as usize]
pub fn program_id(&self, instruction_index: usize) -> &Pubkey {
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.
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");
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);
let program_keys = serialize(&self.program_keys).expect("serialize program_keys");
data.extend_from_slice(&program_keys);
let program_ids = serialize(&self.program_ids).expect("serialize program_ids");
data.extend_from_slice(&program_ids);
let instructions = serialize(&self.instructions).expect("serialize instructions");
data.extend_from_slice(&instructions);
@ -151,7 +152,7 @@ impl Transaction {
/// Verify that references in the instructions are valid
pub fn verify_refs(&self) -> bool {
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;
}
for account_index in &instruction.accounts {
@ -192,12 +193,12 @@ mod tests {
let prog2 = Keypair::new().pubkey();
let instructions = vec![
Instruction {
program_id: 0,
program_ids_index: 0,
userdata: vec![],
accounts: vec![0, 1],
},
Instruction {
program_id: 1,
program_ids_index: 1,
userdata: vec![],
accounts: vec![0, 2],
},
@ -224,7 +225,7 @@ mod tests {
fn test_refs_invalid_program_id() {
let key = Keypair::new();
let instructions = vec![Instruction {
program_id: 1,
program_ids_index: 1,
userdata: vec![],
accounts: vec![],
}];
@ -242,7 +243,7 @@ mod tests {
fn test_refs_invalid_account() {
let key = Keypair::new();
let instructions = vec![Instruction {
program_id: 0,
program_ids_index: 0,
userdata: vec![],
accounts: vec![1],
}];