Created
May 30, 2023 18:33
-
-
Save timfong888/62d037da405512c62a7b226f0272f664 to your computer and use it in GitHub Desktop.
Trying to figure out why mnemonic isn't working as an ENV variable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 "use strict"; | |
2 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | |
3 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | |
4 return new (P || (P = Promise))(function (resolve, reject) { | |
5 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | |
6 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | |
7 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | |
8 step((generator = generator.apply(thisArg, _arguments || [])).next()); | |
9 }); | |
10 }; | |
11 var __importDefault = (this && this.__importDefault) || function (mod) { | |
12 return (mod && mod.__esModule) ? mod : { "default": mod }; | |
13 }; | |
14 Object.defineProperty(exports, "__esModule", { value: true }); | |
15 const fs_1 = __importDefault(require("fs")); | |
16 const path_1 = __importDefault(require("path")); | |
17 const yaml_1 = require("yaml"); | |
18 const umzug_1 = require("umzug"); | |
19 const common_ts_1 = require("@graphprotocol/common-ts"); | |
20 const indexer_common_1 = require("@graphprotocol/indexer-common"); | |
21 const agent_1 = require("../agent"); | |
22 const indexer_1 = require("../indexer"); | |
23 const ethers_1 = require("ethers"); | |
24 const cost_1 = require("../cost"); | |
25 const syncing_server_1 = require("../syncing-server"); | |
26 const utils_1 = require("../utils"); | |
27 exports.default = { | |
28 command: 'start', | |
29 describe: 'Start the agent', | |
30 builder: (yargs) => { | |
31 return yargs | |
32 .option('ethereum', { | |
33 description: 'Ethereum node or provider URL', | |
34 type: 'string', | |
35 required: true, | |
36 group: 'Ethereum', | |
37 }) | |
38 .option('ethereum-polling-interval', { | |
39 description: 'Polling interval for the Ethereum provider (ms)', | |
40 type: 'number', | |
41 default: 4000, | |
42 group: 'Ethereum', | |
43 }) | |
44 .option('gas-increase-timeout', { | |
45 description: 'Time (in seconds) after which transactions will be resubmitted with a higher gas price', | |
46 type: 'number', | |
47 default: 240, | |
48 group: 'Ethereum', | |
49 coerce: arg => arg * 1000, | |
50 }) | |
51 .option('gas-increase-factor', { | |
52 description: 'Factor by which gas prices are increased when resubmitting transactions', | |
53 type: 'number', | |
54 default: 1.2, | |
55 group: 'Ethereum', | |
56 }) | |
57 .option('gas-price-max', { | |
58 description: 'The maximum gas price (gwei) to use for transactions', | |
59 type: 'number', | |
60 default: 100, | |
61 deprecated: true, | |
62 group: 'Ethereum', | |
63 coerce: arg => arg * Math.pow(10, 9), | |
64 }) | |
65 .option('base-fee-per-gas-max', { | |
66 description: 'The maximum base fee per gas (gwei) to use for transactions, for legacy transactions this will be treated as the max gas price', | |
67 type: 'number', | |
68 required: false, | |
69 group: 'Ethereum', | |
70 coerce: arg => arg * Math.pow(10, 9), | |
71 }) | |
72 .option('transaction-attempts', { | |
73 description: 'The maximum number of transaction attempts (Use 0 for unlimited)', | |
74 type: 'number', | |
75 default: 0, | |
76 group: 'Ethereum', | |
77 }) | |
78 .option('mnemonic', { | |
79 description: 'Mnemonic for the operator wallet', | |
80 type: 'string', | |
81 required: true, | |
82 group: 'Ethereum', | |
83 }) | |
84 .option('indexer-address', { | |
85 description: 'Ethereum address of the indexer', | |
86 type: 'string', | |
87 required: true, | |
88 group: 'Ethereum', | |
89 }) | |
90 .option('graph-node-query-endpoint', { | |
91 description: 'Graph Node endpoint for querying subgraphs', | |
92 type: 'string', | |
93 required: true, | |
94 group: 'Indexer Infrastructure', | |
95 }) | |
96 .option('graph-node-status-endpoint', { | |
97 description: 'Graph Node endpoint for indexing statuses etc.', | |
98 type: 'string', | |
99 required: true, | |
100 group: 'Indexer Infrastructure', | |
101 }) | |
102 .option('graph-node-admin-endpoint', { | |
103 description: 'Graph Node endpoint for applying and updating subgraph deployments', | |
104 type: 'string', | |
105 required: true, | |
106 group: 'Indexer Infrastructure', | |
107 }) | |
108 .option('public-indexer-url', { | |
109 description: 'Indexer endpoint for receiving requests from the network', | |
110 type: 'string', | |
111 required: true, | |
112 group: 'Indexer Infrastructure', | |
113 }) | |
114 .options('indexer-geo-coordinates', { | |
115 description: `Coordinates describing the Indexer's location using latitude and longitude`, | |
116 type: 'string', | |
117 array: true, | |
118 default: ['31.780715', '-41.179504'], | |
119 group: 'Indexer Infrastructure', | |
120 coerce: arg => arg.reduce((acc, value) => [...acc, ...value.split(' ')], []), | |
121 }) | |
122 .option('network-subgraph-deployment', { | |
123 description: 'Network subgraph deployment', | |
124 type: 'string', | |
125 group: 'Network Subgraph', | |
126 }) | |
127 .option('network-subgraph-endpoint', { | |
128 description: 'Endpoint to query the network subgraph from', | |
129 type: 'string', | |
130 group: 'Network Subgraph', | |
131 }) | |
132 .option('allocate-on-network-subgraph', { | |
133 description: 'Whether to allocate to the network subgraph', | |
134 type: 'boolean', | |
135 default: false, | |
136 group: 'Network Subgraph', | |
137 }) | |
138 .option('epoch-subgraph-endpoint', { | |
139 description: 'Endpoint to query the epoch block oracle subgraph from', | |
140 type: 'string', | |
141 required: true, | |
142 group: 'Protocol', | |
143 }) | |
144 .option('index-node-ids', { | |
145 description: 'Node IDs of Graph nodes to use for indexing (separated by commas)', | |
146 type: 'string', | |
147 array: true, | |
148 required: true, | |
149 coerce: arg => arg.reduce((acc, value) => [...acc, ...value.split(',')], []), | |
150 group: 'Indexer Infrastructure', | |
151 }) | |
152 .option('default-allocation-amount', { | |
153 description: 'Default amount of GRT to allocate to a subgraph deployment', | |
154 type: 'string', | |
155 default: '0.01', | |
156 required: false, | |
157 group: 'Protocol', | |
158 coerce: arg => (0, common_ts_1.parseGRT)(arg), | |
159 }) | |
160 .option('indexer-management-port', { | |
161 description: 'Port to serve the indexer management API at', | |
162 type: 'number', | |
163 default: 8000, | |
164 required: false, | |
165 group: 'Indexer Infrastructure', | |
166 }) | |
167 .option('metrics-port', { | |
168 description: 'Port to serve Prometheus metrics at', | |
169 type: 'number', | |
170 defaut: 7300, | |
171 required: false, | |
172 group: 'Indexer Infrastructure', | |
173 }) | |
174 .option('syncing-port', { | |
175 description: 'Port to serve the network subgraph and other syncing data for indexer service at', | |
176 type: 'number', | |
177 default: 8002, | |
178 required: false, | |
179 group: 'Indexer Infrastructure', | |
180 }) | |
181 .option('restake-rewards', { | |
182 description: `Restake claimed indexer rewards, if set to 'false' rewards will be returned to the wallet`, | |
183 type: 'boolean', | |
184 default: true, | |
185 group: 'Indexer Infrastructure', | |
186 }) | |
187 .option('rebate-claim-threshold', { | |
188 description: `Minimum value of rebate for a single allocation (in GRT) in order for it to be included in a batch rebate claim on-chain`, | |
189 type: 'string', | |
190 default: '200', | |
191 group: 'Query Fees', | |
192 coerce: arg => (0, common_ts_1.parseGRT)(arg), | |
193 }) | |
194 .option('rebate-claim-batch-threshold', { | |
195 description: `Minimum total value of all rebates in an batch (in GRT) before the batch is claimed on-chain`, | |
196 type: 'string', | |
197 default: '2000', | |
198 group: 'Query Fees', | |
199 coerce: arg => (0, common_ts_1.parseGRT)(arg), | |
200 }) | |
201 .option('rebate-claim-max-batch-size', { | |
202 description: `Maximum number of rebates inside a batch. Upper bound is constrained by available system memory, and by the block gas limit`, | |
203 type: 'number', | |
204 default: 100, | |
205 group: 'Query Fees', | |
206 }) | |
207 .option('voucher-redemption-threshold', { | |
208 description: `Minimum value of rebate for a single allocation (in GRT) in order for it to be included in a batch rebate claim on-chain`, | |
209 type: 'string', | |
210 default: '200', | |
211 group: 'Query Fees', | |
212 coerce: arg => (0, common_ts_1.parseGRT)(arg), | |
213 }) | |
214 .option('voucher-redemption-batch-threshold', { | |
215 description: `Minimum total value of all rebates in an batch (in GRT) before the batch is claimed on-chain`, | |
216 type: 'string', | |
217 default: '2000', | |
218 group: 'Query Fees', | |
219 coerce: arg => (0, common_ts_1.parseGRT)(arg), | |
220 }) | |
221 .option('voucher-redemption-max-batch-size', { | |
222 description: `Maximum number of rebates inside a batch. Upper bound is constrained by available system memory, and by the block gas limit`, | |
223 type: 'number', | |
224 default: 100, | |
225 group: 'Query Fees', | |
226 }) | |
227 .option('inject-dai', { | |
228 description: 'Inject the GRT to DAI/USDC conversion rate into cost model variables', | |
229 type: 'boolean', | |
230 default: true, | |
231 group: 'Cost Models', | |
232 }) | |
233 .option('dai-contract', { | |
234 description: 'Address of the DAI or USDC contract to use for the --inject-dai conversion rate', | |
235 type: 'string', | |
236 // Default to USDC | |
237 default: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', | |
238 }) | |
239 .option('postgres-host', { | |
240 description: 'Postgres host', | |
241 type: 'string', | |
242 required: true, | |
243 group: 'Postgres', | |
244 }) | |
245 .option('postgres-port', { | |
246 description: 'Postgres port', | |
247 type: 'number', | |
248 default: 5432, | |
249 group: 'Postgres', | |
250 }) | |
251 .option('postgres-username', { | |
252 description: 'Postgres username', | |
253 type: 'string', | |
254 required: false, | |
255 default: 'postgres', | |
256 group: 'Postgres', | |
257 }) | |
258 .option('postgres-password', { | |
259 description: 'Postgres password', | |
260 type: 'string', | |
261 default: '', | |
262 required: false, | |
263 group: 'Postgres', | |
264 }) | |
265 .option('postgres-database', { | |
266 description: 'Postgres database name', | |
267 type: 'string', | |
268 required: true, | |
269 group: 'Postgres', | |
270 }) | |
271 .option('log-level', { | |
272 description: 'Log level', | |
273 type: 'string', | |
274 default: 'debug', | |
275 group: 'Indexer Infrastructure', | |
276 }) | |
277 .option('register', { | |
278 description: 'Whether to register the indexer on chain', | |
279 type: 'boolean', | |
280 default: true, | |
281 group: 'Protocol', | |
282 }) | |
283 .option('offchain-subgraphs', { | |
284 description: 'Subgraphs to index that are not on chain (comma-separated)', | |
285 type: 'string', | |
286 array: true, | |
287 default: [], | |
288 coerce: arg => arg | |
289 .reduce((acc, value) => [...acc, ...value.split(',')], []) | |
290 .map((id) => id.trim()) | |
291 .filter((id) => id.length > 0), | |
292 }) | |
293 .option('poi-disputable-epochs', { | |
294 description: 'The number of epochs in the past to look for potential POI disputes', | |
295 type: 'number', | |
296 default: 1, | |
297 group: 'Disputes', | |
298 }) | |
299 .option('poi-dispute-monitoring', { | |
300 description: 'Monitor the network for potential POI disputes', | |
301 type: 'boolean', | |
302 default: false, | |
303 group: 'Disputes', | |
304 }) | |
305 .check(argv => { | |
306 if (!argv['network-subgraph-endpoint'] && | |
307 !argv['network-subgraph-deployment']) { | |
308 return `At least one of --network-subgraph-endpoint and --network-subgraph-deployment must be provided`; | |
309 } | |
310 if (argv['indexer-geo-coordinates']) { | |
311 const [geo1, geo2] = argv['indexer-geo-coordinates']; | |
312 if (!+geo1 || !+geo2) { | |
313 return 'Invalid --indexer-geo-coordinates provided. Must be of format e.g.: 31.780715 -41.179504'; | |
314 } | |
315 } | |
316 if (argv['gas-increase-timeout']) { | |
317 if (argv['gas-increase-timeout'] < 30000) { | |
318 return 'Invalid --gas-increase-timeout provided. Must be at least 30 seconds'; | |
319 } | |
320 } | |
321 if (argv['gas-increase-factor'] <= 1.0) { | |
322 return 'Invalid --gas-increase-factor provided. Must be > 1.0'; | |
323 } | |
324 if (!Number.isInteger(argv['rebate-claim-max-batch-size']) || | |
325 argv['rebate-claim-max-batch-size'] <= 0) { | |
326 return 'Invalid --rebate-claim-max-batch-size provided. Must be > 0 and an integer.'; | |
327 } | |
328 return true; | |
329 }) | |
330 .option('collect-receipts-endpoint', { | |
331 description: 'Client endpoint for collecting receipts', | |
332 type: 'string', | |
333 required: false, | |
334 group: 'Query Fees', | |
335 }) | |
336 .option('allocation-management', { | |
337 description: 'Indexer agent allocation management automation mode (auto|manual) ', | |
338 type: 'string', | |
339 required: false, | |
340 default: 'auto', | |
341 group: 'Indexer Infrastructure', | |
342 }) | |
343 .option('auto-allocation-min-batch-size', { | |
344 description: `Minimum number of allocation transactions inside a batch for auto allocation management. No obvious upperbound, with default of 1`, | |
345 type: 'number', | |
346 default: 1, | |
347 group: 'Indexer Infrastructure', | |
348 }) | |
349 .config({ | |
350 key: 'config-file', | |
351 description: 'Indexer agent configuration file (YAML format)', | |
352 parseFn: function (cfgFilePath) { | |
353 return (0, yaml_1.parse)(fs_1.default.readFileSync(cfgFilePath, 'utf-8')); | |
354 }, | |
355 }); | |
356 }, | |
357 handler: ( | |
358 // eslint-disable-next-line @typescript-eslint/no-explicit-any | |
359 argv) => __awaiter(void 0, void 0, void 0, function* () { | |
360 const logger = (0, common_ts_1.createLogger)({ | |
361 name: 'IndexerAgent', | |
362 async: false, | |
363 level: argv.logLevel, | |
364 }); | |
365 if (argv.gasIncreaseTimeout < 90000) { | |
366 logger.warn('Gas increase timeout is set to less than 90 seconds (~ 6 blocks). This may lead to high gas usage', { gasIncreaseTimeout: argv.gasIncreaseTimeout / 1000.0 }); | |
367 } | |
368 if (argv.gasIncreaseFactor > 1.5) { | |
369 logger.warn(`Gas increase factor is set to > 1.5. This may lead to high gas usage`, { gasIncreaseFactor: argv.gasIncreaseFactor }); | |
370 } | |
371 if (argv.rebateClaimThreshold.lt(argv.voucherRedemptionThreshold)) { | |
372 logger.warn(`Rebate single minimum claim value is less than voucher minimum redemption value, but claims depend on redemptions`, { | |
373 voucherRedemptionThreshold: (0, common_ts_1.formatGRT)(argv.voucherRedemptionThreshold), | |
374 rebateClaimThreshold: (0, common_ts_1.formatGRT)(argv.rebateClaimThreshold), | |
375 }); | |
376 } | |
377 if (argv.rebateClaimThreshold.eq(0)) { | |
378 logger.warn(`Minimum query fee rebate value is 0 GRT, which may lead to claiming unprofitable rebates`); | |
379 } | |
380 if (argv.rebateClaimMaxBatchSize > 200) { | |
381 logger.warn(`Setting the max batch size for rebate claims to more than 200 may result in batches that are too large to fit into a block`, { rebateClaimMaxBatchSize: argv.rebateClaimMaxBatchSize }); | |
382 } | |
383 if (argv.voucherRedemptionThreshold.eq(0)) { | |
384 logger.warn(`Minimum voucher redemption value is 0 GRT, which may lead to redeeming unprofitable vouchers`); | |
385 } | |
386 if (argv.voucherRedemptionMaxBatchSize > 200) { | |
387 logger.warn(`Setting the max batch size for voucher redemptions to more than 200 may result in batches that are too large to fit into a block`, { voucherRedemptionMaxBatchSize: argv.voucherRedemptionMaxBatchSize }); | |
388 } | |
389 process.on('unhandledRejection', err => { | |
390 logger.warn(`Unhandled promise rejection`, { | |
391 err: (0, indexer_common_1.indexerError)(indexer_common_1.IndexerErrorCode.IE035, err), | |
392 }); | |
393 }); | |
394 process.on('uncaughtException', err => { | |
395 logger.warn(`Uncaught exception`, { | |
396 err: (0, indexer_common_1.indexerError)(indexer_common_1.IndexerErrorCode.IE036, err), | |
397 }); | |
398 }); | |
399 // Spin up a metrics server | |
400 const metrics = (0, common_ts_1.createMetrics)(); | |
401 (0, common_ts_1.createMetricsServer)({ | |
402 logger: logger.child({ component: 'MetricsServer' }), | |
403 registry: metrics.registry, | |
404 port: argv.metricsPort, | |
405 }); | |
406 // Register indexer error metrics so we can track any errors that happen | |
407 // inside the agent | |
408 (0, indexer_common_1.registerIndexerErrorMetrics)(metrics); | |
409 const indexingStatusResolver = new indexer_common_1.IndexingStatusResolver({ | |
410 logger: logger, | |
411 statusEndpoint: argv.graphNodeStatusEndpoint, | |
412 }); | |
413 // Parse the Network Subgraph optional argument | |
414 const networkSubgraphDeploymentId = argv.networkSubgraphDeployment | |
415 ? new common_ts_1.SubgraphDeploymentID(argv.networkSubgraphDeployment) | |
416 : undefined; | |
417 const networkSubgraph = yield indexer_common_1.NetworkSubgraph.create({ | |
418 logger, | |
419 endpoint: argv.networkSubgraphEndpoint, | |
420 deployment: networkSubgraphDeploymentId !== undefined | |
421 ? { | |
422 indexingStatusResolver: indexingStatusResolver, | |
423 deployment: networkSubgraphDeploymentId, | |
424 graphNodeQueryEndpoint: argv.graphNodeQueryEndpoint, | |
425 } | |
426 : undefined, | |
427 }); | |
428 const networkProvider = yield indexer_common_1.Network.provider(logger, metrics, argv.ethereum, argv.ethereumPollingInterval); | |
429 const networkMeta = yield networkProvider.getNetwork(); | |
430 logger.info(`Connect to contracts`, { | |
431 network: networkMeta.name, | |
432 chainId: networkMeta.chainId, | |
433 providerNetworkChainID: networkProvider.network.chainId, | |
434 }); | |
435 logger.info(`Connect wallet`, { | |
436 network: networkMeta.name, | |
437 chainId: networkMeta.chainId, | |
438 }); | |
439 let wallet = ethers_1.Wallet.fromMnemonic(argv.mnemonic); | |
440 wallet = wallet.connect(networkProvider); | |
441 logger.info(`Connected wallet`); | |
442 let contracts = undefined; | |
443 try { | |
444 contracts = yield (0, common_ts_1.connectContracts)(wallet, networkMeta.chainId); | |
445 } | |
446 catch (err) { | |
447 logger.error(`Failed to connect to contracts, please ensure you are using the intended Ethereum network`, { | |
448 err, | |
449 }); | |
450 process.exit(1); | |
451 } | |
452 logger.info(`Successfully connected to contracts`, { | |
453 curation: contracts.curation.address, | |
454 disputeManager: contracts.disputeManager.address, | |
455 epochManager: contracts.epochManager.address, | |
456 gns: contracts.gns.address, | |
457 rewardsManager: contracts.rewardsManager.address, | |
458 serviceRegistry: contracts.serviceRegistry.address, | |
459 staking: contracts.staking.address, | |
460 token: contracts.token.address, | |
461 }); | |
462 const indexerAddress = (0, common_ts_1.toAddress)(argv.indexerAddress); | |
463 const epochSubgraph = yield indexer_common_1.EpochSubgraph.create(argv.epochSubgraphEndpoint); | |
464 const networkMonitor = new indexer_common_1.NetworkMonitor((0, indexer_common_1.resolveChainId)(networkMeta.chainId), contracts, (0, common_ts_1.toAddress)(indexerAddress), logger.child({ component: 'NetworkMonitor' }), indexingStatusResolver, networkSubgraph, networkProvider, epochSubgraph); | |
465 logger.info('Connect to database', { | |
466 host: argv.postgresHost, | |
467 port: argv.postgresPort, | |
468 database: argv.postgresDatabase, | |
469 }); | |
470 const sequelize = yield (0, common_ts_1.connectDatabase)({ | |
471 logging: undefined, | |
472 host: argv.postgresHost, | |
473 port: argv.postgresPort, | |
474 username: argv.postgresUsername, | |
475 password: argv.postgresPassword, | |
476 database: argv.postgresDatabase, | |
477 }); | |
478 logger.info('Successfully connected to database'); | |
479 // Automatic database migrations | |
480 logger.info(`Run database migrations`); | |
481 // If the application is being executed using ts-node __dirname may be in /src rather than /dist | |
482 const migrations_path = __dirname.includes('dist') | |
483 ? path_1.default.join(__dirname, '..', 'db', 'migrations', '*.js') | |
484 : path_1.default.join(__dirname, '..', '..', 'dist', 'db', 'migrations', '*.js'); | |
485 try { | |
486 const umzug = new umzug_1.Umzug({ | |
487 migrations: { | |
488 glob: migrations_path, | |
489 }, | |
490 context: { | |
491 queryInterface: sequelize.getQueryInterface(), | |
492 logger, | |
493 indexingStatusResolver, | |
494 graphNodeAdminEndpoint: argv.graphNodeAdminEndpoint, | |
495 networkMonitor, | |
496 }, | |
497 storage: new umzug_1.SequelizeStorage({ sequelize }), | |
498 logger: console, | |
499 }); | |
500 const pending = yield umzug.pending(); | |
501 const executed = yield umzug.executed(); | |
502 logger.debug(`Migrations status`, { pending, executed }); | |
503 yield umzug.up(); | |
504 } | |
505 catch (err) { | |
506 logger.fatal(`Failed to run database migrations`, { | |
507 err: (0, indexer_common_1.indexerError)(indexer_common_1.IndexerErrorCode.IE001, err), | |
508 }); | |
509 process.exit(1); | |
510 } | |
511 logger.info(`Successfully ran database migrations`); | |
512 logger.info(`Sync database models`); | |
513 const managementModels = (0, indexer_common_1.defineIndexerManagementModels)(sequelize); | |
514 const queryFeeModels = (0, indexer_common_1.defineQueryFeeModels)(sequelize); | |
515 yield sequelize.sync(); | |
516 logger.info(`Successfully synced database models`); | |
517 logger.info('Connect to network'); | |
518 const maxGasFee = argv.baseFeeGasMax || argv.gasPriceMax; | |
519 const network = yield indexer_common_1.Network.create(logger, networkProvider, contracts, wallet, indexerAddress, argv.publicIndexerUrl, argv.indexerGeoCoordinates, networkSubgraph, argv.restakeRewards, argv.rebateClaimThreshold, argv.rebateClaimBatchThreshold, argv.rebateClaimMaxBatchSize, argv.poiDisputeMonitoring, argv.poiDisputableEpochs, argv.gasIncreaseTimeout, argv.gasIncreaseFactor, maxGasFee, argv.transactionAttempts); | |
520 logger.info('Successfully connected to network', { | |
521 restakeRewards: argv.restakeRewards, | |
522 }); | |
523 const receiptCollector = new indexer_common_1.AllocationReceiptCollector({ | |
524 logger, | |
525 metrics, | |
526 transactionManager: network.transactionManager, | |
527 models: queryFeeModels, | |
528 allocationExchange: network.contracts.allocationExchange, | |
529 collectEndpoint: argv.collectReceiptsEndpoint, | |
530 voucherRedemptionThreshold: argv.voucherRedemptionThreshold, | |
531 voucherRedemptionBatchThreshold: argv.voucherRedemptionBatchThreshold, | |
532 voucherRedemptionMaxBatchSize: argv.voucherRedemptionMaxBatchSize, | |
533 }); | |
534 yield receiptCollector.queuePendingReceiptsFromDatabase(); | |
535 logger.info('Launch indexer management API server'); | |
536 const allocationManagementMode = indexer_common_1.AllocationManagementMode[argv.allocationManagement.toUpperCase()]; | |
537 const indexerManagementClient = yield (0, indexer_common_1.createIndexerManagementClient)({ | |
538 models: managementModels, | |
539 address: indexerAddress, | |
540 contracts, | |
541 indexingStatusResolver, | |
542 indexNodeIDs: argv.indexNodeIds, | |
543 deploymentManagementEndpoint: argv.graphNodeAdminEndpoint, | |
544 networkSubgraph, | |
545 logger, | |
546 defaults: { | |
547 globalIndexingRule: { | |
548 allocationAmount: argv.defaultAllocationAmount, | |
549 parallelAllocations: 1, | |
550 }, | |
551 }, | |
552 features: { | |
553 injectDai: argv.injectDai, | |
554 }, | |
555 transactionManager: network.transactionManager, | |
556 receiptCollector, | |
557 networkMonitor, | |
558 allocationManagementMode, | |
559 autoAllocationMinBatchSize: argv.autoAllocationMinBatchSize, | |
560 }); | |
561 yield (0, indexer_common_1.createIndexerManagementServer)({ | |
562 logger, | |
563 client: indexerManagementClient, | |
564 port: argv.indexerManagementPort, | |
565 }); | |
566 logger.info(`Successfully launched indexer management API server`); | |
567 const indexer = new indexer_1.Indexer(logger, argv.graphNodeAdminEndpoint, indexingStatusResolver, indexerManagementClient, argv.indexNodeIds, argv.defaultAllocationAmount, indexerAddress, allocationManagementMode); | |
568 if (networkSubgraphDeploymentId !== undefined) { | |
569 // Make sure the network subgraph is being indexed | |
570 yield indexer.ensure(`indexer-agent/${networkSubgraphDeploymentId.ipfsHash.slice(-10)}`, networkSubgraphDeploymentId); | |
571 // Validate if the Network Subgraph belongs to the current provider's network. | |
572 // This check must be performed after we ensure the Network Subgraph is being indexed. | |
573 try { | |
574 yield validateNetworkId(networkMeta, argv.networkSubgraphDeployment, indexingStatusResolver, logger); | |
575 } | |
576 catch (e) { | |
577 logger.critical('Failed to validate Network Subgraph. Exiting.', e); | |
578 process.exit(1); | |
579 } | |
580 } | |
581 // Monitor ETH balance of the operator and write the latest value to a metric | |
582 yield (0, utils_1.monitorEthBalance)(logger, wallet, metrics); | |
583 logger.info(`Launch syncing server`); | |
584 yield (0, syncing_server_1.createSyncingServer)({ | |
585 logger, | |
586 networkSubgraph, | |
587 port: argv.syncingPort, | |
588 }); | |
589 logger.info(`Successfully launched syncing server`); | |
590 (0, cost_1.startCostModelAutomation)({ | |
591 logger, | |
592 ethereum: networkProvider, | |
593 contracts: network.contracts, | |
594 indexerManagement: indexerManagementClient, | |
595 injectDai: argv.injectDai, | |
596 daiContractAddress: (0, common_ts_1.toAddress)(argv.daiContract), | |
597 metrics, | |
598 }); | |
599 yield (0, agent_1.startAgent)({ | |
600 logger, | |
601 metrics, | |
602 indexer, | |
603 network, | |
604 networkMonitor, | |
605 networkSubgraph, | |
606 allocateOnNetworkSubgraph: argv.allocateOnNetworkSubgraph, | |
607 registerIndexer: argv.register, | |
608 offchainSubgraphs: argv.offchainSubgraphs.map((s) => new common_ts_1.SubgraphDeploymentID(s)), | |
609 receiptCollector, | |
610 }); | |
611 }), | |
612 }; | |
613 // Compares the CAIP-2 chain ID between the Ethereum provider and the Network Subgraph and requires | |
614 // they are equal. | |
615 function validateNetworkId(providerNetwork, networkSubgraphDeploymentIpfsHash, indexingStatusResolver, logger) { | |
616 return __awaiter(this, void 0, void 0, function* () { | |
617 const subgraphNetworkId = new common_ts_1.SubgraphDeploymentID(networkSubgraphDeploymentIpfsHash); | |
618 const { network: subgraphNetworkChainName } = yield indexingStatusResolver.subgraphFeatures(subgraphNetworkId); | |
619 if (!subgraphNetworkChainName) { | |
620 // This is unlikely to happen because we expect that the Network Subgraph manifest is valid. | |
621 const errorMsg = 'Failed to fetch the networkId for the Network Subgraph'; | |
622 logger.error(errorMsg, { networkSubgraphDeploymentIpfsHash }); | |
623 throw new Error(errorMsg); | |
624 } | |
625 const providerChainId = (0, indexer_common_1.resolveChainId)(providerNetwork.chainId); | |
626 const networkSubgraphChainId = (0, indexer_common_1.resolveChainId)(subgraphNetworkChainName); | |
627 if (providerChainId !== networkSubgraphChainId) { | |
628 const errorMsg = 'The configured provider and the Network Subgraph have different CAIP-2 chain IDs. ' + | |
629 'Please ensure that both Network Subgraph and the Ethereum provider are correctly configured.'; | |
630 logger.error(errorMsg, { | |
631 networkSubgraphDeploymentIpfsHash, | |
632 networkSubgraphChainId, | |
633 providerChainId, | |
634 }); | |
635 throw new Error(errorMsg); | |
636 } | |
637 }); | |
638 } | |
639 //# sourceMappingURL=start.js.map |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment