3939        timing:: AtomicInterval , 
4040        transaction:: Transaction , 
4141    } , 
42-     solana_vote:: { 
43-         vote_parser:: { self ,  ParsedVote } , 
44-         vote_transaction:: VoteTransaction , 
45-     } , 
42+     solana_vote:: vote_parser:: { self ,  ParsedVote ,  ParsedVoteTransaction } , 
4643    std:: { 
4744        cmp:: max, 
4845        collections:: HashMap , 
@@ -287,6 +284,10 @@ impl ClusterInfoVoteListener {
287284            votes. len ( ) , 
288285        ) ; 
289286        let  root_bank = root_bank_cache. root_bank ( ) ; 
287+         let  first_alpenglow_slot = root_bank
288+             . feature_set 
289+             . activated_slot ( & solana_feature_set:: secp256k1_program_enabled:: id ( ) ) 
290+             . unwrap_or ( Slot :: MAX ) ; 
290291        let  epoch_schedule = root_bank. epoch_schedule ( ) ; 
291292        votes
292293            . into_iter ( ) 
@@ -297,8 +298,12 @@ impl ClusterInfoVoteListener {
297298                !packet_batch[ 0 ] . meta ( ) . discard ( ) 
298299            } ) 
299300            . filter_map ( |( tx,  packet_batch) | { 
300-                 let  ( vote_account_key,  vote,  ..)  = vote_parser:: parse_vote_transaction ( & tx) ?; 
301+                 let  ( vote_account_key,  vote,  ..)  = vote_parser:: parse_vote_transaction ( & tx) 
302+                     . or_else ( || vote_parser:: parse_alpenglow_vote_transaction ( & tx) ) ?; 
301303                let  slot = vote. last_voted_slot ( ) ?; 
304+                 if  ( slot >= first_alpenglow_slot)  ^ vote. is_alpenglow_vote ( )  { 
305+                     return  None ; 
306+                 } 
302307                let  epoch = epoch_schedule. get_epoch ( slot) ; 
303308                let  authorized_voter = root_bank
304309                    . epoch_stakes ( epoch) ?
@@ -394,6 +399,7 @@ impl ClusterInfoVoteListener {
394399        subscriptions :  & RpcSubscriptions , 
395400        gossip_verified_vote_hash_sender :  & GossipVerifiedVoteHashSender , 
396401        verified_vote_sender :  & VerifiedVoteSender , 
402+         // TODO: send replayed Alpenglow transactions as well 
397403        replay_votes_receiver :  & ReplayVoteReceiver , 
398404        bank_notification_sender :  & Option < BankNotificationSender > , 
399405        duplicate_confirmed_slot_sender :  & Option < DuplicateConfirmedSlotsSender > , 
@@ -442,7 +448,7 @@ impl ClusterInfoVoteListener {
442448
443449    #[ allow( clippy:: too_many_arguments) ]  
444450    fn  track_new_votes_and_notify_confirmations ( 
445-         vote :  VoteTransaction , 
451+         vote :  ParsedVoteTransaction , 
446452        vote_pubkey :  & Pubkey , 
447453        vote_transaction_signature :  Signature , 
448454        vote_tracker :  & VoteTracker , 
@@ -459,13 +465,17 @@ impl ClusterInfoVoteListener {
459465        bank_hash_cache :  & mut  BankHashCache , 
460466        dumped_slot_subscription :  & Mutex < bool > , 
461467    )  { 
462-         if  vote. is_empty ( )  { 
468+         if  vote. slots ( ) . is_empty ( )  { 
463469            return ; 
464470        } 
465471
466472        // Hold lock for whole function to ensure hash consistency with bank_forks 
467473        let  mut  slots_dumped = dumped_slot_subscription. lock ( ) . unwrap ( ) ; 
468-         let  ( last_vote_slot,  last_vote_hash)  = vote. last_voted_slot_hash ( ) . unwrap ( ) ; 
474+         let  Some ( ( last_vote_slot,  last_vote_hash) )  = vote. last_voted_slot_hash ( )  else  { 
475+             // TODO: handle sending skip votes to replay because skp votes don't have a hash and will 
476+             // return 
477+             return ; 
478+         } ; 
469479
470480        let  latest_vote_slot = latest_vote_slot_per_validator
471481            . entry ( * vote_pubkey) 
@@ -535,20 +545,29 @@ impl ClusterInfoVoteListener {
535545                    let  _ = gossip_verified_vote_hash_sender. send ( ( * vote_pubkey,  slot,  hash) ) ; 
536546                } 
537547
538-                 if  reached_threshold_results[ 0 ]  { 
539-                     if  let  Some ( sender)  = duplicate_confirmed_slot_sender { 
540-                         let  _ = sender. send ( vec ! [ ( slot,  hash) ] ) ; 
548+                 let  first_alpenglow_slot = root_bank
549+                     . feature_set 
550+                     . activated_slot ( & solana_feature_set:: secp256k1_program_enabled:: id ( ) ) 
551+                     . unwrap_or ( Slot :: MAX ) ; 
552+ 
553+                 // Optimistic confirmation and duplicate confirmation are no longer relevant after 
554+                 // alpenglow 
555+                 if  slot < first_alpenglow_slot { 
556+                     if  reached_threshold_results[ 0 ]  { 
557+                         if  let  Some ( sender)  = duplicate_confirmed_slot_sender { 
558+                             let  _ = sender. send ( vec ! [ ( slot,  hash) ] ) ; 
559+                         } 
541560                    } 
542-                 } 
543-                 if  reached_threshold_results [ 1 ]   { 
544-                     new_optimistic_confirmed_slots . push ( ( slot ,  hash ) ) ; 
545-                     // Notify subscribers about new optimistic confirmation 
546-                     if   let   Some ( sender )  = bank_notification_sender  { 
547-                         sender 
548-                             . send ( BankNotification :: OptimisticallyConfirmed ( slot ) ) 
549-                             . unwrap_or_else ( |err|  { 
550-                                 warn ! ( "bank_notification_sender failed: {:?}" ,  err ) 
551-                              } ) ; 
561+                      if  reached_threshold_results [ 1 ]   { 
562+                         new_optimistic_confirmed_slots . push ( ( slot ,  hash ) ) ; 
563+                          // Notify subscribers about new optimistic confirmation 
564+                          if   let   Some ( sender )  = bank_notification_sender  { 
565+                             sender 
566+                                  . send ( BankNotification :: OptimisticallyConfirmed ( slot ) ) 
567+                                  . unwrap_or_else ( |err|  { 
568+                                      warn ! ( "bank_notification_sender failed: {:?}" ,  err ) 
569+                                 } ) ; 
570+                         } 
552571                    } 
553572                } 
554573
@@ -588,7 +607,10 @@ impl ClusterInfoVoteListener {
588607        * latest_vote_slot = max ( * latest_vote_slot,  last_vote_slot) ; 
589608
590609        if  is_new_vote { 
591-             subscriptions. notify_vote ( * vote_pubkey,  vote,  vote_transaction_signature) ; 
610+             // TODO: Make sure to notify on notarization votes as well 
611+             if  let  Some ( tower_vote)  = vote. try_into_tower_transaction ( )  { 
612+                 subscriptions. notify_vote ( * vote_pubkey,  tower_vote,  vote_transaction_signature) ; 
613+             } 
592614            let  _ = verified_vote_sender. send ( ( * vote_pubkey,  vote_slots) ) ; 
593615        } 
594616    } 
@@ -616,7 +638,10 @@ impl ClusterInfoVoteListener {
616638        let  mut  gossip_vote_txn_processing_time = Measure :: start ( "gossip_vote_processing_time" ) ; 
617639        let  votes = gossip_vote_txs
618640            . iter ( ) 
619-             . filter_map ( vote_parser:: parse_vote_transaction) 
641+             . filter_map ( |tx| { 
642+                 vote_parser:: parse_vote_transaction ( tx) 
643+                     . or_else ( || vote_parser:: parse_alpenglow_vote_transaction ( tx) ) 
644+             } ) 
620645            . zip ( repeat ( /*is_gossip:*/  true ) ) 
621646            . chain ( replayed_votes. into_iter ( ) . zip ( repeat ( /*is_gossip:*/  false ) ) ) ; 
622647        for  ( ( vote_pubkey,  vote,  _switch_proof,  signature) ,  is_gossip)  in  votes { 
@@ -637,7 +662,7 @@ impl ClusterInfoVoteListener {
637662                latest_vote_slot_per_validator, 
638663                bank_hash_cache, 
639664                dumped_slot_subscription, 
640-             ) ; 
665+             ) 
641666        } 
642667        gossip_vote_txn_processing_time. stop ( ) ; 
643668        let  gossip_vote_txn_processing_time_us = gossip_vote_txn_processing_time. as_us ( ) ; 
@@ -749,7 +774,7 @@ mod tests {
749774            pubkey:: Pubkey , 
750775            signature:: { Keypair ,  Signature ,  Signer } , 
751776        } , 
752-         solana_vote:: vote_transaction, 
777+         solana_vote:: vote_transaction:: { self ,   VoteTransaction } , 
753778        solana_vote_program:: vote_state:: { TowerSync ,  Vote ,  MAX_LOCKOUT_HISTORY } , 
754779        std:: { 
755780            collections:: BTreeSet , 
@@ -962,7 +987,7 @@ mod tests {
962987                replay_votes_sender
963988                    . send ( ( 
964989                        vote_keypair. pubkey ( ) , 
965-                         VoteTransaction :: from ( replay_vote. clone ( ) ) , 
990+                         ParsedVoteTransaction :: Tower ( VoteTransaction :: from ( replay_vote. clone ( ) ) ) , 
966991                        switch_proof_hash, 
967992                        Signature :: default ( ) , 
968993                    ) ) 
@@ -1285,7 +1310,10 @@ mod tests {
12851310                    replay_votes_sender
12861311                        . send ( ( 
12871312                            vote_keypair. pubkey ( ) , 
1288-                             VoteTransaction :: from ( Vote :: new ( vec ! [ vote_slot] ,  Hash :: default ( ) ) ) , 
1313+                             ParsedVoteTransaction :: Tower ( VoteTransaction :: from ( Vote :: new ( 
1314+                                 vec ! [ vote_slot] , 
1315+                                 Hash :: default ( ) , 
1316+                             ) ) ) , 
12891317                            switch_proof_hash, 
12901318                            Signature :: default ( ) , 
12911319                        ) ) 
@@ -1334,6 +1362,7 @@ mod tests {
13341362        run_test_process_votes3 ( Some ( Hash :: default ( ) ) ) ; 
13351363    } 
13361364
1365+     // TODO: Add Alpenglow equivalent tests 
13371366    #[ test]  
13381367    fn  test_vote_tracker_references ( )  { 
13391368        // Create some voters at genesis 
@@ -1388,7 +1417,10 @@ mod tests {
13881417            // Add gossip vote for same slot, should not affect outcome 
13891418            vec ! [ ( 
13901419                validator0_keypairs. vote_keypair. pubkey( ) , 
1391-                 VoteTransaction :: from( Vote :: new( vec![ voted_slot] ,  Hash :: default ( ) ) ) , 
1420+                 ParsedVoteTransaction :: Tower ( VoteTransaction :: from( Vote :: new( 
1421+                     vec![ voted_slot] , 
1422+                     Hash :: default ( ) , 
1423+                 ) ) ) , 
13921424                None , 
13931425                Signature :: default ( ) , 
13941426            ) ] , 
@@ -1437,7 +1469,10 @@ mod tests {
14371469            vote_txs, 
14381470            vec ! [ ( 
14391471                validator_keypairs[ 1 ] . vote_keypair. pubkey( ) , 
1440-                 VoteTransaction :: from( Vote :: new( vec![ first_slot_in_new_epoch] ,  Hash :: default ( ) ) ) , 
1472+                 ParsedVoteTransaction :: Tower ( VoteTransaction :: from( Vote :: new( 
1473+                     vec![ first_slot_in_new_epoch] , 
1474+                     Hash :: default ( ) , 
1475+                 ) ) ) , 
14411476                None , 
14421477                Signature :: default ( ) , 
14431478            ) ] , 
0 commit comments