Skip to content

Commit f7b173e

Browse files
committed
gnd: Add semantic manifest validation (source.abi, unique names, handlers)
Add three new validation checks that run during both codegen and build: 1. source.abi cross-reference: Verify that each Ethereum data source's source.abi references an ABI name that exists in mapping.abis. 2. Unique names: Check that data source names and template names are each unique within their category. 3. Handler presence: Ensure Ethereum data sources and templates define at least one event, call, or block handler. To support these checks, extend the DataSource and Template structs with source_abi, event_handlers, call_handlers, and block_handlers fields, populated from graph-node's parsed types during manifest conversion.
1 parent 2cbe1b7 commit f7b173e

2 files changed

Lines changed: 448 additions & 3 deletions

File tree

gnd/src/manifest.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ pub struct DataSource {
6666
pub abis: Vec<Abi>,
6767
/// For subgraph data sources: the IPFS deployment ID of the referenced subgraph.
6868
pub source_address: Option<String>,
69+
/// The ABI name referenced in `source.abi` (Ethereum data sources only).
70+
pub source_abi: Option<String>,
71+
/// Event handler names from the mapping.
72+
pub event_handlers: Vec<String>,
73+
/// Call handler names from the mapping.
74+
pub call_handlers: Vec<String>,
75+
/// Block handler names from the mapping.
76+
pub block_handlers: Vec<String>,
6977
}
7078

7179
impl DataSource {
@@ -84,6 +92,14 @@ pub struct Template {
8492
pub mapping_file: Option<String>,
8593
pub api_version: Option<Version>,
8694
pub abis: Vec<Abi>,
95+
/// The ABI name referenced in `source.abi` (Ethereum templates only).
96+
pub source_abi: Option<String>,
97+
/// Event handler names from the mapping.
98+
pub event_handlers: Vec<String>,
99+
/// Call handler names from the mapping.
100+
pub call_handlers: Vec<String>,
101+
/// Block handler names from the mapping.
102+
pub block_handlers: Vec<String>,
87103
}
88104

89105
impl Manifest {
@@ -176,6 +192,25 @@ fn convert_data_source(ds: GraphUnresolvedDS<Chain>) -> DataSource {
176192
})
177193
.collect(),
178194
source_address: eth.source.address.map(|a| format!("{:?}", a)),
195+
source_abi: Some(eth.source.abi.clone()),
196+
event_handlers: eth
197+
.mapping
198+
.event_handlers
199+
.iter()
200+
.map(|h| h.handler.clone())
201+
.collect(),
202+
call_handlers: eth
203+
.mapping
204+
.call_handlers
205+
.iter()
206+
.map(|h| h.handler.clone())
207+
.collect(),
208+
block_handlers: eth
209+
.mapping
210+
.block_handlers
211+
.iter()
212+
.map(|h| h.handler.clone())
213+
.collect(),
179214
},
180215
GraphUnresolvedDS::Subgraph(sub) => DataSource {
181216
name: sub.name.clone(),
@@ -195,6 +230,10 @@ fn convert_data_source(ds: GraphUnresolvedDS<Chain>) -> DataSource {
195230
})
196231
.collect(),
197232
source_address: Some(sub.source.address().to_string()),
233+
source_abi: None,
234+
event_handlers: vec![],
235+
call_handlers: vec![],
236+
block_handlers: vec![],
198237
},
199238
GraphUnresolvedDS::Offchain(off) => DataSource {
200239
name: off.name.clone(),
@@ -204,6 +243,10 @@ fn convert_data_source(ds: GraphUnresolvedDS<Chain>) -> DataSource {
204243
api_version: Version::parse(&off.mapping.api_version).ok(),
205244
abis: vec![],
206245
source_address: None,
246+
source_abi: None,
247+
event_handlers: vec![],
248+
call_handlers: vec![],
249+
block_handlers: vec![],
207250
},
208251
GraphUnresolvedDS::Amp(amp) => DataSource {
209252
name: amp.name.clone(),
@@ -213,6 +256,10 @@ fn convert_data_source(ds: GraphUnresolvedDS<Chain>) -> DataSource {
213256
api_version: None,
214257
abis: vec![],
215258
source_address: None,
259+
source_abi: None,
260+
event_handlers: vec![],
261+
call_handlers: vec![],
262+
block_handlers: vec![],
216263
},
217264
}
218265
}
@@ -235,6 +282,25 @@ fn convert_template(t: GraphUnresolvedDST<Chain>) -> Template {
235282
file: a.file.link.clone(),
236283
})
237284
.collect(),
285+
source_abi: Some(eth.source.abi.clone()),
286+
event_handlers: eth
287+
.mapping
288+
.event_handlers
289+
.iter()
290+
.map(|h| h.handler.clone())
291+
.collect(),
292+
call_handlers: eth
293+
.mapping
294+
.call_handlers
295+
.iter()
296+
.map(|h| h.handler.clone())
297+
.collect(),
298+
block_handlers: eth
299+
.mapping
300+
.block_handlers
301+
.iter()
302+
.map(|h| h.handler.clone())
303+
.collect(),
238304
},
239305
GraphUnresolvedDST::Offchain(off) => Template {
240306
name: off.name.clone(),
@@ -243,6 +309,10 @@ fn convert_template(t: GraphUnresolvedDST<Chain>) -> Template {
243309
mapping_file: Some(off.mapping.file.link.clone()),
244310
api_version: Version::parse(&off.mapping.api_version).ok(),
245311
abis: vec![],
312+
source_abi: None,
313+
event_handlers: vec![],
314+
call_handlers: vec![],
315+
block_handlers: vec![],
246316
},
247317
GraphUnresolvedDST::Subgraph(sub) => Template {
248318
name: sub.name.clone(),
@@ -261,6 +331,10 @@ fn convert_template(t: GraphUnresolvedDST<Chain>) -> Template {
261331
file: a.file.link.clone(),
262332
})
263333
.collect(),
334+
source_abi: None,
335+
event_handlers: vec![],
336+
call_handlers: vec![],
337+
block_handlers: vec![],
264338
},
265339
}
266340
}

0 commit comments

Comments
 (0)