Simple cap by including sysvars and native programs (#13884)

* Simpler cap by including sysvars and native programs

* Fix tests

* Add comment

* revert some unrelated code

* Update test_bank_update_sysvar_account for cap.

* Test cap. for add_native_program using new helper

* Improve the cap adjustment with new tests

* Fix typo...

* Adjust test for improved code coverage

* Rename simpler_capitalization => simple_capitalization

* More rename and bonus commenting
This commit is contained in:
Ryo Onodera
2020-12-14 21:03:24 +09:00
committed by GitHub
parent 4bcc8afdc0
commit de9ac43ebf
8 changed files with 439 additions and 63 deletions

View File

@@ -2246,7 +2246,12 @@ impl AccountsDB {
lamports: u64,
owner: &Pubkey,
executable: bool,
simple_capitalization_enabled: bool,
) -> u64 {
if simple_capitalization_enabled {
return lamports;
}
let is_specially_retained = (solana_sdk::native_loader::check_id(owner) && executable)
|| solana_sdk::sysvar::check_id(owner);
@@ -2265,6 +2270,7 @@ impl AccountsDB {
slot: Slot,
ancestors: &Ancestors,
check_hash: bool,
simple_capitalization_enabled: bool,
) -> Result<(Hash, u64), BankHashVerificationError> {
use BankHashVerificationError::*;
let mut scan = Measure::start("scan");
@@ -2295,6 +2301,7 @@ impl AccountsDB {
account_info.lamports,
&account.account_meta.owner,
account.account_meta.executable,
simple_capitalization_enabled,
);
if check_hash {
@@ -2353,9 +2360,14 @@ impl AccountsDB {
bank_hash_info.snapshot_hash
}
pub fn update_accounts_hash(&self, slot: Slot, ancestors: &Ancestors) -> (Hash, u64) {
pub fn update_accounts_hash(
&self,
slot: Slot,
ancestors: &Ancestors,
simple_capitalization_enabled: bool,
) -> (Hash, u64) {
let (hash, total_lamports) = self
.calculate_accounts_hash(slot, ancestors, false)
.calculate_accounts_hash(slot, ancestors, false, simple_capitalization_enabled)
.unwrap();
let mut bank_hashes = self.bank_hashes.write().unwrap();
let mut bank_hash_info = bank_hashes.get_mut(&slot).unwrap();
@@ -2368,11 +2380,12 @@ impl AccountsDB {
slot: Slot,
ancestors: &Ancestors,
total_lamports: u64,
simple_capitalization_enabled: bool,
) -> Result<(), BankHashVerificationError> {
use BankHashVerificationError::*;
let (calculated_hash, calculated_lamports) =
self.calculate_accounts_hash(slot, ancestors, true)?;
self.calculate_accounts_hash(slot, ancestors, true, simple_capitalization_enabled)?;
if calculated_lamports != total_lamports {
warn!(
@@ -4015,8 +4028,8 @@ pub mod tests {
let ancestors = linear_ancestors(latest_slot);
assert_eq!(
daccounts.update_accounts_hash(latest_slot, &ancestors),
accounts.update_accounts_hash(latest_slot, &ancestors)
daccounts.update_accounts_hash(latest_slot, &ancestors, true),
accounts.update_accounts_hash(latest_slot, &ancestors, true)
);
}
@@ -4169,12 +4182,12 @@ pub mod tests {
let ancestors = linear_ancestors(current_slot);
info!("ancestors: {:?}", ancestors);
let hash = accounts.update_accounts_hash(current_slot, &ancestors);
let hash = accounts.update_accounts_hash(current_slot, &ancestors, true);
accounts.clean_accounts(None);
assert_eq!(
accounts.update_accounts_hash(current_slot, &ancestors),
accounts.update_accounts_hash(current_slot, &ancestors, true),
hash
);
@@ -4291,7 +4304,7 @@ pub mod tests {
accounts.add_root(current_slot);
accounts.print_accounts_stats("pre_f");
accounts.update_accounts_hash(4, &HashMap::default());
accounts.update_accounts_hash(4, &HashMap::default(), true);
let accounts = f(accounts, current_slot);
@@ -4303,7 +4316,7 @@ pub mod tests {
assert_load_account(&accounts, current_slot, dummy_pubkey, dummy_lamport);
accounts
.verify_bank_hash_and_lamports(4, &HashMap::default(), 1222)
.verify_bank_hash_and_lamports(4, &HashMap::default(), 1222, true)
.unwrap();
}
@@ -4700,15 +4713,15 @@ pub mod tests {
db.store(some_slot, &[(&key, &account)]);
db.add_root(some_slot);
db.update_accounts_hash(some_slot, &ancestors);
db.update_accounts_hash(some_slot, &ancestors, true);
assert_matches!(
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1),
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1, true),
Ok(_)
);
db.bank_hashes.write().unwrap().remove(&some_slot).unwrap();
assert_matches!(
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1),
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1, true),
Err(MissingBankHash)
);
@@ -4723,7 +4736,7 @@ pub mod tests {
.unwrap()
.insert(some_slot, bank_hash_info);
assert_matches!(
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1),
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1, true),
Err(MismatchedBankHash)
);
}
@@ -4742,9 +4755,9 @@ pub mod tests {
db.store(some_slot, &[(&key, &account)]);
db.add_root(some_slot);
db.update_accounts_hash(some_slot, &ancestors);
db.update_accounts_hash(some_slot, &ancestors, true);
assert_matches!(
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1),
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1, true),
Ok(_)
);
@@ -4756,15 +4769,19 @@ pub mod tests {
&solana_sdk::native_loader::create_loadable_account("foo", 1),
)],
);
db.update_accounts_hash(some_slot, &ancestors);
db.update_accounts_hash(some_slot, &ancestors, true);
assert_matches!(
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1),
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1, false),
Ok(_)
);
assert_matches!(
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 2, true),
Ok(_)
);
assert_matches!(
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 10),
Err(MismatchedTotalLamports(expected, actual)) if expected == 1 && actual == 10
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 10, true),
Err(MismatchedTotalLamports(expected, actual)) if expected == 2 && actual == 10
);
}
@@ -4781,9 +4798,9 @@ pub mod tests {
.unwrap()
.insert(some_slot, BankHashInfo::default());
db.add_root(some_slot);
db.update_accounts_hash(some_slot, &ancestors);
db.update_accounts_hash(some_slot, &ancestors, true);
assert_matches!(
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 0),
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 0, true),
Ok(_)
);
}
@@ -4808,7 +4825,7 @@ pub mod tests {
db.store_accounts_default(some_slot, accounts, &[some_hash]);
db.add_root(some_slot);
assert_matches!(
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1),
db.verify_bank_hash_and_lamports(some_slot, &ancestors, 1, true),
Err(MismatchedAccountHash)
);
}
@@ -5284,14 +5301,14 @@ pub mod tests {
);
let no_ancestors = HashMap::default();
accounts.update_accounts_hash(current_slot, &no_ancestors);
accounts.update_accounts_hash(current_slot, &no_ancestors, true);
accounts
.verify_bank_hash_and_lamports(current_slot, &no_ancestors, 22300)
.verify_bank_hash_and_lamports(current_slot, &no_ancestors, 22300, true)
.unwrap();
let accounts = reconstruct_accounts_db_via_serialization(&accounts, current_slot);
accounts
.verify_bank_hash_and_lamports(current_slot, &no_ancestors, 22300)
.verify_bank_hash_and_lamports(current_slot, &no_ancestors, 22300, true)
.unwrap();
// repeating should be no-op
@@ -5488,7 +5505,7 @@ pub mod tests {
fn test_account_balance_for_capitalization_normal() {
// system accounts
assert_eq!(
AccountsDB::account_balance_for_capitalization(10, &Pubkey::default(), false),
AccountsDB::account_balance_for_capitalization(10, &Pubkey::default(), false, true),
10
);
// any random program data accounts
@@ -5496,7 +5513,17 @@ pub mod tests {
AccountsDB::account_balance_for_capitalization(
10,
&solana_sdk::pubkey::new_rand(),
false
false,
true,
),
10
);
assert_eq!(
AccountsDB::account_balance_for_capitalization(
10,
&solana_sdk::pubkey::new_rand(),
false,
false,
),
10
);
@@ -5512,16 +5539,40 @@ pub mod tests {
AccountsDB::account_balance_for_capitalization(
normal_sysvar.lamports,
&normal_sysvar.owner,
normal_sysvar.executable
normal_sysvar.executable,
false,
),
0
);
assert_eq!(
AccountsDB::account_balance_for_capitalization(
normal_sysvar.lamports,
&normal_sysvar.owner,
normal_sysvar.executable,
true,
),
1
);
// currently transactions can send any lamports to sysvars although this is not sensible.
assert_eq!(
AccountsDB::account_balance_for_capitalization(10, &solana_sdk::sysvar::id(), false),
AccountsDB::account_balance_for_capitalization(
10,
&solana_sdk::sysvar::id(),
false,
false
),
9
);
assert_eq!(
AccountsDB::account_balance_for_capitalization(
10,
&solana_sdk::sysvar::id(),
false,
true
),
10
);
}
#[test]
@@ -5531,20 +5582,40 @@ pub mod tests {
AccountsDB::account_balance_for_capitalization(
normal_native_program.lamports,
&normal_native_program.owner,
normal_native_program.executable
normal_native_program.executable,
false,
),
0
);
assert_eq!(
AccountsDB::account_balance_for_capitalization(
normal_native_program.lamports,
&normal_native_program.owner,
normal_native_program.executable,
true,
),
1
);
// test maliciously assigned bogus native loader account
assert_eq!(
AccountsDB::account_balance_for_capitalization(
1,
&solana_sdk::native_loader::id(),
false
false,
false,
),
1
)
);
assert_eq!(
AccountsDB::account_balance_for_capitalization(
1,
&solana_sdk::native_loader::id(),
false,
true,
),
1
);
}
#[test]