mirror of
https://github.com/cerc-io/watcher-ts
synced 2024-11-19 12:26:19 +00:00
Remove watchers after moving them out to their own repos (#365)
* Remove all watchers after moving them out * Add missing dependencies
This commit is contained in:
parent
e841b6a7c3
commit
7f91fa7ed8
@ -1,5 +0,0 @@
|
||||
# Don't lint node_modules.
|
||||
node_modules
|
||||
|
||||
# Don't lint build output.
|
||||
dist
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
"semistandard",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 12,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"indent": ["error", 2, { "SwitchCase": 1 }],
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": [
|
||||
"warn",
|
||||
{
|
||||
"allowArgumentsExplicitlyTypedAsAny": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
6
packages/address-watcher/.gitignore
vendored
6
packages/address-watcher/.gitignore
vendored
@ -1,6 +0,0 @@
|
||||
.idea/
|
||||
.vscode/
|
||||
node_modules/
|
||||
build/
|
||||
tmp/
|
||||
temp/
|
@ -1,33 +0,0 @@
|
||||
# Address Watcher
|
||||
|
||||
## Setup
|
||||
|
||||
First try the [stack orchestrator](https://github.com/cerc-io/stack-orchestrator) to quickly get started. Advanced users can see [here](/docs/README.md) for instructions on setting up a local environment by hand.
|
||||
|
||||
Build files:
|
||||
|
||||
```bash
|
||||
yarn && yarn build
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
Run the following commands in different terminals:
|
||||
|
||||
GraphQL server:
|
||||
|
||||
```bash
|
||||
yarn server
|
||||
```
|
||||
|
||||
Job runner for processing the tracing requests queue:
|
||||
|
||||
```bash
|
||||
yarn job-runner
|
||||
```
|
||||
|
||||
To fill a block range:
|
||||
|
||||
```bash
|
||||
yarn fill --start-block 1 --end-block 1000
|
||||
```
|
@ -1,28 +0,0 @@
|
||||
[server]
|
||||
host = "127.0.0.1"
|
||||
port = 3002
|
||||
|
||||
[database]
|
||||
type = "postgres"
|
||||
host = "localhost"
|
||||
port = 5432
|
||||
database = "address-watcher"
|
||||
username = "postgres"
|
||||
password = "postgres"
|
||||
synchronize = true
|
||||
logging = false
|
||||
|
||||
[upstream]
|
||||
traceProviderEndpoint = "http://127.0.0.1:8545"
|
||||
|
||||
[upstream.ethServer]
|
||||
gqlApiEndpoint = "http://127.0.0.1:8082/graphql"
|
||||
|
||||
[upstream.cache]
|
||||
name = "requests"
|
||||
enabled = false
|
||||
deleteOnStart = false
|
||||
|
||||
[jobQueue]
|
||||
dbConnectionString = "postgres://postgres:postgres@localhost/address-watcher-job-queue"
|
||||
maxCompletionLagInSecs = 300
|
@ -1,64 +0,0 @@
|
||||
{
|
||||
"name": "@cerc-io/address-watcher",
|
||||
"version": "0.2.38",
|
||||
"description": "Address Watcher",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "mocha -r ts-node/register src/**/*.test.ts",
|
||||
"build": "tsc",
|
||||
"server": "DEBUG=vulcanize:* node --enable-source-maps dist/server.js",
|
||||
"server:dev": "DEBUG=vulcanize:* nodemon --watch src src/server.ts",
|
||||
"job-runner": "DEBUG=vulcanize:* node --enable-source-maps dist/job-runner.js",
|
||||
"job-runner:dev": "DEBUG=vulcanize:* nodemon --watch src src/job-runner.ts",
|
||||
"fill": "DEBUG=vulcanize:* node --enable-source-maps dist/fill.js",
|
||||
"fill:dev": "DEBUG=vulcanize:* ts-node src/fill.ts"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/cerc-io/watcher-ts.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "AGPL-3.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/cerc-io/watcher-ts/issues"
|
||||
},
|
||||
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.3.19",
|
||||
"@cerc-io/cache": "^0.2.38",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.38",
|
||||
"@cerc-io/solidity-mapper": "^0.2.38",
|
||||
"@cerc-io/tracing-client": "^0.2.38",
|
||||
"@cerc-io/util": "^0.2.38",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"debug": "^4.3.1",
|
||||
"ethers": "^5.4.4",
|
||||
"express": "^4.18.2",
|
||||
"graphql": "^15.5.0",
|
||||
"lodash": "^4.17.21",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"typeorm": "^0.2.32",
|
||||
"typeorm-naming-strategies": "^2.0.0",
|
||||
"yargs": "^17.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ethersproject/abi": "^5.3.0",
|
||||
"@types/chai": "^4.2.19",
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/mocha": "^8.2.2",
|
||||
"@types/yargs": "^17.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.47.1",
|
||||
"@typescript-eslint/parser": "^5.47.1",
|
||||
"chai": "^4.3.4",
|
||||
"eslint": "^8.35.0",
|
||||
"eslint-config-semistandard": "^15.0.1",
|
||||
"eslint-config-standard": "^16.0.3",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-standard": "^5.0.0",
|
||||
"mocha": "^8.4.0",
|
||||
"nodemon": "^2.0.7"
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import assert from 'assert';
|
||||
import yargs from 'yargs';
|
||||
import 'reflect-metadata';
|
||||
import { ethers } from 'ethers';
|
||||
|
||||
import { Config, DEFAULT_CONFIG_PATH, getConfig } from '@cerc-io/util';
|
||||
|
||||
import { Database } from '../database';
|
||||
|
||||
(async () => {
|
||||
const argv = await yargs.parserConfiguration({
|
||||
'parse-numbers': false
|
||||
}).options({
|
||||
configFile: {
|
||||
type: 'string',
|
||||
require: true,
|
||||
demandOption: true,
|
||||
describe: 'configuration file path (toml)',
|
||||
default: DEFAULT_CONFIG_PATH
|
||||
},
|
||||
address: {
|
||||
type: 'string',
|
||||
require: true,
|
||||
demandOption: true,
|
||||
describe: 'Address to watch'
|
||||
},
|
||||
startingBlock: {
|
||||
type: 'number',
|
||||
default: 1,
|
||||
describe: 'Starting block'
|
||||
}
|
||||
}).argv;
|
||||
|
||||
const config: Config = await getConfig(argv.configFile);
|
||||
const { database: dbConfig } = config;
|
||||
|
||||
assert(dbConfig);
|
||||
|
||||
const db = new Database(dbConfig);
|
||||
await db.init();
|
||||
|
||||
// Always use the checksum address (https://docs.ethers.io/v5/api/utils/address/#utils-getAddress).
|
||||
const address = ethers.utils.getAddress(argv.address);
|
||||
|
||||
await db.saveAccount(address, argv.startingBlock);
|
||||
await db.close();
|
||||
})();
|
@ -1,141 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import assert from 'assert';
|
||||
import { Connection, ConnectionOptions, createConnection, DeepPartial } from 'typeorm';
|
||||
import { SnakeNamingStrategy } from 'typeorm-naming-strategies';
|
||||
import path from 'path';
|
||||
|
||||
import { Account } from './entity/Account';
|
||||
import { BlockProgress } from './entity/BlockProgress';
|
||||
import { Trace } from './entity/Trace';
|
||||
|
||||
export class Database {
|
||||
_config: ConnectionOptions;
|
||||
_conn!: Connection;
|
||||
|
||||
constructor (config: ConnectionOptions) {
|
||||
assert(config);
|
||||
|
||||
this._config = {
|
||||
...config,
|
||||
entities: [path.join(__dirname, 'entity/*')]
|
||||
};
|
||||
}
|
||||
|
||||
async init (): Promise<void> {
|
||||
assert(!this._conn);
|
||||
|
||||
this._conn = await createConnection({
|
||||
...this._config,
|
||||
namingStrategy: new SnakeNamingStrategy()
|
||||
});
|
||||
}
|
||||
|
||||
async close (): Promise<void> {
|
||||
return this._conn.close();
|
||||
}
|
||||
|
||||
async isWatchedAddress (address: string): Promise<boolean> {
|
||||
const numRows = await this._conn.getRepository(Account)
|
||||
.createQueryBuilder()
|
||||
.where('address = :address', { address })
|
||||
.getCount();
|
||||
|
||||
return numRows > 0;
|
||||
}
|
||||
|
||||
async saveAccount (address: string, startingBlock: number): Promise<void> {
|
||||
await this._conn.transaction(async (tx) => {
|
||||
const repo = tx.getRepository(Account);
|
||||
|
||||
const numRows = await repo
|
||||
.createQueryBuilder()
|
||||
.where('address = :address', { address })
|
||||
.getCount();
|
||||
|
||||
if (numRows === 0) {
|
||||
const entity = repo.create({ address, startingBlock });
|
||||
await repo.save(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async getAccount (address: string): Promise<Account | undefined> {
|
||||
return this._conn.getRepository(Account)
|
||||
.createQueryBuilder()
|
||||
.where('address = :address', { address })
|
||||
.getOne();
|
||||
}
|
||||
|
||||
async getTrace (txHash: string): Promise<Trace | undefined> {
|
||||
const repo = this._conn.getRepository(Trace);
|
||||
return repo.findOne({ where: { txHash } });
|
||||
}
|
||||
|
||||
async saveTrace ({ txHash, blockNumber, blockHash, trace }: DeepPartial<Trace>): Promise<void> {
|
||||
await this._conn.transaction(async (tx) => {
|
||||
const repo = tx.getRepository(Trace);
|
||||
|
||||
const numRows = await repo
|
||||
.createQueryBuilder()
|
||||
.where('tx_hash = :txHash', { txHash })
|
||||
.getCount();
|
||||
|
||||
if (numRows === 0) {
|
||||
const entity = repo.create({ txHash, blockNumber, blockHash, trace });
|
||||
await repo.save(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async saveTraceEntity (trace: Trace): Promise<Trace> {
|
||||
const repo = this._conn.getRepository(Trace);
|
||||
return repo.save(trace);
|
||||
}
|
||||
|
||||
async getAppearances (address: string, fromBlockNumber: number, toBlockNumber: number): Promise<Trace[]> {
|
||||
return this._conn.getRepository(Trace)
|
||||
.createQueryBuilder('trace')
|
||||
.leftJoinAndSelect('trace.accounts', 'account')
|
||||
.where('address = :address AND block_number >= :fromBlockNumber AND block_number <= :toBlockNumber', { address, fromBlockNumber, toBlockNumber })
|
||||
.orderBy({ block_number: 'ASC' })
|
||||
.getMany();
|
||||
}
|
||||
|
||||
async getBlockProgress (blockHash: string): Promise<BlockProgress | undefined> {
|
||||
const repo = this._conn.getRepository(BlockProgress);
|
||||
return repo.findOne({ where: { blockHash } });
|
||||
}
|
||||
|
||||
async initBlockProgress (blockHash: string, blockNumber: number, numTx: number): Promise<void> {
|
||||
await this._conn.transaction(async (tx) => {
|
||||
const repo = tx.getRepository(BlockProgress);
|
||||
|
||||
const numRows = await repo
|
||||
.createQueryBuilder()
|
||||
.where('block_hash = :blockHash', { blockHash })
|
||||
.getCount();
|
||||
|
||||
if (numRows === 0) {
|
||||
const entity = repo.create({ blockHash, blockNumber, numTx, numTracedTx: 0, isComplete: (numTx === 0) });
|
||||
await repo.save(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async updateBlockProgress (blockHash: string): Promise<void> {
|
||||
await this._conn.transaction(async (tx) => {
|
||||
const repo = tx.getRepository(BlockProgress);
|
||||
const entity = await repo.findOne({ where: { blockHash } });
|
||||
if (entity && !entity.isComplete) {
|
||||
entity.numTracedTx++;
|
||||
if (entity.numTracedTx >= entity.numTx) {
|
||||
entity.isComplete = true;
|
||||
}
|
||||
await repo.save(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, ManyToMany, JoinTable } from 'typeorm';
|
||||
import { Trace } from './Trace';
|
||||
|
||||
@Entity()
|
||||
export class Account {
|
||||
@PrimaryColumn('varchar', { length: 42 })
|
||||
address!: string;
|
||||
|
||||
@Column('integer')
|
||||
startingBlock!: number;
|
||||
|
||||
@ManyToMany(() => Trace, trace => trace.accounts)
|
||||
@JoinTable()
|
||||
appearances: Trace[];
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class BlockProgress {
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('integer')
|
||||
numTx!: number;
|
||||
|
||||
@Column('integer')
|
||||
numTracedTx!: number;
|
||||
|
||||
@Column('boolean')
|
||||
isComplete!: boolean;
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index, ManyToMany } from 'typeorm';
|
||||
|
||||
import { Account } from './Account';
|
||||
|
||||
@Entity()
|
||||
@Index(['txHash'], { unique: true })
|
||||
@Index(['blockNumber'])
|
||||
export class Trace {
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
txHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('text')
|
||||
trace!: string;
|
||||
|
||||
@ManyToMany(() => Account, account => account.appearances, { eager: true, cascade: ['insert'] })
|
||||
accounts: Account[];
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import assert from 'assert';
|
||||
import 'reflect-metadata';
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
import debug from 'debug';
|
||||
|
||||
import { getCache } from '@cerc-io/cache';
|
||||
import { EthClient } from '@cerc-io/ipld-eth-client';
|
||||
import { Config, DEFAULT_CONFIG_PATH, getConfig, JobQueue } from '@cerc-io/util';
|
||||
|
||||
import { Database } from './database';
|
||||
import { QUEUE_TX_TRACING } from './tx-watcher';
|
||||
|
||||
const log = debug('vulcanize:server');
|
||||
|
||||
export const main = async (): Promise<any> => {
|
||||
const argv = await yargs(hideBin(process.argv)).parserConfiguration({
|
||||
'parse-numbers': false
|
||||
}).options({
|
||||
configFile: {
|
||||
alias: 'f',
|
||||
type: 'string',
|
||||
require: true,
|
||||
demandOption: true,
|
||||
describe: 'configuration file path (toml)',
|
||||
default: DEFAULT_CONFIG_PATH
|
||||
},
|
||||
startBlock: {
|
||||
type: 'number',
|
||||
require: true,
|
||||
demandOption: true,
|
||||
describe: 'Block number to start processing at'
|
||||
},
|
||||
endBlock: {
|
||||
type: 'number',
|
||||
require: true,
|
||||
demandOption: true,
|
||||
describe: 'Block number to stop processing at'
|
||||
}
|
||||
}).argv;
|
||||
|
||||
const config = await getConfig<Config>(argv.configFile);
|
||||
|
||||
assert(config.server, 'Missing server config');
|
||||
|
||||
const { upstream, database: dbConfig, jobQueue: jobQueueConfig } = config;
|
||||
|
||||
assert(dbConfig, 'Missing database config');
|
||||
|
||||
const db = new Database(dbConfig);
|
||||
await db.init();
|
||||
|
||||
assert(upstream, 'Missing upstream config');
|
||||
const { ethServer: { gqlApiEndpoint }, traceProviderEndpoint, cache: cacheConfig } = upstream;
|
||||
assert(gqlApiEndpoint, 'Missing upstream ethServer.gqlApiEndpoint');
|
||||
assert(traceProviderEndpoint, 'Missing upstream traceProviderEndpoint');
|
||||
|
||||
const cache = await getCache(cacheConfig);
|
||||
const ethClient = new EthClient({
|
||||
gqlEndpoint: gqlApiEndpoint,
|
||||
cache
|
||||
});
|
||||
|
||||
assert(jobQueueConfig, 'Missing job queue config');
|
||||
|
||||
const { dbConnectionString, maxCompletionLagInSecs } = jobQueueConfig;
|
||||
assert(dbConnectionString, 'Missing job queue db connection string');
|
||||
|
||||
const jobQueue = new JobQueue({ dbConnectionString, maxCompletionLag: maxCompletionLagInSecs });
|
||||
await jobQueue.start();
|
||||
|
||||
for (let blockNumber = argv.startBlock; blockNumber <= argv.endBlock; blockNumber++) {
|
||||
log(`Fill block ${blockNumber}`);
|
||||
|
||||
// TODO: Add pause between requests so as to not overwhelm the upsteam server.
|
||||
const result = await ethClient.getBlockWithTransactions({ blockNumber });
|
||||
const { allEthHeaderCids: { nodes: blockNodes } } = result;
|
||||
for (let bi = 0; bi < blockNodes.length; bi++) {
|
||||
const { blockHash, ethTransactionCidsByHeaderId: { nodes: txNodes } } = blockNodes[bi];
|
||||
const blockProgress = await db.getBlockProgress(blockHash);
|
||||
if (blockProgress) {
|
||||
log(`Block number ${blockNumber}, block hash ${blockHash} already known, skip filling`);
|
||||
} else {
|
||||
await db.initBlockProgress(blockHash, blockNumber, txNodes.length);
|
||||
|
||||
for (let ti = 0; ti < txNodes.length; ti++) {
|
||||
const { txHash } = txNodes[ti];
|
||||
log(`Filling block number ${blockNumber}, block hash ${blockHash}, tx hash ${txHash}`);
|
||||
|
||||
// Never push appearances from fill jobs to GQL subscribers, as this command can be run multiple times
|
||||
// for the same block range, and/or process the same block in multiple different runs spread over a
|
||||
// period of time. Also, the tx's are probably too old anyway for publishing.
|
||||
await jobQueue.pushJob(QUEUE_TX_TRACING, { txHash, blockHash, publish: false, publishBlockProgress: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
main().then(() => {
|
||||
process.exit();
|
||||
}).catch(err => {
|
||||
log(err);
|
||||
});
|
@ -1,111 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import assert from 'assert';
|
||||
import debug from 'debug';
|
||||
import { ethers } from 'ethers';
|
||||
|
||||
import { EthClient } from '@cerc-io/ipld-eth-client';
|
||||
import { GetStorageAt } from '@cerc-io/solidity-mapper';
|
||||
import { TracingClient } from '@cerc-io/tracing-client';
|
||||
|
||||
import { addressesInTrace } from './util';
|
||||
import { Database } from './database';
|
||||
import { Trace } from './entity/Trace';
|
||||
import { Account } from './entity/Account';
|
||||
import { BlockProgress } from './entity/BlockProgress';
|
||||
|
||||
const log = debug('vulcanize:indexer');
|
||||
|
||||
export class Indexer {
|
||||
_db: Database;
|
||||
_ethClient: EthClient;
|
||||
_getStorageAt: GetStorageAt;
|
||||
_tracingClient: TracingClient;
|
||||
|
||||
constructor (db: Database, ethClient: EthClient, tracingClient: TracingClient) {
|
||||
assert(db);
|
||||
assert(ethClient);
|
||||
assert(tracingClient);
|
||||
|
||||
this._db = db;
|
||||
this._ethClient = ethClient;
|
||||
this._tracingClient = tracingClient;
|
||||
this._getStorageAt = this._ethClient.getStorageAt.bind(this._ethClient);
|
||||
}
|
||||
|
||||
async isWatchedAddress (address : string): Promise<boolean> {
|
||||
assert(address);
|
||||
|
||||
return this._db.isWatchedAddress(ethers.utils.getAddress(address));
|
||||
}
|
||||
|
||||
async watchAddress (address: string, startingBlock: number): Promise<boolean> {
|
||||
// Always use the checksum address (https://docs.ethers.io/v5/api/utils/address/#utils-getAddress).
|
||||
await this._db.saveAccount(ethers.utils.getAddress(address), startingBlock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async getTrace (txHash: string): Promise<Trace | undefined> {
|
||||
return this._db.getTrace(txHash);
|
||||
}
|
||||
|
||||
async traceTxAndIndexAppearances (txHash: string): Promise<Trace> {
|
||||
let entity = await this._db.getTrace(txHash);
|
||||
if (entity) {
|
||||
log(`traceTx: db hit ${txHash}`);
|
||||
} else {
|
||||
log(`traceTx: db miss, fetching from tracing API server ${txHash}`);
|
||||
|
||||
const tx = await this._tracingClient.getTx(txHash);
|
||||
const trace = await this._tracingClient.getTxTrace(txHash, 'callTraceWithAddresses', '15s');
|
||||
|
||||
await this._db.saveTrace({
|
||||
txHash,
|
||||
blockNumber: tx.blockNumber,
|
||||
blockHash: tx.blockHash,
|
||||
trace: JSON.stringify(trace)
|
||||
});
|
||||
|
||||
entity = await this._db.getTrace(txHash);
|
||||
|
||||
assert(entity);
|
||||
await this._indexAppearances(entity);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
async getAppearances (address: string, fromBlockNumber: number, toBlockNumber: number): Promise<Trace[]> {
|
||||
return this._db.getAppearances(address, fromBlockNumber, toBlockNumber);
|
||||
}
|
||||
|
||||
async getBlockProgress (blockHash: string): Promise<BlockProgress | undefined> {
|
||||
return this._db.getBlockProgress(blockHash);
|
||||
}
|
||||
|
||||
async updateBlockProgress (blockHash: string): Promise<void> {
|
||||
return this._db.updateBlockProgress(blockHash);
|
||||
}
|
||||
|
||||
async _indexAppearances (trace: Trace): Promise<Trace> {
|
||||
const traceObj = JSON.parse(trace.trace);
|
||||
|
||||
// TODO: Check if tx has failed?
|
||||
const addresses = addressesInTrace(traceObj);
|
||||
|
||||
trace.accounts = addresses.map((address: string) => {
|
||||
assert(address);
|
||||
|
||||
const account = new Account();
|
||||
account.address = ethers.utils.getAddress(address);
|
||||
account.startingBlock = trace.blockNumber;
|
||||
|
||||
return account;
|
||||
});
|
||||
|
||||
return await this._db.saveTraceEntity(trace);
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import assert from 'assert';
|
||||
import 'reflect-metadata';
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
import debug from 'debug';
|
||||
|
||||
import { getCache } from '@cerc-io/cache';
|
||||
import { EthClient } from '@cerc-io/ipld-eth-client';
|
||||
import { TracingClient } from '@cerc-io/tracing-client';
|
||||
import { getConfig, JobQueue, DEFAULT_CONFIG_PATH, Config } from '@cerc-io/util';
|
||||
|
||||
import { Indexer } from './indexer';
|
||||
import { Database } from './database';
|
||||
import { QUEUE_TX_TRACING } from './tx-watcher';
|
||||
|
||||
const log = debug('vulcanize:server');
|
||||
|
||||
export const main = async (): Promise<any> => {
|
||||
const argv = await yargs(hideBin(process.argv))
|
||||
.option('f', {
|
||||
alias: 'config-file',
|
||||
demandOption: true,
|
||||
describe: 'configuration file path (toml)',
|
||||
type: 'string',
|
||||
default: DEFAULT_CONFIG_PATH
|
||||
})
|
||||
.argv;
|
||||
|
||||
const config: Config = await getConfig(argv.f);
|
||||
|
||||
assert(config.server, 'Missing server config');
|
||||
|
||||
const { upstream, database: dbConfig, jobQueue: jobQueueConfig } = config;
|
||||
|
||||
assert(dbConfig, 'Missing database config');
|
||||
|
||||
const db = new Database(dbConfig);
|
||||
await db.init();
|
||||
|
||||
assert(upstream, 'Missing upstream config');
|
||||
const { ethServer: { gqlApiEndpoint }, traceProviderEndpoint, cache: cacheConfig } = upstream;
|
||||
assert(gqlApiEndpoint, 'Missing upstream ethServer.gqlApiEndpoint');
|
||||
assert(traceProviderEndpoint, 'Missing upstream traceProviderEndpoint');
|
||||
|
||||
const cache = await getCache(cacheConfig);
|
||||
const ethClient = new EthClient({
|
||||
gqlEndpoint: gqlApiEndpoint,
|
||||
cache
|
||||
});
|
||||
|
||||
const tracingClient = new TracingClient(traceProviderEndpoint);
|
||||
|
||||
const indexer = new Indexer(db, ethClient, tracingClient);
|
||||
|
||||
assert(jobQueueConfig, 'Missing job queue config');
|
||||
|
||||
const { dbConnectionString, maxCompletionLagInSecs } = jobQueueConfig;
|
||||
assert(dbConnectionString, 'Missing job queue db connection string');
|
||||
|
||||
const jobQueue = new JobQueue({ dbConnectionString, maxCompletionLag: maxCompletionLagInSecs });
|
||||
await jobQueue.start();
|
||||
|
||||
await jobQueue.subscribe(QUEUE_TX_TRACING, async (job) => {
|
||||
const { data: { txHash } } = job;
|
||||
await indexer.traceTxAndIndexAppearances(txHash);
|
||||
await jobQueue.markComplete(job);
|
||||
});
|
||||
};
|
||||
|
||||
main().then(() => {
|
||||
log('Starting job runner...');
|
||||
}).catch(err => {
|
||||
log(err);
|
||||
});
|
@ -1,73 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import debug from 'debug';
|
||||
import { withFilter } from 'graphql-subscriptions';
|
||||
import { ethers } from 'ethers';
|
||||
|
||||
import { Indexer } from './indexer';
|
||||
import { TxWatcher } from './tx-watcher';
|
||||
|
||||
const log = debug('vulcanize:resolver');
|
||||
|
||||
interface WatchAddressParams {
|
||||
address: string,
|
||||
startingBlock: number
|
||||
}
|
||||
|
||||
interface AppearanceParams {
|
||||
address: string,
|
||||
fromBlockNumber: number,
|
||||
toBlockNumber: number
|
||||
}
|
||||
|
||||
export const createResolvers = async (indexer: Indexer, txWatcher: TxWatcher): Promise<any> => {
|
||||
return {
|
||||
Subscription: {
|
||||
onAddressEvent: {
|
||||
subscribe: withFilter(
|
||||
() => txWatcher.getAddressEventIterator(),
|
||||
(payload: any, variables: any) => {
|
||||
return payload.onAddressEvent.address === ethers.utils.getAddress(variables.address);
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
onBlockProgressEvent: {
|
||||
subscribe: () => txWatcher.getBlockProgressEventIterator()
|
||||
}
|
||||
},
|
||||
|
||||
Mutation: {
|
||||
watchAddress: (_: any, { address, startingBlock = 1 }: WatchAddressParams): Promise<boolean> => {
|
||||
address = ethers.utils.getAddress(address);
|
||||
|
||||
log('watchAddress', address, startingBlock);
|
||||
return indexer.watchAddress(address, startingBlock);
|
||||
}
|
||||
},
|
||||
|
||||
Query: {
|
||||
appearances: async (_: any, { address, fromBlockNumber, toBlockNumber }: AppearanceParams): Promise<any> => {
|
||||
address = ethers.utils.getAddress(address);
|
||||
|
||||
log('appearances', address, fromBlockNumber, toBlockNumber);
|
||||
return indexer.getAppearances(address, fromBlockNumber, toBlockNumber);
|
||||
},
|
||||
|
||||
traceTx: async (_: any, { txHash }: { txHash: string }): Promise<any> => {
|
||||
log('traceTx', txHash);
|
||||
|
||||
const { blockHash, blockNumber, trace } = await indexer.traceTxAndIndexAppearances(txHash);
|
||||
|
||||
return {
|
||||
txHash,
|
||||
blockNumber,
|
||||
blockHash,
|
||||
trace
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
@ -1,79 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { gql } from '@apollo/client/core';
|
||||
|
||||
export default gql`
|
||||
# Types
|
||||
|
||||
type TxTrace {
|
||||
txHash: String!
|
||||
blockNumber: Int!
|
||||
blockHash: String!
|
||||
trace: String!
|
||||
}
|
||||
|
||||
# Watched address event, include additional context over and above the event data.
|
||||
type WatchedAddressEvent {
|
||||
address: String!
|
||||
txTrace: TxTrace!
|
||||
}
|
||||
|
||||
type BlockProgressEvent {
|
||||
blockNumber: Int!
|
||||
blockHash: String!
|
||||
numTx: Int!
|
||||
numTracedTx: Int!
|
||||
isComplete: Boolean!
|
||||
}
|
||||
|
||||
#
|
||||
# Queries
|
||||
#
|
||||
|
||||
type Query {
|
||||
|
||||
#
|
||||
# Developer API methods
|
||||
#
|
||||
|
||||
appearances(
|
||||
address: String!
|
||||
fromBlockNumber: Int!
|
||||
toBlockNumber: Int!
|
||||
): [TxTrace!]
|
||||
|
||||
#
|
||||
# Low level utility methods
|
||||
#
|
||||
|
||||
traceTx(
|
||||
txHash: String!
|
||||
): TxTrace
|
||||
}
|
||||
|
||||
#
|
||||
# Subscriptions
|
||||
#
|
||||
type Subscription {
|
||||
|
||||
# Watch for address events (at head of chain).
|
||||
onAddressEvent(address: String!): WatchedAddressEvent!
|
||||
|
||||
# Watch for block progress events from filler process.
|
||||
onBlockProgressEvent: BlockProgressEvent!
|
||||
}
|
||||
|
||||
#
|
||||
# Mutations
|
||||
#
|
||||
type Mutation {
|
||||
|
||||
# Actively watch and index data for the address.
|
||||
watchAddress(
|
||||
address: String!
|
||||
startingBlock: Int
|
||||
): Boolean!
|
||||
}
|
||||
`;
|
@ -1,92 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import assert from 'assert';
|
||||
import 'reflect-metadata';
|
||||
import express, { Application } from 'express';
|
||||
import { PubSub } from 'graphql-subscriptions';
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
import debug from 'debug';
|
||||
|
||||
import { getCache } from '@cerc-io/cache';
|
||||
import { EthClient } from '@cerc-io/ipld-eth-client';
|
||||
import { TracingClient } from '@cerc-io/tracing-client';
|
||||
import { getConfig, JobQueue, DEFAULT_CONFIG_PATH, createAndStartServer, Config } from '@cerc-io/util';
|
||||
|
||||
import typeDefs from './schema';
|
||||
|
||||
import { createResolvers } from './resolvers';
|
||||
import { Indexer } from './indexer';
|
||||
import { Database } from './database';
|
||||
import { TxWatcher } from './tx-watcher';
|
||||
|
||||
const log = debug('vulcanize:server');
|
||||
|
||||
export const main = async (): Promise<any> => {
|
||||
const argv = await yargs(hideBin(process.argv))
|
||||
.option('f', {
|
||||
alias: 'config-file',
|
||||
demandOption: true,
|
||||
describe: 'configuration file path (toml)',
|
||||
type: 'string',
|
||||
default: DEFAULT_CONFIG_PATH
|
||||
})
|
||||
.argv;
|
||||
|
||||
const config: Config = await getConfig(argv.f);
|
||||
|
||||
assert(config.server, 'Missing server config');
|
||||
|
||||
const { upstream, database: dbConfig, jobQueue: jobQueueConfig } = config;
|
||||
|
||||
assert(dbConfig, 'Missing database config');
|
||||
|
||||
const db = new Database(dbConfig);
|
||||
await db.init();
|
||||
|
||||
assert(upstream, 'Missing upstream config');
|
||||
const { ethServer: { gqlApiEndpoint }, traceProviderEndpoint, cache: cacheConfig } = upstream;
|
||||
assert(gqlApiEndpoint, 'Missing upstream ethServer.gqlApiEndpoint');
|
||||
assert(traceProviderEndpoint, 'Missing upstream traceProviderEndpoint');
|
||||
|
||||
const cache = await getCache(cacheConfig);
|
||||
const ethClient = new EthClient({
|
||||
gqlEndpoint: gqlApiEndpoint,
|
||||
cache
|
||||
});
|
||||
|
||||
const tracingClient = new TracingClient(traceProviderEndpoint);
|
||||
|
||||
const indexer = new Indexer(db, ethClient, tracingClient);
|
||||
|
||||
assert(jobQueueConfig, 'Missing job queue config');
|
||||
|
||||
const { dbConnectionString, maxCompletionLagInSecs } = jobQueueConfig;
|
||||
assert(dbConnectionString, 'Missing job queue db connection string');
|
||||
assert(dbConnectionString, 'Missing job queue max completion lag time (seconds)');
|
||||
|
||||
const jobQueue = new JobQueue({ dbConnectionString, maxCompletionLag: maxCompletionLagInSecs });
|
||||
await jobQueue.start();
|
||||
|
||||
// Note: In-memory pubsub works fine for now, as each watcher is a single process anyway.
|
||||
// Later: https://www.apollographql.com/docs/apollo-server/data/subscriptions/#production-pubsub-libraries
|
||||
const pubsub = new PubSub();
|
||||
const txWatcher = new TxWatcher(ethClient, indexer, pubsub, jobQueue);
|
||||
await txWatcher.start();
|
||||
|
||||
const resolvers = await createResolvers(indexer, txWatcher);
|
||||
|
||||
// Create an Express app
|
||||
const app: Application = express();
|
||||
const server = createAndStartServer(app, typeDefs, resolvers, config.server);
|
||||
|
||||
return { app, server };
|
||||
};
|
||||
|
||||
main().then(() => {
|
||||
log('Starting server...');
|
||||
}).catch(err => {
|
||||
log(err);
|
||||
});
|
@ -1,126 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import assert from 'assert';
|
||||
import debug from 'debug';
|
||||
import { PubSub } from 'graphql-subscriptions';
|
||||
|
||||
import { EthClient } from '@cerc-io/ipld-eth-client';
|
||||
import { JobQueue } from '@cerc-io/util';
|
||||
|
||||
import { Indexer } from './indexer';
|
||||
import { BlockProgress } from './entity/BlockProgress';
|
||||
|
||||
const log = debug('vulcanize:tx-watcher');
|
||||
|
||||
export const AddressEvent = 'address-event';
|
||||
export const BlockProgressEvent = 'block-progress-event';
|
||||
export const QUEUE_TX_TRACING = 'tx-tracing';
|
||||
|
||||
export class TxWatcher {
|
||||
_ethClient: EthClient;
|
||||
_indexer: Indexer;
|
||||
_pubsub: PubSub;
|
||||
_watchTxSubscription: ZenObservable.Subscription | undefined;
|
||||
_jobQueue: JobQueue;
|
||||
|
||||
constructor (ethClient: EthClient, indexer: Indexer, pubsub: PubSub, jobQueue: JobQueue) {
|
||||
this._ethClient = ethClient;
|
||||
this._indexer = indexer;
|
||||
this._pubsub = pubsub;
|
||||
this._jobQueue = jobQueue;
|
||||
}
|
||||
|
||||
getAddressEventIterator (): AsyncIterator<any> {
|
||||
return this._pubsub.asyncIterator([AddressEvent]);
|
||||
}
|
||||
|
||||
getBlockProgressEventIterator (): AsyncIterator<any> {
|
||||
return this._pubsub.asyncIterator([BlockProgressEvent]);
|
||||
}
|
||||
|
||||
async start (): Promise<void> {
|
||||
assert(!this._watchTxSubscription, 'subscription already started');
|
||||
|
||||
log('Started watching upstream tx...');
|
||||
|
||||
this._jobQueue.onComplete(QUEUE_TX_TRACING, async (job) => {
|
||||
const { data: { request, failed, state, createdOn } } = job;
|
||||
|
||||
await this._indexer.updateBlockProgress(request.data.blockHash);
|
||||
const blockProgress = await this._indexer.getBlockProgress(request.data.blockHash);
|
||||
if (blockProgress && request.data.publishBlockProgress) {
|
||||
await this.publishBlockProgressToSubscribers(blockProgress);
|
||||
}
|
||||
|
||||
const timeElapsedInSeconds = (Date.now() - Date.parse(createdOn)) / 1000;
|
||||
log(`Job onComplete tx ${request.data.txHash} publish ${!!request.data.publish}`);
|
||||
if (!failed && state === 'completed' && request.data.publish) {
|
||||
// Check for max acceptable lag time between tracing request and sending results to live subscribers.
|
||||
if (timeElapsedInSeconds <= this._jobQueue.maxCompletionLag) {
|
||||
return await this.publishAddressEventToSubscribers(request.data.txHash, timeElapsedInSeconds);
|
||||
} else {
|
||||
log(`tx ${request.data.txHash} is too old (${timeElapsedInSeconds}s), not broadcasting to live subscribers`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Update to pull based watcher.
|
||||
// this._watchTxSubscription = await this._ethClient.watchTransactions(async (value) => {
|
||||
// const { txHash, ethHeaderCidByHeaderId: { blockHash, blockNumber } } = _.get(value, 'data.listen.relatedNode');
|
||||
// log('watchTransaction', JSON.stringify({ txHash, blockHash, blockNumber }, null, 2));
|
||||
// await this._jobQueue.pushJob(QUEUE_TX_TRACING, { txHash, blockHash, publish: true });
|
||||
// });
|
||||
}
|
||||
|
||||
async publishAddressEventToSubscribers (txHash: string, timeElapsedInSeconds: number): Promise<void> {
|
||||
const traceObj = await this._indexer.getTrace(txHash);
|
||||
if (!traceObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { blockNumber, blockHash, trace } = traceObj;
|
||||
|
||||
for (let i = 0; i < traceObj.accounts.length; i++) {
|
||||
const account = traceObj.accounts[i];
|
||||
|
||||
log(`publishing trace for ${txHash} (${timeElapsedInSeconds}s elapsed) to GQL subscribers for address ${account.address}`);
|
||||
|
||||
// Publishing the event here will result in pushing the payload to GQL subscribers for `onAddressEvent(address)`.
|
||||
await this._pubsub.publish(AddressEvent, {
|
||||
onAddressEvent: {
|
||||
address: account.address,
|
||||
txTrace: {
|
||||
txHash,
|
||||
blockHash,
|
||||
blockNumber,
|
||||
trace
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async publishBlockProgressToSubscribers (blockProgress: BlockProgress): Promise<void> {
|
||||
const { blockHash, blockNumber, numTx, numTracedTx, isComplete } = blockProgress;
|
||||
|
||||
// Publishing the event here will result in pushing the payload to GQL subscribers for `onAddressEvent(address)`.
|
||||
await this._pubsub.publish(BlockProgressEvent, {
|
||||
onBlockProgressEvent: {
|
||||
blockHash,
|
||||
blockNumber,
|
||||
numTx,
|
||||
numTracedTx,
|
||||
isComplete
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async stop (): Promise<void> {
|
||||
if (this._watchTxSubscription) {
|
||||
log('Stopped watching upstream tx');
|
||||
this._watchTxSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
// https://medium.com/@steveruiz/using-a-javascript-library-without-type-declarations-in-a-typescript-project-3643490015f3
|
||||
declare module 'canonical-json'
|
||||
declare module 'lodash-contrib';
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "common",
|
||||
"version": "0.1.0",
|
||||
"license": "AGPL-3.0",
|
||||
"typings": "main.d.ts"
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { describe, it } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
|
||||
import { addressesInTrace } from './util';
|
||||
|
||||
describe('addressInTrace', () => {
|
||||
it('should parse an empty trace', () => {
|
||||
const addresses = addressesInTrace({});
|
||||
expect(addresses).to.eql([]);
|
||||
});
|
||||
|
||||
it('should parse an unnested trace', () => {
|
||||
const addresses = addressesInTrace({
|
||||
from: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||
to: '0xCA6D29232D1435D8198E3E5302495417dD073d61'
|
||||
});
|
||||
|
||||
expect(addresses).to.eql([
|
||||
'0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
'0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse an unnested trace with an addresses field', () => {
|
||||
const addresses = addressesInTrace({
|
||||
from: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||
to: '0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
addresses: {
|
||||
'0x9273D9437B0bf2F1b7999d8dB72960d6379564d1': {},
|
||||
'0xd86fB467B78901310e9967A2C8B601A5E794c12C': {}
|
||||
}
|
||||
});
|
||||
|
||||
expect(addresses).to.eql([
|
||||
'0x9273D9437B0bf2F1b7999d8dB72960d6379564d1',
|
||||
'0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
'0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||
'0xd86fB467B78901310e9967A2C8B601A5E794c12C'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse a nested trace', () => {
|
||||
const addresses = addressesInTrace({
|
||||
from: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||
to: '0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
calls: [{
|
||||
from: '0x9273D9437B0bf2F1b7999d8dB72960d6379564d1',
|
||||
to: '0xd86fB467B78901310e9967A2C8B601A5E794c12C'
|
||||
},
|
||||
{
|
||||
from: '0xf29340ca4ad7A797dF2d67Be58d354EC284AE62f',
|
||||
to: '0xEcFF6b14D3ed9569108b413f846279E64E39BC92'
|
||||
}]
|
||||
});
|
||||
|
||||
expect(addresses).to.eql([
|
||||
'0x9273D9437B0bf2F1b7999d8dB72960d6379564d1',
|
||||
'0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
'0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||
'0xEcFF6b14D3ed9569108b413f846279E64E39BC92',
|
||||
'0xd86fB467B78901310e9967A2C8B601A5E794c12C',
|
||||
'0xf29340ca4ad7A797dF2d67Be58d354EC284AE62f'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse a nested trace with an addresses field', () => {
|
||||
const addresses = addressesInTrace({
|
||||
from: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||
to: '0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
calls: [{
|
||||
from: '0x9273D9437B0bf2F1b7999d8dB72960d6379564d1',
|
||||
to: '0xd86fB467B78901310e9967A2C8B601A5E794c12C',
|
||||
addresses: {
|
||||
'0xf29340ca4ad7A797dF2d67Be58d354EC284AE62f': {},
|
||||
'0xEcFF6b14D3ed9569108b413f846279E64E39BC92': {}
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
expect(addresses).to.eql([
|
||||
'0x9273D9437B0bf2F1b7999d8dB72960d6379564d1',
|
||||
'0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
'0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||
'0xEcFF6b14D3ed9569108b413f846279E64E39BC92',
|
||||
'0xd86fB467B78901310e9967A2C8B601A5E794c12C',
|
||||
'0xf29340ca4ad7A797dF2d67Be58d354EC284AE62f'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not return duplicate addresses', () => {
|
||||
const addresses = addressesInTrace({
|
||||
from: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||
to: '0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
calls: [{
|
||||
from: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||
to: '0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
addresses: {
|
||||
'0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc': {},
|
||||
'0xCA6D29232D1435D8198E3E5302495417dD073d61': {}
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
expect(addresses).to.eql([
|
||||
'0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
'0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return correct addresses for an ERC20 transfer', () => {
|
||||
/* eslint-disable */
|
||||
const trace = {
|
||||
"type": "CALL",
|
||||
"from": "0xdc7d7a8920c8eecc098da5b7522a5f31509b5bfc",
|
||||
"to": "0x1ca7c995f8ef0a2989bbce08d5b7efe50a584aa1",
|
||||
"value": "0x0",
|
||||
"gas": "0x4edf",
|
||||
"gasUsed": "0x3982",
|
||||
"input": "0xa9059cbb000000000000000000000000ca6d29232d1435d8198e3e5302495417dd073d610000000000000000000000000000000000000000000000000de0b6b3a7640000",
|
||||
"output": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"time": "66.609994ms",
|
||||
"addresses": {
|
||||
"0xca6d29232d1435d8198e3e5302495417dd073d61": {
|
||||
"confidence": 1,
|
||||
"opcodes": [
|
||||
"CALLDATALOAD", "AND", "SWAP1", "DUP5", "DUP3", "AND", "DUP4", "POP", "DUP6", "AND", "AND", "DUP5", "AND", "AND", "DUP2", "AND", "POP", "SWAP2"
|
||||
]
|
||||
},
|
||||
"0xdc7d7a8920c8eecc098da5b7522a5f31509b5bfc": {
|
||||
"confidence": 1,
|
||||
"opcodes": [
|
||||
"CALLER", "POP", "JUMP", "JUMPDEST", "DUP4", "AND", "DUP4", "POP", "DUP8", "AND", "AND", "DUP6", "AND", "AND", "DUP4", "AND", "POP"
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
/* eslint-enable */
|
||||
|
||||
const addresses = addressesInTrace(trace);
|
||||
expect(addresses).to.eql([
|
||||
'0x1ca7c995f8eF0A2989BbcE08D5B7Efe50A584aa1',
|
||||
'0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||
'0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc'
|
||||
]);
|
||||
});
|
||||
});
|
@ -1,33 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import _ from 'lodash';
|
||||
import { ethers } from 'ethers';
|
||||
|
||||
export const addressesInTrace = (obj: any): any => {
|
||||
return _.uniq(_.compact(_.flattenDeep(addressesIn(obj))))
|
||||
.sort()
|
||||
.map(address => ethers.utils.getAddress(<string>address));
|
||||
};
|
||||
|
||||
const addressesIn = (obj: any): any => {
|
||||
const addresses: any = [];
|
||||
|
||||
if (obj) {
|
||||
addresses.push(obj.from);
|
||||
addresses.push(obj.to);
|
||||
|
||||
if (obj.addresses) {
|
||||
addresses.push(_.keys(obj.addresses));
|
||||
}
|
||||
|
||||
if (obj.calls) {
|
||||
obj.calls.forEach((call: any) => {
|
||||
addresses.push(addressesIn(call));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return addresses;
|
||||
};
|
@ -1,77 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
||||
"lib": [ "ES5", "ES6", "ES2020" ], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
|
||||
"declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
"sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "dist", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
"downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
"strictPropertyInitialization": false, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
"typeRoots": [
|
||||
"./src/types"
|
||||
], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
|
||||
/* Advanced Options */
|
||||
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
||||
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
|
||||
"resolveJsonModule": true /* Enabling the option allows importing JSON, and validating the types in that JSON file. */
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["dist", "src/**/*.test.ts"]
|
||||
}
|
@ -28,8 +28,10 @@
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/node": "16.11.7",
|
||||
"@types/yargs": "^17.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.47.1",
|
||||
"@typescript-eslint/parser": "^5.47.1",
|
||||
"copyfiles": "^2.4.1",
|
||||
"eslint-config-semistandard": "^15.0.1",
|
||||
"eslint-config-standard": "^5.0.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
|
@ -40,7 +40,9 @@
|
||||
"devDependencies": {
|
||||
"@openzeppelin/contracts": "^4.3.2",
|
||||
"@types/js-yaml": "^4.0.3",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/node": "^16.9.0",
|
||||
"@types/yargs": "^17.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.47.1",
|
||||
"@typescript-eslint/parser": "^5.47.1",
|
||||
"eslint": "^8.35.0",
|
||||
|
@ -1,2 +0,0 @@
|
||||
# Don't lint build output.
|
||||
dist
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
"semistandard",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 12,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"indent": ["error", 2, { "SwitchCase": 1 }],
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": [
|
||||
"warn",
|
||||
{
|
||||
"allowArgumentsExplicitlyTypedAsAny": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
# EdenNetwork Watcher
|
||||
|
||||
## Setup
|
||||
|
||||
First try the [stack orchestrator](https://github.com/cerc-io/stack-orchestrator) to quickly get started. Advanced users can see [here](/docs/README.md) for instructions on setting up a local environment by hand.
|
||||
|
||||
|
||||
## Run
|
||||
|
||||
Setup with:
|
||||
|
||||
```bash
|
||||
yarn && yarn build
|
||||
```
|
||||
|
||||
then checkout the [CLI guide](/docs/cli.md) for examples of commands that can be run on this watcher.
|
@ -1,43 +0,0 @@
|
||||
# Config to generate eden-watcher using codegen.
|
||||
# Contracts to watch (required).
|
||||
contracts:
|
||||
# Contract name.
|
||||
- name: EdenNetwork
|
||||
# Contract file path or an url.
|
||||
path: ~/eden/governance/contracts/EdenNetwork.sol
|
||||
# Contract kind (should match that in {subgraphPath}/subgraph.yaml if subgraphPath provided)
|
||||
kind: EdenNetwork
|
||||
|
||||
# Contract name.
|
||||
- name: MerkleDistributor
|
||||
# Contract file path or an url.
|
||||
path: ~/eden/governance/contracts/MerkleDistributor.sol
|
||||
# Contract kind (should match that in {subgraphPath}/subgraph.yaml if subgraphPath provided)
|
||||
kind: EdenNetworkDistribution
|
||||
|
||||
# Contract name.
|
||||
- name: DistributorGovernance
|
||||
# Contract file path or an url.
|
||||
path: ~/eden/governance/contracts/DistributorGovernance.sol
|
||||
# Contract kind (should match that in {subgraphPath}/subgraph.yaml if subgraphPath provided)
|
||||
kind: EdenNetworkGovernance
|
||||
|
||||
# Output folder path (logs output using `stdout` if not provided).
|
||||
outputFolder: ../demo-eden-watcher
|
||||
|
||||
# Code generation mode [eth_call | storage | all | none] (default: all).
|
||||
mode: none
|
||||
|
||||
# Kind of watcher [lazy | active] (default: active).
|
||||
kind: active
|
||||
|
||||
# Watcher server port (default: 3008).
|
||||
port: 3012
|
||||
|
||||
# Flatten the input contract file(s) [true | false] (default: true).
|
||||
flatten: true
|
||||
|
||||
# Path to the subgraph build (optional).
|
||||
subgraphPath: ~/eden/eden-data/packages/subgraph/build
|
||||
|
||||
# NOTE: When passed an *URL* as contract path, it is assumed that it points to an already flattened contract file.
|
@ -1,75 +0,0 @@
|
||||
[server]
|
||||
host = "127.0.0.1"
|
||||
port = 3012
|
||||
kind = "active"
|
||||
|
||||
# Checkpointing state.
|
||||
checkpointing = true
|
||||
|
||||
# Checkpoint interval in number of blocks.
|
||||
checkpointInterval = 2000
|
||||
|
||||
subgraphPath = "../graph-node/test/subgraph/eden"
|
||||
|
||||
# Enable state creation
|
||||
# CAUTION: Disable only if state creation is not desired or can be filled subsequently
|
||||
enableState = true
|
||||
|
||||
# Interval to restart wasm instance periodically
|
||||
wasmRestartBlocksInterval = 20
|
||||
|
||||
# Boolean to filter logs by contract.
|
||||
filterLogs = true
|
||||
|
||||
# Max block range for which to return events in eventsInRange GQL query.
|
||||
# Use -1 for skipping check on block range.
|
||||
maxEventsBlockRange = 1000
|
||||
|
||||
# Interval in number of blocks at which to clear entities cache.
|
||||
clearEntitiesCacheInterval = 1000
|
||||
|
||||
# GQL cache settings
|
||||
[server.gqlCache]
|
||||
enabled = true
|
||||
|
||||
# Max in-memory cache size (in bytes) (default 8 MB)
|
||||
# maxCacheSize
|
||||
|
||||
# GQL cache-control max-age settings (in seconds)
|
||||
maxAge = 15
|
||||
timeTravelMaxAge = 86400 # 1 day
|
||||
|
||||
[metrics]
|
||||
host = "127.0.0.1"
|
||||
port = 9000
|
||||
[metrics.gql]
|
||||
port = 9001
|
||||
|
||||
[database]
|
||||
type = "postgres"
|
||||
host = "localhost"
|
||||
port = 5432
|
||||
database = "eden-watcher"
|
||||
username = "postgres"
|
||||
password = "postgres"
|
||||
synchronize = true
|
||||
logging = false
|
||||
|
||||
[upstream]
|
||||
[upstream.ethServer]
|
||||
gqlApiEndpoint = "http://127.0.0.1:8083/graphql"
|
||||
rpcProviderEndpoint = "http://127.0.0.1:8082"
|
||||
|
||||
[upstream.cache]
|
||||
name = "requests"
|
||||
enabled = false
|
||||
deleteOnStart = false
|
||||
|
||||
[jobQueue]
|
||||
dbConnectionString = "postgres://postgres:postgres@localhost/eden-watcher-job-queue"
|
||||
maxCompletionLagInSecs = 300
|
||||
jobDelayInMilliSecs = 100
|
||||
eventsInBatch = 50
|
||||
blockDelayInMilliSecs = 2000
|
||||
prefetchBlocksInMem = true
|
||||
prefetchBlockCount = 10
|
@ -1,72 +0,0 @@
|
||||
{
|
||||
"name": "@cerc-io/eden-watcher",
|
||||
"version": "0.2.38",
|
||||
"description": "eden-watcher",
|
||||
"private": true,
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"build": "yarn clean && tsc && yarn copy-assets",
|
||||
"clean": "rm -rf ./dist",
|
||||
"copy-assets": "copyfiles -u 1 src/**/*.gql dist/",
|
||||
"server": "DEBUG=vulcanize:* YARN_CHILD_PROCESS=true node --enable-source-maps dist/server.js",
|
||||
"server:dev": "DEBUG=vulcanize:* YARN_CHILD_PROCESS=true ts-node src/server.ts",
|
||||
"job-runner": "DEBUG=vulcanize:* YARN_CHILD_PROCESS=true node --max-old-space-size=3072 --enable-source-maps dist/job-runner.js",
|
||||
"job-runner:dev": "DEBUG=vulcanize:* YARN_CHILD_PROCESS=true ts-node src/job-runner.ts",
|
||||
"watch:contract": "DEBUG=vulcanize:* ts-node src/cli/watch-contract.ts",
|
||||
"fill": "DEBUG=vulcanize:* ts-node src/fill.ts",
|
||||
"fill:state": "DEBUG=vulcanize:* ts-node src/fill.ts --state",
|
||||
"reset": "DEBUG=vulcanize:* ts-node src/cli/reset.ts",
|
||||
"checkpoint": "DEBUG=vulcanize:* node --enable-source-maps --max-old-space-size=3072 dist/cli/checkpoint.js",
|
||||
"checkpoint:dev": "DEBUG=vulcanize:* ts-node src/cli/checkpoint.ts",
|
||||
"export-state": "DEBUG=vulcanize:* node --enable-source-maps --max-old-space-size=3072 dist/cli/export-state.js",
|
||||
"export-state:dev": "DEBUG=vulcanize:* ts-node src/cli/export-state.ts",
|
||||
"import-state": "DEBUG=vulcanize:* node --enable-source-maps --max-old-space-size=3072 dist/cli/import-state.js",
|
||||
"import-state:dev": "DEBUG=vulcanize:* ts-node src/cli/import-state.ts",
|
||||
"inspect-cid": "DEBUG=vulcanize:* ts-node src/cli/inspect-cid.ts",
|
||||
"index-block": "DEBUG=vulcanize:* ts-node src/cli/index-block.ts"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/cerc-io/watcher-ts.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "AGPL-3.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/cerc-io/watcher-ts/issues"
|
||||
},
|
||||
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.3.19",
|
||||
"@cerc-io/cli": "^0.2.38",
|
||||
"@cerc-io/graph-node": "^0.2.38",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.38",
|
||||
"@cerc-io/solidity-mapper": "^0.2.38",
|
||||
"@cerc-io/util": "^0.2.38",
|
||||
"@ethersproject/providers": "^5.4.4",
|
||||
"apollo-type-bigint": "^0.1.3",
|
||||
"debug": "^4.3.1",
|
||||
"decimal.js": "^10.3.1",
|
||||
"ethers": "^5.4.4",
|
||||
"graphql": "^15.5.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"typeorm": "^0.2.32",
|
||||
"yargs": "^17.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ethersproject/abi": "^5.3.0",
|
||||
"@types/yargs": "^17.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.47.1",
|
||||
"@typescript-eslint/parser": "^5.47.1",
|
||||
"copyfiles": "^2.4.1",
|
||||
"eslint": "^8.35.0",
|
||||
"eslint-config-semistandard": "^15.0.1",
|
||||
"eslint-config-standard": "^16.0.3",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-standard": "^5.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^5.0.2"
|
||||
}
|
||||
}
|
@ -1,723 +0,0 @@
|
||||
{
|
||||
"abi": [
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_admin",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "_blockProducers",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "_collectors",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "producer",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "BlockProducerAdded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "producer",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "BlockProducerRemoved",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "producer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "collector",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "BlockProducerRewardCollectorChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [],
|
||||
"name": "RewardScheduleChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "previousAdminRole",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "newAdminRole",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "RoleAdminChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "RoleGranted",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "RoleRevoked",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "DEFAULT_ADMIN_ROLE",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "DELEGATOR_ROLE",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "GOV_ROLE",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "REWARD_SCHEDULE_ENTRY_LENGTH",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "producer",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "add",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "producers",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "addBatch",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "blockProducer",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "producer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "collector",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "delegate",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "producers",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "collectors",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "delegateBatch",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "getRoleAdmin",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getRoleMember",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "getRoleMemberCount",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "grantRole",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "hasRole",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "producer",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "remove",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "producers",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "removeBatch",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "renounceRole",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "revokeRole",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "rewardCollector",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "rewardScheduleEntries",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "rewardScheduleEntry",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "startTime",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "epochDuration",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "rewardsPerEpoch",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"internalType": "struct IGovernance.RewardScheduleEntry",
|
||||
"name": "",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "set",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "setRewardSchedule",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes4",
|
||||
"name": "interfaceId",
|
||||
"type": "bytes4"
|
||||
}
|
||||
],
|
||||
"name": "supportsInterface",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"storageLayout": {
|
||||
"storage": [
|
||||
{
|
||||
"astId": 380,
|
||||
"contract": "DistributorGovernance.sol:DistributorGovernance",
|
||||
"label": "_roles",
|
||||
"offset": 0,
|
||||
"slot": "0",
|
||||
"type": "t_mapping(t_bytes32,t_struct(RoleData)375_storage)"
|
||||
},
|
||||
{
|
||||
"astId": 1210,
|
||||
"contract": "DistributorGovernance.sol:DistributorGovernance",
|
||||
"label": "_roleMembers",
|
||||
"offset": 0,
|
||||
"slot": "1",
|
||||
"type": "t_mapping(t_bytes32,t_struct(AddressSet)969_storage)"
|
||||
},
|
||||
{
|
||||
"astId": 1721,
|
||||
"contract": "DistributorGovernance.sol:DistributorGovernance",
|
||||
"label": "rewardCollector",
|
||||
"offset": 0,
|
||||
"slot": "2",
|
||||
"type": "t_mapping(t_address,t_address)"
|
||||
},
|
||||
{
|
||||
"astId": 1727,
|
||||
"contract": "DistributorGovernance.sol:DistributorGovernance",
|
||||
"label": "blockProducer",
|
||||
"offset": 0,
|
||||
"slot": "3",
|
||||
"type": "t_mapping(t_address,t_bool)"
|
||||
},
|
||||
{
|
||||
"astId": 1730,
|
||||
"contract": "DistributorGovernance.sol:DistributorGovernance",
|
||||
"label": "_rewardSchedule",
|
||||
"offset": 0,
|
||||
"slot": "4",
|
||||
"type": "t_bytes_storage"
|
||||
}
|
||||
],
|
||||
"types": {
|
||||
"t_address": {
|
||||
"encoding": "inplace",
|
||||
"label": "address",
|
||||
"numberOfBytes": "20"
|
||||
},
|
||||
"t_array(t_bytes32)dyn_storage": {
|
||||
"base": "t_bytes32",
|
||||
"encoding": "dynamic_array",
|
||||
"label": "bytes32[]",
|
||||
"numberOfBytes": "32"
|
||||
},
|
||||
"t_bool": {
|
||||
"encoding": "inplace",
|
||||
"label": "bool",
|
||||
"numberOfBytes": "1"
|
||||
},
|
||||
"t_bytes32": {
|
||||
"encoding": "inplace",
|
||||
"label": "bytes32",
|
||||
"numberOfBytes": "32"
|
||||
},
|
||||
"t_bytes_storage": {
|
||||
"encoding": "bytes",
|
||||
"label": "bytes",
|
||||
"numberOfBytes": "32"
|
||||
},
|
||||
"t_mapping(t_address,t_address)": {
|
||||
"encoding": "mapping",
|
||||
"key": "t_address",
|
||||
"label": "mapping(address => address)",
|
||||
"numberOfBytes": "32",
|
||||
"value": "t_address"
|
||||
},
|
||||
"t_mapping(t_address,t_bool)": {
|
||||
"encoding": "mapping",
|
||||
"key": "t_address",
|
||||
"label": "mapping(address => bool)",
|
||||
"numberOfBytes": "32",
|
||||
"value": "t_bool"
|
||||
},
|
||||
"t_mapping(t_bytes32,t_struct(AddressSet)969_storage)": {
|
||||
"encoding": "mapping",
|
||||
"key": "t_bytes32",
|
||||
"label": "mapping(bytes32 => struct EnumerableSet.AddressSet)",
|
||||
"numberOfBytes": "32",
|
||||
"value": "t_struct(AddressSet)969_storage"
|
||||
},
|
||||
"t_mapping(t_bytes32,t_struct(RoleData)375_storage)": {
|
||||
"encoding": "mapping",
|
||||
"key": "t_bytes32",
|
||||
"label": "mapping(bytes32 => struct AccessControl.RoleData)",
|
||||
"numberOfBytes": "32",
|
||||
"value": "t_struct(RoleData)375_storage"
|
||||
},
|
||||
"t_mapping(t_bytes32,t_uint256)": {
|
||||
"encoding": "mapping",
|
||||
"key": "t_bytes32",
|
||||
"label": "mapping(bytes32 => uint256)",
|
||||
"numberOfBytes": "32",
|
||||
"value": "t_uint256"
|
||||
},
|
||||
"t_struct(AddressSet)969_storage": {
|
||||
"encoding": "inplace",
|
||||
"label": "struct EnumerableSet.AddressSet",
|
||||
"members": [
|
||||
{
|
||||
"astId": 968,
|
||||
"contract": "DistributorGovernance.sol:DistributorGovernance",
|
||||
"label": "_inner",
|
||||
"offset": 0,
|
||||
"slot": "0",
|
||||
"type": "t_struct(Set)698_storage"
|
||||
}
|
||||
],
|
||||
"numberOfBytes": "64"
|
||||
},
|
||||
"t_struct(RoleData)375_storage": {
|
||||
"encoding": "inplace",
|
||||
"label": "struct AccessControl.RoleData",
|
||||
"members": [
|
||||
{
|
||||
"astId": 372,
|
||||
"contract": "DistributorGovernance.sol:DistributorGovernance",
|
||||
"label": "members",
|
||||
"offset": 0,
|
||||
"slot": "0",
|
||||
"type": "t_mapping(t_address,t_bool)"
|
||||
},
|
||||
{
|
||||
"astId": 374,
|
||||
"contract": "DistributorGovernance.sol:DistributorGovernance",
|
||||
"label": "adminRole",
|
||||
"offset": 0,
|
||||
"slot": "1",
|
||||
"type": "t_bytes32"
|
||||
}
|
||||
],
|
||||
"numberOfBytes": "64"
|
||||
},
|
||||
"t_struct(Set)698_storage": {
|
||||
"encoding": "inplace",
|
||||
"label": "struct EnumerableSet.Set",
|
||||
"members": [
|
||||
{
|
||||
"astId": 693,
|
||||
"contract": "DistributorGovernance.sol:DistributorGovernance",
|
||||
"label": "_values",
|
||||
"offset": 0,
|
||||
"slot": "0",
|
||||
"type": "t_array(t_bytes32)dyn_storage"
|
||||
},
|
||||
{
|
||||
"astId": 697,
|
||||
"contract": "DistributorGovernance.sol:DistributorGovernance",
|
||||
"label": "_indexes",
|
||||
"offset": 0,
|
||||
"slot": "1",
|
||||
"type": "t_mapping(t_bytes32,t_uint256)"
|
||||
}
|
||||
],
|
||||
"numberOfBytes": "64"
|
||||
},
|
||||
"t_uint256": {
|
||||
"encoding": "inplace",
|
||||
"label": "uint256",
|
||||
"numberOfBytes": "32"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,942 +0,0 @@
|
||||
{
|
||||
"abi": [
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "newAdmin",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "oldAdmin",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AdminUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint8",
|
||||
"name": "slot",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "delegate",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint128",
|
||||
"name": "newBidAmount",
|
||||
"type": "uint128"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint128",
|
||||
"name": "oldBidAmount",
|
||||
"type": "uint128"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint16",
|
||||
"name": "taxNumerator",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint16",
|
||||
"name": "taxDenominator",
|
||||
"type": "uint16"
|
||||
}
|
||||
],
|
||||
"name": "SlotClaimed",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint8",
|
||||
"name": "slot",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "newDelegate",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "oldDelegate",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "SlotDelegateUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "staker",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "stakeAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Stake",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint16",
|
||||
"name": "newNumerator",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint16",
|
||||
"name": "newDenominator",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint16",
|
||||
"name": "oldNumerator",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint16",
|
||||
"name": "oldDenominator",
|
||||
"type": "uint16"
|
||||
}
|
||||
],
|
||||
"name": "TaxRateUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "staker",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "unstakedAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Unstake",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "withdrawer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "withdrawalAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Withdraw",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "MIN_BID",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "admin",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "slot",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "bid",
|
||||
"type": "uint128"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "delegate",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "claimSlot",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "slot",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "bid",
|
||||
"type": "uint128"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "delegate",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "deadline",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "v",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "r",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "s",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "claimSlotWithPermit",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "contract IERC20Extended",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "contract ILockManager",
|
||||
"name": "_lockManager",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_admin",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint16",
|
||||
"name": "_taxNumerator",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"internalType": "uint16",
|
||||
"name": "_taxDenominator",
|
||||
"type": "uint16"
|
||||
}
|
||||
],
|
||||
"name": "initialize",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "lockManager",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "contract ILockManager",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "lockedBalance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newAdmin",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setAdmin",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "slot",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "delegate",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setSlotDelegate",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint16",
|
||||
"name": "numerator",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"internalType": "uint16",
|
||||
"name": "denominator",
|
||||
"type": "uint16"
|
||||
}
|
||||
],
|
||||
"name": "setTaxRate",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "slot",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"name": "slotBalance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "balance",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"name": "slotBid",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "bidder",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint16",
|
||||
"name": "taxNumerator",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"internalType": "uint16",
|
||||
"name": "taxDenominator",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "periodStart",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "bidAmount",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "slot",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"name": "slotCost",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "slot",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"name": "slotDelegate",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"name": "slotExpiration",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "slot",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"name": "slotForeclosed",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "slot",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"name": "slotOwner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "amount",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"name": "stake",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "amount",
|
||||
"type": "uint128"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "deadline",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "v",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "r",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "s",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "stakeWithPermit",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "stakedBalance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "taxDenominator",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint16",
|
||||
"name": "",
|
||||
"type": "uint16"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "taxNumerator",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint16",
|
||||
"name": "",
|
||||
"type": "uint16"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "token",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "contract IERC20Extended",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "amount",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"name": "unstake",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "amount",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"name": "withdraw",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"storageLayout": {
|
||||
"storage": [
|
||||
{
|
||||
"astId": 322,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "_initialized",
|
||||
"offset": 0,
|
||||
"slot": "0",
|
||||
"type": "t_bool"
|
||||
},
|
||||
{
|
||||
"astId": 325,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "_initializing",
|
||||
"offset": 1,
|
||||
"slot": "0",
|
||||
"type": "t_bool"
|
||||
},
|
||||
{
|
||||
"astId": 381,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "slotExpiration",
|
||||
"offset": 0,
|
||||
"slot": "1",
|
||||
"type": "t_mapping(t_uint8,t_uint64)"
|
||||
},
|
||||
{
|
||||
"astId": 386,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "_slotDelegate",
|
||||
"offset": 0,
|
||||
"slot": "2",
|
||||
"type": "t_mapping(t_uint8,t_address)"
|
||||
},
|
||||
{
|
||||
"astId": 391,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "_slotOwner",
|
||||
"offset": 0,
|
||||
"slot": "3",
|
||||
"type": "t_mapping(t_uint8,t_address)"
|
||||
},
|
||||
{
|
||||
"astId": 397,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "slotBid",
|
||||
"offset": 0,
|
||||
"slot": "4",
|
||||
"type": "t_mapping(t_uint8,t_struct(Bid)376_storage)"
|
||||
},
|
||||
{
|
||||
"astId": 402,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "stakedBalance",
|
||||
"offset": 0,
|
||||
"slot": "5",
|
||||
"type": "t_mapping(t_address,t_uint128)"
|
||||
},
|
||||
{
|
||||
"astId": 407,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "lockedBalance",
|
||||
"offset": 0,
|
||||
"slot": "6",
|
||||
"type": "t_mapping(t_address,t_uint128)"
|
||||
},
|
||||
{
|
||||
"astId": 411,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "token",
|
||||
"offset": 0,
|
||||
"slot": "7",
|
||||
"type": "t_contract(IERC20Extended)318"
|
||||
},
|
||||
{
|
||||
"astId": 415,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "lockManager",
|
||||
"offset": 0,
|
||||
"slot": "8",
|
||||
"type": "t_contract(ILockManager)133"
|
||||
},
|
||||
{
|
||||
"astId": 418,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "admin",
|
||||
"offset": 0,
|
||||
"slot": "9",
|
||||
"type": "t_address"
|
||||
},
|
||||
{
|
||||
"astId": 421,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "taxNumerator",
|
||||
"offset": 20,
|
||||
"slot": "9",
|
||||
"type": "t_uint16"
|
||||
},
|
||||
{
|
||||
"astId": 424,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "taxDenominator",
|
||||
"offset": 22,
|
||||
"slot": "9",
|
||||
"type": "t_uint16"
|
||||
},
|
||||
{
|
||||
"astId": 427,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "MIN_BID",
|
||||
"offset": 0,
|
||||
"slot": "10",
|
||||
"type": "t_uint128"
|
||||
},
|
||||
{
|
||||
"astId": 430,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "_NOT_ENTERED",
|
||||
"offset": 0,
|
||||
"slot": "11",
|
||||
"type": "t_uint256"
|
||||
},
|
||||
{
|
||||
"astId": 433,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "_ENTERED",
|
||||
"offset": 0,
|
||||
"slot": "12",
|
||||
"type": "t_uint256"
|
||||
},
|
||||
{
|
||||
"astId": 436,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "_status",
|
||||
"offset": 0,
|
||||
"slot": "13",
|
||||
"type": "t_uint256"
|
||||
}
|
||||
],
|
||||
"types": {
|
||||
"t_address": {
|
||||
"encoding": "inplace",
|
||||
"label": "address",
|
||||
"numberOfBytes": "20"
|
||||
},
|
||||
"t_bool": {
|
||||
"encoding": "inplace",
|
||||
"label": "bool",
|
||||
"numberOfBytes": "1"
|
||||
},
|
||||
"t_contract(IERC20Extended)318": {
|
||||
"encoding": "inplace",
|
||||
"label": "contract IERC20Extended",
|
||||
"numberOfBytes": "20"
|
||||
},
|
||||
"t_contract(ILockManager)133": {
|
||||
"encoding": "inplace",
|
||||
"label": "contract ILockManager",
|
||||
"numberOfBytes": "20"
|
||||
},
|
||||
"t_mapping(t_address,t_uint128)": {
|
||||
"encoding": "mapping",
|
||||
"key": "t_address",
|
||||
"label": "mapping(address => uint128)",
|
||||
"numberOfBytes": "32",
|
||||
"value": "t_uint128"
|
||||
},
|
||||
"t_mapping(t_uint8,t_address)": {
|
||||
"encoding": "mapping",
|
||||
"key": "t_uint8",
|
||||
"label": "mapping(uint8 => address)",
|
||||
"numberOfBytes": "32",
|
||||
"value": "t_address"
|
||||
},
|
||||
"t_mapping(t_uint8,t_struct(Bid)376_storage)": {
|
||||
"encoding": "mapping",
|
||||
"key": "t_uint8",
|
||||
"label": "mapping(uint8 => struct EdenNetwork.Bid)",
|
||||
"numberOfBytes": "32",
|
||||
"value": "t_struct(Bid)376_storage"
|
||||
},
|
||||
"t_mapping(t_uint8,t_uint64)": {
|
||||
"encoding": "mapping",
|
||||
"key": "t_uint8",
|
||||
"label": "mapping(uint8 => uint64)",
|
||||
"numberOfBytes": "32",
|
||||
"value": "t_uint64"
|
||||
},
|
||||
"t_struct(Bid)376_storage": {
|
||||
"encoding": "inplace",
|
||||
"label": "struct EdenNetwork.Bid",
|
||||
"members": [
|
||||
{
|
||||
"astId": 367,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "bidder",
|
||||
"offset": 0,
|
||||
"slot": "0",
|
||||
"type": "t_address"
|
||||
},
|
||||
{
|
||||
"astId": 369,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "taxNumerator",
|
||||
"offset": 20,
|
||||
"slot": "0",
|
||||
"type": "t_uint16"
|
||||
},
|
||||
{
|
||||
"astId": 371,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "taxDenominator",
|
||||
"offset": 22,
|
||||
"slot": "0",
|
||||
"type": "t_uint16"
|
||||
},
|
||||
{
|
||||
"astId": 373,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "periodStart",
|
||||
"offset": 24,
|
||||
"slot": "0",
|
||||
"type": "t_uint64"
|
||||
},
|
||||
{
|
||||
"astId": 375,
|
||||
"contract": "EdenNetwork.sol:EdenNetwork",
|
||||
"label": "bidAmount",
|
||||
"offset": 0,
|
||||
"slot": "1",
|
||||
"type": "t_uint128"
|
||||
}
|
||||
],
|
||||
"numberOfBytes": "64"
|
||||
},
|
||||
"t_uint128": {
|
||||
"encoding": "inplace",
|
||||
"label": "uint128",
|
||||
"numberOfBytes": "16"
|
||||
},
|
||||
"t_uint16": {
|
||||
"encoding": "inplace",
|
||||
"label": "uint16",
|
||||
"numberOfBytes": "2"
|
||||
},
|
||||
"t_uint256": {
|
||||
"encoding": "inplace",
|
||||
"label": "uint256",
|
||||
"numberOfBytes": "32"
|
||||
},
|
||||
"t_uint64": {
|
||||
"encoding": "inplace",
|
||||
"label": "uint64",
|
||||
"numberOfBytes": "8"
|
||||
},
|
||||
"t_uint8": {
|
||||
"encoding": "inplace",
|
||||
"label": "uint8",
|
||||
"numberOfBytes": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,44 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { CreateCheckpointCmd } from '@cerc-io/cli';
|
||||
import { getGraphDbAndWatcher } from '@cerc-io/graph-node';
|
||||
|
||||
import { Database, ENTITY_QUERY_TYPE_MAP, ENTITY_TO_LATEST_ENTITY_MAP } from '../../database';
|
||||
import { Indexer } from '../../indexer';
|
||||
|
||||
export const command = 'create';
|
||||
|
||||
export const desc = 'Create checkpoint';
|
||||
|
||||
export const builder = {
|
||||
address: {
|
||||
type: 'string',
|
||||
require: true,
|
||||
demandOption: true,
|
||||
describe: 'Contract address to create the checkpoint for.'
|
||||
},
|
||||
blockHash: {
|
||||
type: 'string',
|
||||
describe: 'Blockhash at which to create the checkpoint.'
|
||||
}
|
||||
};
|
||||
|
||||
export const handler = async (argv: any): Promise<void> => {
|
||||
const createCheckpointCmd = new CreateCheckpointCmd();
|
||||
await createCheckpointCmd.init(argv, Database);
|
||||
|
||||
const { graphWatcher } = await getGraphDbAndWatcher(
|
||||
createCheckpointCmd.config.server,
|
||||
createCheckpointCmd.clients.ethClient,
|
||||
createCheckpointCmd.ethProvider,
|
||||
createCheckpointCmd.database.baseDatabase,
|
||||
ENTITY_QUERY_TYPE_MAP,
|
||||
ENTITY_TO_LATEST_ENTITY_MAP
|
||||
);
|
||||
|
||||
await createCheckpointCmd.initIndexer(Indexer, graphWatcher);
|
||||
|
||||
await createCheckpointCmd.exec();
|
||||
};
|
@ -1,40 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { VerifyCheckpointCmd } from '@cerc-io/cli';
|
||||
import { getGraphDbAndWatcher } from '@cerc-io/graph-node';
|
||||
|
||||
import { Database, ENTITY_QUERY_TYPE_MAP, ENTITY_TO_LATEST_ENTITY_MAP } from '../../database';
|
||||
import { Indexer } from '../../indexer';
|
||||
|
||||
export const command = 'verify';
|
||||
|
||||
export const desc = 'Verify checkpoint';
|
||||
|
||||
export const builder = {
|
||||
cid: {
|
||||
type: 'string',
|
||||
alias: 'c',
|
||||
demandOption: true,
|
||||
describe: 'Checkpoint CID to be verified'
|
||||
}
|
||||
};
|
||||
|
||||
export const handler = async (argv: any): Promise<void> => {
|
||||
const verifyCheckpointCmd = new VerifyCheckpointCmd();
|
||||
await verifyCheckpointCmd.init(argv, Database);
|
||||
|
||||
const { graphWatcher, graphDb } = await getGraphDbAndWatcher(
|
||||
verifyCheckpointCmd.config.server,
|
||||
verifyCheckpointCmd.clients.ethClient,
|
||||
verifyCheckpointCmd.ethProvider,
|
||||
verifyCheckpointCmd.database.baseDatabase,
|
||||
ENTITY_QUERY_TYPE_MAP,
|
||||
ENTITY_TO_LATEST_ENTITY_MAP
|
||||
);
|
||||
|
||||
await verifyCheckpointCmd.initIndexer(Indexer, graphWatcher);
|
||||
|
||||
await verifyCheckpointCmd.exec(graphDb);
|
||||
};
|
@ -1,39 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import yargs from 'yargs';
|
||||
import 'reflect-metadata';
|
||||
import debug from 'debug';
|
||||
|
||||
import { DEFAULT_CONFIG_PATH } from '@cerc-io/util';
|
||||
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
|
||||
const log = debug('vulcanize:checkpoint');
|
||||
|
||||
const main = async () => {
|
||||
return yargs(hideBin(process.argv))
|
||||
.parserConfiguration({
|
||||
'parse-numbers': false
|
||||
}).options({
|
||||
configFile: {
|
||||
alias: 'f',
|
||||
type: 'string',
|
||||
require: true,
|
||||
demandOption: true,
|
||||
describe: 'configuration file path (toml)',
|
||||
default: DEFAULT_CONFIG_PATH
|
||||
}
|
||||
})
|
||||
.commandDir('checkpoint-cmds', { extensions: ['ts', 'js'], exclude: /([a-zA-Z0-9\s_\\.\-:])+(.d.ts)$/ })
|
||||
.demandCommand(1)
|
||||
.help()
|
||||
.argv;
|
||||
};
|
||||
|
||||
main().then(() => {
|
||||
process.exit();
|
||||
}).catch(err => {
|
||||
log(err);
|
||||
});
|
@ -1,38 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import 'reflect-metadata';
|
||||
import debug from 'debug';
|
||||
|
||||
import { ExportStateCmd } from '@cerc-io/cli';
|
||||
import { getGraphDbAndWatcher } from '@cerc-io/graph-node';
|
||||
|
||||
import { Database, ENTITY_QUERY_TYPE_MAP, ENTITY_TO_LATEST_ENTITY_MAP } from '../database';
|
||||
import { Indexer } from '../indexer';
|
||||
|
||||
const log = debug('vulcanize:export-state');
|
||||
|
||||
const main = async (): Promise<void> => {
|
||||
const exportStateCmd = new ExportStateCmd();
|
||||
await exportStateCmd.init(Database);
|
||||
|
||||
const { graphWatcher } = await getGraphDbAndWatcher(
|
||||
exportStateCmd.config.server,
|
||||
exportStateCmd.clients.ethClient,
|
||||
exportStateCmd.ethProvider,
|
||||
exportStateCmd.database.baseDatabase,
|
||||
ENTITY_QUERY_TYPE_MAP,
|
||||
ENTITY_TO_LATEST_ENTITY_MAP
|
||||
);
|
||||
|
||||
await exportStateCmd.initIndexer(Indexer, graphWatcher);
|
||||
|
||||
await exportStateCmd.exec();
|
||||
};
|
||||
|
||||
main().catch(err => {
|
||||
log(err);
|
||||
}).finally(() => {
|
||||
process.exit(0);
|
||||
});
|
@ -1,39 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import 'reflect-metadata';
|
||||
import debug from 'debug';
|
||||
|
||||
import { ImportStateCmd } from '@cerc-io/cli';
|
||||
import { getGraphDbAndWatcher } from '@cerc-io/graph-node';
|
||||
|
||||
import { Database, ENTITY_QUERY_TYPE_MAP, ENTITY_TO_LATEST_ENTITY_MAP } from '../database';
|
||||
import { Indexer } from '../indexer';
|
||||
import { State } from '../entity/State';
|
||||
|
||||
const log = debug('vulcanize:import-state');
|
||||
|
||||
export const main = async (): Promise<any> => {
|
||||
const importStateCmd = new ImportStateCmd();
|
||||
await importStateCmd.init(Database);
|
||||
|
||||
const { graphWatcher, graphDb } = await getGraphDbAndWatcher(
|
||||
importStateCmd.config.server,
|
||||
importStateCmd.clients.ethClient,
|
||||
importStateCmd.ethProvider,
|
||||
importStateCmd.database.baseDatabase,
|
||||
ENTITY_QUERY_TYPE_MAP,
|
||||
ENTITY_TO_LATEST_ENTITY_MAP
|
||||
);
|
||||
|
||||
await importStateCmd.initIndexer(Indexer, graphWatcher);
|
||||
|
||||
await importStateCmd.exec(State, graphDb);
|
||||
};
|
||||
|
||||
main().catch(err => {
|
||||
log(err);
|
||||
}).finally(() => {
|
||||
process.exit(0);
|
||||
});
|
@ -1,38 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import 'reflect-metadata';
|
||||
import debug from 'debug';
|
||||
|
||||
import { IndexBlockCmd } from '@cerc-io/cli';
|
||||
import { getGraphDbAndWatcher } from '@cerc-io/graph-node';
|
||||
|
||||
import { Database, ENTITY_QUERY_TYPE_MAP, ENTITY_TO_LATEST_ENTITY_MAP } from '../database';
|
||||
import { Indexer } from '../indexer';
|
||||
|
||||
const log = debug('vulcanize:index-block');
|
||||
|
||||
const main = async (): Promise<void> => {
|
||||
const indexBlockCmd = new IndexBlockCmd();
|
||||
await indexBlockCmd.init(Database);
|
||||
|
||||
const { graphWatcher } = await getGraphDbAndWatcher(
|
||||
indexBlockCmd.config.server,
|
||||
indexBlockCmd.clients.ethClient,
|
||||
indexBlockCmd.ethProvider,
|
||||
indexBlockCmd.database.baseDatabase,
|
||||
ENTITY_QUERY_TYPE_MAP,
|
||||
ENTITY_TO_LATEST_ENTITY_MAP
|
||||
);
|
||||
|
||||
await indexBlockCmd.initIndexer(Indexer, graphWatcher);
|
||||
|
||||
await indexBlockCmd.exec();
|
||||
};
|
||||
|
||||
main().catch(err => {
|
||||
log(err);
|
||||
}).finally(() => {
|
||||
process.exit(0);
|
||||
});
|
@ -1,38 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import 'reflect-metadata';
|
||||
import debug from 'debug';
|
||||
|
||||
import { InspectCIDCmd } from '@cerc-io/cli';
|
||||
import { getGraphDbAndWatcher } from '@cerc-io/graph-node';
|
||||
|
||||
import { Database, ENTITY_QUERY_TYPE_MAP, ENTITY_TO_LATEST_ENTITY_MAP } from '../database';
|
||||
import { Indexer } from '../indexer';
|
||||
|
||||
const log = debug('vulcanize:inspect-cid');
|
||||
|
||||
const main = async (): Promise<void> => {
|
||||
const inspectCIDCmd = new InspectCIDCmd();
|
||||
await inspectCIDCmd.init(Database);
|
||||
|
||||
const { graphWatcher } = await getGraphDbAndWatcher(
|
||||
inspectCIDCmd.config.server,
|
||||
inspectCIDCmd.clients.ethClient,
|
||||
inspectCIDCmd.ethProvider,
|
||||
inspectCIDCmd.database.baseDatabase,
|
||||
ENTITY_QUERY_TYPE_MAP,
|
||||
ENTITY_TO_LATEST_ENTITY_MAP
|
||||
);
|
||||
|
||||
await inspectCIDCmd.initIndexer(Indexer, graphWatcher);
|
||||
|
||||
await inspectCIDCmd.exec();
|
||||
};
|
||||
|
||||
main().catch(err => {
|
||||
log(err);
|
||||
}).finally(() => {
|
||||
process.exit(0);
|
||||
});
|
@ -1,22 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import debug from 'debug';
|
||||
|
||||
import { getConfig, resetJobs, Config } from '@cerc-io/util';
|
||||
|
||||
const log = debug('vulcanize:reset-job-queue');
|
||||
|
||||
export const command = 'job-queue';
|
||||
|
||||
export const desc = 'Reset job queue';
|
||||
|
||||
export const builder = {};
|
||||
|
||||
export const handler = async (argv: any): Promise<void> => {
|
||||
const config: Config = await getConfig(argv.configFile);
|
||||
await resetJobs(config);
|
||||
|
||||
log('Job queue reset successfully');
|
||||
};
|
@ -1,24 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { ResetStateCmd } from '@cerc-io/cli';
|
||||
|
||||
import { Database } from '../../database';
|
||||
|
||||
export const command = 'state';
|
||||
|
||||
export const desc = 'Reset State to a given block number';
|
||||
|
||||
export const builder = {
|
||||
blockNumber: {
|
||||
type: 'number'
|
||||
}
|
||||
};
|
||||
|
||||
export const handler = async (argv: any): Promise<void> => {
|
||||
const resetStateCmd = new ResetStateCmd();
|
||||
await resetStateCmd.init(argv, Database);
|
||||
|
||||
await resetStateCmd.exec();
|
||||
};
|
@ -1,37 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { ResetWatcherCmd } from '@cerc-io/cli';
|
||||
import { getGraphDbAndWatcher } from '@cerc-io/graph-node';
|
||||
|
||||
import { Database, ENTITY_QUERY_TYPE_MAP, ENTITY_TO_LATEST_ENTITY_MAP } from '../../database';
|
||||
import { Indexer } from '../../indexer';
|
||||
|
||||
export const command = 'watcher';
|
||||
|
||||
export const desc = 'Reset watcher to a block number';
|
||||
|
||||
export const builder = {
|
||||
blockNumber: {
|
||||
type: 'number'
|
||||
}
|
||||
};
|
||||
|
||||
export const handler = async (argv: any): Promise<void> => {
|
||||
const resetWatcherCmd = new ResetWatcherCmd();
|
||||
await resetWatcherCmd.init(argv, Database);
|
||||
|
||||
const { graphWatcher } = await getGraphDbAndWatcher(
|
||||
resetWatcherCmd.config.server,
|
||||
resetWatcherCmd.clients.ethClient,
|
||||
resetWatcherCmd.ethProvider,
|
||||
resetWatcherCmd.database.baseDatabase,
|
||||
ENTITY_QUERY_TYPE_MAP,
|
||||
ENTITY_TO_LATEST_ENTITY_MAP
|
||||
);
|
||||
|
||||
await resetWatcherCmd.initIndexer(Indexer, graphWatcher);
|
||||
|
||||
await resetWatcherCmd.exec();
|
||||
};
|
@ -1,24 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import 'reflect-metadata';
|
||||
import debug from 'debug';
|
||||
|
||||
import { getResetYargs } from '@cerc-io/util';
|
||||
|
||||
const log = debug('vulcanize:reset');
|
||||
|
||||
const main = async () => {
|
||||
return getResetYargs()
|
||||
.commandDir('reset-cmds', { extensions: ['ts', 'js'], exclude: /([a-zA-Z0-9\s_\\.\-:])+(.d.ts)$/ })
|
||||
.demandCommand(1)
|
||||
.help()
|
||||
.argv;
|
||||
};
|
||||
|
||||
main().then(() => {
|
||||
process.exit();
|
||||
}).catch(err => {
|
||||
log(err);
|
||||
});
|
@ -1,38 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import 'reflect-metadata';
|
||||
import debug from 'debug';
|
||||
|
||||
import { WatchContractCmd } from '@cerc-io/cli';
|
||||
import { getGraphDbAndWatcher } from '@cerc-io/graph-node';
|
||||
|
||||
import { Database, ENTITY_QUERY_TYPE_MAP, ENTITY_TO_LATEST_ENTITY_MAP } from '../database';
|
||||
import { Indexer } from '../indexer';
|
||||
|
||||
const log = debug('vulcanize:watch-contract');
|
||||
|
||||
const main = async (): Promise<void> => {
|
||||
const watchContractCmd = new WatchContractCmd();
|
||||
await watchContractCmd.init(Database);
|
||||
|
||||
const { graphWatcher } = await getGraphDbAndWatcher(
|
||||
watchContractCmd.config.server,
|
||||
watchContractCmd.clients.ethClient,
|
||||
watchContractCmd.ethProvider,
|
||||
watchContractCmd.database.baseDatabase,
|
||||
ENTITY_QUERY_TYPE_MAP,
|
||||
ENTITY_TO_LATEST_ENTITY_MAP
|
||||
);
|
||||
|
||||
await watchContractCmd.initIndexer(Indexer, graphWatcher);
|
||||
|
||||
await watchContractCmd.exec();
|
||||
};
|
||||
|
||||
main().catch(err => {
|
||||
log(err);
|
||||
}).finally(() => {
|
||||
process.exit(0);
|
||||
});
|
@ -1,55 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { gql } from '@apollo/client/core';
|
||||
import { GraphQLClient, GraphQLConfig } from '@cerc-io/ipld-eth-client';
|
||||
|
||||
import { queries, mutations, subscriptions } from './gql';
|
||||
|
||||
export class Client {
|
||||
_config: GraphQLConfig;
|
||||
_client: GraphQLClient;
|
||||
|
||||
constructor (config: GraphQLConfig) {
|
||||
this._config = config;
|
||||
|
||||
this._client = new GraphQLClient(config);
|
||||
}
|
||||
|
||||
async getEvents (blockHash: string, contractAddress: string, name: string): Promise<any> {
|
||||
const { events } = await this._client.query(
|
||||
gql(queries.events),
|
||||
{ blockHash, contractAddress, name }
|
||||
);
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
async getEventsInRange (fromBlockNumber: number, toBlockNumber: number): Promise<any> {
|
||||
const { eventsInRange } = await this._client.query(
|
||||
gql(queries.eventsInRange),
|
||||
{ fromBlockNumber, toBlockNumber }
|
||||
);
|
||||
|
||||
return eventsInRange;
|
||||
}
|
||||
|
||||
async watchContract (contractAddress: string, startingBlock?: number): Promise<any> {
|
||||
const { watchContract } = await this._client.mutate(
|
||||
gql(mutations.watchContract),
|
||||
{ contractAddress, startingBlock }
|
||||
);
|
||||
|
||||
return watchContract;
|
||||
}
|
||||
|
||||
async watchEvents (onNext: (value: any) => void): Promise<ZenObservable.Subscription> {
|
||||
return this._client.subscribe(
|
||||
gql(subscriptions.onEvent),
|
||||
({ data }) => {
|
||||
onNext(data.onEvent);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -1,272 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import assert from 'assert';
|
||||
import { Connection, ConnectionOptions, DeepPartial, FindConditions, QueryRunner, FindManyOptions, EntityTarget } from 'typeorm';
|
||||
import path from 'path';
|
||||
|
||||
import { Database as BaseDatabase, DatabaseInterface, QueryOptions, StateKind, Where } from '@cerc-io/util';
|
||||
|
||||
import { Contract } from './entity/Contract';
|
||||
import { Event } from './entity/Event';
|
||||
import { SyncStatus } from './entity/SyncStatus';
|
||||
import { StateSyncStatus } from './entity/StateSyncStatus';
|
||||
import { BlockProgress } from './entity/BlockProgress';
|
||||
import { State } from './entity/State';
|
||||
import { Account } from './entity/Account';
|
||||
import { Claim } from './entity/Claim';
|
||||
import { Distribution } from './entity/Distribution';
|
||||
import { Distributor } from './entity/Distributor';
|
||||
import { Epoch } from './entity/Epoch';
|
||||
import { Network } from './entity/Network';
|
||||
import { Producer } from './entity/Producer';
|
||||
import { ProducerEpoch } from './entity/ProducerEpoch';
|
||||
import { ProducerRewardCollectorChange } from './entity/ProducerRewardCollectorChange';
|
||||
import { ProducerSet } from './entity/ProducerSet';
|
||||
import { ProducerSetChange } from './entity/ProducerSetChange';
|
||||
import { RewardSchedule } from './entity/RewardSchedule';
|
||||
import { RewardScheduleEntry } from './entity/RewardScheduleEntry';
|
||||
import { Slash } from './entity/Slash';
|
||||
import { Slot } from './entity/Slot';
|
||||
import { SlotClaim } from './entity/SlotClaim';
|
||||
import { Staker } from './entity/Staker';
|
||||
|
||||
export const SUBGRAPH_ENTITIES = new Set([Account, Claim, Distribution, Distributor, Epoch, Network, Producer, ProducerEpoch, ProducerRewardCollectorChange, ProducerSet, ProducerSetChange, RewardSchedule, RewardScheduleEntry, Slash, Slot, SlotClaim, Staker]);
|
||||
export const ENTITIES = [...SUBGRAPH_ENTITIES];
|
||||
export const ENTITY_TO_LATEST_ENTITY_MAP = new Map();
|
||||
export const ENTITY_QUERY_TYPE_MAP = new Map();
|
||||
|
||||
export class Database implements DatabaseInterface {
|
||||
_config: ConnectionOptions;
|
||||
_conn!: Connection;
|
||||
_baseDatabase: BaseDatabase;
|
||||
|
||||
constructor (config: ConnectionOptions) {
|
||||
assert(config);
|
||||
|
||||
this._config = {
|
||||
...config,
|
||||
entities: [path.join(__dirname, 'entity/*')],
|
||||
subscribers: [path.join(__dirname, 'entity/Subscriber.*')]
|
||||
};
|
||||
|
||||
this._baseDatabase = new BaseDatabase(this._config);
|
||||
}
|
||||
|
||||
get baseDatabase (): BaseDatabase {
|
||||
return this._baseDatabase;
|
||||
}
|
||||
|
||||
async init (): Promise<void> {
|
||||
this._conn = await this._baseDatabase.init();
|
||||
}
|
||||
|
||||
async close (): Promise<void> {
|
||||
return this._baseDatabase.close();
|
||||
}
|
||||
|
||||
getNewState (): State {
|
||||
return new State();
|
||||
}
|
||||
|
||||
async getStates (where: FindConditions<State>): Promise<State[]> {
|
||||
const repo = this._conn.getRepository(State);
|
||||
|
||||
return this._baseDatabase.getStates(repo, where);
|
||||
}
|
||||
|
||||
async getLatestState (contractAddress: string, kind: StateKind | null, blockNumber?: number): Promise<State | undefined> {
|
||||
const repo = this._conn.getRepository(State);
|
||||
|
||||
return this._baseDatabase.getLatestState(repo, contractAddress, kind, blockNumber);
|
||||
}
|
||||
|
||||
async getPrevState (blockHash: string, contractAddress: string, kind?: string): Promise<State | undefined> {
|
||||
const repo = this._conn.getRepository(State);
|
||||
|
||||
return this._baseDatabase.getPrevState(repo, blockHash, contractAddress, kind);
|
||||
}
|
||||
|
||||
// Fetch all diff States after the specified block number.
|
||||
async getDiffStatesInRange (contractAddress: string, startblock: number, endBlock: number): Promise<State[]> {
|
||||
const repo = this._conn.getRepository(State);
|
||||
|
||||
return this._baseDatabase.getDiffStatesInRange(repo, contractAddress, startblock, endBlock);
|
||||
}
|
||||
|
||||
async saveOrUpdateState (dbTx: QueryRunner, state: State): Promise<State> {
|
||||
const repo = dbTx.manager.getRepository(State);
|
||||
|
||||
return this._baseDatabase.saveOrUpdateState(repo, state);
|
||||
}
|
||||
|
||||
async removeStates (dbTx: QueryRunner, blockNumber: number, kind: string): Promise<void> {
|
||||
const repo = dbTx.manager.getRepository(State);
|
||||
|
||||
await this._baseDatabase.removeStates(repo, blockNumber, kind);
|
||||
}
|
||||
|
||||
async removeStatesAfterBlock (dbTx: QueryRunner, blockNumber: number): Promise<void> {
|
||||
const repo = dbTx.manager.getRepository(State);
|
||||
|
||||
await this._baseDatabase.removeStatesAfterBlock(repo, blockNumber);
|
||||
}
|
||||
|
||||
async getStateSyncStatus (): Promise<StateSyncStatus | undefined> {
|
||||
const repo = this._conn.getRepository(StateSyncStatus);
|
||||
|
||||
return this._baseDatabase.getStateSyncStatus(repo);
|
||||
}
|
||||
|
||||
async updateStateSyncStatusIndexedBlock (queryRunner: QueryRunner, blockNumber: number, force?: boolean): Promise<StateSyncStatus> {
|
||||
const repo = queryRunner.manager.getRepository(StateSyncStatus);
|
||||
|
||||
return this._baseDatabase.updateStateSyncStatusIndexedBlock(repo, blockNumber, force);
|
||||
}
|
||||
|
||||
async updateStateSyncStatusCheckpointBlock (queryRunner: QueryRunner, blockNumber: number, force?: boolean): Promise<StateSyncStatus> {
|
||||
const repo = queryRunner.manager.getRepository(StateSyncStatus);
|
||||
|
||||
return this._baseDatabase.updateStateSyncStatusCheckpointBlock(repo, blockNumber, force);
|
||||
}
|
||||
|
||||
async getContracts (): Promise<Contract[]> {
|
||||
const repo = this._conn.getRepository(Contract);
|
||||
|
||||
return this._baseDatabase.getContracts(repo);
|
||||
}
|
||||
|
||||
async createTransactionRunner (): Promise<QueryRunner> {
|
||||
return this._baseDatabase.createTransactionRunner();
|
||||
}
|
||||
|
||||
async getProcessedBlockCountForRange (fromBlockNumber: number, toBlockNumber: number): Promise<{ expected: number, actual: number }> {
|
||||
const repo = this._conn.getRepository(BlockProgress);
|
||||
|
||||
return this._baseDatabase.getProcessedBlockCountForRange(repo, fromBlockNumber, toBlockNumber);
|
||||
}
|
||||
|
||||
async getEventsInRange (fromBlockNumber: number, toBlockNumber: number): Promise<Array<Event>> {
|
||||
const repo = this._conn.getRepository(Event);
|
||||
|
||||
return this._baseDatabase.getEventsInRange(repo, fromBlockNumber, toBlockNumber);
|
||||
}
|
||||
|
||||
async saveEventEntity (queryRunner: QueryRunner, entity: Event): Promise<Event> {
|
||||
const repo = queryRunner.manager.getRepository(Event);
|
||||
return this._baseDatabase.saveEventEntity(repo, entity);
|
||||
}
|
||||
|
||||
async getBlockEvents (blockHash: string, where: Where, queryOptions: QueryOptions): Promise<Event[]> {
|
||||
const repo = this._conn.getRepository(Event);
|
||||
|
||||
return this._baseDatabase.getBlockEvents(repo, blockHash, where, queryOptions);
|
||||
}
|
||||
|
||||
async saveBlockWithEvents (queryRunner: QueryRunner, block: DeepPartial<BlockProgress>, events: DeepPartial<Event>[]): Promise<BlockProgress> {
|
||||
const blockRepo = queryRunner.manager.getRepository(BlockProgress);
|
||||
const eventRepo = queryRunner.manager.getRepository(Event);
|
||||
|
||||
return this._baseDatabase.saveBlockWithEvents(blockRepo, eventRepo, block, events);
|
||||
}
|
||||
|
||||
async saveEvents (queryRunner: QueryRunner, events: Event[]): Promise<void> {
|
||||
const eventRepo = queryRunner.manager.getRepository(Event);
|
||||
|
||||
return this._baseDatabase.saveEvents(eventRepo, events);
|
||||
}
|
||||
|
||||
async saveBlockProgress (queryRunner: QueryRunner, block: DeepPartial<BlockProgress>): Promise<BlockProgress> {
|
||||
const repo = queryRunner.manager.getRepository(BlockProgress);
|
||||
|
||||
return this._baseDatabase.saveBlockProgress(repo, block);
|
||||
}
|
||||
|
||||
async saveContract (queryRunner: QueryRunner, address: string, kind: string, checkpoint: boolean, startingBlock: number): Promise<Contract> {
|
||||
const repo = queryRunner.manager.getRepository(Contract);
|
||||
|
||||
return this._baseDatabase.saveContract(repo, address, kind, checkpoint, startingBlock);
|
||||
}
|
||||
|
||||
async updateSyncStatusIndexedBlock (queryRunner: QueryRunner, blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
||||
const repo = queryRunner.manager.getRepository(SyncStatus);
|
||||
|
||||
return this._baseDatabase.updateSyncStatusIndexedBlock(repo, blockHash, blockNumber, force);
|
||||
}
|
||||
|
||||
async updateSyncStatusCanonicalBlock (queryRunner: QueryRunner, blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
||||
const repo = queryRunner.manager.getRepository(SyncStatus);
|
||||
|
||||
return this._baseDatabase.updateSyncStatusCanonicalBlock(repo, blockHash, blockNumber, force);
|
||||
}
|
||||
|
||||
async updateSyncStatusChainHead (queryRunner: QueryRunner, blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
||||
const repo = queryRunner.manager.getRepository(SyncStatus);
|
||||
|
||||
return this._baseDatabase.updateSyncStatusChainHead(repo, blockHash, blockNumber, force);
|
||||
}
|
||||
|
||||
async getSyncStatus (queryRunner: QueryRunner): Promise<SyncStatus | undefined> {
|
||||
const repo = queryRunner.manager.getRepository(SyncStatus);
|
||||
|
||||
return this._baseDatabase.getSyncStatus(repo);
|
||||
}
|
||||
|
||||
async getEvent (id: string): Promise<Event | undefined> {
|
||||
const repo = this._conn.getRepository(Event);
|
||||
|
||||
return this._baseDatabase.getEvent(repo, id);
|
||||
}
|
||||
|
||||
async getBlocksAtHeight (height: number, isPruned: boolean): Promise<BlockProgress[]> {
|
||||
const repo = this._conn.getRepository(BlockProgress);
|
||||
|
||||
return this._baseDatabase.getBlocksAtHeight(repo, height, isPruned);
|
||||
}
|
||||
|
||||
async markBlocksAsPruned (queryRunner: QueryRunner, blocks: BlockProgress[]): Promise<void> {
|
||||
const repo = queryRunner.manager.getRepository(BlockProgress);
|
||||
|
||||
return this._baseDatabase.markBlocksAsPruned(repo, blocks);
|
||||
}
|
||||
|
||||
async getBlockProgress (blockHash: string): Promise<BlockProgress | undefined> {
|
||||
const repo = this._conn.getRepository(BlockProgress);
|
||||
return this._baseDatabase.getBlockProgress(repo, blockHash);
|
||||
}
|
||||
|
||||
async getBlockProgressEntities (where: FindConditions<BlockProgress>, options: FindManyOptions<BlockProgress>): Promise<BlockProgress[]> {
|
||||
const repo = this._conn.getRepository(BlockProgress);
|
||||
|
||||
return this._baseDatabase.getBlockProgressEntities(repo, where, options);
|
||||
}
|
||||
|
||||
async getEntitiesForBlock (blockHash: string, tableName: string): Promise<any[]> {
|
||||
return this._baseDatabase.getEntitiesForBlock(blockHash, tableName);
|
||||
}
|
||||
|
||||
async updateBlockProgress (queryRunner: QueryRunner, block: BlockProgress, lastProcessedEventIndex: number): Promise<BlockProgress> {
|
||||
const repo = queryRunner.manager.getRepository(BlockProgress);
|
||||
|
||||
return this._baseDatabase.updateBlockProgress(repo, block, lastProcessedEventIndex);
|
||||
}
|
||||
|
||||
async removeEntities<Entity> (queryRunner: QueryRunner, entity: new () => Entity, findConditions?: FindManyOptions<Entity> | FindConditions<Entity>): Promise<void> {
|
||||
return this._baseDatabase.removeEntities(queryRunner, entity, findConditions);
|
||||
}
|
||||
|
||||
async deleteEntitiesByConditions<Entity> (queryRunner: QueryRunner, entity: EntityTarget<Entity>, findConditions: FindConditions<Entity>): Promise<void> {
|
||||
await this._baseDatabase.deleteEntitiesByConditions(queryRunner, entity, findConditions);
|
||||
}
|
||||
|
||||
async getAncestorAtDepth (blockHash: string, depth: number): Promise<string> {
|
||||
return this._baseDatabase.getAncestorAtDepth(blockHash, depth);
|
||||
}
|
||||
|
||||
_getPropertyColumnMapForEntity (entityName: string): Map<string, string> {
|
||||
return this._conn.getMetadata(entityName).ownColumns.reduce((acc, curr) => {
|
||||
return acc.set(curr.propertyName, curr.databaseName);
|
||||
}, new Map<string, string>());
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
|
||||
import { bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Account {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
totalClaimed!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
totalSlashed!: bigint;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
import { bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Block {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('boolean')
|
||||
fromActiveProducer!: boolean;
|
||||
|
||||
@Column('varchar')
|
||||
hash!: string;
|
||||
|
||||
@Column('varchar')
|
||||
parentHash!: string;
|
||||
|
||||
@Column('varchar')
|
||||
unclesHash!: string;
|
||||
|
||||
@Column('varchar')
|
||||
author!: string;
|
||||
|
||||
@Column('varchar')
|
||||
stateRoot!: string;
|
||||
|
||||
@Column('varchar')
|
||||
transactionsRoot!: string;
|
||||
|
||||
@Column('varchar')
|
||||
receiptsRoot!: string;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
number!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
gasUsed!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
gasLimit!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
timestamp!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
difficulty!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
totalDifficulty!: bigint;
|
||||
|
||||
@Column('numeric', { nullable: true, transformer: bigintTransformer })
|
||||
size!: bigint;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryGeneratedColumn, Column, Index, CreateDateColumn } from 'typeorm';
|
||||
import { BlockProgressInterface } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockHash'], { unique: true })
|
||||
@Index(['blockNumber'])
|
||||
@Index(['parentHash'])
|
||||
export class BlockProgress implements BlockProgressInterface {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: number;
|
||||
|
||||
@Column('varchar')
|
||||
cid!: string;
|
||||
|
||||
@Column('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('varchar', { length: 66 })
|
||||
parentHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('integer')
|
||||
blockTimestamp!: number;
|
||||
|
||||
@Column('integer')
|
||||
numEvents!: number;
|
||||
|
||||
@Column('integer')
|
||||
numProcessedEvents!: number;
|
||||
|
||||
@Column('integer')
|
||||
lastProcessedEventIndex!: number;
|
||||
|
||||
@Column('boolean')
|
||||
isComplete!: boolean;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt!: Date;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
|
||||
import { bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Claim {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
timestamp!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
index!: bigint;
|
||||
|
||||
@Column('varchar')
|
||||
account!: string;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
totalEarned!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
claimed!: bigint;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryGeneratedColumn, Column, Index } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
@Index(['address'], { unique: true })
|
||||
export class Contract {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: number;
|
||||
|
||||
@Column('varchar', { length: 42 })
|
||||
address!: string;
|
||||
|
||||
@Column('varchar')
|
||||
kind!: string;
|
||||
|
||||
@Column('boolean')
|
||||
checkpoint!: boolean;
|
||||
|
||||
@Column('integer')
|
||||
startingBlock!: number;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
|
||||
import { bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Distribution {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('varchar')
|
||||
distributor!: string;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
timestamp!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
distributionNumber!: bigint;
|
||||
|
||||
@Column('varchar')
|
||||
merkleRoot!: string;
|
||||
|
||||
@Column('varchar')
|
||||
metadataURI!: string;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Distributor {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
currentDistribution!: string;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
import Decimal from 'decimal.js';
|
||||
|
||||
import { bigintTransformer, decimalTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Epoch {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('boolean')
|
||||
finalized!: boolean;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
epochNumber!: bigint;
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
startBlock!: string;
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
endBlock!: string;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
producerBlocks!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
allBlocks!: bigint;
|
||||
|
||||
@Column('numeric', { default: 0, transformer: decimalTransformer })
|
||||
producerBlocksRatio!: Decimal;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryGeneratedColumn, Column, Index, ManyToOne } from 'typeorm';
|
||||
import { BlockProgress } from './BlockProgress';
|
||||
|
||||
@Entity()
|
||||
@Index(['block', 'contract'])
|
||||
@Index(['block', 'contract', 'eventName'])
|
||||
export class Event {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: number;
|
||||
|
||||
@ManyToOne(() => BlockProgress, { onDelete: 'CASCADE' })
|
||||
block!: BlockProgress;
|
||||
|
||||
@Column('varchar', { length: 66 })
|
||||
txHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
index!: number;
|
||||
|
||||
@Column('varchar', { length: 42 })
|
||||
contract!: string;
|
||||
|
||||
@Column('varchar', { length: 256 })
|
||||
eventName!: string;
|
||||
|
||||
@Column('text')
|
||||
eventInfo!: string;
|
||||
|
||||
@Column('text')
|
||||
extraInfo!: string;
|
||||
|
||||
@Column('text')
|
||||
proof!: string;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class FrothyEntity {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar')
|
||||
name!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
|
||||
import { bigintArrayTransformer, bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Network {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
slot0!: string;
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
slot1!: string;
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
slot2!: string;
|
||||
|
||||
@Column('varchar', { array: true })
|
||||
stakers!: string[];
|
||||
|
||||
@Column('numeric', { nullable: true, transformer: bigintTransformer })
|
||||
numStakers!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
totalStaked!: bigint;
|
||||
|
||||
// https://github.com/brianc/node-postgres/issues/1943#issuecomment-520500053
|
||||
@Column('varchar', { transformer: bigintArrayTransformer, array: true })
|
||||
stakedPercentiles!: bigint[];
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
import { bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Producer {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('boolean')
|
||||
active!: boolean;
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
rewardCollector!: string;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
rewards!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
confirmedBlocks!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
pendingEpochBlocks!: bigint;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
import Decimal from 'decimal.js';
|
||||
|
||||
import { bigintTransformer, decimalTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class ProducerEpoch {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('varchar')
|
||||
address!: string;
|
||||
|
||||
@Column('varchar')
|
||||
epoch!: string;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
totalRewards!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
blocksProduced!: bigint;
|
||||
|
||||
@Column('numeric', { default: 0, transformer: decimalTransformer })
|
||||
blocksProducedRatio!: Decimal;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
import { bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class ProducerRewardCollectorChange {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
_blockNumber!: bigint;
|
||||
|
||||
@Column('varchar')
|
||||
producer!: string;
|
||||
|
||||
@Column('varchar')
|
||||
rewardCollector!: string;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class ProducerSet {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('varchar', { array: true })
|
||||
producers!: string[];
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
import { bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
enum ProducerSetChangeType {
|
||||
Added = 'Added',
|
||||
Removed = 'Removed'
|
||||
}
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class ProducerSetChange {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
_blockNumber!: bigint;
|
||||
|
||||
@Column('varchar')
|
||||
producer!: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: ProducerSetChangeType
|
||||
})
|
||||
changeType!: ProducerSetChangeType;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class RewardSchedule {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('varchar', { array: true })
|
||||
rewardScheduleEntries!: string[];
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
lastEpoch!: string;
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
pendingEpoch!: string;
|
||||
|
||||
@Column('varchar', { nullable: true })
|
||||
activeRewardScheduleEntry!: string;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
import { bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class RewardScheduleEntry {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
startTime!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
epochDuration!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
rewardsPerEpoch!: bigint;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
|
||||
import { bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Slash {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
timestamp!: bigint;
|
||||
|
||||
@Column('varchar')
|
||||
account!: string;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
slashed!: bigint;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
import Decimal from 'decimal.js';
|
||||
|
||||
import { bigintTransformer, decimalTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Slot {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('varchar')
|
||||
owner!: string;
|
||||
|
||||
@Column('varchar')
|
||||
delegate!: string;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
winningBid!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
oldBid!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
startTime!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
expirationTime!: bigint;
|
||||
|
||||
@Column('numeric', { default: 0, transformer: decimalTransformer })
|
||||
taxRatePerDay!: Decimal;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
import Decimal from 'decimal.js';
|
||||
|
||||
import { bigintTransformer, decimalTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class SlotClaim {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('varchar')
|
||||
slot!: string;
|
||||
|
||||
@Column('varchar')
|
||||
owner!: string;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
winningBid!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
oldBid!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
startTime!: bigint;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
expirationTime!: bigint;
|
||||
|
||||
@Column('numeric', { default: 0, transformer: decimalTransformer })
|
||||
taxRatePerDay!: Decimal;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryColumn, Column, Index } from 'typeorm';
|
||||
import { bigintTransformer } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
@Index(['blockNumber'])
|
||||
export class Staker {
|
||||
@PrimaryColumn('varchar')
|
||||
id!: string;
|
||||
|
||||
@PrimaryColumn('varchar', { length: 66 })
|
||||
blockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
blockNumber!: number;
|
||||
|
||||
@Column('numeric', { transformer: bigintTransformer })
|
||||
staked!: bigint;
|
||||
|
||||
@Column('numeric', { nullable: true, transformer: bigintTransformer })
|
||||
rank!: bigint;
|
||||
|
||||
@Column('boolean', { default: false })
|
||||
isPruned!: boolean;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryGeneratedColumn, Column, Index, ManyToOne } from 'typeorm';
|
||||
|
||||
import { StateKind } from '@cerc-io/util';
|
||||
|
||||
import { BlockProgress } from './BlockProgress';
|
||||
|
||||
@Entity()
|
||||
@Index(['cid'], { unique: true })
|
||||
@Index(['block', 'contractAddress'])
|
||||
@Index(['block', 'contractAddress', 'kind'], { unique: true })
|
||||
export class State {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: number;
|
||||
|
||||
@ManyToOne(() => BlockProgress, { onDelete: 'CASCADE' })
|
||||
block!: BlockProgress;
|
||||
|
||||
@Column('varchar', { length: 42 })
|
||||
contractAddress!: string;
|
||||
|
||||
@Column('varchar')
|
||||
cid!: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: StateKind
|
||||
})
|
||||
kind!: StateKind;
|
||||
|
||||
@Column('bytea')
|
||||
data!: Buffer;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
export class StateSyncStatus {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: number;
|
||||
|
||||
@Column('integer')
|
||||
latestIndexedBlockNumber!: number;
|
||||
|
||||
@Column('integer', { nullable: true })
|
||||
latestCheckpointBlockNumber!: number;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { EventSubscriber, EntitySubscriberInterface, InsertEvent, UpdateEvent } from 'typeorm';
|
||||
|
||||
import { afterEntityInsertOrUpdate } from '@cerc-io/util';
|
||||
|
||||
import { FrothyEntity } from './FrothyEntity';
|
||||
import { ENTITY_TO_LATEST_ENTITY_MAP, SUBGRAPH_ENTITIES } from '../database';
|
||||
|
||||
@EventSubscriber()
|
||||
export class EntitySubscriber implements EntitySubscriberInterface {
|
||||
async afterInsert (event: InsertEvent<any>): Promise<void> {
|
||||
await afterEntityInsertOrUpdate(FrothyEntity, SUBGRAPH_ENTITIES, event, ENTITY_TO_LATEST_ENTITY_MAP);
|
||||
}
|
||||
|
||||
async afterUpdate (event: UpdateEvent<any>): Promise<void> {
|
||||
await afterEntityInsertOrUpdate(FrothyEntity, SUBGRAPH_ENTITIES, event, ENTITY_TO_LATEST_ENTITY_MAP);
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
|
||||
import { SyncStatusInterface } from '@cerc-io/util';
|
||||
|
||||
@Entity()
|
||||
export class SyncStatus implements SyncStatusInterface {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: number;
|
||||
|
||||
@Column('varchar', { length: 66 })
|
||||
chainHeadBlockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
chainHeadBlockNumber!: number;
|
||||
|
||||
@Column('varchar', { length: 66 })
|
||||
latestIndexedBlockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
latestIndexedBlockNumber!: number;
|
||||
|
||||
@Column('varchar', { length: 66 })
|
||||
latestCanonicalBlockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
latestCanonicalBlockNumber!: number;
|
||||
|
||||
@Column('varchar', { length: 66 })
|
||||
initialIndexedBlockHash!: string;
|
||||
|
||||
@Column('integer')
|
||||
initialIndexedBlockNumber!: number;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import 'reflect-metadata';
|
||||
import debug from 'debug';
|
||||
|
||||
import { FillCmd } from '@cerc-io/cli';
|
||||
import { getContractEntitiesMap } from '@cerc-io/util';
|
||||
import { getGraphDbAndWatcher } from '@cerc-io/graph-node';
|
||||
|
||||
import { Database, ENTITY_QUERY_TYPE_MAP, ENTITY_TO_LATEST_ENTITY_MAP } from './database';
|
||||
import { Indexer } from './indexer';
|
||||
|
||||
const log = debug('vulcanize:fill');
|
||||
|
||||
export const main = async (): Promise<any> => {
|
||||
const fillCmd = new FillCmd();
|
||||
await fillCmd.init(Database);
|
||||
|
||||
const { graphWatcher } = await getGraphDbAndWatcher(
|
||||
fillCmd.config.server,
|
||||
fillCmd.clients.ethClient,
|
||||
fillCmd.ethProvider,
|
||||
fillCmd.database.baseDatabase,
|
||||
ENTITY_QUERY_TYPE_MAP,
|
||||
ENTITY_TO_LATEST_ENTITY_MAP
|
||||
);
|
||||
|
||||
await fillCmd.initIndexer(Indexer, graphWatcher);
|
||||
|
||||
// Get contractEntitiesMap required for fill-state
|
||||
// NOTE: Assuming each entity type is only mapped to a single contract
|
||||
// This is true for eden subgraph; may not be the case for other subgraphs
|
||||
const contractEntitiesMap = getContractEntitiesMap(graphWatcher.dataSources);
|
||||
|
||||
await fillCmd.exec(contractEntitiesMap);
|
||||
};
|
||||
|
||||
main().catch(err => {
|
||||
log(err);
|
||||
}).finally(() => {
|
||||
process.exit();
|
||||
});
|
@ -1,3 +0,0 @@
|
||||
export * as mutations from './mutations';
|
||||
export * as queries from './queries';
|
||||
export * as subscriptions from './subscriptions';
|
@ -1,4 +0,0 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export const watchContract = fs.readFileSync(path.join(__dirname, 'watchContract.gql'), 'utf8');
|
@ -1,3 +0,0 @@
|
||||
mutation watchContract($address: String!, $kind: String!, $checkpoint: Boolean!, $startingBlock: Int){
|
||||
watchContract(address: $address, kind: $kind, checkpoint: $checkpoint, startingBlock: $startingBlock)
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
query account($id: String!, $block: Block_height){
|
||||
account(id: $id, block: $block){
|
||||
id
|
||||
totalClaimed
|
||||
totalSlashed
|
||||
claims{
|
||||
id
|
||||
timestamp
|
||||
index
|
||||
totalEarned
|
||||
claimed
|
||||
}
|
||||
slashes{
|
||||
id
|
||||
timestamp
|
||||
slashed
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
query block($id: String!, $block: Block_height){
|
||||
block(id: $id, block: $block){
|
||||
id
|
||||
fromActiveProducer
|
||||
hash
|
||||
parentHash
|
||||
unclesHash
|
||||
author
|
||||
stateRoot
|
||||
transactionsRoot
|
||||
receiptsRoot
|
||||
number
|
||||
gasUsed
|
||||
gasLimit
|
||||
timestamp
|
||||
difficulty
|
||||
totalDifficulty
|
||||
size
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
query claim($id: String!, $block: Block_height){
|
||||
claim(id: $id, block: $block){
|
||||
id
|
||||
timestamp
|
||||
index
|
||||
account{
|
||||
id
|
||||
totalClaimed
|
||||
totalSlashed
|
||||
}
|
||||
totalEarned
|
||||
claimed
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
query distribution($id: String!, $block: Block_height){
|
||||
distribution(id: $id, block: $block){
|
||||
id
|
||||
distributor{
|
||||
id
|
||||
}
|
||||
timestamp
|
||||
distributionNumber
|
||||
merkleRoot
|
||||
metadataURI
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
query distributor($id: String!, $block: Block_height){
|
||||
distributor(id: $id, block: $block){
|
||||
id
|
||||
currentDistribution{
|
||||
id
|
||||
timestamp
|
||||
distributionNumber
|
||||
merkleRoot
|
||||
metadataURI
|
||||
}
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
query epoch($id: String!, $block: Block_height){
|
||||
epoch(id: $id, block: $block){
|
||||
id
|
||||
finalized
|
||||
epochNumber
|
||||
startBlock{
|
||||
id
|
||||
fromActiveProducer
|
||||
hash
|
||||
parentHash
|
||||
unclesHash
|
||||
author
|
||||
stateRoot
|
||||
transactionsRoot
|
||||
receiptsRoot
|
||||
number
|
||||
gasUsed
|
||||
gasLimit
|
||||
timestamp
|
||||
difficulty
|
||||
totalDifficulty
|
||||
size
|
||||
}
|
||||
endBlock{
|
||||
id
|
||||
fromActiveProducer
|
||||
hash
|
||||
parentHash
|
||||
unclesHash
|
||||
author
|
||||
stateRoot
|
||||
transactionsRoot
|
||||
receiptsRoot
|
||||
number
|
||||
gasUsed
|
||||
gasLimit
|
||||
timestamp
|
||||
difficulty
|
||||
totalDifficulty
|
||||
size
|
||||
}
|
||||
producerBlocks
|
||||
allBlocks
|
||||
producerBlocksRatio
|
||||
producerRewards{
|
||||
id
|
||||
address
|
||||
totalRewards
|
||||
blocksProduced
|
||||
blocksProducedRatio
|
||||
}
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
query events($blockHash: String!, $contractAddress: String!, $name: String){
|
||||
events(blockHash: $blockHash, contractAddress: $contractAddress, name: $name){
|
||||
block{
|
||||
cid
|
||||
hash
|
||||
number
|
||||
timestamp
|
||||
parentHash
|
||||
}
|
||||
tx{
|
||||
hash
|
||||
index
|
||||
from
|
||||
to
|
||||
}
|
||||
contract
|
||||
eventIndex
|
||||
event{
|
||||
... on TransferEvent {
|
||||
from
|
||||
to
|
||||
value
|
||||
}
|
||||
... on ApprovalEvent {
|
||||
owner
|
||||
spender
|
||||
value
|
||||
}
|
||||
... on AuthorizationUsedEvent {
|
||||
authorizer
|
||||
nonce
|
||||
}
|
||||
... on AdminUpdatedEvent {
|
||||
newAdmin
|
||||
oldAdmin
|
||||
}
|
||||
... on TaxRateUpdatedEvent {
|
||||
newNumerator
|
||||
newDenominator
|
||||
oldNumerator
|
||||
oldDenominator
|
||||
}
|
||||
... on SlotClaimedEvent {
|
||||
slot
|
||||
owner
|
||||
delegate
|
||||
newBidAmount
|
||||
oldBidAmount
|
||||
taxNumerator
|
||||
taxDenominator
|
||||
}
|
||||
... on SlotDelegateUpdatedEvent {
|
||||
slot
|
||||
owner
|
||||
newDelegate
|
||||
oldDelegate
|
||||
}
|
||||
... on StakeEvent {
|
||||
staker
|
||||
stakeAmount
|
||||
}
|
||||
... on UnstakeEvent {
|
||||
staker
|
||||
unstakedAmount
|
||||
}
|
||||
... on WithdrawEvent {
|
||||
withdrawer
|
||||
withdrawalAmount
|
||||
}
|
||||
... on ApprovalForAllEvent {
|
||||
owner
|
||||
operator
|
||||
approved
|
||||
}
|
||||
... on BlockProducerAddedEvent {
|
||||
producer
|
||||
}
|
||||
... on BlockProducerRemovedEvent {
|
||||
producer
|
||||
}
|
||||
... on BlockProducerRewardCollectorChangedEvent {
|
||||
producer
|
||||
collector
|
||||
}
|
||||
... on RewardScheduleChangedEvent {
|
||||
dummy
|
||||
}
|
||||
... on ClaimedEvent {
|
||||
index
|
||||
totalEarned
|
||||
account
|
||||
claimed
|
||||
}
|
||||
... on SlashedEvent {
|
||||
account
|
||||
slashed
|
||||
}
|
||||
... on MerkleRootUpdatedEvent {
|
||||
merkleRoot
|
||||
distributionNumber
|
||||
metadataURI
|
||||
}
|
||||
... on AccountUpdatedEvent {
|
||||
account
|
||||
totalClaimed
|
||||
totalSlashed
|
||||
}
|
||||
... on PermanentURIEvent {
|
||||
value
|
||||
id
|
||||
}
|
||||
... on GovernanceChangedEvent {
|
||||
from
|
||||
to
|
||||
}
|
||||
... on UpdateThresholdChangedEvent {
|
||||
updateThreshold
|
||||
}
|
||||
... on RoleAdminChangedEvent {
|
||||
role
|
||||
previousAdminRole
|
||||
newAdminRole
|
||||
}
|
||||
... on RoleGrantedEvent {
|
||||
role
|
||||
account
|
||||
sender
|
||||
}
|
||||
... on RoleRevokedEvent {
|
||||
role
|
||||
account
|
||||
sender
|
||||
}
|
||||
}
|
||||
proof{
|
||||
data
|
||||
}
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
query eventsInRange($fromBlockNumber: Int!, $toBlockNumber: Int!){
|
||||
eventsInRange(fromBlockNumber: $fromBlockNumber, toBlockNumber: $toBlockNumber){
|
||||
block{
|
||||
cid
|
||||
hash
|
||||
number
|
||||
timestamp
|
||||
parentHash
|
||||
}
|
||||
tx{
|
||||
hash
|
||||
index
|
||||
from
|
||||
to
|
||||
}
|
||||
contract
|
||||
eventIndex
|
||||
event{
|
||||
... on TransferEvent {
|
||||
from
|
||||
to
|
||||
value
|
||||
}
|
||||
... on ApprovalEvent {
|
||||
owner
|
||||
spender
|
||||
value
|
||||
}
|
||||
... on AuthorizationUsedEvent {
|
||||
authorizer
|
||||
nonce
|
||||
}
|
||||
... on AdminUpdatedEvent {
|
||||
newAdmin
|
||||
oldAdmin
|
||||
}
|
||||
... on TaxRateUpdatedEvent {
|
||||
newNumerator
|
||||
newDenominator
|
||||
oldNumerator
|
||||
oldDenominator
|
||||
}
|
||||
... on SlotClaimedEvent {
|
||||
slot
|
||||
owner
|
||||
delegate
|
||||
newBidAmount
|
||||
oldBidAmount
|
||||
taxNumerator
|
||||
taxDenominator
|
||||
}
|
||||
... on SlotDelegateUpdatedEvent {
|
||||
slot
|
||||
owner
|
||||
newDelegate
|
||||
oldDelegate
|
||||
}
|
||||
... on StakeEvent {
|
||||
staker
|
||||
stakeAmount
|
||||
}
|
||||
... on UnstakeEvent {
|
||||
staker
|
||||
unstakedAmount
|
||||
}
|
||||
... on WithdrawEvent {
|
||||
withdrawer
|
||||
withdrawalAmount
|
||||
}
|
||||
... on ApprovalForAllEvent {
|
||||
owner
|
||||
operator
|
||||
approved
|
||||
}
|
||||
... on BlockProducerAddedEvent {
|
||||
producer
|
||||
}
|
||||
... on BlockProducerRemovedEvent {
|
||||
producer
|
||||
}
|
||||
... on BlockProducerRewardCollectorChangedEvent {
|
||||
producer
|
||||
collector
|
||||
}
|
||||
... on RewardScheduleChangedEvent {
|
||||
dummy
|
||||
}
|
||||
... on ClaimedEvent {
|
||||
index
|
||||
totalEarned
|
||||
account
|
||||
claimed
|
||||
}
|
||||
... on SlashedEvent {
|
||||
account
|
||||
slashed
|
||||
}
|
||||
... on MerkleRootUpdatedEvent {
|
||||
merkleRoot
|
||||
distributionNumber
|
||||
metadataURI
|
||||
}
|
||||
... on AccountUpdatedEvent {
|
||||
account
|
||||
totalClaimed
|
||||
totalSlashed
|
||||
}
|
||||
... on PermanentURIEvent {
|
||||
value
|
||||
id
|
||||
}
|
||||
... on GovernanceChangedEvent {
|
||||
from
|
||||
to
|
||||
}
|
||||
... on UpdateThresholdChangedEvent {
|
||||
updateThreshold
|
||||
}
|
||||
... on RoleAdminChangedEvent {
|
||||
role
|
||||
previousAdminRole
|
||||
newAdminRole
|
||||
}
|
||||
... on RoleGrantedEvent {
|
||||
role
|
||||
account
|
||||
sender
|
||||
}
|
||||
... on RoleRevokedEvent {
|
||||
role
|
||||
account
|
||||
sender
|
||||
}
|
||||
}
|
||||
proof{
|
||||
data
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
query getState($blockHash: String!, $contractAddress: String!, $kind: String){
|
||||
getState(blockHash: $blockHash, contractAddress: $contractAddress, kind: $kind){
|
||||
block{
|
||||
cid
|
||||
hash
|
||||
number
|
||||
timestamp
|
||||
parentHash
|
||||
}
|
||||
contractAddress
|
||||
cid
|
||||
kind
|
||||
data
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
query getStateByCID($cid: String!){
|
||||
getStateByCID(cid: $cid){
|
||||
block{
|
||||
cid
|
||||
hash
|
||||
number
|
||||
timestamp
|
||||
parentHash
|
||||
}
|
||||
contractAddress
|
||||
cid
|
||||
kind
|
||||
data
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export const events = fs.readFileSync(path.join(__dirname, 'events.gql'), 'utf8');
|
||||
export const eventsInRange = fs.readFileSync(path.join(__dirname, 'eventsInRange.gql'), 'utf8');
|
||||
export const producer = fs.readFileSync(path.join(__dirname, 'producer.gql'), 'utf8');
|
||||
export const producerSet = fs.readFileSync(path.join(__dirname, 'producerSet.gql'), 'utf8');
|
||||
export const producerSetChange = fs.readFileSync(path.join(__dirname, 'producerSetChange.gql'), 'utf8');
|
||||
export const producerRewardCollectorChange = fs.readFileSync(path.join(__dirname, 'producerRewardCollectorChange.gql'), 'utf8');
|
||||
export const rewardScheduleEntry = fs.readFileSync(path.join(__dirname, 'rewardScheduleEntry.gql'), 'utf8');
|
||||
export const rewardSchedule = fs.readFileSync(path.join(__dirname, 'rewardSchedule.gql'), 'utf8');
|
||||
export const producerEpoch = fs.readFileSync(path.join(__dirname, 'producerEpoch.gql'), 'utf8');
|
||||
export const epoch = fs.readFileSync(path.join(__dirname, 'epoch.gql'), 'utf8');
|
||||
export const slotClaim = fs.readFileSync(path.join(__dirname, 'slotClaim.gql'), 'utf8');
|
||||
export const slot = fs.readFileSync(path.join(__dirname, 'slot.gql'), 'utf8');
|
||||
export const staker = fs.readFileSync(path.join(__dirname, 'staker.gql'), 'utf8');
|
||||
export const network = fs.readFileSync(path.join(__dirname, 'network.gql'), 'utf8');
|
||||
export const distributor = fs.readFileSync(path.join(__dirname, 'distributor.gql'), 'utf8');
|
||||
export const distribution = fs.readFileSync(path.join(__dirname, 'distribution.gql'), 'utf8');
|
||||
export const claim = fs.readFileSync(path.join(__dirname, 'claim.gql'), 'utf8');
|
||||
export const slash = fs.readFileSync(path.join(__dirname, 'slash.gql'), 'utf8');
|
||||
export const account = fs.readFileSync(path.join(__dirname, 'account.gql'), 'utf8');
|
||||
export const getStateByCID = fs.readFileSync(path.join(__dirname, 'getStateByCID.gql'), 'utf8');
|
||||
export const getState = fs.readFileSync(path.join(__dirname, 'getState.gql'), 'utf8');
|
@ -1,43 +0,0 @@
|
||||
query network($id: String!, $block: Block_height){
|
||||
network(id: $id, block: $block){
|
||||
id
|
||||
slot0{
|
||||
id
|
||||
owner
|
||||
delegate
|
||||
winningBid
|
||||
oldBid
|
||||
startTime
|
||||
expirationTime
|
||||
taxRatePerDay
|
||||
}
|
||||
slot1{
|
||||
id
|
||||
owner
|
||||
delegate
|
||||
winningBid
|
||||
oldBid
|
||||
startTime
|
||||
expirationTime
|
||||
taxRatePerDay
|
||||
}
|
||||
slot2{
|
||||
id
|
||||
owner
|
||||
delegate
|
||||
winningBid
|
||||
oldBid
|
||||
startTime
|
||||
expirationTime
|
||||
taxRatePerDay
|
||||
}
|
||||
stakers{
|
||||
id
|
||||
staked
|
||||
rank
|
||||
}
|
||||
numStakers
|
||||
totalStaked
|
||||
stakedPercentiles
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
query producer($id: String!, $block: Block_height){
|
||||
producer(id: $id, block: $block){
|
||||
id
|
||||
active
|
||||
rewardCollector
|
||||
rewards
|
||||
confirmedBlocks
|
||||
pendingEpochBlocks
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
query producerEpoch($id: String!, $block: Block_height){
|
||||
producerEpoch(id: $id, block: $block){
|
||||
id
|
||||
address
|
||||
epoch{
|
||||
id
|
||||
finalized
|
||||
epochNumber
|
||||
producerBlocks
|
||||
allBlocks
|
||||
producerBlocksRatio
|
||||
}
|
||||
totalRewards
|
||||
blocksProduced
|
||||
blocksProducedRatio
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
query producerRewardCollectorChange($id: String!, $block: Block_height){
|
||||
producerRewardCollectorChange(id: $id, block: $block){
|
||||
id
|
||||
blockNumber
|
||||
producer
|
||||
rewardCollector
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
query producerSet($id: String!, $block: Block_height){
|
||||
producerSet(id: $id, block: $block){
|
||||
id
|
||||
producers{
|
||||
id
|
||||
active
|
||||
rewardCollector
|
||||
rewards
|
||||
confirmedBlocks
|
||||
pendingEpochBlocks
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
query producerSetChange($id: String!, $block: Block_height){
|
||||
producerSetChange(id: $id, block: $block){
|
||||
id
|
||||
blockNumber
|
||||
producer
|
||||
changeType
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
query rewardSchedule($id: String!, $block: Block_height){
|
||||
rewardSchedule(id: $id, block: $block){
|
||||
id
|
||||
rewardScheduleEntries{
|
||||
id
|
||||
startTime
|
||||
epochDuration
|
||||
rewardsPerEpoch
|
||||
}
|
||||
lastEpoch{
|
||||
id
|
||||
finalized
|
||||
epochNumber
|
||||
producerBlocks
|
||||
allBlocks
|
||||
producerBlocksRatio
|
||||
}
|
||||
pendingEpoch{
|
||||
id
|
||||
finalized
|
||||
epochNumber
|
||||
producerBlocks
|
||||
allBlocks
|
||||
producerBlocksRatio
|
||||
}
|
||||
activeRewardScheduleEntry{
|
||||
id
|
||||
startTime
|
||||
epochDuration
|
||||
rewardsPerEpoch
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
query rewardScheduleEntry($id: String!, $block: Block_height){
|
||||
rewardScheduleEntry(id: $id, block: $block){
|
||||
id
|
||||
startTime
|
||||
epochDuration
|
||||
rewardsPerEpoch
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
query slash($id: String!, $block: Block_height){
|
||||
slash(id: $id, block: $block){
|
||||
id
|
||||
timestamp
|
||||
account{
|
||||
id
|
||||
totalClaimed
|
||||
totalSlashed
|
||||
}
|
||||
slashed
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
query slot($id: String!, $block: Block_height){
|
||||
slot(id: $id, block: $block){
|
||||
id
|
||||
owner
|
||||
delegate
|
||||
winningBid
|
||||
oldBid
|
||||
startTime
|
||||
expirationTime
|
||||
taxRatePerDay
|
||||
claims{
|
||||
id
|
||||
owner
|
||||
winningBid
|
||||
oldBid
|
||||
startTime
|
||||
expirationTime
|
||||
taxRatePerDay
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
query slotClaim($id: String!, $block: Block_height){
|
||||
slotClaim(id: $id, block: $block){
|
||||
id
|
||||
slot{
|
||||
id
|
||||
owner
|
||||
delegate
|
||||
winningBid
|
||||
oldBid
|
||||
startTime
|
||||
expirationTime
|
||||
taxRatePerDay
|
||||
}
|
||||
owner
|
||||
winningBid
|
||||
oldBid
|
||||
startTime
|
||||
expirationTime
|
||||
taxRatePerDay
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user