@@ -74,7 +74,7 @@ pub trait Config: Send + Sync + 'static {
7474 /// data/logic into it.
7575 ///
7676 /// If no additional logic is required - just specify [`Node`].
77- type Node : Clone + Send + Sync + ' static ;
77+ type Node : AsRef < PeerId > + Clone + Send + Sync + ' static ;
7878
7979 /// Creates a new [`Config::Node`].
8080 fn new_node ( & self , operator_id : node_operator:: Id , node : Node ) -> Self :: Node ;
@@ -96,7 +96,9 @@ struct Inner<C: Config> {
9696 config : C ,
9797 smart_contract : C :: SmartContract ,
9898 view : ArcSwap < View < C > > ,
99- watch : watch:: Receiver < ( ) > ,
99+
100+ watch_tx : watch:: Sender < ( ) > ,
101+ watch_rx : watch:: Receiver < ( ) > ,
100102}
101103
102104/// Version of a WCN [`Cluster`].
@@ -187,7 +189,8 @@ where
187189 config : cfg,
188190 smart_contract : contract,
189191 view : ArcSwap :: new ( Arc :: new ( view) ) ,
190- watch : rx,
192+ watch_tx : tx. clone ( ) ,
193+ watch_rx : rx,
191194 } ) ;
192195
193196 let guard = Task {
@@ -225,13 +228,55 @@ impl<C: Config> Cluster<C> {
225228 pub fn updates ( & self ) -> impl Stream < Item = ( ) > + Send + ' static {
226229 // TODO: periodically check with the SC to prevent drift
227230
228- tokio_stream:: wrappers:: WatchStream :: new ( self . inner . watch . clone ( ) )
231+ tokio_stream:: wrappers:: WatchStream :: new ( self . inner . watch_rx . clone ( ) )
232+ }
233+
234+ /// Creates a new [`Watch`] of this [`Cluster`].
235+ pub fn watch ( & self ) -> Watch {
236+ let mut rx = self . inner . watch_rx . clone ( ) ;
237+ rx. mark_changed ( ) ;
238+
239+ Watch {
240+ inner : rx,
241+ _tx : self . inner . watch_tx . clone ( ) ,
242+ }
229243 }
230244
231245 /// Returns reference to the underlying [`SmartContract`].
232246 pub fn smart_contract ( & self ) -> & C :: SmartContract {
233247 & self . inner . smart_contract
234248 }
249+
250+ /// Indicates whether this [`Cluster`] contains a [`Node`] with the provided
251+ /// ID.
252+ pub fn contains_node ( & self , peer_id : & PeerId ) -> bool
253+ where
254+ C :: Node : AsRef < PeerId > ,
255+ {
256+ self . using_view ( |view| view. node_operators ( ) . contains_node ( peer_id) )
257+ }
258+
259+ /// Checks whether the provided [`keyspace`] version is compatible with
260+ /// current state of the [`Cluster`].
261+ pub fn validate_keyspace_version ( & self , version : u64 ) -> bool {
262+ self . using_view ( |view| view. validate_keyspace_version ( version) )
263+ }
264+ }
265+
266+ /// Handle to track [`Cluster`] updates.
267+ pub struct Watch {
268+ inner : watch:: Receiver < ( ) > ,
269+ _tx : watch:: Sender < ( ) > ,
270+ }
271+
272+ impl Watch {
273+ /// Resolves when the next [`Cluster`] update occurs.
274+ ///
275+ /// First time after creation resolves immediately.
276+ pub async fn cluster_updated ( & mut self ) {
277+ // NOTE(unwrap): we are holding the `Sender`, so it won't ever error.
278+ self . inner . changed ( ) . await . unwrap ( )
279+ }
235280}
236281
237282impl < C : Config > Cluster < C >
0 commit comments