|
|
@@ -15,7 +15,7 @@ use {
|
|
|
ops::Index,
|
|
|
sync::{
|
|
|
atomic::{AtomicBool, AtomicU64, Ordering},
|
|
|
- Arc,
|
|
|
+ Arc, RwLock,
|
|
|
},
|
|
|
time::Instant,
|
|
|
},
|
|
|
@@ -77,7 +77,7 @@ impl Index<u64> for BankForks {
|
|
|
}
|
|
|
|
|
|
impl BankForks {
|
|
|
- pub fn new(bank: Bank) -> Self {
|
|
|
+ pub fn new_rw_arc(bank: Bank) -> Arc<RwLock<Self>> {
|
|
|
let root = bank.slot();
|
|
|
Self::new_from_banks(&[Arc::new(bank)], root)
|
|
|
}
|
|
|
@@ -154,7 +154,7 @@ impl BankForks {
|
|
|
self[self.root()].clone()
|
|
|
}
|
|
|
|
|
|
- pub fn new_from_banks(initial_forks: &[Arc<Bank>], root: Slot) -> Self {
|
|
|
+ pub fn new_from_banks(initial_forks: &[Arc<Bank>], root: Slot) -> Arc<RwLock<Self>> {
|
|
|
let mut banks = HashMap::new();
|
|
|
|
|
|
// Iterate through the heads of all the different forks
|
|
|
@@ -175,7 +175,7 @@ impl BankForks {
|
|
|
descendants.entry(parent).or_default().insert(*slot);
|
|
|
}
|
|
|
}
|
|
|
- Self {
|
|
|
+ let bank_forks = Arc::new(RwLock::new(Self {
|
|
|
root: Arc::new(AtomicSlot::new(root)),
|
|
|
banks,
|
|
|
descendants,
|
|
|
@@ -184,7 +184,16 @@ impl BankForks {
|
|
|
last_accounts_hash_slot: root,
|
|
|
in_vote_only_mode: Arc::new(AtomicBool::new(false)),
|
|
|
highest_slot_at_startup: 0,
|
|
|
+ }));
|
|
|
+
|
|
|
+ for bank in bank_forks.read().unwrap().banks.values() {
|
|
|
+ bank.loaded_programs_cache
|
|
|
+ .write()
|
|
|
+ .unwrap()
|
|
|
+ .set_fork_graph(bank_forks.clone());
|
|
|
}
|
|
|
+
|
|
|
+ bank_forks
|
|
|
}
|
|
|
|
|
|
pub fn insert(&mut self, mut bank: Bank) -> Arc<Bank> {
|
|
|
@@ -696,7 +705,8 @@ mod tests {
|
|
|
fn test_bank_forks_new() {
|
|
|
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
|
|
let bank = Bank::new_for_tests(&genesis_config);
|
|
|
- let mut bank_forks = BankForks::new(bank);
|
|
|
+ let bank_forks = BankForks::new_rw_arc(bank);
|
|
|
+ let mut bank_forks = bank_forks.write().unwrap();
|
|
|
let child_bank = Bank::new_from_parent(bank_forks[0].clone(), &Pubkey::default(), 1);
|
|
|
child_bank.register_tick(&Hash::default());
|
|
|
bank_forks.insert(child_bank);
|
|
|
@@ -711,19 +721,20 @@ mod tests {
|
|
|
let child_bank = Arc::new(Bank::new_from_parent(bank.clone(), &Pubkey::default(), 1));
|
|
|
|
|
|
let bank_forks = BankForks::new_from_banks(&[bank.clone(), child_bank.clone()], 0);
|
|
|
- assert_eq!(bank_forks.root(), 0);
|
|
|
- assert_eq!(bank_forks.working_bank().slot(), 1);
|
|
|
+ assert_eq!(bank_forks.read().unwrap().root(), 0);
|
|
|
+ assert_eq!(bank_forks.read().unwrap().working_bank().slot(), 1);
|
|
|
|
|
|
let bank_forks = BankForks::new_from_banks(&[child_bank, bank], 0);
|
|
|
- assert_eq!(bank_forks.root(), 0);
|
|
|
- assert_eq!(bank_forks.working_bank().slot(), 1);
|
|
|
+ assert_eq!(bank_forks.read().unwrap().root(), 0);
|
|
|
+ assert_eq!(bank_forks.read().unwrap().working_bank().slot(), 1);
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
|
fn test_bank_forks_descendants() {
|
|
|
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
|
|
let bank = Bank::new_for_tests(&genesis_config);
|
|
|
- let mut bank_forks = BankForks::new(bank);
|
|
|
+ let bank_forks = BankForks::new_rw_arc(bank);
|
|
|
+ let mut bank_forks = bank_forks.write().unwrap();
|
|
|
let bank0 = bank_forks[0].clone();
|
|
|
let bank = Bank::new_from_parent(bank0.clone(), &Pubkey::default(), 1);
|
|
|
bank_forks.insert(bank);
|
|
|
@@ -740,7 +751,8 @@ mod tests {
|
|
|
fn test_bank_forks_ancestors() {
|
|
|
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
|
|
let bank = Bank::new_for_tests(&genesis_config);
|
|
|
- let mut bank_forks = BankForks::new(bank);
|
|
|
+ let bank_forks = BankForks::new_rw_arc(bank);
|
|
|
+ let mut bank_forks = bank_forks.write().unwrap();
|
|
|
let bank0 = bank_forks[0].clone();
|
|
|
let bank = Bank::new_from_parent(bank0.clone(), &Pubkey::default(), 1);
|
|
|
bank_forks.insert(bank);
|
|
|
@@ -758,7 +770,8 @@ mod tests {
|
|
|
fn test_bank_forks_frozen_banks() {
|
|
|
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
|
|
let bank = Bank::new_for_tests(&genesis_config);
|
|
|
- let mut bank_forks = BankForks::new(bank);
|
|
|
+ let bank_forks = BankForks::new_rw_arc(bank);
|
|
|
+ let mut bank_forks = bank_forks.write().unwrap();
|
|
|
let bank0 = bank_forks[0].clone();
|
|
|
let child_bank = Bank::new_from_parent(bank0, &Pubkey::default(), 1);
|
|
|
bank_forks.insert(child_bank);
|
|
|
@@ -770,7 +783,8 @@ mod tests {
|
|
|
fn test_bank_forks_active_banks() {
|
|
|
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
|
|
let bank = Bank::new_for_tests(&genesis_config);
|
|
|
- let mut bank_forks = BankForks::new(bank);
|
|
|
+ let bank_forks = BankForks::new_rw_arc(bank);
|
|
|
+ let mut bank_forks = bank_forks.write().unwrap();
|
|
|
let bank0 = bank_forks[0].clone();
|
|
|
let child_bank = Bank::new_from_parent(bank0, &Pubkey::default(), 1);
|
|
|
bank_forks.insert(child_bank);
|
|
|
@@ -822,11 +836,13 @@ mod tests {
|
|
|
};
|
|
|
|
|
|
let bank0 = Bank::new_for_tests(&genesis_config);
|
|
|
- let mut bank_forks0 = BankForks::new(bank0);
|
|
|
+ let bank_forks0 = BankForks::new_rw_arc(bank0);
|
|
|
+ let mut bank_forks0 = bank_forks0.write().unwrap();
|
|
|
bank_forks0.set_root(0, &abs_request_sender, None);
|
|
|
|
|
|
let bank1 = Bank::new_for_tests(&genesis_config);
|
|
|
- let mut bank_forks1 = BankForks::new(bank1);
|
|
|
+ let bank_forks1 = BankForks::new_rw_arc(bank1);
|
|
|
+ let mut bank_forks1 = bank_forks1.write().unwrap();
|
|
|
|
|
|
let additional_timestamp_secs = 2;
|
|
|
|
|
|
@@ -882,10 +898,11 @@ mod tests {
|
|
|
.collect()
|
|
|
}
|
|
|
|
|
|
- fn extend_bank_forks(bank_forks: &mut BankForks, parent_child_pairs: &[(Slot, Slot)]) {
|
|
|
+ fn extend_bank_forks(bank_forks: Arc<RwLock<BankForks>>, parent_child_pairs: &[(Slot, Slot)]) {
|
|
|
for (parent, child) in parent_child_pairs.iter() {
|
|
|
- bank_forks.insert(Bank::new_from_parent(
|
|
|
- bank_forks[*parent].clone(),
|
|
|
+ let parent: Arc<Bank> = bank_forks.read().unwrap().banks[parent].clone();
|
|
|
+ bank_forks.write().unwrap().insert(Bank::new_from_parent(
|
|
|
+ parent,
|
|
|
&Pubkey::default(),
|
|
|
*child,
|
|
|
));
|
|
|
@@ -896,13 +913,13 @@ mod tests {
|
|
|
fn test_bank_forks_with_set_root() {
|
|
|
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
|
|
let bank = Bank::new_for_tests(&genesis_config);
|
|
|
- let mut bank_forks = BankForks::new(bank);
|
|
|
+ let bank_forks = BankForks::new_rw_arc(bank);
|
|
|
|
|
|
let parent_child_pairs = vec![(0, 1), (1, 2), (0, 3), (3, 4)];
|
|
|
- extend_bank_forks(&mut bank_forks, &parent_child_pairs);
|
|
|
+ extend_bank_forks(bank_forks.clone(), &parent_child_pairs);
|
|
|
|
|
|
assert_eq!(
|
|
|
- bank_forks.ancestors(),
|
|
|
+ bank_forks.read().unwrap().ancestors(),
|
|
|
make_hash_map(vec![
|
|
|
(0, vec![]),
|
|
|
(1, vec![0]),
|
|
|
@@ -912,7 +929,7 @@ mod tests {
|
|
|
])
|
|
|
);
|
|
|
assert_eq!(
|
|
|
- bank_forks.descendants(),
|
|
|
+ bank_forks.read().unwrap().descendants(),
|
|
|
make_hash_map(vec![
|
|
|
(0, vec![1, 2, 3, 4]),
|
|
|
(1, vec![2]),
|
|
|
@@ -921,26 +938,29 @@ mod tests {
|
|
|
(4, vec![]),
|
|
|
])
|
|
|
);
|
|
|
- bank_forks.set_root(
|
|
|
+ bank_forks.write().unwrap().set_root(
|
|
|
2,
|
|
|
&AbsRequestSender::default(),
|
|
|
None, // highest confirmed root
|
|
|
);
|
|
|
- bank_forks[2].squash();
|
|
|
- assert_eq!(bank_forks.ancestors(), make_hash_map(vec![(2, vec![]),]));
|
|
|
+ bank_forks.read().unwrap().get(2).unwrap().squash();
|
|
|
assert_eq!(
|
|
|
- bank_forks.descendants(),
|
|
|
+ bank_forks.read().unwrap().ancestors(),
|
|
|
+ make_hash_map(vec![(2, vec![]),])
|
|
|
+ );
|
|
|
+ assert_eq!(
|
|
|
+ bank_forks.read().unwrap().descendants(),
|
|
|
make_hash_map(vec![(0, vec![2]), (1, vec![2]), (2, vec![]),])
|
|
|
);
|
|
|
|
|
|
let parent_child_pairs = vec![(2, 5), (5, 6)];
|
|
|
- extend_bank_forks(&mut bank_forks, &parent_child_pairs);
|
|
|
+ extend_bank_forks(bank_forks.clone(), &parent_child_pairs);
|
|
|
assert_eq!(
|
|
|
- bank_forks.ancestors(),
|
|
|
+ bank_forks.read().unwrap().ancestors(),
|
|
|
make_hash_map(vec![(2, vec![]), (5, vec![2]), (6, vec![2, 5])])
|
|
|
);
|
|
|
assert_eq!(
|
|
|
- bank_forks.descendants(),
|
|
|
+ bank_forks.read().unwrap().descendants(),
|
|
|
make_hash_map(vec![
|
|
|
(0, vec![2]),
|
|
|
(1, vec![2]),
|
|
|
@@ -956,13 +976,13 @@ mod tests {
|
|
|
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
|
|
let bank = Bank::new_for_tests(&genesis_config);
|
|
|
assert_eq!(bank.slot(), 0);
|
|
|
- let mut bank_forks = BankForks::new(bank);
|
|
|
+ let bank_forks = BankForks::new_rw_arc(bank);
|
|
|
|
|
|
let parent_child_pairs = vec![(0, 1), (1, 2), (0, 3), (3, 4)];
|
|
|
- extend_bank_forks(&mut bank_forks, &parent_child_pairs);
|
|
|
+ extend_bank_forks(bank_forks.clone(), &parent_child_pairs);
|
|
|
|
|
|
assert_eq!(
|
|
|
- bank_forks.ancestors(),
|
|
|
+ bank_forks.read().unwrap().ancestors(),
|
|
|
make_hash_map(vec![
|
|
|
(0, vec![]),
|
|
|
(1, vec![0]),
|
|
|
@@ -972,7 +992,7 @@ mod tests {
|
|
|
])
|
|
|
);
|
|
|
assert_eq!(
|
|
|
- bank_forks.descendants(),
|
|
|
+ bank_forks.read().unwrap().descendants(),
|
|
|
make_hash_map(vec![
|
|
|
(0, vec![1, 2, 3, 4]),
|
|
|
(1, vec![2]),
|
|
|
@@ -981,25 +1001,25 @@ mod tests {
|
|
|
(4, vec![]),
|
|
|
])
|
|
|
);
|
|
|
- bank_forks.set_root(
|
|
|
+ bank_forks.write().unwrap().set_root(
|
|
|
2,
|
|
|
&AbsRequestSender::default(),
|
|
|
Some(1), // highest confirmed root
|
|
|
);
|
|
|
- bank_forks[2].squash();
|
|
|
+ bank_forks.read().unwrap().get(2).unwrap().squash();
|
|
|
assert_eq!(
|
|
|
- bank_forks.ancestors(),
|
|
|
+ bank_forks.read().unwrap().ancestors(),
|
|
|
make_hash_map(vec![(1, vec![]), (2, vec![]),])
|
|
|
);
|
|
|
assert_eq!(
|
|
|
- bank_forks.descendants(),
|
|
|
+ bank_forks.read().unwrap().descendants(),
|
|
|
make_hash_map(vec![(0, vec![1, 2]), (1, vec![2]), (2, vec![]),])
|
|
|
);
|
|
|
|
|
|
let parent_child_pairs = vec![(2, 5), (5, 6)];
|
|
|
- extend_bank_forks(&mut bank_forks, &parent_child_pairs);
|
|
|
+ extend_bank_forks(bank_forks.clone(), &parent_child_pairs);
|
|
|
assert_eq!(
|
|
|
- bank_forks.ancestors(),
|
|
|
+ bank_forks.read().unwrap().ancestors(),
|
|
|
make_hash_map(vec![
|
|
|
(1, vec![]),
|
|
|
(2, vec![]),
|
|
|
@@ -1008,7 +1028,7 @@ mod tests {
|
|
|
])
|
|
|
);
|
|
|
assert_eq!(
|
|
|
- bank_forks.descendants(),
|
|
|
+ bank_forks.read().unwrap().descendants(),
|
|
|
make_hash_map(vec![
|
|
|
(0, vec![1, 2]),
|
|
|
(1, vec![2]),
|
|
|
@@ -1023,7 +1043,7 @@ mod tests {
|
|
|
fn test_fork_graph() {
|
|
|
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
|
|
let bank = Bank::new_for_tests(&genesis_config);
|
|
|
- let mut bank_forks = BankForks::new(bank);
|
|
|
+ let bank_forks = BankForks::new_rw_arc(bank);
|
|
|
|
|
|
let parent_child_pairs = vec![
|
|
|
(0, 1),
|
|
|
@@ -1036,7 +1056,7 @@ mod tests {
|
|
|
(4, 6),
|
|
|
(6, 12),
|
|
|
];
|
|
|
- extend_bank_forks(&mut bank_forks, &parent_child_pairs);
|
|
|
+ extend_bank_forks(bank_forks.clone(), &parent_child_pairs);
|
|
|
|
|
|
// Fork graph created for the test
|
|
|
// 0
|
|
|
@@ -1048,7 +1068,7 @@ mod tests {
|
|
|
// 8 5 6
|
|
|
// | |
|
|
|
// 10 12
|
|
|
-
|
|
|
+ let mut bank_forks = bank_forks.write().unwrap();
|
|
|
assert_matches!(bank_forks.relationship(0, 3), BlockRelation::Ancestor);
|
|
|
assert_matches!(bank_forks.relationship(0, 10), BlockRelation::Ancestor);
|
|
|
assert_matches!(bank_forks.relationship(0, 12), BlockRelation::Ancestor);
|