This commit is contained in:
anatoly yakovenko 2018-09-09 07:07:38 -07:00 committed by GitHub
parent ebcac3c2d1
commit a89b611e9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 17 deletions

View File

@ -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());

View File

@ -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)

View File

@ -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)
}