remove `purge` parameter to accounts (#2990)
This commit is contained in:
parent
873007bae1
commit
163874d4da
|
@ -429,11 +429,9 @@ impl AccountsDB {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store the account update. If the update is to delete the account because
|
/// Store the account update.
|
||||||
/// the token balance is 0, purge needs to be set to true for the delete
|
fn store_account(&self, fork: Fork, pubkey: &Pubkey, account: &Account) {
|
||||||
/// to occur in place.
|
if account.tokens == 0 && self.is_squashed(fork) {
|
||||||
fn store_account(&self, fork: Fork, purge: bool, pubkey: &Pubkey, account: &Account) {
|
|
||||||
if account.tokens == 0 && purge {
|
|
||||||
// purge if balance is 0 and no checkpoints
|
// purge if balance is 0 and no checkpoints
|
||||||
let index = self.index_info.index.read().unwrap();
|
let index = self.index_info.index.read().unwrap();
|
||||||
let map = index.get(&pubkey).unwrap();
|
let map = index.get(&pubkey).unwrap();
|
||||||
|
@ -459,20 +457,19 @@ impl AccountsDB {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store(&self, fork: Fork, purge: bool, pubkey: &Pubkey, account: &Account) {
|
pub fn store(&self, fork: Fork, pubkey: &Pubkey, account: &Account) {
|
||||||
{
|
{
|
||||||
if !self.index_info.index.read().unwrap().contains_key(&pubkey) {
|
if !self.index_info.index.read().unwrap().contains_key(&pubkey) {
|
||||||
let mut windex = self.index_info.index.write().unwrap();
|
let mut windex = self.index_info.index.write().unwrap();
|
||||||
windex.insert(*pubkey, AccountMap(RwLock::new(HashMap::new())));
|
windex.insert(*pubkey, AccountMap(RwLock::new(HashMap::new())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.store_account(fork, purge, pubkey, account);
|
self.store_account(fork, pubkey, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store_accounts(
|
pub fn store_accounts(
|
||||||
&self,
|
&self,
|
||||||
fork: Fork,
|
fork: Fork,
|
||||||
purge: bool,
|
|
||||||
txs: &[Transaction],
|
txs: &[Transaction],
|
||||||
res: &[Result<()>],
|
res: &[Result<()>],
|
||||||
loaded: &[Result<(InstructionAccounts, InstructionLoaders)>],
|
loaded: &[Result<(InstructionAccounts, InstructionLoaders)>],
|
||||||
|
@ -506,7 +503,7 @@ impl AccountsDB {
|
||||||
let tx = &txs[i];
|
let tx = &txs[i];
|
||||||
let acc = raccs.as_ref().unwrap();
|
let acc = raccs.as_ref().unwrap();
|
||||||
for (key, account) in tx.account_keys.iter().zip(acc.0.iter()) {
|
for (key, account) in tx.account_keys.iter().zip(acc.0.iter()) {
|
||||||
self.store(fork, purge, key, account);
|
self.store(fork, key, account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -649,6 +646,16 @@ impl AccountsDB {
|
||||||
parents
|
parents
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_squashed(&self, fork: Fork) -> bool {
|
||||||
|
self.fork_info
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get(&fork)
|
||||||
|
.unwrap()
|
||||||
|
.parents
|
||||||
|
.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
fn get_merged_index(
|
fn get_merged_index(
|
||||||
&self,
|
&self,
|
||||||
fork: Fork,
|
fork: Fork,
|
||||||
|
@ -668,7 +675,7 @@ impl AccountsDB {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// become the root accountsDB
|
/// make fork a root, i.e. forget its heritage
|
||||||
fn squash(&self, fork: Fork) {
|
fn squash(&self, fork: Fork) {
|
||||||
let parents = self.remove_parents(fork);
|
let parents = self.remove_parents(fork);
|
||||||
let tx_count = parents
|
let tx_count = parents
|
||||||
|
@ -769,10 +776,8 @@ impl Accounts {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Slow because lock is held for 1 operation insted of many
|
/// Slow because lock is held for 1 operation insted of many
|
||||||
/// * purge - if the account token value is 0 and purge is true then delete the account.
|
pub fn store_slow(&self, fork: Fork, pubkey: &Pubkey, account: &Account) {
|
||||||
/// purge should be set to false for overlays, and true for the root checkpoint.
|
self.accounts_db.store(fork, pubkey, account);
|
||||||
pub fn store_slow(&self, fork: Fork, purge: bool, pubkey: &Pubkey, account: &Account) {
|
|
||||||
self.accounts_db.store(fork, purge, pubkey, account);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lock_account(
|
fn lock_account(
|
||||||
|
@ -871,18 +876,14 @@ impl Accounts {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store the accounts into the DB
|
/// Store the accounts into the DB
|
||||||
/// * purge - if the account token value is 0 and purge is true then delete the account.
|
|
||||||
/// purge should be set to false for overlays, and true for the root checkpoint.
|
|
||||||
pub fn store_accounts(
|
pub fn store_accounts(
|
||||||
&self,
|
&self,
|
||||||
fork: Fork,
|
fork: Fork,
|
||||||
purge: bool,
|
|
||||||
txs: &[Transaction],
|
txs: &[Transaction],
|
||||||
res: &[Result<()>],
|
res: &[Result<()>],
|
||||||
loaded: &[Result<(InstructionAccounts, InstructionLoaders)>],
|
loaded: &[Result<(InstructionAccounts, InstructionLoaders)>],
|
||||||
) {
|
) {
|
||||||
self.accounts_db
|
self.accounts_db.store_accounts(fork, txs, res, loaded)
|
||||||
.store_accounts(fork, purge, txs, res, loaded)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn increment_transaction_count(&self, fork: Fork, tx_count: usize) {
|
pub fn increment_transaction_count(&self, fork: Fork, tx_count: usize) {
|
||||||
|
@ -914,21 +915,6 @@ mod tests {
|
||||||
use solana_sdk::transaction::Instruction;
|
use solana_sdk::transaction::Instruction;
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::Transaction;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_purge() {
|
|
||||||
let paths = "purge".to_string();
|
|
||||||
let db = AccountsDB::new(0, &paths);
|
|
||||||
let key = Pubkey::default();
|
|
||||||
let account = Account::new(0, 0, Pubkey::default());
|
|
||||||
// accounts are deleted when their token value is 0 and purge is true
|
|
||||||
db.store(0, false, &key, &account);
|
|
||||||
assert_eq!(db.load(0, &key, true), Some(account.clone()));
|
|
||||||
// purge should be set to true for the root checkpoint
|
|
||||||
db.store(0, true, &key, &account);
|
|
||||||
assert_eq!(db.load(0, &key, true), None);
|
|
||||||
cleanup_dirs(&paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_accounts(
|
fn load_accounts(
|
||||||
tx: Transaction,
|
tx: Transaction,
|
||||||
ka: &Vec<(Pubkey, Account)>,
|
ka: &Vec<(Pubkey, Account)>,
|
||||||
|
@ -936,7 +922,7 @@ mod tests {
|
||||||
) -> Vec<Result<(InstructionAccounts, InstructionLoaders)>> {
|
) -> Vec<Result<(InstructionAccounts, InstructionLoaders)>> {
|
||||||
let accounts = Accounts::new(0, None);
|
let accounts = Accounts::new(0, None);
|
||||||
for ka in ka.iter() {
|
for ka in ka.iter() {
|
||||||
accounts.store_slow(0, true, &ka.0, &ka.1);
|
accounts.store_slow(0, &ka.0, &ka.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = accounts.load_accounts(0, &[tx], vec![Ok(())], error_counters);
|
let res = accounts.load_accounts(0, &[tx], vec![Ok(())], error_counters);
|
||||||
|
@ -1321,7 +1307,7 @@ mod tests {
|
||||||
let account0 = Account::new(1, 0, key);
|
let account0 = Account::new(1, 0, key);
|
||||||
|
|
||||||
// store value 1 in the "root", i.e. db zero
|
// store value 1 in the "root", i.e. db zero
|
||||||
db.store(0, true, &key, &account0);
|
db.store(0, &key, &account0);
|
||||||
|
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||||
create_account(&db, &mut pubkeys, 100, 0);
|
create_account(&db, &mut pubkeys, 100, 0);
|
||||||
|
@ -1333,9 +1319,9 @@ mod tests {
|
||||||
assert_eq!(compare_account(&default_account, &account), true);
|
assert_eq!(compare_account(&default_account, &account), true);
|
||||||
}
|
}
|
||||||
db.add_fork(1, Some(0));
|
db.add_fork(1, Some(0));
|
||||||
// store value 0 in the child, but don't purge (see purge test above)
|
// store value 0 in the child
|
||||||
let account1 = Account::new(0, 0, key);
|
let account1 = Account::new(0, 0, key);
|
||||||
db.store(1, false, &key, &account1);
|
db.store(1, &key, &account1);
|
||||||
|
|
||||||
// masking accounts is done at the Accounts level, at accountsDB we see
|
// masking accounts is done at the Accounts level, at accountsDB we see
|
||||||
// original account
|
// original account
|
||||||
|
@ -1365,12 +1351,12 @@ mod tests {
|
||||||
let paths = "unsquash".to_string();
|
let paths = "unsquash".to_string();
|
||||||
let db0 = AccountsDB::new(0, &paths);
|
let db0 = AccountsDB::new(0, &paths);
|
||||||
let account0 = Account::new(1, 0, key);
|
let account0 = Account::new(1, 0, key);
|
||||||
db0.store(0, true, &key, &account0);
|
db0.store(0, &key, &account0);
|
||||||
|
|
||||||
db0.add_fork(1, Some(0));
|
db0.add_fork(1, Some(0));
|
||||||
// 0 tokens in the child
|
// 0 tokens in the child
|
||||||
let account1 = Account::new(0, 0, key);
|
let account1 = Account::new(0, 0, key);
|
||||||
db0.store(1, false, &key, &account1);
|
db0.store(1, &key, &account1);
|
||||||
|
|
||||||
// masking accounts is done at the Accounts level, at accountsDB we see
|
// masking accounts is done at the Accounts level, at accountsDB we see
|
||||||
// original account
|
// original account
|
||||||
|
@ -1400,7 +1386,7 @@ mod tests {
|
||||||
nvote -= 1;
|
nvote -= 1;
|
||||||
}
|
}
|
||||||
assert!(accounts.load(0, &pubkey, true).is_none());
|
assert!(accounts.load(0, &pubkey, true).is_none());
|
||||||
accounts.store(0, true, &pubkey, &default_account);
|
accounts.store(0, &pubkey, &default_account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1409,7 +1395,7 @@ mod tests {
|
||||||
let idx = thread_rng().gen_range(0, range);
|
let idx = thread_rng().gen_range(0, range);
|
||||||
if let Some(mut account) = accounts.load(0, &pubkeys[idx], true) {
|
if let Some(mut account) = accounts.load(0, &pubkeys[idx], true) {
|
||||||
account.tokens = account.tokens + 1;
|
account.tokens = account.tokens + 1;
|
||||||
accounts.store(0, true, &pubkeys[idx], &account);
|
accounts.store(0, &pubkeys[idx], &account);
|
||||||
if account.tokens == 0 {
|
if account.tokens == 0 {
|
||||||
assert!(accounts.load(0, &pubkeys[idx], true).is_none());
|
assert!(accounts.load(0, &pubkeys[idx], true).is_none());
|
||||||
} else {
|
} else {
|
||||||
|
@ -1491,7 +1477,7 @@ mod tests {
|
||||||
];
|
];
|
||||||
let pubkey1 = Keypair::new().pubkey();
|
let pubkey1 = Keypair::new().pubkey();
|
||||||
let account1 = Account::new(1, ACCOUNT_DATA_FILE_SIZE as usize / 2, pubkey1);
|
let account1 = Account::new(1, ACCOUNT_DATA_FILE_SIZE as usize / 2, pubkey1);
|
||||||
accounts.store(0, true, &pubkey1, &account1);
|
accounts.store(0, &pubkey1, &account1);
|
||||||
{
|
{
|
||||||
let stores = accounts.storage.read().unwrap();
|
let stores = accounts.storage.read().unwrap();
|
||||||
assert_eq!(stores.len(), 1);
|
assert_eq!(stores.len(), 1);
|
||||||
|
@ -1501,7 +1487,7 @@ mod tests {
|
||||||
|
|
||||||
let pubkey2 = Keypair::new().pubkey();
|
let pubkey2 = Keypair::new().pubkey();
|
||||||
let account2 = Account::new(1, ACCOUNT_DATA_FILE_SIZE as usize / 2, pubkey2);
|
let account2 = Account::new(1, ACCOUNT_DATA_FILE_SIZE as usize / 2, pubkey2);
|
||||||
accounts.store(0, true, &pubkey2, &account2);
|
accounts.store(0, &pubkey2, &account2);
|
||||||
{
|
{
|
||||||
let stores = accounts.storage.read().unwrap();
|
let stores = accounts.storage.read().unwrap();
|
||||||
assert_eq!(stores.len(), 2);
|
assert_eq!(stores.len(), 2);
|
||||||
|
@ -1515,7 +1501,7 @@ mod tests {
|
||||||
|
|
||||||
for i in 0..25 {
|
for i in 0..25 {
|
||||||
let index = i % 2;
|
let index = i % 2;
|
||||||
accounts.store(0, true, &pubkey1, &account1);
|
accounts.store(0, &pubkey1, &account1);
|
||||||
{
|
{
|
||||||
let stores = accounts.storage.read().unwrap();
|
let stores = accounts.storage.read().unwrap();
|
||||||
assert_eq!(stores.len(), 3);
|
assert_eq!(stores.len(), 3);
|
||||||
|
|
|
@ -243,7 +243,6 @@ impl Bank {
|
||||||
|
|
||||||
self.accounts().store_slow(
|
self.accounts().store_slow(
|
||||||
self.id,
|
self.id,
|
||||||
self.is_root(),
|
|
||||||
&genesis_block.bootstrap_leader_vote_account_id,
|
&genesis_block.bootstrap_leader_vote_account_id,
|
||||||
&bootstrap_leader_vote_account,
|
&bootstrap_leader_vote_account,
|
||||||
);
|
);
|
||||||
|
@ -260,8 +259,7 @@ impl Bank {
|
||||||
|
|
||||||
pub fn add_native_program(&self, name: &str, program_id: &Pubkey) {
|
pub fn add_native_program(&self, name: &str, program_id: &Pubkey) {
|
||||||
let account = native_loader::create_program_account(name);
|
let account = native_loader::create_program_account(name);
|
||||||
self.accounts()
|
self.accounts().store_slow(self.id, program_id, &account);
|
||||||
.store_slow(self.id, self.is_root(), program_id, &account);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_builtin_programs(&self) {
|
fn add_builtin_programs(&self) {
|
||||||
|
@ -548,7 +546,7 @@ impl Bank {
|
||||||
// assert!(!self.is_frozen());
|
// assert!(!self.is_frozen());
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
self.accounts()
|
self.accounts()
|
||||||
.store_accounts(self.id, self.is_root(), txs, executed, loaded_accounts);
|
.store_accounts(self.id, txs, executed, loaded_accounts);
|
||||||
|
|
||||||
// once committed there is no way to unroll
|
// once committed there is no way to unroll
|
||||||
let write_elapsed = now.elapsed();
|
let write_elapsed = now.elapsed();
|
||||||
|
@ -633,7 +631,7 @@ impl Bank {
|
||||||
}
|
}
|
||||||
|
|
||||||
account.tokens -= tokens;
|
account.tokens -= tokens;
|
||||||
self.accounts().store_slow(self.id, true, pubkey, &account);
|
self.accounts().store_slow(self.id, pubkey, &account);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
None => Err(BankError::AccountNotFound),
|
None => Err(BankError::AccountNotFound),
|
||||||
|
@ -643,8 +641,7 @@ impl Bank {
|
||||||
pub fn deposit(&self, pubkey: &Pubkey, tokens: u64) {
|
pub fn deposit(&self, pubkey: &Pubkey, tokens: u64) {
|
||||||
let mut account = self.get_account(pubkey).unwrap_or_default();
|
let mut account = self.get_account(pubkey).unwrap_or_default();
|
||||||
account.tokens += tokens;
|
account.tokens += tokens;
|
||||||
self.accounts()
|
self.accounts().store_slow(self.id, pubkey, &account);
|
||||||
.store_slow(self.id, self.is_root(), pubkey, &account);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accounts(&self) -> Arc<Accounts> {
|
fn accounts(&self) -> Arc<Accounts> {
|
||||||
|
|
Loading…
Reference in New Issue