Skip to content

Commit 947d825

Browse files
committed
all: Introduce subgraph-specific settings
It is now possible to set the history_blocks for a subgraph from a config file that matches on subgraph names. Settings are matched in the order in which they appear in the config file. `graphman config check` checks that config file for validity if one is set in the environment
1 parent a85e1df commit 947d825

File tree

8 files changed

+151
-4
lines changed

8 files changed

+151
-4
lines changed

core/src/subgraph/registrar.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use graph::blockchain::Blockchain;
66
use graph::blockchain::BlockchainKind;
77
use graph::blockchain::BlockchainMap;
88
use graph::components::store::{DeploymentId, DeploymentLocator, SubscriptionManager};
9+
use graph::components::subgraph::Settings;
910
use graph::data::subgraph::schema::DeploymentCreate;
1011
use graph::data::subgraph::Graft;
1112
use graph::prelude::{
@@ -24,6 +25,7 @@ pub struct SubgraphRegistrar<P, S, SM> {
2425
node_id: NodeId,
2526
version_switching_mode: SubgraphVersionSwitchingMode,
2627
assignment_event_stream_cancel_guard: CancelGuard, // cancels on drop
28+
settings: Arc<Settings>,
2729
}
2830

2931
impl<P, S, SM> SubgraphRegistrar<P, S, SM>
@@ -41,6 +43,7 @@ where
4143
chains: Arc<BlockchainMap>,
4244
node_id: NodeId,
4345
version_switching_mode: SubgraphVersionSwitchingMode,
46+
settings: Arc<Settings>,
4447
) -> Self {
4548
let logger = logger_factory.component_logger("SubgraphRegistrar", None);
4649
let logger_factory = logger_factory.with_parent(logger.clone());
@@ -58,6 +61,7 @@ where
5861
node_id,
5962
version_switching_mode,
6063
assignment_event_stream_cancel_guard: CancelGuard::new(),
64+
settings,
6165
}
6266
}
6367

@@ -297,6 +301,10 @@ where
297301
SubgraphRegistrarError::ResolveError(SubgraphManifestResolveError::ResolveError(e))
298302
})?;
299303

304+
// Give priority to deployment specific history_blocks value.
305+
let history_blocks =
306+
history_blocks.or(self.settings.for_name(&name).map(|c| c.history_blocks));
307+
300308
let deployment_locator = match kind {
301309
BlockchainKind::Arweave => {
302310
create_subgraph_version::<graph_chain_arweave::Chain, _>(

graph/src/components/subgraph/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod instance_manager;
44
mod proof_of_indexing;
55
mod provider;
66
mod registrar;
7+
mod settings;
78

89
pub use crate::prelude::Entity;
910

@@ -16,3 +17,4 @@ pub use self::proof_of_indexing::{
1617
};
1718
pub use self::provider::SubgraphAssignmentProvider;
1819
pub use self::registrar::{SubgraphRegistrar, SubgraphVersionSwitchingMode};
20+
pub use self::settings::{Setting, Settings};
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//! Facilities for dealing with subgraph-specific settings
2+
use std::fs::read_to_string;
3+
4+
use crate::{
5+
anyhow,
6+
prelude::{regex::Regex, SubgraphName},
7+
};
8+
use serde::{Deserialize, Serialize};
9+
10+
#[derive(Clone, Debug, Deserialize, Serialize)]
11+
pub enum Predicate {
12+
#[serde(alias = "name", with = "serde_regex")]
13+
Name(Regex),
14+
}
15+
16+
impl Predicate {
17+
fn matches(&self, name: &SubgraphName) -> bool {
18+
match self {
19+
Predicate::Name(rx) => rx.is_match(name.as_str()),
20+
}
21+
}
22+
}
23+
24+
#[derive(Clone, Debug, Deserialize, Serialize)]
25+
pub struct Setting {
26+
#[serde(alias = "match")]
27+
pred: Predicate,
28+
pub history_blocks: i32,
29+
}
30+
31+
impl Setting {
32+
fn matches(&self, name: &SubgraphName) -> bool {
33+
self.pred.matches(name)
34+
}
35+
}
36+
37+
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
38+
pub struct Settings {
39+
#[serde(alias = "setting")]
40+
settings: Vec<Setting>,
41+
}
42+
43+
impl Settings {
44+
pub fn from_file(path: &str) -> Result<Self, anyhow::Error> {
45+
Self::from_str(&read_to_string(path)?)
46+
}
47+
48+
pub fn from_str(toml: &str) -> Result<Self, anyhow::Error> {
49+
toml::from_str::<Self>(toml).map_err(anyhow::Error::from)
50+
}
51+
52+
pub fn for_name(&self, name: &SubgraphName) -> Option<&Setting> {
53+
self.settings.iter().find(|setting| setting.matches(name))
54+
}
55+
}
56+
57+
#[cfg(test)]
58+
mod test {
59+
use super::{Predicate, Settings};
60+
61+
#[test]
62+
fn parses_correctly() {
63+
let content = r#"
64+
[[setting]]
65+
match = { name = ".*" }
66+
history_blocks = 10000
67+
68+
[[setting]]
69+
match = { name = "xxxxx" }
70+
history_blocks = 10000
71+
72+
[[setting]]
73+
match = { name = ".*!$" }
74+
history_blocks = 10000
75+
"#;
76+
77+
let section = Settings::from_str(content).unwrap();
78+
assert_eq!(section.settings.len(), 3);
79+
80+
let rule1 = match &section.settings[0].pred {
81+
Predicate::Name(name) => name,
82+
};
83+
assert_eq!(rule1.as_str(), ".*");
84+
85+
let rule2 = match &section.settings[1].pred {
86+
Predicate::Name(name) => name,
87+
};
88+
assert_eq!(rule2.as_str(), "xxxxx");
89+
let rule1 = match &section.settings[2].pred {
90+
Predicate::Name(name) => name,
91+
};
92+
assert_eq!(rule1.as_str(), ".*!$");
93+
}
94+
}

graph/src/env/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ pub struct EnvVars {
172172
/// Set by the environment variable `ETHEREUM_REORG_THRESHOLD`. The default
173173
/// value is 250 blocks.
174174
pub reorg_threshold: BlockNumber,
175+
/// Set by the env var `GRAPH_EXPERIMENTAL_SUBGRAPH_SETTINGS` which should point
176+
/// to a file with subgraph-specific settings
177+
pub subgraph_settings: Option<String>,
175178
}
176179

177180
impl EnvVars {
@@ -229,6 +232,7 @@ impl EnvVars {
229232
external_ws_base_url: inner.external_ws_base_url,
230233
static_filters_threshold: inner.static_filters_threshold,
231234
reorg_threshold: inner.reorg_threshold,
235+
subgraph_settings: inner.subgraph_settings,
232236
})
233237
}
234238

@@ -347,6 +351,8 @@ struct Inner {
347351
// JSON-RPC specific.
348352
#[envconfig(from = "ETHEREUM_REORG_THRESHOLD", default = "250")]
349353
reorg_threshold: BlockNumber,
354+
#[envconfig(from = "GRAPH_EXPERIMENTAL_SUBGRAPH_SETTINGS")]
355+
subgraph_settings: Option<String>,
350356
}
351357

352358
#[derive(Clone, Debug)]

node/src/main.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use graph::blockchain::{
99
BasicBlockchainBuilder, Blockchain, BlockchainBuilder, BlockchainKind, BlockchainMap,
1010
};
1111
use graph::components::store::BlockStore;
12+
use graph::components::subgraph::Settings;
1213
use graph::data::graphql::effort::LoadManager;
1314
use graph::endpoint::EndpointMetrics;
1415
use graph::env::EnvVars;
@@ -137,6 +138,21 @@ async fn main() {
137138
}
138139
Ok(config) => config,
139140
};
141+
142+
let subgraph_settings = match env_vars.subgraph_settings {
143+
Some(ref path) => {
144+
info!(logger, "Reading subgraph configuration file `{}`", path);
145+
match Settings::from_file(path) {
146+
Ok(rules) => rules,
147+
Err(e) => {
148+
eprintln!("configuration error in subgraph settings {}: {}", path, e);
149+
std::process::exit(1);
150+
}
151+
}
152+
}
153+
None => Settings::default(),
154+
};
155+
140156
if opt.check_config {
141157
match config.to_json() {
142158
Ok(txt) => println!("{}", txt),
@@ -481,6 +497,7 @@ async fn main() {
481497
blockchain_map,
482498
node_id.clone(),
483499
version_switching_mode,
500+
Arc::new(subgraph_settings),
484501
));
485502
graph::spawn(
486503
subgraph_registrar

node/src/manager/commands/config.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ use std::{collections::BTreeMap, sync::Arc};
22

33
use graph::{
44
anyhow::bail,
5+
components::subgraph::Settings,
56
endpoint::EndpointMetrics,
7+
env::EnvVars,
68
itertools::Itertools,
79
prelude::{
810
anyhow::{anyhow, Error},
@@ -39,13 +41,27 @@ pub fn check(config: &Config, print: bool) -> Result<(), Error> {
3941
Ok(txt) => {
4042
if print {
4143
println!("{}", txt);
42-
} else {
43-
println!("Successfully validated configuration");
44+
return Ok(());
4445
}
45-
Ok(())
4646
}
47-
Err(e) => Err(anyhow!("error serializing config: {}", e)),
47+
Err(e) => bail!("error serializing config: {}", e),
4848
}
49+
50+
let env_vars = EnvVars::from_env().unwrap();
51+
if let Some(path) = &env_vars.subgraph_settings {
52+
match Settings::from_file(path) {
53+
Ok(_) => {
54+
println!("Successfully validated subgraph settings from {path}");
55+
}
56+
Err(e) => {
57+
eprintln!("configuration error in subgraph settings {}: {}", path, e);
58+
std::process::exit(1);
59+
}
60+
}
61+
};
62+
63+
println!("Successfully validated configuration");
64+
Ok(())
4965
}
5066

5167
pub fn pools(config: &Config, nodes: Vec<String>, shard: bool) -> Result<(), Error> {

node/src/manager/commands/run.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use graph::blockchain::client::ChainClient;
1717
use graph::blockchain::{BlockchainKind, BlockchainMap};
1818
use graph::cheap_clone::CheapClone;
1919
use graph::components::store::{BlockStore as _, DeploymentLocator};
20+
use graph::components::subgraph::Settings;
2021
use graph::endpoint::EndpointMetrics;
2122
use graph::env::EnvVars;
2223
use graph::firehose::FirehoseEndpoints;
@@ -198,6 +199,7 @@ pub async fn run(
198199
blockchain_map,
199200
node_id.clone(),
200201
SubgraphVersionSwitchingMode::Instant,
202+
Arc::new(Settings::default()),
201203
));
202204

203205
let (name, hash) = if subgraph.contains(':') {

tests/src/fixture/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use graph::blockchain::{
1818
use graph::cheap_clone::CheapClone;
1919
use graph::components::metrics::MetricsRegistry;
2020
use graph::components::store::{BlockStore, DeploymentLocator};
21+
use graph::components::subgraph::Settings;
2122
use graph::data::graphql::effort::LoadManager;
2223
use graph::data::query::{Query, QueryTarget};
2324
use graph::data::subgraph::schema::{SubgraphError, SubgraphHealth};
@@ -408,6 +409,7 @@ pub async fn setup<C: Blockchain>(
408409
blockchain_map.clone(),
409410
node_id.clone(),
410411
SubgraphVersionSwitchingMode::Instant,
412+
Arc::new(Settings::default()),
411413
));
412414

413415
SubgraphRegistrar::create_subgraph(subgraph_registrar.as_ref(), subgraph_name.clone())

0 commit comments

Comments
 (0)