Skip to content

Commit 7704fac

Browse files
authored
Disallow non ethereum mainnet networks on studio (#743)
* command-helpers: Add validator for studio network * init: Disallow non ethereum mainnet on studio * deploy: Disallow non ethereum mainnet on studio
1 parent 8f98d8e commit 7704fac

File tree

4 files changed

+128
-5
lines changed

4 files changed

+128
-5
lines changed

src/command-helpers/studio.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const validateStudioNetwork = ({ studio, product, network }) => {
2+
let isStudio = studio || product === 'subgraph-studio'
3+
let isEthereumMainnet = network === 'mainnet'
4+
5+
if (isStudio && !isEthereumMainnet) {
6+
throw new Error(`Non Ethereum mainnet subgraphs should not be deployed to the studio`)
7+
}
8+
}
9+
10+
module.exports = {
11+
validateStudioNetwork,
12+
}

src/command-helpers/studio.test.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const { validateStudioNetwork } = require('./studio')
2+
3+
describe('Version Command Helpers', () => {
4+
describe('validateStudioNetwork', () => {
5+
describe("When it's studio", () => {
6+
test("And it's Ethereum mainnet", () => {
7+
expect(() => validateStudioNetwork({
8+
studio: true,
9+
network: 'mainnet',
10+
}))
11+
.not
12+
.toThrow(new Error('Non Ethereum mainnet subgraphs should not be deployed to the studio'))
13+
})
14+
15+
test("And it's NOT Ethereum mainnet", () => {
16+
expect(() => validateStudioNetwork({
17+
product: 'subgraph-studio',
18+
network: 'xdai',
19+
}))
20+
.toThrow(new Error('Non Ethereum mainnet subgraphs should not be deployed to the studio'))
21+
})
22+
})
23+
24+
describe("When it's NOT studio", () => {
25+
test("And it's Ethereum mainnet", () => {
26+
expect(() => validateStudioNetwork({
27+
studio: false,
28+
network: 'mainnet',
29+
}))
30+
.not
31+
.toThrow(new Error('Non Ethereum mainnet subgraphs should not be deployed to the studio'))
32+
})
33+
34+
test("And it's NOT Ethereum mainnet", () => {
35+
expect(() => validateStudioNetwork({
36+
product: 'hosted-service',
37+
network: 'xdai',
38+
}))
39+
.not
40+
.toThrow(new Error('Non Ethereum mainnet subgraphs should not be deployed to the studio'))
41+
})
42+
})
43+
})
44+
})

src/commands/deploy.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const { withSpinner } = require('../command-helpers/spinner')
1111
const { validateSubgraphName } = require('../command-helpers/subgraph')
1212
const { DEFAULT_IPFS_URL } = require('../command-helpers/ipfs')
1313
const { assertManifestApiVersion, assertGraphTsVersion } = require('../command-helpers/version')
14+
const { validateStudioNetwork } = require('../command-helpers/studio')
15+
const { loadManifest } = require('../migrations/util/load-manifest')
1416

1517
const HELP = `
1618
${chalk.bold('graph deploy')} [options] ${chalk.bold('<subgraph-name>')} ${chalk.bold(
@@ -125,6 +127,22 @@ module.exports = {
125127
? manifest
126128
: filesystem.resolve('subgraph.yaml')
127129

130+
try {
131+
let manifestFile = await loadManifest(manifest)
132+
133+
for (const { network } of manifestFile.dataSources || []) {
134+
validateStudioNetwork({ studio, product, network })
135+
}
136+
137+
for (const { network } of manifestFile.templates || []) {
138+
validateStudioNetwork({ studio, product, network })
139+
}
140+
} catch (e) {
141+
print.error(e.message)
142+
process.exitCode = 1
143+
return
144+
}
145+
128146
// Show help text if requested
129147
if (help) {
130148
print.info(HELP)

src/commands/init.js

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ const {
99
getSubgraphBasename,
1010
validateSubgraphName,
1111
} = require('../command-helpers/subgraph')
12+
const { validateStudioNetwork } = require('../command-helpers/studio')
1213
const { withSpinner, step } = require('../command-helpers/spinner')
1314
const { fixParameters } = require('../command-helpers/gluegun')
1415
const { chooseNodeUrl } = require('../command-helpers/node')
16+
const { loadManifest } = require('../migrations/util/load-manifest')
1517
const { abiEvents, generateScaffold, writeScaffold } = require('../scaffold')
1618
const ABI = require('../abi')
1719

@@ -381,7 +383,7 @@ module.exports = {
381383
if (fromExample && subgraphName && directory) {
382384
return await initSubgraphFromExample(
383385
toolbox,
384-
{ allowSimpleName, directory, subgraphName },
386+
{ allowSimpleName, directory, subgraphName, studio, product },
385387
{ commands },
386388
)
387389
}
@@ -421,7 +423,9 @@ module.exports = {
421423
network,
422424
subgraphName,
423425
contractName,
424-
node
426+
node,
427+
studio,
428+
product,
425429
},
426430
{ commands },
427431
)
@@ -455,6 +459,8 @@ module.exports = {
455459
{
456460
subgraphName: inputs.subgraphName,
457461
directory: inputs.directory,
462+
studio: inputs.studio,
463+
product: inputs.product,
458464
},
459465
{ commands },
460466
)
@@ -476,7 +482,9 @@ module.exports = {
476482
address: inputs.address,
477483
indexEvents,
478484
contractName: inputs.contractName,
479-
node
485+
node,
486+
studio: inputs.studio,
487+
product: inputs.product,
480488
},
481489
{ commands },
482490
)
@@ -567,7 +575,7 @@ Make sure to visit the documentation on https://thegraph.com/docs/ for further i
567575

568576
const initSubgraphFromExample = async (
569577
toolbox,
570-
{ allowSimpleName, subgraphName, directory },
578+
{ allowSimpleName, subgraphName, directory, studio, product },
571579
{ commands },
572580
) => {
573581
let { filesystem, print, system } = toolbox
@@ -602,6 +610,24 @@ const initSubgraphFromExample = async (
602610
return
603611
}
604612

613+
try {
614+
// It doesn't matter if we changed the URL we clone the YAML,
615+
// we'll check it's network anyway. If it's a studio subgraph we're dealing with.
616+
let manifestFile = await loadManifest(path.join(directory, 'subgraph.yaml'))
617+
618+
for (const { network } of manifestFile.dataSources || []) {
619+
validateStudioNetwork({ studio, product, network })
620+
}
621+
622+
for (const { network } of manifestFile.templates || []) {
623+
validateStudioNetwork({ studio, product, network })
624+
}
625+
} catch (e) {
626+
print.error(e.message)
627+
process.exitCode = 1
628+
return
629+
}
630+
605631
// Update package.json to match the subgraph name
606632
let prepared = await withSpinner(
607633
`Update subgraph name and commands in package.json`,
@@ -661,7 +687,19 @@ const initSubgraphFromExample = async (
661687

662688
const initSubgraphFromContract = async (
663689
toolbox,
664-
{allowSimpleName, subgraphName, directory, abi, network, address, indexEvents, contractName, node},
690+
{
691+
allowSimpleName,
692+
subgraphName,
693+
directory,
694+
abi,
695+
network,
696+
address,
697+
indexEvents,
698+
contractName,
699+
node,
700+
studio,
701+
product,
702+
},
665703
{ commands },
666704
) => {
667705
let { print } = toolbox
@@ -686,6 +724,17 @@ const initSubgraphFromContract = async (
686724
return
687725
}
688726

727+
// We can validate this before the scaffold because we receive
728+
// the network from the form or via command line argument.
729+
// We don't need to read the manifest in this case.
730+
try {
731+
validateStudioNetwork({ studio, product, network })
732+
} catch (e) {
733+
print.error(e.message)
734+
process.exitCode = 1
735+
return
736+
}
737+
689738
// Scaffold subgraph from ABI
690739
let scaffold = await withSpinner(
691740
`Create subgraph scaffold`,

0 commit comments

Comments
 (0)