From aca9232a77e0c2dac6de743e59caaa12701b159d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 29 Oct 2025 14:22:21 -0300 Subject: [PATCH 1/3] feat: support both legacy and horizon dispute managers for attestation verification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- src/client_query.rs | 4 ++-- src/client_query/context.rs | 1 + src/config.rs | 1 + src/indexer_client.rs | 20 ++++++++++++++------ src/main.rs | 10 ++++++++++ 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/client_query.rs b/src/client_query.rs index 281c69d7..47ff58c1 100644 --- a/src/client_query.rs +++ b/src/client_query.rs @@ -303,7 +303,7 @@ async fn run_indexer_queries( let start_time = Instant::now(); // URL checked: ref df8e647b-1e6e-422a-8846-dc9ee7e0dcc2 let deployment_url = url.join(&format!("subgraphs/id/{deployment}")).unwrap(); - let auth = IndexerAuth::Paid(&receipt, ctx.attestation_domain); + let auth = IndexerAuth::Paid(&receipt, ctx.attestation_domain, ctx.legacy_attestation_domain); let result = indexer_client .query_indexer(deployment_url, auth, &indexer_query) .in_current_span() @@ -695,7 +695,7 @@ pub async fn handle_indexer_query( .url .join(&format!("subgraphs/id/{deployment}")) .unwrap(); - let indexer_auth = IndexerAuth::Paid(&receipt, ctx.attestation_domain); + let indexer_auth = IndexerAuth::Paid(&receipt, ctx.attestation_domain, ctx.legacy_attestation_domain); let indexer_start_time = Instant::now(); let result = ctx diff --git a/src/client_query/context.rs b/src/client_query/context.rs index 99737a53..644c67f9 100644 --- a/src/client_query/context.rs +++ b/src/client_query/context.rs @@ -18,5 +18,6 @@ pub struct Context { pub network: NetworkService, pub indexing_perf: IndexingPerformance, pub attestation_domain: &'static Eip712Domain, + pub legacy_attestation_domain: &'static Eip712Domain, pub reporter: mpsc::UnboundedSender, } diff --git a/src/config.rs b/src/config.rs index 1a0c0672..4aaefe8e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -128,6 +128,7 @@ pub enum BlocklistEntry { pub struct AttestationConfig { pub chain_id: String, pub dispute_manager: Address, + pub legacy_dispute_manager: Address, } /// The exchange rate provider. diff --git a/src/indexer_client.rs b/src/indexer_client.rs index b6d27944..6f91b38f 100644 --- a/src/indexer_client.rs +++ b/src/indexer_client.rs @@ -35,7 +35,7 @@ pub struct IndexerClient { } pub enum IndexerAuth<'a> { - Paid(&'a Receipt, &'a Eip712Domain), + Paid(&'a Receipt, &'a Eip712Domain, &'a Eip712Domain), Free(&'a str), } @@ -47,7 +47,7 @@ impl IndexerClient { query: &str, ) -> Result { let (auth_key, auth_value) = match auth { - IndexerAuth::Paid(receipt, _) => ("Tap-Receipt", receipt.serialize()), + IndexerAuth::Paid(receipt, _, _) => ("Tap-Receipt", receipt.serialize()), IndexerAuth::Free(token) => (AUTHORIZATION.as_str(), format!("Bearer {token}")), }; @@ -113,18 +113,26 @@ impl IndexerClient { return Err(BadResponse(format!("unattestable response: {error}"))); } - if let IndexerAuth::Paid(receipt, attestation_domain) = auth { + if let IndexerAuth::Paid(receipt, attestation_domain, legacy_attestation_domain) = auth { match &payload.attestation { Some(attestation) => { let allocation = receipt.allocation(); - if let Err(err) = attestation::verify( - attestation_domain, + if let Err(legacy_err) = attestation::verify( + legacy_attestation_domain, attestation, &allocation, query, &original_response, ) { - return Err(BadResponse(format!("bad attestation: {err}"))); + if let Err(err) = attestation::verify( + attestation_domain, + attestation, + &allocation, + query, + &original_response, + ) { + return Err(BadResponse(format!("bad attestation: {legacy_err} - {err}"))); + } } } None => { diff --git a/src/main.rs b/src/main.rs index aaf12ed8..24ac8cb6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -104,6 +104,15 @@ async fn main() { conf.attestations.dispute_manager, ))); + let legacy_attestation_domain: &'static Eip712Domain = + Box::leak(Box::new(attestation::eip712_domain( + conf.attestations + .chain_id + .parse::() + .expect("failed to parse attestation domain chain_id"), + conf.attestations.legacy_dispute_manager, + ))); + let indexer_client = IndexerClient { client: http_client.clone(), }; @@ -171,6 +180,7 @@ async fn main() { indexing_perf, network, attestation_domain, + legacy_attestation_domain, reporter, }; From 5d4d4a58f4dff3ed1719440406e6784a29e6a0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 29 Oct 2025 14:23:14 -0300 Subject: [PATCH 2/3] chore: make clippy happy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- src/client_query.rs | 12 ++++++++++-- src/indexer_client.rs | 18 +++++++++--------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/client_query.rs b/src/client_query.rs index 47ff58c1..638b0eac 100644 --- a/src/client_query.rs +++ b/src/client_query.rs @@ -303,7 +303,11 @@ async fn run_indexer_queries( let start_time = Instant::now(); // URL checked: ref df8e647b-1e6e-422a-8846-dc9ee7e0dcc2 let deployment_url = url.join(&format!("subgraphs/id/{deployment}")).unwrap(); - let auth = IndexerAuth::Paid(&receipt, ctx.attestation_domain, ctx.legacy_attestation_domain); + let auth = IndexerAuth::Paid( + &receipt, + ctx.attestation_domain, + ctx.legacy_attestation_domain, + ); let result = indexer_client .query_indexer(deployment_url, auth, &indexer_query) .in_current_span() @@ -695,7 +699,11 @@ pub async fn handle_indexer_query( .url .join(&format!("subgraphs/id/{deployment}")) .unwrap(); - let indexer_auth = IndexerAuth::Paid(&receipt, ctx.attestation_domain, ctx.legacy_attestation_domain); + let indexer_auth = IndexerAuth::Paid( + &receipt, + ctx.attestation_domain, + ctx.legacy_attestation_domain, + ); let indexer_start_time = Instant::now(); let result = ctx diff --git a/src/indexer_client.rs b/src/indexer_client.rs index 6f91b38f..c0669042 100644 --- a/src/indexer_client.rs +++ b/src/indexer_client.rs @@ -123,16 +123,16 @@ impl IndexerClient { &allocation, query, &original_response, + ) && let Err(err) = attestation::verify( + attestation_domain, + attestation, + &allocation, + query, + &original_response, ) { - if let Err(err) = attestation::verify( - attestation_domain, - attestation, - &allocation, - query, - &original_response, - ) { - return Err(BadResponse(format!("bad attestation: {legacy_err} - {err}"))); - } + return Err(BadResponse(format!( + "bad attestation: {legacy_err} - {err}" + ))); } } None => { From 628e289d2582d0843a5a48596201b299a25003f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 14 Nov 2025 15:37:37 -0300 Subject: [PATCH 3/3] chore: bump gatway version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e883539c..7692e3cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2162,7 +2162,7 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "graph-gateway" -version = "27.2.3" +version = "27.3.0" dependencies = [ "anyhow", "assert_matches", diff --git a/Cargo.toml b/Cargo.toml index 8369c46b..69470b40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2024" name = "graph-gateway" -version = "27.2.3" +version = "27.3.0" [profile.release] lto = true