Skip to content

Commit 5fa85ac

Browse files
refactor: use tokio::watch for escrow_accounts (#413)
1 parent be1a25b commit 5fa85ac

File tree

16 files changed

+191
-220
lines changed

16 files changed

+191
-220
lines changed

common/src/escrow_accounts.rs

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@ use std::{
99

1010
use alloy::primitives::{Address, U256};
1111
use anyhow::{anyhow, Result};
12-
use eventuals::{timer, Eventual, EventualExt};
1312
use graphql_client::GraphQLQuery;
1413
use thiserror::Error;
15-
use tokio::time::sleep;
14+
use tokio::sync::watch::Receiver;
1615
use tracing::{error, warn};
1716

18-
use crate::prelude::SubgraphClient;
17+
use crate::{prelude::SubgraphClient, watcher};
1918

2019
#[derive(Error, Debug)]
2120
pub enum EscrowAccountsError {
@@ -99,27 +98,16 @@ type BigInt = String;
9998
)]
10099
pub struct EscrowAccountQuery;
101100

102-
pub fn escrow_accounts(
101+
pub async fn escrow_accounts(
103102
escrow_subgraph: &'static SubgraphClient,
104103
indexer_address: Address,
105104
interval: Duration,
106105
reject_thawing_signers: bool,
107-
) -> Eventual<EscrowAccounts> {
108-
timer(interval).map_with_retry(
109-
move |_| async move {
110-
get_escrow_accounts(escrow_subgraph, indexer_address, reject_thawing_signers)
111-
.await
112-
.map_err(|e| e.to_string())
113-
},
114-
move |err: String| {
115-
error!(
116-
"Failed to fetch escrow accounts for indexer {:?}: {}",
117-
indexer_address, err
118-
);
119-
120-
sleep(interval.div_f32(2.0))
121-
},
122-
)
106+
) -> Result<Receiver<EscrowAccounts>, anyhow::Error> {
107+
watcher::new_watcher(interval, move || {
108+
get_escrow_accounts(escrow_subgraph, indexer_address, reject_thawing_signers)
109+
})
110+
.await
123111
}
124112

125113
async fn get_escrow_accounts(
@@ -238,15 +226,17 @@ mod tests {
238226
);
239227
mock_server.register(mock).await;
240228

241-
let accounts = escrow_accounts(
229+
let mut accounts = escrow_accounts(
242230
escrow_subgraph,
243231
*test_vectors::INDEXER_ADDRESS,
244232
Duration::from_secs(60),
245233
true,
246-
);
247-
234+
)
235+
.await
236+
.unwrap();
237+
accounts.changed().await.unwrap();
248238
assert_eq!(
249-
accounts.value().await.unwrap(),
239+
accounts.borrow().clone(),
250240
EscrowAccounts::new(
251241
test_vectors::ESCROW_ACCOUNTS_BALANCES.to_owned(),
252242
test_vectors::ESCROW_ACCOUNTS_SENDERS_TO_SIGNERS.to_owned(),

common/src/indexer_service/http/indexer_service.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use axum::{
1414
};
1515
use axum::{serve, ServiceExt};
1616
use build_info::BuildInfo;
17-
use eventuals::Eventual;
1817
use prometheus::TextEncoder;
1918
use reqwest::StatusCode;
2019
use serde::{de::DeserializeOwned, Serialize};
@@ -83,8 +82,6 @@ where
8382
{
8483
#[error("Issues with provided receipt: {0}")]
8584
ReceiptError(tap_core::Error),
86-
#[error("Service is not ready yet, try again in a moment")]
87-
ServiceNotReady,
8885
#[error("No attestation signer found for allocation `{0}`")]
8986
NoSignerForAllocation(Address),
9087
#[error("Invalid request body: {0}")]
@@ -120,8 +117,6 @@ where
120117
}
121118

122119
let status = match self {
123-
ServiceNotReady => StatusCode::SERVICE_UNAVAILABLE,
124-
125120
Unauthorized => StatusCode::UNAUTHORIZED,
126121

127122
NoSignerForAllocation(_) | FailedToSignAttestation => StatusCode::INTERNAL_SERVER_ERROR,
@@ -188,7 +183,7 @@ where
188183
pub service_impl: Arc<I>,
189184

190185
// tap
191-
pub escrow_accounts: Eventual<EscrowAccounts>,
186+
pub escrow_accounts: Receiver<EscrowAccounts>,
192187
pub domain_separator: Eip712Domain,
193188
}
194189

@@ -311,7 +306,9 @@ impl IndexerService {
311306
options.config.indexer.indexer_address,
312307
options.config.subgraphs.escrow.config.syncing_interval_secs,
313308
true, // Reject thawing signers eagerly
314-
);
309+
)
310+
.await
311+
.expect("Error creating escrow_accounts channel");
315312

316313
// Establish Database connection necessary for serving indexer management
317314
// requests with defined schema

common/src/indexer_service/http/request_handler.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ where
132132
});
133133

134134
// recover the signer address
135-
// get escrow accounts from eventual
135+
// get escrow accounts from channel
136136
// return sender from signer
137137
//
138138
// TODO: We are currently doing this process twice.
@@ -141,13 +141,9 @@ where
141141
let signer = receipt
142142
.recover_signer(&state.domain_separator)
143143
.map_err(IndexerServiceError::CouldNotDecodeSigner)?;
144-
145-
let escrow_accounts = state
144+
let sender = state
146145
.escrow_accounts
147-
.value_immediate()
148-
.ok_or(IndexerServiceError::ServiceNotReady)?;
149-
150-
let sender = escrow_accounts
146+
.borrow()
151147
.get_sender_for_signer(&signer)
152148
.map_err(IndexerServiceError::EscrowAccount)?;
153149

common/src/tap.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use crate::tap::checks::value_check::MinimumValue;
1010
use crate::{escrow_accounts::EscrowAccounts, prelude::Allocation};
1111
use alloy::dyn_abi::Eip712Domain;
1212
use alloy::primitives::Address;
13-
use eventuals::Eventual;
1413
use receipt_store::{DatabaseReceipt, InnerContext};
1514
use sqlx::PgPool;
1615
use std::fmt::Debug;
@@ -44,7 +43,7 @@ impl IndexerTapContext {
4443
pub async fn get_checks(
4544
pgpool: PgPool,
4645
indexer_allocations: Receiver<HashMap<Address, Allocation>>,
47-
escrow_accounts: Eventual<EscrowAccounts>,
46+
escrow_accounts: Receiver<EscrowAccounts>,
4847
domain_separator: Eip712Domain,
4948
timestamp_error_tolerance: Duration,
5049
receipt_max_value: u128,

common/src/tap/checks/deny_list_check.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use crate::escrow_accounts::EscrowAccounts;
55
use alloy::dyn_abi::Eip712Domain;
66
use alloy::primitives::Address;
7-
use eventuals::Eventual;
87
use sqlx::postgres::PgListener;
98
use sqlx::PgPool;
109
use std::collections::HashSet;
@@ -16,10 +15,11 @@ use tap_core::receipt::{
1615
state::Checking,
1716
ReceiptWithState,
1817
};
18+
use tokio::sync::watch::Receiver;
1919
use tracing::error;
2020

2121
pub struct DenyListCheck {
22-
escrow_accounts: Eventual<EscrowAccounts>,
22+
escrow_accounts: Receiver<EscrowAccounts>,
2323
domain_separator: Eip712Domain,
2424
sender_denylist: Arc<RwLock<HashSet<Address>>>,
2525
_sender_denylist_watcher_handle: Arc<tokio::task::JoinHandle<()>>,
@@ -29,7 +29,7 @@ pub struct DenyListCheck {
2929
impl DenyListCheck {
3030
pub async fn new(
3131
pgpool: PgPool,
32-
escrow_accounts: Eventual<EscrowAccounts>,
32+
escrow_accounts: Receiver<EscrowAccounts>,
3333
domain_separator: Eip712Domain,
3434
) -> Self {
3535
// Listen to pg_notify events. We start it before updating the sender_denylist so that we
@@ -163,7 +163,7 @@ impl Check for DenyListCheck {
163163
anyhow::anyhow!(e)
164164
})
165165
.map_err(CheckError::Failed)?;
166-
let escrow_accounts_snapshot = self.escrow_accounts.value_immediate().unwrap_or_default();
166+
let escrow_accounts_snapshot = self.escrow_accounts.borrow();
167167

168168
let receipt_sender = escrow_accounts_snapshot
169169
.get_sender_for_signer(&receipt_signer)
@@ -200,6 +200,7 @@ mod tests {
200200

201201
use alloy::hex::ToHexExt;
202202
use tap_core::receipt::{Context, ReceiptWithState};
203+
use tokio::sync::watch;
203204

204205
use crate::test_vectors::{self, create_signed_receipt, TAP_SENDER};
205206

@@ -209,14 +210,15 @@ mod tests {
209210

210211
async fn new_deny_list_check(pgpool: PgPool) -> DenyListCheck {
211212
// Mock escrow accounts
212-
let escrow_accounts = Eventual::from_value(EscrowAccounts::new(
213+
let escrow_accounts_rx = watch::channel(EscrowAccounts::new(
213214
test_vectors::ESCROW_ACCOUNTS_BALANCES.to_owned(),
214215
test_vectors::ESCROW_ACCOUNTS_SENDERS_TO_SIGNERS.to_owned(),
215-
));
216+
))
217+
.1;
216218

217219
DenyListCheck::new(
218220
pgpool,
219-
escrow_accounts,
221+
escrow_accounts_rx,
220222
test_vectors::TAP_EIP712_DOMAIN.to_owned(),
221223
)
222224
.await

common/src/tap/checks/sender_balance_check.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@ use crate::escrow_accounts::EscrowAccounts;
55
use alloy::dyn_abi::Eip712Domain;
66
use alloy::primitives::U256;
77
use anyhow::anyhow;
8-
use eventuals::Eventual;
98
use tap_core::receipt::{
109
checks::{Check, CheckError, CheckResult},
1110
state::Checking,
1211
ReceiptWithState,
1312
};
13+
use tokio::sync::watch::Receiver;
1414
use tracing::error;
1515

1616
pub struct SenderBalanceCheck {
17-
escrow_accounts: Eventual<EscrowAccounts>,
17+
escrow_accounts: Receiver<EscrowAccounts>,
1818

1919
domain_separator: Eip712Domain,
2020
}
2121

2222
impl SenderBalanceCheck {
23-
pub fn new(escrow_accounts: Eventual<EscrowAccounts>, domain_separator: Eip712Domain) -> Self {
23+
pub fn new(escrow_accounts: Receiver<EscrowAccounts>, domain_separator: Eip712Domain) -> Self {
2424
Self {
2525
escrow_accounts,
2626
domain_separator,
@@ -35,7 +35,7 @@ impl Check for SenderBalanceCheck {
3535
_: &tap_core::receipt::Context,
3636
receipt: &ReceiptWithState<Checking>,
3737
) -> CheckResult {
38-
let escrow_accounts_snapshot = self.escrow_accounts.value_immediate().unwrap_or_default();
38+
let escrow_accounts_snapshot = self.escrow_accounts.borrow();
3939

4040
let receipt_signer = receipt
4141
.signed_receipt()

tap-agent/src/agent.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ pub async fn start_agent() -> (ActorRef<SenderAccountsManagerMessage>, JoinHandl
128128
*indexer_address,
129129
*escrow_sync_interval,
130130
false,
131-
);
131+
)
132+
.await
133+
.expect("Error creating escrow_accounts channel");
132134

133135
let config = Box::leak(Box::new(SenderAccountConfig::from_config(&CONFIG)));
134136

0 commit comments

Comments
 (0)