Switch programs activation to whole-set based gating (#11750)

* Implement Debug for MessageProcessor

* Switch from delta-based gating to whole-set gating

* Remove dbg!

* Fix clippy

* Clippy

* Add test

* add loader to stable operating mode at proper epoch

* refresh_programs_and_inflation after ancestor setup

* Callback via snapshot; avoid account re-add; Debug

* Fix test

* Fix test and fix the past history

* Make callback management stricter and cleaner

* Fix test

* Test overwrite and frozen for native programs

* Test epoch callback with genesis-programs

* Add assertions for parent bank

* Add tests and some minor cleaning

* Remove unsteady assertion...

* Fix test...

* Fix DOS

* Skip ensuring account by dual (whole/delta) gating

* Fix frozen abi implementation...

* Move compute budget constatnt init back into bank

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
This commit is contained in:
Jack May
2020-08-25 09:49:15 -07:00
committed by GitHub
parent 2c5366f259
commit db4bbb3569
10 changed files with 761 additions and 176 deletions

View File

@ -309,6 +309,14 @@ pub struct ProcessOptions {
pub frozen_accounts: Vec<Pubkey>,
}
fn initiate_callback(mut bank: &mut Arc<Bank>, genesis_config: &GenesisConfig) {
Arc::get_mut(&mut bank)
.unwrap()
.initiate_entered_epoch_callback(solana_genesis_programs::get_entered_epoch_callback(
genesis_config.operating_mode,
));
}
pub fn process_blockstore(
genesis_config: &GenesisConfig,
blockstore: &Blockstore,
@ -325,15 +333,24 @@ pub fn process_blockstore(
}
// Setup bank for slot 0
let mut bank0 = Bank::new_with_paths(&genesis_config, account_paths, &opts.frozen_accounts);
let callback =
solana_genesis_programs::get_entered_epoch_callback(genesis_config.operating_mode);
callback(&mut bank0);
let bank0 = Arc::new(bank0);
let mut bank0 = Arc::new(Bank::new_with_paths(
&genesis_config,
account_paths,
&opts.frozen_accounts,
));
initiate_callback(&mut bank0, genesis_config);
info!("processing ledger for slot 0...");
let recyclers = VerifyRecyclers::default();
process_bank_0(&bank0, blockstore, &opts, &recyclers)?;
process_blockstore_from_root(genesis_config, blockstore, bank0, &opts, &recyclers, None)
do_process_blockstore_from_root(
genesis_config,
blockstore,
bank0,
&opts,
&recyclers,
None,
false,
)
}
// Process blockstore from a known root bank
@ -344,6 +361,26 @@ pub fn process_blockstore_from_root(
opts: &ProcessOptions,
recyclers: &VerifyRecyclers,
transaction_status_sender: Option<TransactionStatusSender>,
) -> BlockstoreProcessorResult {
do_process_blockstore_from_root(
genesis_config,
blockstore,
bank,
opts,
recyclers,
transaction_status_sender,
true,
)
}
fn do_process_blockstore_from_root(
genesis_config: &GenesisConfig,
blockstore: &Blockstore,
mut bank: Arc<Bank>,
opts: &ProcessOptions,
recyclers: &VerifyRecyclers,
transaction_status_sender: Option<TransactionStatusSender>,
enable_callback: bool,
) -> BlockstoreProcessorResult {
info!("processing ledger from slot {}...", bank.slot());
let allocated = thread_mem_usage::Allocatedp::default();
@ -355,9 +392,9 @@ pub fn process_blockstore_from_root(
let now = Instant::now();
let mut root = start_slot;
bank.set_entered_epoch_callback(solana_genesis_programs::get_entered_epoch_callback(
genesis_config.operating_mode,
));
if enable_callback {
initiate_callback(&mut bank, genesis_config);
}
if let Some(ref new_hard_forks) = opts.new_hard_forks {
let hard_forks = bank.hard_forks();
@ -2573,7 +2610,8 @@ pub mod tests {
blockstore.set_roots(&[3, 5]).unwrap();
// Set up bank1
let bank0 = Arc::new(Bank::new(&genesis_config));
let mut bank0 = Arc::new(Bank::new(&genesis_config));
initiate_callback(&mut bank0, &genesis_config);
let opts = ProcessOptions {
poh_verify: true,
..ProcessOptions::default()
@ -2594,13 +2632,14 @@ pub mod tests {
bank1.squash();
// Test process_blockstore_from_root() from slot 1 onwards
let (bank_forks, _leader_schedule) = process_blockstore_from_root(
let (bank_forks, _leader_schedule) = do_process_blockstore_from_root(
&genesis_config,
&blockstore,
bank1,
&opts,
&recyclers,
None,
false,
)
.unwrap();
@ -3065,4 +3104,95 @@ pub mod tests {
run_test_process_blockstore_with_supermajority_root(None);
run_test_process_blockstore_with_supermajority_root(Some(1))
}
#[test]
fn test_process_blockstore_feature_activations_since_genesis() {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(123);
let (ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_config);
let blockstore = Blockstore::open(&ledger_path).unwrap();
let opts = ProcessOptions::default();
let (bank_forks, _leader_schedule) =
process_blockstore(&genesis_config, &blockstore, vec![], opts).unwrap();
assert_eq!(bank_forks.working_bank().slot(), 0);
assert_eq!(
bank_forks.working_bank().builtin_loader_ids(),
vec![
solana_sdk::bpf_loader::id(),
solana_sdk::bpf_loader_deprecated::id()
]
);
}
#[test]
fn test_process_blockstore_feature_activations_from_snapshot() {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(123);
let (ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_config);
let blockstore = Blockstore::open(&ledger_path).unwrap();
// Set up bank1
let mut bank0 = Arc::new(Bank::new(&genesis_config));
initiate_callback(&mut bank0, &genesis_config);
let recyclers = VerifyRecyclers::default();
let opts = ProcessOptions::default();
process_bank_0(&bank0, &blockstore, &opts, &recyclers).unwrap();
let restored_slot = genesis_config.epoch_schedule.get_first_slot_in_epoch(1);
let mut bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), restored_slot);
bank1.squash();
// this is similar to snapshot deserialization
bank1.reset_callback_and_message_processor();
assert_eq!(bank1.builtin_loader_ids(), vec![]);
let bank1 = Arc::new(bank1);
let (bank_forks, _leader_schedule) = process_blockstore_from_root(
&genesis_config,
&blockstore,
bank1,
&opts,
&recyclers,
None,
)
.unwrap();
assert_eq!(bank_forks.working_bank().slot(), restored_slot);
assert_eq!(
bank_forks.working_bank().builtin_loader_ids(),
vec![
solana_sdk::bpf_loader::id(),
solana_sdk::bpf_loader_deprecated::id()
]
);
}
#[test]
fn test_process_blockstore_feature_activations_into_epoch_with_activation() {
let GenesisConfigInfo {
mut genesis_config, ..
} = create_genesis_config(123);
genesis_config.operating_mode = solana_sdk::genesis_config::OperatingMode::Stable;
let (ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_config);
let blockstore = Blockstore::open(&ledger_path).unwrap();
let opts = ProcessOptions::default();
let (bank_forks, _leader_schedule) =
process_blockstore(&genesis_config, &blockstore, vec![], opts).unwrap();
let bank0 = bank_forks.working_bank();
assert_eq!(bank0.builtin_loader_ids(), vec![]);
let restored_slot = genesis_config.epoch_schedule.get_first_slot_in_epoch(34);
let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), restored_slot);
assert_eq!(bank0.slot(), 0);
assert_eq!(bank0.builtin_loader_ids(), vec![]);
assert_eq!(bank1.slot(), restored_slot);
assert_eq!(
bank1.builtin_loader_ids(),
vec![solana_sdk::bpf_loader_deprecated::id()]
);
}
}