Skip to content

Commit 5ee3d86

Browse files
committed
feat: add dispute manager eventual
1 parent 56b82ef commit 5ee3d86

File tree

5 files changed

+160
-11
lines changed

5 files changed

+160
-11
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Copyright 2023-, GraphOps and Semiotic Labs.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use std::time::Duration;
5+
6+
use alloy_primitives::Address;
7+
use eventuals::{timer, Eventual, EventualExt};
8+
use log::warn;
9+
use serde::Deserialize;
10+
use serde_json::json;
11+
use tokio::time::sleep;
12+
13+
use crate::network_subgraph::NetworkSubgraph;
14+
15+
pub fn dispute_manager(
16+
network_subgraph: &'static NetworkSubgraph,
17+
graph_network_id: u64,
18+
interval: Duration,
19+
) -> Eventual<Address> {
20+
#[derive(Deserialize)]
21+
#[serde(rename_all = "camelCase")]
22+
struct DisputeManagerResponse {
23+
graph_network: Option<GraphNetwork>,
24+
}
25+
26+
#[derive(Deserialize)]
27+
#[serde(rename_all = "camelCase")]
28+
struct GraphNetwork {
29+
dispute_manager: Address,
30+
}
31+
32+
timer(interval).map_with_retry(
33+
move |_| async move {
34+
let response = network_subgraph
35+
.query::<DisputeManagerResponse>(&json!({
36+
"query": r#"
37+
query network($id: ID!) {
38+
graphNetwork(id: $id) {
39+
disputeManager
40+
}
41+
}
42+
"#,
43+
"variables": {
44+
"id": graph_network_id
45+
}
46+
}))
47+
.await
48+
.map_err(|e| e.to_string())?;
49+
50+
if let Some(errors) = response.errors {
51+
warn!(
52+
"Errors encountered querying the dispute manager for network {}: {}",
53+
graph_network_id,
54+
errors
55+
.into_iter()
56+
.map(|e| e.message)
57+
.collect::<Vec<_>>()
58+
.join(", ")
59+
);
60+
}
61+
62+
response
63+
.data
64+
.and_then(|data| data.graph_network)
65+
.map(|network| network.dispute_manager)
66+
.ok_or_else(|| {
67+
format!("Network {} not found in network subgraph", graph_network_id)
68+
})
69+
},
70+
move |err: String| {
71+
warn!(
72+
"Failed to query dispute manager for network {}: {}",
73+
graph_network_id, err,
74+
);
75+
76+
// Sleep for a bit before we retry
77+
sleep(interval.div_f32(2.0))
78+
},
79+
)
80+
}
81+
82+
#[cfg(test)]
83+
mod test {
84+
use serde_json::json;
85+
use wiremock::{
86+
matchers::{method, path},
87+
Mock, MockServer, ResponseTemplate,
88+
};
89+
90+
use crate::{
91+
prelude::NetworkSubgraph,
92+
test_vectors::{self, DISPUTE_MANAGER_ADDRESS},
93+
};
94+
95+
use super::*;
96+
97+
async fn setup_mock_network_subgraph() -> (&'static NetworkSubgraph, MockServer) {
98+
// Set up a mock network subgraph
99+
let mock_server = MockServer::start().await;
100+
let network_subgraph_endpoint = NetworkSubgraph::local_deployment_endpoint(
101+
&mock_server.uri(),
102+
&test_vectors::NETWORK_SUBGRAPH_DEPLOYMENT,
103+
);
104+
let network_subgraph = NetworkSubgraph::new(
105+
Some(&mock_server.uri()),
106+
Some(&test_vectors::NETWORK_SUBGRAPH_DEPLOYMENT),
107+
network_subgraph_endpoint.as_ref(),
108+
);
109+
110+
// Mock result for current epoch requests
111+
mock_server
112+
.register(
113+
Mock::given(method("POST"))
114+
.and(path(format!(
115+
"/subgraphs/id/{}",
116+
*test_vectors::NETWORK_SUBGRAPH_DEPLOYMENT
117+
)))
118+
.respond_with(ResponseTemplate::new(200).set_body_json(
119+
json!({ "data": { "graphNetwork": { "disputeManager": *DISPUTE_MANAGER_ADDRESS }}}),
120+
)),
121+
)
122+
.await;
123+
124+
(Box::leak(Box::new(network_subgraph)), mock_server)
125+
}
126+
127+
#[test_log::test(tokio::test)]
128+
async fn test_parses_dispute_manager_from_network_subgraph_correctly() {
129+
let (network_subgraph, _mock_server) = setup_mock_network_subgraph().await;
130+
131+
let dispute_manager = dispute_manager(network_subgraph, 1, Duration::from_secs(60));
132+
133+
assert_eq!(
134+
dispute_manager.value().await.unwrap(),
135+
*DISPUTE_MANAGER_ADDRESS
136+
);
137+
}
138+
}

common/src/attestations/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright 2023-, GraphOps and Semiotic Labs.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
pub mod dispute_manager;
45
pub mod signer;
56
pub mod signers;

common/src/attestations/signers.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use alloy_primitives::Address;
55
use ethers_core::types::U256;
6-
use eventuals::{Eventual, EventualExt};
6+
use eventuals::{join, Eventual, EventualExt};
77
use log::warn;
88
use std::collections::HashMap;
99
use std::sync::Arc;
@@ -16,7 +16,7 @@ pub fn attestation_signers(
1616
indexer_allocations: Eventual<HashMap<Address, Allocation>>,
1717
indexer_mnemonic: String,
1818
chain_id: U256,
19-
dispute_manager: Address,
19+
dispute_manager: Eventual<Address>,
2020
) -> Eventual<HashMap<Address, AttestationSigner>> {
2121
let attestation_signers_map: &'static Mutex<HashMap<Address, AttestationSigner>> =
2222
Box::leak(Box::new(Mutex::new(HashMap::new())));
@@ -25,7 +25,7 @@ pub fn attestation_signers(
2525

2626
// Whenever the indexer's active or recently closed allocations change, make sure
2727
// we have attestation signers for all of them
28-
indexer_allocations.map(move |allocations| {
28+
join((indexer_allocations, dispute_manager)).map(move |(allocations, dispute_manager)| {
2929
let indexer_mnemonic = indexer_mnemonic.clone();
3030
async move {
3131
let mut signers = attestation_signers_map.lock().await;
@@ -72,12 +72,15 @@ mod tests {
7272
#[tokio::test]
7373
async fn test_attestation_signers_update_with_allocations() {
7474
let (mut allocations_writer, allocations) = Eventual::<HashMap<Address, Allocation>>::new();
75+
let (mut dispute_manager_writer, dispute_manager) = Eventual::<Address>::new();
76+
77+
dispute_manager_writer.write(*DISPUTE_MANAGER_ADDRESS);
7578

7679
let signers = attestation_signers(
7780
allocations,
7881
(*INDEXER_OPERATOR_MNEMONIC).to_string(),
7982
U256::from(1),
80-
*DISPUTE_MANAGER_ADDRESS,
83+
dispute_manager,
8184
);
8285
let mut signers = signers.subscribe();
8386

common/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pub mod prelude {
1414
pub use super::allocations::{
1515
monitor::indexer_allocations, Allocation, AllocationStatus, SubgraphDeployment,
1616
};
17-
pub use super::attestations::{signer::AttestationSigner, signers::attestation_signers};
17+
pub use super::attestations::{
18+
dispute_manager::dispute_manager, signer::AttestationSigner, signers::attestation_signers,
19+
};
1820
pub use super::network_subgraph::NetworkSubgraph;
1921
}

service/src/main.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright 2023-, GraphOps and Semiotic Labs.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use alloy_primitives::Address;
54
use alloy_sol_types::eip712_domain;
65
use axum::Server;
76
use dotenvy::dotenv;
@@ -10,7 +9,9 @@ use std::{net::SocketAddr, str::FromStr, time::Duration};
109
use toolshed::thegraph::DeploymentId;
1110
use tracing::info;
1211

13-
use indexer_common::prelude::{attestation_signers, indexer_allocations, NetworkSubgraph};
12+
use indexer_common::prelude::{
13+
attestation_signers, dispute_manager, indexer_allocations, NetworkSubgraph,
14+
};
1415

1516
use util::{package_version, shutdown_signal};
1617

@@ -86,13 +87,17 @@ async fn main() -> Result<(), std::io::Error> {
8687
Duration::from_secs(config.network_subgraph.allocation_syncing_interval),
8788
);
8889

90+
// TODO: Chain ID should be a config
91+
let graph_network_id = 1;
92+
93+
let dispute_manager =
94+
dispute_manager(network_subgraph, graph_network_id, Duration::from_secs(60));
95+
8996
let attestation_signers = attestation_signers(
9097
indexer_allocations.clone(),
9198
config.ethereum.mnemonic.clone(),
92-
// TODO: Chain ID should be a config
93-
U256::from(1),
94-
// TODO: Dispute manager address should be a config
95-
Address::from_str("0xdeadbeefcafebabedeadbeefcafebabedeadbeef").unwrap(),
99+
U256::from(graph_network_id),
100+
dispute_manager,
96101
);
97102

98103
// Establish Database connection necessary for serving indexer management

0 commit comments

Comments
 (0)