Skip to content

Commit 8ac152c

Browse files
committed
graph :Add spec version validations for composed subgraphs
1 parent 7b786cb commit 8ac152c

File tree

2 files changed

+179
-0
lines changed

2 files changed

+179
-0
lines changed

graph/src/data/subgraph/mod.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,56 @@ pub type SubgraphManifest<C> =
672672
pub struct UnvalidatedSubgraphManifest<C: Blockchain>(SubgraphManifest<C>);
673673

674674
impl<C: Blockchain> UnvalidatedSubgraphManifest<C> {
675+
fn validate_subgraph_datasources(
676+
data_sources: &[DataSource<C>],
677+
spec_version: &Version,
678+
) -> Vec<SubgraphManifestValidationError> {
679+
let mut errors = Vec::new();
680+
681+
// Check spec version support for subgraph datasources
682+
if *spec_version < SPEC_VERSION_1_3_0 {
683+
if data_sources
684+
.iter()
685+
.any(|ds| matches!(ds, DataSource::Subgraph(_)))
686+
{
687+
errors.push(SubgraphManifestValidationError::DataSourceValidation(
688+
"subgraph".to_string(),
689+
anyhow!(
690+
"Subgraph datasources are not supported prior to spec version {}",
691+
SPEC_VERSION_1_3_0
692+
),
693+
));
694+
return errors;
695+
}
696+
}
697+
698+
let subgraph_ds_count = data_sources
699+
.iter()
700+
.filter(|ds| matches!(ds, DataSource::Subgraph(_)))
701+
.count();
702+
703+
if subgraph_ds_count > 1 {
704+
errors.push(SubgraphManifestValidationError::DataSourceValidation(
705+
"subgraph".to_string(),
706+
anyhow!("Cannot have more than one subgraph datasource"),
707+
));
708+
}
709+
710+
let has_subgraph_ds = subgraph_ds_count > 0;
711+
let has_onchain_ds = data_sources
712+
.iter()
713+
.any(|d| matches!(d, DataSource::Onchain(_)));
714+
715+
if has_subgraph_ds && has_onchain_ds {
716+
errors.push(SubgraphManifestValidationError::DataSourceValidation(
717+
"subgraph".to_string(),
718+
anyhow!("Subgraph datasources cannot be used alongside onchain datasources"),
719+
));
720+
}
721+
722+
errors
723+
}
724+
675725
/// Entry point for resolving a subgraph definition.
676726
/// Right now the only supported links are of the form:
677727
/// `/ipfs/QmUmg7BZC1YP1ca66rRtWKxpXp77WgVHrnv263JtDuvs2k`
@@ -742,6 +792,12 @@ impl<C: Blockchain> UnvalidatedSubgraphManifest<C> {
742792
}
743793
}
744794

795+
// Validate subgraph datasource constraints
796+
errors.extend(Self::validate_subgraph_datasources(
797+
&self.0.data_sources,
798+
&self.0.spec_version,
799+
));
800+
745801
match errors.is_empty() {
746802
true => Ok(self.0),
747803
false => Err(errors),
@@ -1005,6 +1061,17 @@ impl<C: Blockchain> UnresolvedSubgraphManifest<C> {
10051061
);
10061062
}
10071063

1064+
// Validate subgraph datasource constraints
1065+
if let Some(error) = UnvalidatedSubgraphManifest::<C>::validate_subgraph_datasources(
1066+
&data_sources,
1067+
&spec_version,
1068+
)
1069+
.into_iter()
1070+
.next()
1071+
{
1072+
return Err(anyhow::Error::from(error).into());
1073+
}
1074+
10081075
// Check the min_spec_version of each data source against the spec version of the subgraph
10091076
let min_spec_version_mismatch = data_sources
10101077
.iter()

store/test-store/tests/chain/ethereum/manifest.rs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,3 +1706,115 @@ dataSources:
17061706
assert_eq!(3, decls.len());
17071707
});
17081708
}
1709+
1710+
#[tokio::test]
1711+
async fn multiple_subgraph_ds_manifest_should_fail() {
1712+
let yaml = "
1713+
schema:
1714+
file:
1715+
/: /ipfs/Qmschema
1716+
dataSources:
1717+
- name: SubgraphSource1
1718+
kind: subgraph
1719+
entities:
1720+
- User
1721+
network: mainnet
1722+
source:
1723+
address: 'QmSource'
1724+
startBlock: 9562480
1725+
mapping:
1726+
apiVersion: 0.0.6
1727+
language: wasm/assemblyscript
1728+
entities:
1729+
- TestEntity
1730+
file:
1731+
/: /ipfs/Qmmapping
1732+
handlers:
1733+
- handler: handleEntity
1734+
entity: User
1735+
- name: SubgraphSource2
1736+
kind: subgraph
1737+
entities:
1738+
- Profile
1739+
network: mainnet
1740+
source:
1741+
address: 'QmSource2'
1742+
startBlock: 9562500
1743+
mapping:
1744+
apiVersion: 0.0.6
1745+
language: wasm/assemblyscript
1746+
entities:
1747+
- TestEntity
1748+
file:
1749+
/: /ipfs/Qmmapping
1750+
handlers:
1751+
- handler: handleProfile
1752+
entity: Profile
1753+
specVersion: 1.3.0
1754+
";
1755+
1756+
let result = try_resolve_manifest(yaml, SPEC_VERSION_1_3_0).await;
1757+
assert!(result.is_err());
1758+
let err = result.unwrap_err();
1759+
assert!(err
1760+
.to_string()
1761+
.contains("Cannot have more than one subgraph datasource"));
1762+
}
1763+
1764+
#[tokio::test]
1765+
async fn mixed_subgraph_and_onchain_ds_manifest_should_fail() {
1766+
let yaml = "
1767+
schema:
1768+
file:
1769+
/: /ipfs/Qmschema
1770+
dataSources:
1771+
- name: SubgraphSource
1772+
kind: subgraph
1773+
entities:
1774+
- User
1775+
network: mainnet
1776+
source:
1777+
address: 'QmSource'
1778+
startBlock: 9562480
1779+
mapping:
1780+
apiVersion: 0.0.6
1781+
language: wasm/assemblyscript
1782+
entities:
1783+
- TestEntity
1784+
file:
1785+
/: /ipfs/Qmmapping
1786+
handlers:
1787+
- handler: handleEntity
1788+
entity: User
1789+
- kind: ethereum/contract
1790+
name: Gravity
1791+
network: mainnet
1792+
source:
1793+
address: '0x2E645469f354BB4F5c8a05B3b30A929361cf77eC'
1794+
abi: Gravity
1795+
startBlock: 1
1796+
mapping:
1797+
kind: ethereum/events
1798+
apiVersion: 0.0.6
1799+
language: wasm/assemblyscript
1800+
entities:
1801+
- Gravatar
1802+
abis:
1803+
- name: Gravity
1804+
file:
1805+
/: /ipfs/Qmabi
1806+
file:
1807+
/: /ipfs/Qmmapping
1808+
handlers:
1809+
- event: NewGravatar(uint256,address,string,string)
1810+
handler: handleNewGravatar
1811+
specVersion: 1.3.0
1812+
";
1813+
1814+
let result = try_resolve_manifest(yaml, SPEC_VERSION_1_3_0).await;
1815+
assert!(result.is_err());
1816+
let err = result.unwrap_err();
1817+
assert!(err
1818+
.to_string()
1819+
.contains("Subgraph datasources cannot be used alongside onchain datasources"));
1820+
}

0 commit comments

Comments
 (0)