1use {
2 crate::consensus::{Stake, tower_vote_state::TowerVoteState},
3 agave_votor::commitment::{
4 CommitmentAggregationData as AlpenglowCommitmentAggregationData,
5 CommitmentType as AlpenglowCommitmentType,
6 },
7 crossbeam_channel::{Receiver, RecvTimeoutError, Sender, bounded, select, unbounded},
8 solana_clock::Slot,
9 solana_measure::measure::Measure,
10 solana_metrics::datapoint_info,
11 solana_pubkey::Pubkey,
12 solana_rpc::rpc_subscriptions::RpcSubscriptions,
13 solana_runtime::{
14 bank::Bank,
15 commitment::{BlockCommitment, BlockCommitmentCache, CommitmentSlots, VOTE_THRESHOLD_SIZE},
16 },
17 std::{
18 cmp::max,
19 collections::HashMap,
20 sync::{
21 Arc, RwLock,
22 atomic::{AtomicBool, Ordering},
23 },
24 thread::{self, Builder, JoinHandle},
25 time::Duration,
26 },
27};
28
29pub struct TowerCommitmentAggregationData {
30 bank: Arc<Bank>,
31 root: Slot,
32 total_stake: Stake,
33 node_vote_state: (Pubkey, TowerVoteState),
36}
37
38impl TowerCommitmentAggregationData {
39 pub fn new(
40 bank: Arc<Bank>,
41 root: Slot,
42 total_stake: Stake,
43 node_vote_state: (Pubkey, TowerVoteState),
44 ) -> Self {
45 Self {
46 bank,
47 root,
48 total_stake,
49 node_vote_state,
50 }
51 }
52}
53
54fn get_highest_super_majority_root(mut rooted_stake: Vec<(Slot, u64)>, total_stake: u64) -> Slot {
55 rooted_stake.sort_by(|a, b| a.0.cmp(&b.0).reverse());
56 let mut stake_sum = 0;
57 for (root, stake) in rooted_stake {
58 stake_sum += stake;
59 if (stake_sum as f64 / total_stake as f64) > VOTE_THRESHOLD_SIZE {
60 return root;
61 }
62 }
63 0
64}
65
66pub struct AggregateCommitmentService {
67 t_commitment: JoinHandle<()>,
68}
69
70impl AggregateCommitmentService {
71 pub fn new(
72 exit: Arc<AtomicBool>,
73 block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
74 subscriptions: Option<Arc<RpcSubscriptions>>,
75 ) -> (
76 Sender<TowerCommitmentAggregationData>,
77 Sender<AlpenglowCommitmentAggregationData>,
78 Self,
79 ) {
80 let (sender, receiver): (
81 Sender<TowerCommitmentAggregationData>,
82 Receiver<TowerCommitmentAggregationData>,
83 ) = unbounded();
84 let (ag_sender, ag_receiver): (
88 Sender<AlpenglowCommitmentAggregationData>,
89 Receiver<AlpenglowCommitmentAggregationData>,
90 ) = bounded(1000);
91
92 (
93 sender,
94 ag_sender,
95 Self {
96 t_commitment: Builder::new()
97 .name("solAggCommitSvc".to_string())
98 .spawn(move || {
99 loop {
100 if exit.load(Ordering::Relaxed) {
101 break;
102 }
103
104 if let Err(RecvTimeoutError::Disconnected) = Self::run(
105 &receiver,
106 &ag_receiver,
107 &block_commitment_cache,
108 subscriptions.as_deref(),
109 &exit,
110 ) {
111 break;
112 }
113 }
114 })
115 .unwrap(),
116 },
117 )
118 }
119
120 fn run(
121 receiver: &Receiver<TowerCommitmentAggregationData>,
122 ag_receiver: &Receiver<AlpenglowCommitmentAggregationData>,
123 block_commitment_cache: &RwLock<BlockCommitmentCache>,
124 rpc_subscriptions: Option<&RpcSubscriptions>,
125 exit: &AtomicBool,
126 ) -> Result<(), RecvTimeoutError> {
127 loop {
128 if exit.load(Ordering::Relaxed) {
129 return Ok(());
130 }
131
132 let mut aggregate_commitment_time = Measure::start("aggregate-commitment-ms");
133 let commitment_slots = select! {
134 recv(receiver) -> msg => {
135 let data = msg?;
136 let data = receiver.try_iter().last().unwrap_or(data);
137 let ancestors = data.bank.status_cache_ancestors();
138 if ancestors.is_empty() {
139 continue;
140 }
141 Self::update_commitment_cache(block_commitment_cache, data, ancestors)
142 }
143 recv(ag_receiver) -> msg => {
144 let data = msg?;
145 let data = ag_receiver.try_iter().last().unwrap_or(data);
146 Self::alpenglow_update_commitment_cache(
147 block_commitment_cache,
148 data.commitment_type,
149 data.slot,
150 )
151 }
152 default(Duration::from_secs(1)) => continue
153 };
154 aggregate_commitment_time.stop();
155
156 datapoint_info!(
157 "block-commitment-cache",
158 (
159 "aggregate-commitment-ms",
160 aggregate_commitment_time.as_ms() as i64,
161 i64
162 ),
163 (
164 "highest-super-majority-root",
165 commitment_slots.highest_super_majority_root as i64,
166 i64
167 ),
168 (
169 "highest-confirmed-slot",
170 commitment_slots.highest_confirmed_slot as i64,
171 i64
172 ),
173 );
174
175 if let Some(rpc_subscriptions) = rpc_subscriptions {
176 rpc_subscriptions.notify_subscribers(commitment_slots);
180 }
181 }
182 }
183
184 fn alpenglow_update_commitment_cache(
185 block_commitment_cache: &RwLock<BlockCommitmentCache>,
186 update_type: AlpenglowCommitmentType,
187 slot: Slot,
188 ) -> CommitmentSlots {
189 let mut w_block_commitment_cache = block_commitment_cache.write().unwrap();
190
191 match update_type {
192 AlpenglowCommitmentType::Notarize => {
193 w_block_commitment_cache.set_slot(slot);
195 }
196 AlpenglowCommitmentType::Rooted => {
197 w_block_commitment_cache.set_highest_confirmed_slot(slot);
200 w_block_commitment_cache.set_root(slot);
201 w_block_commitment_cache.set_highest_super_majority_root(slot);
202 }
203 }
204 w_block_commitment_cache.commitment_slots()
205 }
206
207 fn update_commitment_cache(
208 block_commitment_cache: &RwLock<BlockCommitmentCache>,
209 aggregation_data: TowerCommitmentAggregationData,
210 ancestors: Vec<u64>,
211 ) -> CommitmentSlots {
212 let (block_commitment, rooted_stake) = Self::aggregate_commitment(
213 &ancestors,
214 &aggregation_data.bank,
215 &aggregation_data.node_vote_state,
216 );
217
218 let highest_super_majority_root =
219 get_highest_super_majority_root(rooted_stake, aggregation_data.total_stake);
220
221 let mut new_block_commitment = BlockCommitmentCache::new(
222 block_commitment,
223 aggregation_data.total_stake,
224 CommitmentSlots {
225 slot: aggregation_data.bank.slot(),
226 root: aggregation_data.root,
227 highest_confirmed_slot: aggregation_data.root,
228 highest_super_majority_root,
229 },
230 );
231 let highest_confirmed_slot = new_block_commitment.calculate_highest_confirmed_slot();
232 new_block_commitment.set_highest_confirmed_slot(highest_confirmed_slot);
233
234 let mut w_block_commitment_cache = block_commitment_cache.write().unwrap();
235
236 let highest_super_majority_root = max(
237 new_block_commitment.highest_super_majority_root(),
238 w_block_commitment_cache.highest_super_majority_root(),
239 );
240 new_block_commitment.set_highest_super_majority_root(highest_super_majority_root);
241
242 *w_block_commitment_cache = new_block_commitment;
243 w_block_commitment_cache.commitment_slots()
244 }
245
246 pub fn aggregate_commitment(
247 ancestors: &[Slot],
248 bank: &Bank,
249 (node_vote_pubkey, node_vote_state): &(Pubkey, TowerVoteState),
250 ) -> (HashMap<Slot, BlockCommitment>, Vec<(Slot, u64)>) {
251 assert!(!ancestors.is_empty());
252
253 for a in ancestors.windows(2) {
255 assert!(a[0] < a[1]);
256 }
257
258 let mut commitment = HashMap::new();
259 let mut rooted_stake: Vec<(Slot, u64)> = Vec::new();
260 for (pubkey, (lamports, account)) in bank.vote_accounts().iter() {
261 if *lamports == 0 {
262 continue;
263 }
264 let vote_state = if pubkey == node_vote_pubkey {
265 node_vote_state.clone()
267 } else {
268 TowerVoteState::from(account.vote_state_view())
269 };
270 Self::aggregate_commitment_for_vote_account(
271 &mut commitment,
272 &mut rooted_stake,
273 &vote_state,
274 ancestors,
275 *lamports,
276 );
277 }
278
279 (commitment, rooted_stake)
280 }
281
282 fn aggregate_commitment_for_vote_account(
283 commitment: &mut HashMap<Slot, BlockCommitment>,
284 rooted_stake: &mut Vec<(Slot, u64)>,
285 vote_state: &TowerVoteState,
286 ancestors: &[Slot],
287 lamports: u64,
288 ) {
289 assert!(!ancestors.is_empty());
290 let mut ancestors_index = 0;
291 if let Some(root) = vote_state.root_slot {
292 for (i, a) in ancestors.iter().enumerate() {
293 if *a <= root {
294 commitment
295 .entry(*a)
296 .or_default()
297 .increase_rooted_stake(lamports);
298 } else {
299 ancestors_index = i;
300 break;
301 }
302 }
303 rooted_stake.push((root, lamports));
304 }
305
306 for vote in &vote_state.votes {
307 while ancestors[ancestors_index] <= vote.slot() {
308 commitment
309 .entry(ancestors[ancestors_index])
310 .or_default()
311 .increase_confirmation_stake(vote.confirmation_count() as usize, lamports);
312 ancestors_index += 1;
313
314 if ancestors_index == ancestors.len() {
315 return;
316 }
317 }
318 }
319 }
320
321 pub fn join(self) -> thread::Result<()> {
322 self.t_commitment.join()
323 }
324}
325
326#[cfg(test)]
327mod tests {
328 use {
329 super::*,
330 solana_account::{Account, ReadableAccount, state_traits::StateMut},
331 solana_leader_schedule::SlotLeader,
332 solana_ledger::genesis_utils::{GenesisConfigInfo, create_genesis_config},
333 solana_pubkey::Pubkey,
334 solana_runtime::{
335 genesis_utils::{ValidatorVoteKeypairs, create_genesis_config_with_vote_accounts},
336 stake_utils,
337 },
338 solana_signer::Signer,
339 solana_vote::vote_transaction,
340 solana_vote_program::vote_state::{
341 self, BLS_PUBLIC_KEY_COMPRESSED_SIZE, MAX_LOCKOUT_HISTORY, TowerSync, VoteStateV4,
342 VoteStateVersions, handler::VoteStateHandler, process_slot_vote_unchecked,
343 },
344 };
345
346 #[test]
347 fn test_get_highest_super_majority_root() {
348 assert_eq!(get_highest_super_majority_root(vec![], 10), 0);
349 let rooted_stake = vec![(0, 5), (1, 5)];
350 assert_eq!(get_highest_super_majority_root(rooted_stake, 10), 0);
351 let rooted_stake = vec![(1, 5), (0, 10), (2, 5), (1, 4)];
352 assert_eq!(get_highest_super_majority_root(rooted_stake, 10), 1);
353 }
354
355 #[test]
356 fn test_aggregate_commitment_for_vote_account_1() {
357 let ancestors = vec![3, 4, 5, 7, 9, 11];
358 let mut commitment = HashMap::new();
359 let mut rooted_stake = vec![];
360 let lamports = 5;
361 let mut vote_state = TowerVoteState::default();
362
363 let root = *ancestors.last().unwrap();
364 vote_state.root_slot = Some(root);
365 AggregateCommitmentService::aggregate_commitment_for_vote_account(
366 &mut commitment,
367 &mut rooted_stake,
368 &vote_state,
369 &ancestors,
370 lamports,
371 );
372
373 for a in ancestors {
374 let mut expected = BlockCommitment::default();
375 expected.increase_rooted_stake(lamports);
376 assert_eq!(*commitment.get(&a).unwrap(), expected);
377 }
378 assert_eq!(rooted_stake[0], (root, lamports));
379 }
380
381 #[test]
382 fn test_aggregate_commitment_for_vote_account_2() {
383 let ancestors = vec![3, 4, 5, 7, 9, 11];
384 let mut commitment = HashMap::new();
385 let mut rooted_stake = vec![];
386 let lamports = 5;
387 let mut vote_state = TowerVoteState::default();
388
389 let root = ancestors[2];
390 vote_state.root_slot = Some(root);
391 vote_state.process_next_vote_slot(*ancestors.last().unwrap());
392 AggregateCommitmentService::aggregate_commitment_for_vote_account(
393 &mut commitment,
394 &mut rooted_stake,
395 &vote_state,
396 &ancestors,
397 lamports,
398 );
399
400 for a in ancestors {
401 let mut expected = BlockCommitment::default();
402 if a <= root {
403 expected.increase_rooted_stake(lamports);
404 } else {
405 expected.increase_confirmation_stake(1, lamports);
406 }
407 assert_eq!(*commitment.get(&a).unwrap(), expected);
408 }
409 assert_eq!(rooted_stake[0], (root, lamports));
410 }
411
412 #[test]
413 fn test_aggregate_commitment_for_vote_account_3() {
414 let ancestors = vec![3, 4, 5, 7, 9, 10, 11];
415 let mut commitment = HashMap::new();
416 let mut rooted_stake = vec![];
417 let lamports = 5;
418 let mut vote_state = TowerVoteState::default();
419
420 let root = ancestors[2];
421 vote_state.root_slot = Some(root);
422 assert!(ancestors[4] + 2 >= ancestors[6]);
423 vote_state.process_next_vote_slot(ancestors[4]);
424 vote_state.process_next_vote_slot(ancestors[6]);
425 AggregateCommitmentService::aggregate_commitment_for_vote_account(
426 &mut commitment,
427 &mut rooted_stake,
428 &vote_state,
429 &ancestors,
430 lamports,
431 );
432
433 for (i, a) in ancestors.iter().enumerate() {
434 if *a <= root {
435 let mut expected = BlockCommitment::default();
436 expected.increase_rooted_stake(lamports);
437 assert_eq!(*commitment.get(a).unwrap(), expected);
438 } else if i <= 4 {
439 let mut expected = BlockCommitment::default();
440 expected.increase_confirmation_stake(2, lamports);
441 assert_eq!(*commitment.get(a).unwrap(), expected);
442 } else if i <= 6 {
443 let mut expected = BlockCommitment::default();
444 expected.increase_confirmation_stake(1, lamports);
445 assert_eq!(*commitment.get(a).unwrap(), expected);
446 }
447 }
448 assert_eq!(rooted_stake[0], (root, lamports));
449 }
450
451 fn do_test_aggregate_commitment_validity(with_node_vote_state: bool) {
452 let ancestors = vec![3, 4, 5, 7, 9, 10, 11];
453 let GenesisConfigInfo {
454 mut genesis_config, ..
455 } = create_genesis_config(10_000);
456
457 let rooted_stake_amount = 40;
458
459 let sk1 = solana_pubkey::new_rand();
460 let pk1 = solana_pubkey::new_rand();
461 let mut vote_account1 = vote_state::create_v4_account_with_authorized(
462 &solana_pubkey::new_rand(),
463 &pk1,
464 [0u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
465 &pk1,
466 0,
467 &pk1,
468 0,
469 &pk1,
470 100,
471 );
472 let stake_account1 = stake_utils::create_stake_account(
473 &sk1,
474 &pk1,
475 &vote_account1,
476 &genesis_config.rent,
477 100,
478 );
479 let sk2 = solana_pubkey::new_rand();
480 let pk2 = solana_pubkey::new_rand();
481 let mut vote_account2 = vote_state::create_v4_account_with_authorized(
482 &solana_pubkey::new_rand(),
483 &pk2,
484 [0u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
485 &pk2,
486 0,
487 &pk2,
488 0,
489 &pk2,
490 50,
491 );
492 let stake_account2 =
493 stake_utils::create_stake_account(&sk2, &pk2, &vote_account2, &genesis_config.rent, 50);
494 let sk3 = solana_pubkey::new_rand();
495 let pk3 = solana_pubkey::new_rand();
496 let mut vote_account3 = vote_state::create_v4_account_with_authorized(
497 &solana_pubkey::new_rand(),
498 &pk3,
499 [0u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
500 &pk3,
501 0,
502 &pk3,
503 0,
504 &pk3,
505 1,
506 );
507 let stake_account3 = stake_utils::create_stake_account(
508 &sk3,
509 &pk3,
510 &vote_account3,
511 &genesis_config.rent,
512 rooted_stake_amount,
513 );
514 let sk4 = solana_pubkey::new_rand();
515 let pk4 = solana_pubkey::new_rand();
516 let mut vote_account4 = vote_state::create_v4_account_with_authorized(
517 &solana_pubkey::new_rand(),
518 &pk4,
519 [0u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
520 &pk4,
521 0,
522 &pk4,
523 0,
524 &pk4,
525 1,
526 );
527 let stake_account4 = stake_utils::create_stake_account(
528 &sk4,
529 &pk4,
530 &vote_account4,
531 &genesis_config.rent,
532 rooted_stake_amount,
533 );
534
535 genesis_config.accounts.extend(
536 vec![
537 (pk1, vote_account1.clone()),
538 (sk1, stake_account1),
539 (pk2, vote_account2.clone()),
540 (sk2, stake_account2),
541 (pk3, vote_account3.clone()),
542 (sk3, stake_account3),
543 (pk4, vote_account4.clone()),
544 (sk4, stake_account4),
545 ]
546 .into_iter()
547 .map(|(key, account)| (key, Account::from(account))),
548 );
549
550 let bank = Arc::new(Bank::new_for_tests(&genesis_config));
552
553 let mut vote_state1 =
554 VoteStateHandler::new_v4(VoteStateV4::deserialize(vote_account1.data(), &pk1).unwrap());
555 process_slot_vote_unchecked(&mut vote_state1, 3);
556 process_slot_vote_unchecked(&mut vote_state1, 5);
557 let vote_state1 = vote_state1.unwrap_v4();
558 if !with_node_vote_state {
559 let versioned = VoteStateVersions::new_v4(vote_state1.clone());
560 vote_account1.set_state(&versioned).unwrap();
561 bank.store_account(&pk1, &vote_account1);
562 }
563
564 let mut vote_state2 =
565 VoteStateHandler::new_v4(VoteStateV4::deserialize(vote_account2.data(), &pk2).unwrap());
566 process_slot_vote_unchecked(&mut vote_state2, 9);
567 process_slot_vote_unchecked(&mut vote_state2, 10);
568 let versioned = VoteStateVersions::new_v4(vote_state2.unwrap_v4());
569 vote_account2.set_state(&versioned).unwrap();
570 bank.store_account(&pk2, &vote_account2);
571
572 let mut vote_state3 = VoteStateV4::deserialize(vote_account3.data(), &pk3).unwrap();
573 vote_state3.root_slot = Some(1);
574 let versioned = VoteStateVersions::new_v4(vote_state3);
575 vote_account3.set_state(&versioned).unwrap();
576 bank.store_account(&pk3, &vote_account3);
577
578 let mut vote_state4 = VoteStateV4::deserialize(vote_account4.data(), &pk4).unwrap();
579 vote_state4.root_slot = Some(2);
580 let versioned = VoteStateVersions::new_v4(vote_state4);
581 vote_account4.set_state(&versioned).unwrap();
582 bank.store_account(&pk4, &vote_account4);
583
584 let node_vote_pubkey = if with_node_vote_state {
585 pk1
586 } else {
587 solana_pubkey::new_rand()
589 };
590
591 let (commitment, rooted_stake) = AggregateCommitmentService::aggregate_commitment(
592 &ancestors,
593 &bank,
594 &(node_vote_pubkey, TowerVoteState::from(vote_state1)),
595 );
596
597 for a in ancestors {
598 if a <= 3 {
599 let mut expected = BlockCommitment::default();
600 expected.increase_confirmation_stake(2, 150);
601 assert_eq!(*commitment.get(&a).unwrap(), expected);
602 } else if a <= 5 {
603 let mut expected = BlockCommitment::default();
604 expected.increase_confirmation_stake(1, 100);
605 expected.increase_confirmation_stake(2, 50);
606 assert_eq!(*commitment.get(&a).unwrap(), expected);
607 } else if a <= 9 {
608 let mut expected = BlockCommitment::default();
609 expected.increase_confirmation_stake(2, 50);
610 assert_eq!(*commitment.get(&a).unwrap(), expected);
611 } else if a <= 10 {
612 let mut expected = BlockCommitment::default();
613 expected.increase_confirmation_stake(1, 50);
614 assert_eq!(*commitment.get(&a).unwrap(), expected);
615 } else {
616 assert!(!commitment.contains_key(&a));
617 }
618 }
619 assert_eq!(rooted_stake.len(), 2);
620 assert_eq!(get_highest_super_majority_root(rooted_stake, 100), 1)
621 }
622
623 #[test]
624 fn test_aggregate_commitment_validity_with_node_vote_state() {
625 do_test_aggregate_commitment_validity(true)
626 }
627
628 #[test]
629 fn test_aggregate_commitment_validity_without_node_vote_state() {
630 do_test_aggregate_commitment_validity(false);
631 }
632
633 #[test]
634 fn test_highest_super_majority_root_advance() {
635 fn get_vote_state(vote_pubkey: Pubkey, bank: &Bank) -> TowerVoteState {
636 let vote_account = bank.get_vote_account(&vote_pubkey).unwrap();
637 TowerVoteState::from(vote_account.vote_state_view())
638 }
639
640 let block_commitment_cache = RwLock::new(BlockCommitmentCache::new_for_tests());
641
642 let validator_vote_keypairs = ValidatorVoteKeypairs::new_rand();
643 let validator_keypairs = vec![&validator_vote_keypairs];
644 let GenesisConfigInfo { genesis_config, .. } = create_genesis_config_with_vote_accounts(
645 1_000_000_000,
646 &validator_keypairs,
647 vec![100; 1],
648 );
649
650 let (_bank0, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
651
652 for x in 0..33 {
655 let previous_bank = bank_forks.read().unwrap().get(x).unwrap();
656 let bank = Bank::new_from_parent_with_bank_forks(
657 bank_forks.as_ref(),
658 previous_bank.clone(),
659 SlotLeader::default(),
660 x + 1,
661 );
662 let tower_sync = TowerSync::new_from_slot(x, previous_bank.hash());
663 let vote = vote_transaction::new_tower_sync_transaction(
664 tower_sync,
665 previous_bank.last_blockhash(),
666 &validator_vote_keypairs.node_keypair,
667 &validator_vote_keypairs.vote_keypair,
668 &validator_vote_keypairs.vote_keypair,
669 None,
670 );
671 bank.process_transaction(&vote).unwrap();
672 }
673
674 let working_bank = bank_forks.read().unwrap().working_bank();
675 let vote_pubkey = validator_vote_keypairs.vote_keypair.pubkey();
676 let root = get_vote_state(vote_pubkey, &working_bank)
677 .root_slot
678 .unwrap();
679 for x in 0..root {
680 bank_forks.write().unwrap().set_root(x, None, None);
681 }
682
683 let bank33 = bank_forks.read().unwrap().get(33).unwrap();
685 let bank34 = Bank::new_from_parent_with_bank_forks(
686 bank_forks.as_ref(),
687 bank33.clone(),
688 SlotLeader::default(),
689 34,
690 );
691 let tower_sync = TowerSync::new_from_slot(33, bank33.hash());
692 let vote33 = vote_transaction::new_tower_sync_transaction(
693 tower_sync,
694 bank33.last_blockhash(),
695 &validator_vote_keypairs.node_keypair,
696 &validator_vote_keypairs.vote_keypair,
697 &validator_vote_keypairs.vote_keypair,
698 None,
699 );
700 bank34.process_transaction(&vote33).unwrap();
701
702 let working_bank = bank_forks.read().unwrap().working_bank();
703 let vote_state = get_vote_state(vote_pubkey, &working_bank);
704 let root = vote_state.root_slot.unwrap();
705 let ancestors = working_bank.status_cache_ancestors();
706 let _ = AggregateCommitmentService::update_commitment_cache(
707 &block_commitment_cache,
708 TowerCommitmentAggregationData {
709 bank: working_bank,
710 root: 0,
711 total_stake: 100,
712 node_vote_state: (vote_pubkey, vote_state.clone()),
713 },
714 ancestors,
715 );
716 let highest_super_majority_root = block_commitment_cache
717 .read()
718 .unwrap()
719 .highest_super_majority_root();
720 bank_forks
721 .write()
722 .unwrap()
723 .set_root(root, None, Some(highest_super_majority_root));
724 let highest_super_majority_root_bank =
725 bank_forks.read().unwrap().get(highest_super_majority_root);
726 assert!(highest_super_majority_root_bank.is_some());
727
728 let bank33 = bank_forks.read().unwrap().get(33).unwrap();
731 let _bank35 = Bank::new_from_parent_with_bank_forks(
732 bank_forks.as_ref(),
733 bank33,
734 SlotLeader::default(),
735 35,
736 );
737
738 let working_bank = bank_forks.read().unwrap().working_bank();
739 let ancestors = working_bank.status_cache_ancestors();
740 let _ = AggregateCommitmentService::update_commitment_cache(
741 &block_commitment_cache,
742 TowerCommitmentAggregationData {
743 bank: working_bank,
744 root: 1,
745 total_stake: 100,
746 node_vote_state: (vote_pubkey, vote_state),
747 },
748 ancestors,
749 );
750 let highest_super_majority_root = block_commitment_cache
751 .read()
752 .unwrap()
753 .highest_super_majority_root();
754 let highest_super_majority_root_bank =
755 bank_forks.read().unwrap().get(highest_super_majority_root);
756 assert!(highest_super_majority_root_bank.is_some());
757
758 for x in 35..=37 {
761 let previous_bank = bank_forks.read().unwrap().get(x).unwrap();
762 let bank = Bank::new_from_parent_with_bank_forks(
763 bank_forks.as_ref(),
764 previous_bank.clone(),
765 SlotLeader::default(),
766 x + 1,
767 );
768 let lowest_slot = x - MAX_LOCKOUT_HISTORY as u64;
770 let slots: Vec<_> = (lowest_slot..(x + 1)).filter(|s| *s != 34).collect();
771 let tower_sync =
772 TowerSync::new_from_slots(slots, previous_bank.hash(), Some(lowest_slot - 1));
773 let vote = vote_transaction::new_tower_sync_transaction(
774 tower_sync,
775 previous_bank.last_blockhash(),
776 &validator_vote_keypairs.node_keypair,
777 &validator_vote_keypairs.vote_keypair,
778 &validator_vote_keypairs.vote_keypair,
779 None,
780 );
781 bank.process_transaction(&vote).unwrap();
782 }
783
784 let working_bank = bank_forks.read().unwrap().working_bank();
785 let vote_state =
786 get_vote_state(validator_vote_keypairs.vote_keypair.pubkey(), &working_bank);
787 let root = vote_state.root_slot.unwrap();
788 let ancestors = working_bank.status_cache_ancestors();
789 let _ = AggregateCommitmentService::update_commitment_cache(
790 &block_commitment_cache,
791 TowerCommitmentAggregationData {
792 bank: working_bank,
793 root: 0,
794 total_stake: 100,
795 node_vote_state: (vote_pubkey, vote_state),
796 },
797 ancestors,
798 );
799 let highest_super_majority_root = block_commitment_cache
800 .read()
801 .unwrap()
802 .highest_super_majority_root();
803 bank_forks
804 .write()
805 .unwrap()
806 .set_root(root, None, Some(highest_super_majority_root));
807 let highest_super_majority_root_bank =
808 bank_forks.read().unwrap().get(highest_super_majority_root);
809 assert!(highest_super_majority_root_bank.is_some());
810 }
811}