comments (#1165)
This commit is contained in:
parent
ebcac3c2d1
commit
a89b611e9e
25
src/bank.rs
25
src/bank.rs
|
@ -63,7 +63,7 @@ pub enum BankError {
|
|||
LedgerVerificationFailed,
|
||||
/// Contract's transaction token balance does not equal the balance after the transaction
|
||||
UnbalancedTransaction(Signature),
|
||||
/// ContractAlreadyPending
|
||||
/// Contract location Pubkey already contains userdata
|
||||
ContractAlreadyPending(Pubkey),
|
||||
}
|
||||
|
||||
|
@ -232,16 +232,19 @@ impl Bank {
|
|||
last_ids.push_back(*last_id);
|
||||
}
|
||||
|
||||
/// Deduct tokens from the 'from' address the account has sufficient
|
||||
/// funds and isn't a duplicate.
|
||||
fn apply_debits(
|
||||
/// Deduct tokens from the source account if it has sufficient funds and the contract isn't
|
||||
/// pending
|
||||
fn apply_debits_to_budget_payment_plan(
|
||||
tx: &Transaction,
|
||||
accounts: &mut [Account],
|
||||
instruction: &Instruction,
|
||||
) -> Result<()> {
|
||||
{
|
||||
let empty = accounts[0].userdata.is_empty();
|
||||
let tokens = if !empty { 0 } else { accounts[0].tokens };
|
||||
let tokens = if !accounts[0].userdata.is_empty() {
|
||||
0
|
||||
} else {
|
||||
accounts[0].tokens
|
||||
};
|
||||
if let Instruction::NewContract(contract) = &instruction {
|
||||
if contract.tokens < 0 {
|
||||
return Err(BankError::NegativeTokens);
|
||||
|
@ -260,7 +263,7 @@ impl Bank {
|
|||
|
||||
/// Apply only a transaction's credits.
|
||||
/// Note: It is safe to apply credits from multiple transactions in parallel.
|
||||
fn apply_credits(
|
||||
fn apply_credits_to_budget_payment_plan(
|
||||
tx: &Transaction,
|
||||
accounts: &mut [Account],
|
||||
instruction: &Instruction,
|
||||
|
@ -276,7 +279,7 @@ impl Bank {
|
|||
} else {
|
||||
let mut pending = HashMap::new();
|
||||
pending.insert(tx.signature, plan);
|
||||
//TODO this is a temporary on demand allocaiton
|
||||
//TODO this is a temporary on demand allocation
|
||||
//until system contract requires explicit allocation of memory
|
||||
accounts[1].userdata = serialize(&pending).unwrap();
|
||||
accounts[1].tokens += contract.tokens;
|
||||
|
@ -308,8 +311,8 @@ impl Bank {
|
|||
accounts: &mut [Account],
|
||||
) -> Result<()> {
|
||||
let instruction = tx.instruction();
|
||||
Self::apply_debits(tx, accounts, &instruction)?;
|
||||
Self::apply_credits(tx, accounts, &instruction)
|
||||
Self::apply_debits_to_budget_payment_plan(tx, accounts, &instruction)?;
|
||||
Self::apply_credits_to_budget_payment_plan(tx, accounts, &instruction)
|
||||
}
|
||||
//TODO the contract needs to provide a "get_balance" introspection call of the userdata
|
||||
pub fn get_balance_of_budget_payment_plan(account: &Account) -> i64 {
|
||||
|
@ -918,7 +921,7 @@ mod tests {
|
|||
// pubkey's balance will be 0 because the funds are locked up
|
||||
assert_eq!(bank.get_balance(&pubkey), 0);
|
||||
|
||||
// Now, cancel the trancaction. Mint gets her funds back, pubkey never sees them.
|
||||
// Now, cancel the transaction. Mint gets her funds back, pubkey never sees them.
|
||||
let tx = Transaction::new_signature(&mint.keypair(), pubkey, signature, bank.last_id());
|
||||
let res = bank.process_transaction(&tx);
|
||||
assert!(res.is_ok());
|
||||
|
|
|
@ -188,8 +188,8 @@ impl ThinClient {
|
|||
self.process_response(&resp);
|
||||
}
|
||||
trace!("get_balance {:?}", self.balances.get(pubkey));
|
||||
//TODO: call the contract specific get_balance for contract_id's thin client can introspect
|
||||
//instead of hard coding to budget_dsl only
|
||||
// TODO: This is a hard coded call to introspect the balance of a budget_dsl contract
|
||||
// In the future custom contracts would need their own introspection
|
||||
self.balances
|
||||
.get(pubkey)
|
||||
.map(Bank::get_balance_of_budget_payment_plan)
|
||||
|
|
|
@ -84,9 +84,9 @@ pub struct Transaction {
|
|||
|
||||
/// The `Pubkeys` that are executing this transaction userdata. The meaning of each key is
|
||||
/// contract-specific.
|
||||
/// * keys[0] - Typically this is the `from` public key. `signature` is verified with keys[0].
|
||||
/// * keys[0] - Typically this is the `caller` public key. `signature` is verified with keys[0].
|
||||
/// In the future which key pays the fee and which keys have signatures would be configurable.
|
||||
/// * keys[1] - Typically this is the contract context or the recepient of the tokens
|
||||
/// * keys[1] - Typically this is the contract context or the recipient of the tokens
|
||||
pub keys: Vec<Pubkey>,
|
||||
|
||||
/// The ID of a recent ledger entry.
|
||||
|
@ -103,7 +103,7 @@ impl Transaction {
|
|||
/// Create a signed transaction from the given `Instruction`.
|
||||
/// * `from_keypair` - The key used to sign the transcation. This key is stored as keys[0]
|
||||
/// * `transaction_keys` - The keys for the transaction. These are the contract state
|
||||
/// instances or token recepient keys.
|
||||
/// instances or token recipient keys.
|
||||
/// * `userdata` - The input data that the contract will execute with
|
||||
/// * `last_id` - The PoH hash.
|
||||
/// * `fee` - The transaction fee.
|
||||
|
@ -135,7 +135,7 @@ impl Transaction {
|
|||
last_id: Hash,
|
||||
fee: i64,
|
||||
) -> Self {
|
||||
let userdata = serialize(&instruction).expect("serealize instruction");
|
||||
let userdata = serialize(&instruction).unwrap();
|
||||
Self::new_with_userdata(from_keypair, &[contract], userdata, last_id, fee)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue