@@ -24,10 +24,11 @@ use std::{
2424 sync:: Arc ,
2525} ;
2626
27+ use serde:: Deserialize ;
2728use yellowstone_grpc_proto:: geyser:: {
28- CommitmentLevel , SubscribeRequest , SubscribeRequestFilterAccounts ,
29- SubscribeRequestFilterBlocksMeta , SubscribeRequestFilterTransactions , SubscribeUpdateAccount ,
30- SubscribeUpdateBlockMeta , SubscribeUpdateTransaction ,
29+ self , SubscribeRequest , SubscribeRequestFilterAccounts , SubscribeRequestFilterBlocksMeta ,
30+ SubscribeRequestFilterSlots , SubscribeRequestFilterTransactions , SubscribeUpdateAccount ,
31+ SubscribeUpdateBlockMeta , SubscribeUpdateSlot , SubscribeUpdateTransaction ,
3132} ;
3233
3334pub extern crate bs58;
@@ -65,6 +66,8 @@ pub type AccountUpdate = SubscribeUpdateAccount;
6566pub type TransactionUpdate = SubscribeUpdateTransaction ;
6667/// A block meta update from Yellowstone.
6768pub type BlockMetaUpdate = SubscribeUpdateBlockMeta ;
69+ /// A slot update from Yellowstone.
70+ pub type SlotUpdate = SubscribeUpdateSlot ;
6871
6972/// Generic output type for instruction parsers that wraps shared data for all instructions
7073/// in the given transaction.
@@ -154,7 +157,9 @@ pub struct Prefilter {
154157 /// Filters for transaction updates.
155158 pub transaction : Option < TransactionPrefilter > ,
156159 /// Filters for block meta updates.
157- pub ( crate ) block_meta : Option < BlockMetaPrefilter > ,
160+ pub block_meta : Option < BlockMetaPrefilter > ,
161+ /// Filters for slot updates.
162+ pub slot : Option < SlotPrefilter > ,
158163}
159164
160165fn merge_opt < T , F : FnOnce ( & mut T , T ) > ( lhs : & mut Option < T > , rhs : Option < T > , f : F ) {
@@ -177,10 +182,12 @@ impl Prefilter {
177182 account,
178183 transaction,
179184 block_meta,
185+ slot,
180186 } = self ;
181187 merge_opt ( account, other. account , AccountPrefilter :: merge) ;
182188 merge_opt ( transaction, other. transaction , TransactionPrefilter :: merge) ;
183189 merge_opt ( block_meta, other. block_meta , BlockMetaPrefilter :: merge) ;
190+ merge_opt ( slot, other. slot , SlotPrefilter :: merge) ;
184191 }
185192}
186193
@@ -242,10 +249,23 @@ impl TransactionPrefilter {
242249 }
243250}
244251
245- #[ derive( Debug , Default , Clone , PartialEq ) ]
246- pub ( crate ) struct BlockMetaPrefilter { }
252+ /// A prefilter for matching block metadata updates.
253+ #[ derive( Debug , Default , Clone , PartialEq , Copy ) ]
254+ pub struct BlockMetaPrefilter { }
247255
248256impl BlockMetaPrefilter {
257+ /// Merge another block metadata prefilter into this one.
258+ /// This function currently does nothing as the struct has no fields.
259+ pub fn merge ( _lhs : & mut Self , _rhs : Self ) { }
260+ }
261+
262+ /// A prefilter for matching slot updates updates.
263+ #[ derive( Debug , Default , Clone , PartialEq , Copy ) ]
264+ pub struct SlotPrefilter { }
265+
266+ impl SlotPrefilter {
267+ /// Merge another slot prefilter into this one.
268+ /// This function currently does nothing as the struct has no fields.
249269 pub fn merge ( _lhs : & mut Self , _rhs : Self ) { }
250270}
251271
@@ -445,6 +465,8 @@ pub enum PrefilterError {
445465#[ must_use = "Consider calling .build() on this builder" ]
446466pub struct PrefilterBuilder {
447467 error : Option < PrefilterError > ,
468+ slots : bool ,
469+ block_metas : bool ,
448470 accounts : Option < HashSet < Pubkey > > ,
449471 account_owners : Option < HashSet < Pubkey > > ,
450472 /// Matching [`TransactionPrefilter::accounts_include`]
@@ -484,6 +506,8 @@ impl PrefilterBuilder {
484506 error,
485507 accounts,
486508 account_owners,
509+ slots,
510+ block_metas,
487511 transaction_accounts_include,
488512 transaction_accounts_required,
489513 } = self ;
@@ -503,10 +527,13 @@ impl PrefilterBuilder {
503527
504528 let block_meta = BlockMetaPrefilter { } ;
505529
530+ let slot = SlotPrefilter { } ;
531+
506532 Ok ( Prefilter {
507533 account : ( account != AccountPrefilter :: default ( ) ) . then_some ( account) ,
508534 transaction : ( transaction != TransactionPrefilter :: default ( ) ) . then_some ( transaction) ,
509- block_meta : ( block_meta != BlockMetaPrefilter :: default ( ) ) . then_some ( block_meta) ,
535+ block_meta : block_metas. then_some ( block_meta) ,
536+ slot : slots. then_some ( slot) ,
510537 } )
511538 }
512539
@@ -518,6 +545,14 @@ impl PrefilterBuilder {
518545 self
519546 }
520547
548+ /// Set prefilter will request slot updates.
549+ pub fn slots ( self ) -> Self {
550+ self . mutate ( |this| {
551+ this. slots = true ;
552+ Ok ( ( ) )
553+ } )
554+ }
555+
521556 /// Set the accounts that this prefilter will match.
522557 pub fn accounts < I : IntoIterator > ( self , it : I ) -> Self
523558 where I :: Item : AsRef < [ u8 ] > {
@@ -573,17 +608,6 @@ impl PrefilterBuilder {
573608pub struct Filters {
574609 /// Filters for each parser.
575610 pub parsers_filters : HashMap < String , Prefilter > ,
576- /// Global filters for the subscription.
577- pub global_filters : GlobalFilters ,
578- }
579-
580- /// A collection of global filters shared by all parsers for a Vixen subscription.
581- #[ derive( Debug , Clone , Default , Copy ) ]
582- pub struct GlobalFilters {
583- /// The commitment level for the subscription.
584- pub commitment : Option < CommitmentLevel > ,
585- /// The from slot filter for the subscription.
586- pub from_slot : Option < u64 > ,
587611}
588612
589613impl Filters {
@@ -593,26 +617,30 @@ impl Filters {
593617 pub fn new ( filters : HashMap < String , Prefilter > ) -> Self {
594618 Self {
595619 parsers_filters : filters,
596- global_filters : GlobalFilters :: default ( ) ,
597620 }
598621 }
622+ }
599623
600- /// Set the commitment level filter.
601- #[ inline]
602- #[ must_use]
603- pub fn commitment ( mut self , commitment : Option < CommitmentLevel > ) -> Self {
604- self . global_filters . commitment = commitment;
605-
606- self
607- }
608-
609- /// Set the from slot filter.
610- #[ inline]
611- #[ must_use]
612- pub fn from_slot ( mut self , from_slot : Option < u64 > ) -> Self {
613- self . global_filters . from_slot = from_slot;
614-
615- self
624+ /// Type mirroring the `CommitmentLevel` enum in the `geyser` crate but serializable.
625+ /// Used to avoid need for custom deserialization logic.
626+ #[ derive( Debug , Clone , Copy , Deserialize , clap:: ValueEnum ) ]
627+ #[ serde( rename_all = "lowercase" ) ]
628+ pub enum CommitmentLevel {
629+ /// Processed
630+ Processed ,
631+ /// Confirmed
632+ Confirmed ,
633+ /// Finalized
634+ Finalized ,
635+ }
636+
637+ impl From < geyser:: CommitmentLevel > for CommitmentLevel {
638+ fn from ( value : geyser:: CommitmentLevel ) -> Self {
639+ match value {
640+ geyser:: CommitmentLevel :: Processed => Self :: Processed ,
641+ geyser:: CommitmentLevel :: Confirmed => Self :: Confirmed ,
642+ geyser:: CommitmentLevel :: Finalized => Self :: Finalized ,
643+ }
616644 }
617645}
618646
@@ -635,7 +663,16 @@ impl From<Filters> for SubscribeRequest {
635663 } ) )
636664 } )
637665 . collect ( ) ,
638- slots : [ ] . into_iter ( ) . collect ( ) ,
666+ slots : value
667+ . parsers_filters
668+ . keys ( )
669+ . map ( |k| {
670+ ( k. clone ( ) , SubscribeRequestFilterSlots {
671+ filter_by_commitment : Some ( true ) ,
672+ interslot_updates : None ,
673+ } )
674+ } )
675+ . collect ( ) ,
639676 transactions : value
640677 . parsers_filters
641678 . iter ( )
@@ -669,13 +706,10 @@ impl From<Filters> for SubscribeRequest {
669706 . map ( |k| ( k. clone ( ) , SubscribeRequestFilterBlocksMeta { } ) )
670707 . collect ( ) ,
671708 entry : [ ] . into_iter ( ) . collect ( ) ,
672- commitment : value
673- . global_filters
674- . commitment
675- . map ( |commitment| commitment as i32 ) ,
709+ commitment : None ,
676710 accounts_data_slice : vec ! [ ] ,
677711 ping : None ,
678- from_slot : value . global_filters . from_slot ,
712+ from_slot : None ,
679713 }
680714 }
681715}
0 commit comments