Credit-Only Accounts: Cache account balance for thread-safe load/store (#4691)

* Implement CreditOnlyLocks

* Update credit-only atomic on account load

* Update credit-only atomic after bank.freeze_lock; store credits if all credit-only lock references are dropped

* Commit credit-only credits on bank freeze

* Update core to CreditAccountLocks

* Impl credit-only in System Transfer

* Rework CreditAccountLocks, test, and fix bugs

* Review comments: Pass CreditAccountLocks by reference; Tighten up insert block

* Only store credits on completed slot

* Check balance in bench_exchange funding to ensure commit_credits has completed

* Add is_debitable info to KeyedAccount meta to pass into programs

* Reinstate CreditOnlyLocks check on lock_account

* Rework CreditAccountLocks to remove strong_count usage

* Add multi-threaded credit-only locks test

* Improve RwLocks usage

* Review comments: panic if bad things happen; tighter code

* Assert lock_accounts race does not happen

* Revert panic if bad things happen; not a bad thing
This commit is contained in:
Tyera Eulberg
2019-06-27 17:25:10 -04:00
committed by GitHub
parent 979df17328
commit 66552d7047
12 changed files with 657 additions and 177 deletions

View File

@ -78,6 +78,7 @@ pub type LamportCredit = u64;
#[derive(Debug)]
pub struct KeyedAccount<'a> {
is_signer: bool, // Transaction was signed by this account's key
is_debitable: bool,
key: &'a Pubkey,
pub account: &'a mut Account,
}
@ -95,10 +96,28 @@ impl<'a> KeyedAccount<'a> {
self.key
}
pub fn is_debitable(&self) -> bool {
self.is_debitable
}
pub fn new(key: &'a Pubkey, is_signer: bool, account: &'a mut Account) -> KeyedAccount<'a> {
KeyedAccount {
key,
is_signer,
is_debitable: true,
key,
account,
}
}
pub fn new_credit_only(
key: &'a Pubkey,
is_signer: bool,
account: &'a mut Account,
) -> KeyedAccount<'a> {
KeyedAccount {
is_signer,
is_debitable: false,
key,
account,
}
}
@ -108,6 +127,7 @@ impl<'a> From<(&'a Pubkey, &'a mut Account)> for KeyedAccount<'a> {
fn from((key, account): (&'a Pubkey, &'a mut Account)) -> Self {
KeyedAccount {
is_signer: false,
is_debitable: true,
key,
account,
}
@ -118,6 +138,7 @@ impl<'a> From<&'a mut (Pubkey, Account)> for KeyedAccount<'a> {
fn from((key, account): &'a mut (Pubkey, Account)) -> Self {
KeyedAccount {
is_signer: false,
is_debitable: true,
key,
account,
}
@ -127,3 +148,15 @@ impl<'a> From<&'a mut (Pubkey, Account)> for KeyedAccount<'a> {
pub fn create_keyed_accounts(accounts: &mut [(Pubkey, Account)]) -> Vec<KeyedAccount> {
accounts.iter_mut().map(Into::into).collect()
}
pub fn create_keyed_credit_only_accounts(accounts: &mut [(Pubkey, Account)]) -> Vec<KeyedAccount> {
accounts
.iter_mut()
.map(|(key, account)| KeyedAccount {
is_signer: false,
is_debitable: false,
key,
account,
})
.collect()
}

View File

@ -90,7 +90,7 @@ pub fn assign(from_pubkey: &Pubkey, program_id: &Pubkey) -> Instruction {
pub fn transfer(from_pubkey: &Pubkey, to_pubkey: &Pubkey, lamports: u64) -> Instruction {
let account_metas = vec![
AccountMeta::new(*from_pubkey, true),
AccountMeta::new(*to_pubkey, false),
AccountMeta::new_credit_only(*to_pubkey, false),
];
Instruction::new(
system_program::id(),