Skip to content

Commit 9dc93b5

Browse files
committed
fix: support notifications, configs, watchers
Signed-off-by: Joseph Livesey <[email protected]>
1 parent 491bd8a commit 9dc93b5

File tree

15 files changed

+445
-267
lines changed

15 files changed

+445
-267
lines changed

contrib/indexer-service/config.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ trigger_value_divisor = 500_000
5151
"ACCOUNT0_ADDRESS_PLACEHOLDER" = "http://tap-aggregator:7610"
5252

5353
[horizon]
54-
# Horizon migration mode: legacy | transition | full
55-
# - legacy: Only v1 TAP receipts supported (pre-migration)
56-
# - transition: Both v1 and v2 TAP receipts supported (during migration)
57-
# - full: Only v2 TAP receipts supported (post-migration)
58-
mode = "transition"
54+
# Enable Horizon contracts support for hybrid migration mode
55+
# When enabled: Accept new V2 receipts only, continue processing existing V1 receipts
56+
# When disabled: V1 receipts only (legacy mode)
57+
# If not set, auto-detection from network subgraph will be used
58+
enabled = true

contrib/tap-agent/config.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ trigger_value_divisor = 500_000
5151
"ACCOUNT0_ADDRESS_PLACEHOLDER" = "http://tap-aggregator:7610"
5252

5353
[horizon]
54-
# Horizon migration mode: legacy | transition | full
55-
# - legacy: Only v1 TAP receipts supported (pre-migration)
56-
# - transition: Both v1 and v2 TAP receipts supported (during migration)
57-
# - full: Only v2 TAP receipts supported (post-migration)
58-
mode = "transition"
54+
# Enable Horizon contracts support for hybrid migration mode
55+
# When enabled: Accept new V2 receipts only, continue processing existing V1 receipts
56+
# When disabled: V1 receipts only (legacy mode)
57+
# If not set, auto-detection from network subgraph will be used
58+
enabled = true

crates/config/default_values.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ max_receipts_per_request = 10000
3434
0xDD6a6f76eb36B873C1C184e8b9b9e762FE216490 = "https://tap-aggregator-arbitrum-one.graphops.xyz"
3535

3636
[horizon]
37-
enabled = false
37+
enabled = true

crates/config/maximal-config-example.toml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,7 @@ deployment_id = "Qmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
7878
# Refreshing interval for the Escrow contracts information from the Escrow subgraph.
7979
syncing_interval_secs = 60
8080

81-
[subgraphs.escrow_v2]
82-
# Query URL for the Escrow v2 subgraph (Horizon).
83-
query_url = "http://example.com/escrow-v2-subgraph"
84-
# Optional, Auth token will used a "bearer auth"
85-
# query_auth_token = "super-secret"
86-
# Refreshing interval for the Escrow v2 contracts information.
87-
syncing_interval_secs = 30
81+
# NOTE: V2 escrow accounts are now in the network subgraph, not a separate escrow_v2 subgraph
8882

8983
[blockchain]
9084
# The chain ID of the network that the graph network is running on
@@ -178,4 +172,8 @@ hardhat = "100"
178172
"eip155:1337" = "hardhat"
179173

180174
[horizon]
181-
mode = "transition"
175+
# Enable Horizon contracts support for hybrid migration mode
176+
# When enabled: Accept new V2 receipts only, continue processing existing V1 receipts
177+
# When disabled: V1 receipts only (legacy mode)
178+
# If not set, auto-detection from network subgraph will be used
179+
enabled = true

crates/config/minimal-config-example.toml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,6 @@ query_url = "http://example.com/escrow-subgraph"
4949
# NOTE: Use `query_url` or `deployment_id` only
5050
deployment_id = "Qmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
5151

52-
[subgraphs.escrow_v2]
53-
# Query URL for the Escrow v2 subgraph (Horizon).
54-
query_url = "http://example.com/escrow-v2-subgraph"
55-
syncing_interval_secs = 30
56-
5752
[blockchain]
5853
# The chain ID of the network that the graph network is running on
5954
chain_id = 1337
@@ -70,4 +65,8 @@ receipts_verifier_address = "0x2222222222222222222222222222222222222222"
7065
0xDD6a6f76eb36B873C1C184e8b9b9e762FE216490 = "https://tap-aggregator-arbitrum-one.graphops.xyz"
7166

7267
[horizon]
73-
mode = "transition"
68+
# Enable Horizon contracts support for hybrid migration mode
69+
# When enabled: Accept new V2 receipts only, continue processing existing V1 receipts
70+
# When disabled: V1 receipts only (legacy mode)
71+
# If not set, auto-detection from network subgraph will be used
72+
enabled = true

crates/config/src/config.rs

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -447,26 +447,17 @@ pub struct RavRequestConfig {
447447
pub max_receipts_per_request: u64,
448448
}
449449

450-
/// Horizon upgrade mode configuration
451-
#[derive(Debug, Clone, Deserialize, PartialEq, Default)]
452-
#[serde(rename_all = "lowercase")]
453-
pub enum HorizonMode {
454-
/// Legacy mode: Only v1 TAP receipts supported
455-
#[default]
456-
Legacy,
457-
/// Transition mode: Both v1 and v2 TAP receipts supported (for migration)
458-
Transition,
459-
/// Full mode: Only v2 TAP receipts supported (post-migration)
460-
Full,
461-
}
462-
463-
/// Configuration for the horizon
464-
/// standard
450+
/// Configuration for the horizon migration
465451
#[derive(Debug, Default, Deserialize)]
466452
#[cfg_attr(test, derive(PartialEq))]
467453
pub struct HorizonConfig {
468-
/// Horizon upgrade mode
469-
pub mode: HorizonMode,
454+
/// Enable Horizon contracts support
455+
/// When enabled, the system will:
456+
/// - Accept new V2 TAP receipts only
457+
/// - Continue processing existing V1 receipts for RAV generation
458+
/// - Reject new V1 receipt submissions
459+
#[serde(default)]
460+
pub enabled: bool,
470461
}
471462

472463
#[cfg(test)]
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! Horizon (V2) contract detection utilities
5+
//!
6+
//! This module provides functionality to detect if Horizon (V2) contracts are active
7+
//! in the network by calling the HorizonStaking contract directly.
8+
9+
use alloy::{
10+
contract::{Contract, Interface},
11+
primitives::{Address, U256},
12+
providers::{Provider, ProviderBuilder},
13+
rpc::types::TransactionRequest,
14+
sol,
15+
transports::http::{Client, Http},
16+
};
17+
use anyhow::Result;
18+
19+
sol! {
20+
#[sol(rpc)]
21+
interface HorizonStaking {
22+
function getMaxThawingPeriod() external view returns (uint64);
23+
}
24+
}
25+
26+
/// Detects if Horizon (V2) contracts are active in the network.
27+
///
28+
/// This function calls the `getMaxThawingPeriod()` method on the HorizonStaking contract.
29+
/// If the method returns a value greater than 0, the network is considered to have upgraded to Horizon.
30+
/// If the call fails or returns 0, the network is considered to be in legacy mode.
31+
///
32+
/// This approach matches the proven TypeScript implementation and is more reliable than
33+
/// subgraph queries as it directly queries the source of truth (the contracts).
34+
///
35+
/// # Arguments
36+
/// * `rpc_url` - The RPC endpoint to connect to
37+
/// * `horizon_staking_address` - The address of the HorizonStaking contract
38+
///
39+
/// # Returns
40+
/// * `Ok(true)` if Horizon contracts are active (getMaxThawingPeriod() > 0)
41+
/// * `Ok(false)` if only legacy (V1) contracts are active
42+
/// * `Err(...)` if there was an error calling the contract
43+
pub async fn is_horizon_active(rpc_url: &str, horizon_staking_address: Address) -> Result<bool> {
44+
tracing::debug!(
45+
"Checking if Horizon (V2) contracts are active by calling HorizonStaking.getMaxThawingPeriod() at {}",
46+
horizon_staking_address
47+
);
48+
49+
// Create HTTP provider using alloy
50+
let provider = ProviderBuilder::new().on_http(rpc_url.parse()?);
51+
52+
// Create contract instance
53+
let contract = HorizonStaking::new(horizon_staking_address, &provider);
54+
55+
// Call getMaxThawingPeriod()
56+
match contract.getMaxThawingPeriod().call().await {
57+
Ok(max_thawing_period) => {
58+
let max_thawing_period = max_thawing_period._0;
59+
let horizon_active = max_thawing_period > 0;
60+
61+
if horizon_active {
62+
tracing::info!(
63+
"Horizon (V2) contracts detected - HorizonStaking.getMaxThawingPeriod() returned {}",
64+
max_thawing_period
65+
);
66+
} else {
67+
tracing::info!(
68+
"No Horizon (V2) contracts found - getMaxThawingPeriod() returned 0"
69+
);
70+
}
71+
72+
Ok(horizon_active)
73+
}
74+
Err(e) => {
75+
tracing::warn!(
76+
"Failed to call HorizonStaking.getMaxThawingPeriod() at {}: {}. Assuming legacy mode.",
77+
horizon_staking_address,
78+
e
79+
);
80+
// On error, assume legacy mode (similar to TypeScript implementation)
81+
Ok(false)
82+
}
83+
}
84+
}

crates/monitor/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod client;
77
mod deployment_to_allocation;
88
mod dispute_manager;
99
mod escrow_accounts;
10+
mod horizon_detection;
1011

1112
pub use crate::{
1213
allocations::{indexer_allocations, AllocationWatcher},
@@ -18,4 +19,5 @@ pub use crate::{
1819
empty_escrow_accounts_watcher, escrow_accounts_v1, escrow_accounts_v2, EscrowAccounts,
1920
EscrowAccountsError, EscrowAccountsWatcher,
2021
},
22+
horizon_detection::is_horizon_active,
2123
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Query to detect if Horizon (V2) contracts are active in the network
2+
# This query checks for the existence of PaymentsEscrow accounts which indicate V2 is active
3+
4+
query HorizonDetectionQuery {
5+
paymentsEscrowAccounts(first: 1) {
6+
id
7+
}
8+
}

crates/query/src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,19 @@ pub mod network_escrow_account_v2 {
174174

175175
pub use network_escrow_account_query_v2::Variables;
176176
}
177+
178+
pub mod horizon_detection {
179+
use graphql_client::GraphQLQuery;
180+
type Bytes = String;
181+
182+
#[derive(GraphQLQuery)]
183+
#[graphql(
184+
schema_path = "graphql/network.schema.graphql",
185+
query_path = "graphql/horizon_detection.query.graphql",
186+
response_derives = "Debug",
187+
variables_derives = "Clone"
188+
)]
189+
pub struct HorizonDetectionQuery;
190+
191+
pub use horizon_detection_query::*;
192+
}

0 commit comments

Comments
 (0)