Cleanup field names
This commit is contained in:
parent
680f90df21
commit
b508fdb62c
68
src/bank.rs
68
src/bank.rs
|
@ -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],
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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],
|
||||
}];
|
||||
|
|
Loading…
Reference in New Issue