@@ -54,8 +54,8 @@ impl BlockWatcher {
5454 }
5555
5656 /// Subscribe to block number updates.
57- pub fn subscribe ( & self ) -> watch :: Receiver < u64 > {
58- self . block_number . subscribe ( )
57+ pub fn subscribe ( & self ) -> SharedBlockNumber {
58+ self . block_number . subscribe ( ) . into ( )
5959 }
6060
6161 /// Spawns the block watcher task.
@@ -82,3 +82,41 @@ impl BlockWatcher {
8282 }
8383 }
8484}
85+
86+ /// A shared block number, wrapped in a [`tokio::sync::watch`] Receiver.
87+ ///
88+ /// The block number is periodically updated by a [`BlockWatcher`] task, and
89+ /// can be read or awaited for changes. This allows multiple tasks to observe
90+ /// block number updates.
91+ #[ derive( Debug , Clone ) ]
92+ pub struct SharedBlockNumber ( watch:: Receiver < u64 > ) ;
93+
94+ impl From < watch:: Receiver < u64 > > for SharedBlockNumber {
95+ fn from ( inner : watch:: Receiver < u64 > ) -> Self {
96+ Self ( inner)
97+ }
98+ }
99+
100+ impl SharedBlockNumber {
101+ /// Get the current block number.
102+ pub fn get ( & self ) -> u64 {
103+ * self . 0 . borrow ( )
104+ }
105+
106+ /// Wait for the block number to change, then return the new value.
107+ ///
108+ /// This is implemented using [`Receiver::changed`].
109+ ///
110+ /// [`Receiver::changed`]: tokio::sync::watch::Receiver::changed
111+ pub async fn changed ( & mut self ) -> Result < u64 , watch:: error:: RecvError > {
112+ self . 0 . changed ( ) . await ?;
113+ Ok ( * self . 0 . borrow_and_update ( ) )
114+ }
115+
116+ /// Wait for the block number to reach at least `target`.
117+ ///
118+ /// Returns the block number once it is >= `target`.
119+ pub async fn wait_until ( & mut self , target : u64 ) -> Result < u64 , watch:: error:: RecvError > {
120+ self . 0 . wait_for ( |& n| n >= target) . await . map ( |r| * r)
121+ }
122+ }
0 commit comments