Skip to content

Commit 501b04f

Browse files
feat(argus): Implement Keeper state and main request processing loop (#2542)
* chore: remove fortuna-specific keeper code * feat: first pass at keeper fulfillment state and logic * refactor: replace EscalationPolicy with a stub for now * fix: address pr comments
1 parent 9b60553 commit 501b04f

File tree

7 files changed

+714
-3
lines changed

7 files changed

+714
-3
lines changed

apps/argus/Cargo.lock

+74-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/argus/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ chrono = { version = "0.4.38", features = [
4040
backoff = { version = "0.4.0", features = ["futures", "tokio"] }
4141
thiserror = "1.0.61"
4242
futures-locks = "0.7.1"
43+
async-trait = "0.1.88"
4344

4445

4546
[dev-dependencies]
47+
mockall = "0.13.1"
4648
axum-test = "13.1.1"

apps/argus/src/keeper.rs

+2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ use {
2121
};
2222

2323
pub(crate) mod fee;
24+
pub(crate) mod fulfillment_task;
2425
pub(crate) mod keeper_metrics;
26+
pub(crate) mod state;
2527
pub(crate) mod track;
2628

2729
/// Track metrics in this interval

apps/argus/src/keeper/fee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ use {
33
api::BlockchainState, chain::ethereum::InstrumentedSignablePythContract,
44
keeper::AccountLabel, keeper::ChainId, keeper::KeeperMetrics,
55
},
6-
fortuna::eth_utils::utils::{estimate_tx_cost, send_and_confirm},
76
anyhow::{anyhow, Result},
87
ethers::{
98
middleware::Middleware,
109
signers::Signer,
1110
types::{Address, U256},
1211
},
12+
fortuna::eth_utils::utils::{estimate_tx_cost, send_and_confirm},
1313
std::sync::Arc,
1414
tokio::time::{self, Duration},
1515
tracing::{self, Instrument},
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use anyhow::Result;
2+
use tokio::task::JoinHandle;
3+
4+
use super::state::{EscalationPolicy, PulseRequest};
5+
use async_trait::async_trait;
6+
7+
#[allow(dead_code)]
8+
#[derive(Debug)]
9+
pub struct RequestFulfillmentTask {
10+
/// If None, the task hasn't been spawned. If Some(fut), task is in flight or completed.
11+
pub task: Option<JoinHandle<Result<()>>>,
12+
pub retries: u32,
13+
pub success: bool,
14+
15+
// The error received during fulfillment if `success` is false.
16+
// We don't consider the consumer callback reverting as a failure since we catch those
17+
// in the Pulse contract. Thus, this should only happen if there's a transient RPC error
18+
// (tx failed to land, out of gas, etc)
19+
pub error: Option<String>,
20+
}
21+
22+
#[async_trait]
23+
pub trait RequestFulfiller: Send + Sync + 'static {
24+
#[allow(dead_code)]
25+
async fn fulfill_request(
26+
&self,
27+
request: PulseRequest,
28+
hermes_url: &str,
29+
escalation_policy: EscalationPolicy,
30+
) -> Result<()>;
31+
}
32+
33+
#[allow(dead_code)]
34+
pub struct DefaultRequestFulfiller;
35+
36+
#[async_trait]
37+
impl RequestFulfiller for DefaultRequestFulfiller {
38+
/// Core logic of fulfilling a Pulse request
39+
async fn fulfill_request(
40+
&self,
41+
_request: PulseRequest,
42+
_hermes_url: &str,
43+
_escalation_policy: EscalationPolicy,
44+
) -> Result<()> {
45+
// TODO:
46+
// 1. get price update by calling hermes
47+
// 2. create contract call and submit it with escalation policy
48+
// 3. validate receipt from tx
49+
Ok(())
50+
}
51+
}

apps/argus/src/keeper/keeper_metrics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub struct ChainIdLabel {
2222
}
2323

2424
pub struct KeeperMetrics {
25+
// TODO: reevaluate what metrics are useful for argus
2526
pub current_sequence_number: Family<AccountLabel, Gauge>,
2627
pub end_sequence_number: Family<AccountLabel, Gauge>,
2728
pub balance: Family<AccountLabel, Gauge<f64, AtomicU64>>,

0 commit comments

Comments
 (0)