@@ -2,17 +2,19 @@ use std::{sync::Arc, time::Duration};
22
33use backon:: { BackoffBuilder , ExponentialBuilder } ;
44use mpc_contract:: tee:: proposal:: MpcDockerImageHash ;
5+ use mpc_contract:: tee:: tee_state:: NodeId ;
56use tokio:: sync:: watch;
67
78use crate :: indexer:: {
8- lib:: { get_mpc_allowed_image_hashes, wait_for_full_sync} ,
9+ lib:: { get_mpc_allowed_image_hashes, get_mpc_tee_accounts , wait_for_full_sync} ,
910 IndexerState ,
1011} ;
1112
1213const ALLOWED_IMAGE_HASHES_REFRESH_INTERVAL : std:: time:: Duration =
1314 std:: time:: Duration :: from_secs ( 1 ) ;
1415const MIN_BACKOFF_DURATION : Duration = Duration :: from_secs ( 1 ) ;
1516const MAX_BACKOFF_DURATION : Duration = Duration :: from_secs ( 60 ) ;
17+ const TEE_ACCOUNTS_REFRESH_INTERVAL : std:: time:: Duration = std:: time:: Duration :: from_secs ( 1 ) ;
1618
1719/// This future waits for the indexer to fully sync, and returns
1820/// a [`watch::Receiver`] that will be continuously updated with the latest
@@ -71,3 +73,55 @@ pub async fn monitor_allowed_docker_images(
7173 } ) ;
7274 }
7375}
76+
77+ /// Monitor TEE accounts stored in the contract and update the watch channel when changes are detected
78+ pub async fn monitor_tee_accounts (
79+ sender : watch:: Sender < Vec < NodeId > > ,
80+ indexer_state : Arc < IndexerState > ,
81+ ) {
82+ let fetch_tee_accounts = {
83+ let indexer_state = indexer_state. clone ( ) ;
84+ async move || {
85+ let mut backoff = ExponentialBuilder :: default ( )
86+ . with_min_delay ( MIN_BACKOFF_DURATION )
87+ . with_max_delay ( MAX_BACKOFF_DURATION )
88+ . without_max_times ( )
89+ . with_jitter ( )
90+ . build ( ) ;
91+
92+ loop {
93+ match get_mpc_tee_accounts (
94+ indexer_state. mpc_contract_id . clone ( ) ,
95+ & indexer_state. view_client ,
96+ )
97+ . await
98+ {
99+ Ok ( ( _block_height, tee_accounts) ) => {
100+ break tee_accounts;
101+ }
102+ Err ( e) => {
103+ tracing:: error!( target: "mpc" , "error reading TEE accounts from chain: {:?}" , e) ;
104+
105+ let backoff_duration = backoff. next ( ) . unwrap_or ( MAX_BACKOFF_DURATION ) ;
106+ tokio:: time:: sleep ( backoff_duration) . await ;
107+ }
108+ }
109+ }
110+ }
111+ } ;
112+
113+ wait_for_full_sync ( & indexer_state. client ) . await ;
114+
115+ loop {
116+ tokio:: time:: sleep ( TEE_ACCOUNTS_REFRESH_INTERVAL ) . await ;
117+ let tee_accounts = fetch_tee_accounts ( ) . await ;
118+ sender. send_if_modified ( |previous_tee_accounts| {
119+ if * previous_tee_accounts != tee_accounts {
120+ * previous_tee_accounts = tee_accounts;
121+ true
122+ } else {
123+ false
124+ }
125+ } ) ;
126+ }
127+ }
0 commit comments