mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-01-23 03:29:05 +00:00
Use block number for eth_call in rpc-eth-client
(#435)
* Update subgraph readme to run fill before job-runner * Fix getContractEntitiesMap incase of template data sources * Use rpcSupportsBlockHashParam flag to use blockNumber for rpc client eth_call * Fix optional baseFeePerGas in rpc-eth-client * Fix graph-node tests after changes * Remove completed TODO
This commit is contained in:
parent
e8d8476bef
commit
07887c160e
@ -14,7 +14,7 @@ columns:
|
|||||||
columnType: PrimaryGeneratedColumn
|
columnType: PrimaryGeneratedColumn
|
||||||
- name: cid
|
- name: cid
|
||||||
pgType: varchar
|
pgType: varchar
|
||||||
tsType: string
|
tsType: string | null
|
||||||
columnType: Column
|
columnType: Column
|
||||||
columnOptions:
|
columnOptions:
|
||||||
- option: nullable
|
- option: nullable
|
||||||
|
@ -12,9 +12,6 @@ columns:
|
|||||||
pgType: integer
|
pgType: integer
|
||||||
tsType: number
|
tsType: number
|
||||||
columnType: Column
|
columnType: Column
|
||||||
columnOptions:
|
|
||||||
- option: nullable
|
|
||||||
value: true
|
|
||||||
imports:
|
imports:
|
||||||
- toImport:
|
- toImport:
|
||||||
- Entity
|
- Entity
|
||||||
|
@ -538,6 +538,8 @@ export class Entity {
|
|||||||
option: 'nullable',
|
option: 'nullable',
|
||||||
value: 'true'
|
value: 'true'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
columnObject.tsType = `${tsType} | null`;
|
||||||
}
|
}
|
||||||
|
|
||||||
entityObject.columns.push(columnObject);
|
entityObject.columns.push(columnObject);
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
# Use -1 for skipping check on block range.
|
# Use -1 for skipping check on block range.
|
||||||
maxEventsBlockRange = 1000
|
maxEventsBlockRange = 1000
|
||||||
|
|
||||||
|
# Flag to specify whether RPC endpoint supports block hash as block tag parameter
|
||||||
|
rpcSupportsBlockHashParam = true
|
||||||
|
|
||||||
# GQL cache settings
|
# GQL cache settings
|
||||||
[server.gqlCache]
|
[server.gqlCache]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
@ -116,7 +116,15 @@
|
|||||||
yarn && yarn build
|
yarn && yarn build
|
||||||
```
|
```
|
||||||
|
|
||||||
* In `packages/test-watcher`, run the job-runner:
|
* In `packages/test-watcher`, run fill for the subgraph start block:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn fill --start-block 10 --end-block 10
|
||||||
|
```
|
||||||
|
|
||||||
|
* Subgraph start block is the lowest `startBlock` in example [subgraph.yaml](../graph-node/test/subgraph/example1/subgraph.yaml)
|
||||||
|
|
||||||
|
* Run the job-runner:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn job-runner
|
yarn job-runner
|
||||||
|
@ -71,6 +71,7 @@ xdescribe('call handler in mapping code', () => {
|
|||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{
|
{
|
||||||
|
rpcSupportsBlockHashParam: true,
|
||||||
block: dummyEventData.block,
|
block: dummyEventData.block,
|
||||||
contractAddress: dummyGraphData.dataSource.address
|
contractAddress: dummyGraphData.dataSource.address
|
||||||
},
|
},
|
||||||
|
@ -33,7 +33,7 @@ describe('crypto host api', () => {
|
|||||||
db,
|
db,
|
||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{},
|
{ rpcSupportsBlockHashParam: true },
|
||||||
filePath,
|
filePath,
|
||||||
dummyGraphData
|
dummyGraphData
|
||||||
);
|
);
|
||||||
|
@ -90,6 +90,7 @@ xdescribe('eden wasm loader tests', async () => {
|
|||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{
|
{
|
||||||
|
rpcSupportsBlockHashParam: true,
|
||||||
block: dummyEventData.block,
|
block: dummyEventData.block,
|
||||||
contractAddress
|
contractAddress
|
||||||
},
|
},
|
||||||
@ -210,6 +211,7 @@ xdescribe('eden wasm loader tests', async () => {
|
|||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{
|
{
|
||||||
|
rpcSupportsBlockHashParam: true,
|
||||||
block: dummyEventData.block,
|
block: dummyEventData.block,
|
||||||
contractAddress
|
contractAddress
|
||||||
},
|
},
|
||||||
@ -328,6 +330,7 @@ xdescribe('eden wasm loader tests', async () => {
|
|||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{
|
{
|
||||||
|
rpcSupportsBlockHashParam: true,
|
||||||
block: dummyEventData.block,
|
block: dummyEventData.block,
|
||||||
contractAddress
|
contractAddress
|
||||||
},
|
},
|
||||||
|
@ -33,7 +33,7 @@ describe('ethereum ABI encode decode', () => {
|
|||||||
db,
|
db,
|
||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{},
|
{ rpcSupportsBlockHashParam: true },
|
||||||
filePath,
|
filePath,
|
||||||
dummyGraphData
|
dummyGraphData
|
||||||
);
|
);
|
||||||
|
@ -51,6 +51,7 @@ xdescribe('eth-call wasm tests', () => {
|
|||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{
|
{
|
||||||
|
rpcSupportsBlockHashParam: true,
|
||||||
block: dummyEventData.block,
|
block: dummyEventData.block,
|
||||||
contractAddress
|
contractAddress
|
||||||
},
|
},
|
||||||
|
@ -31,7 +31,7 @@ describe('json host api', () => {
|
|||||||
db,
|
db,
|
||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{},
|
{ rpcSupportsBlockHashParam: true },
|
||||||
filePath,
|
filePath,
|
||||||
dummyGraphData
|
dummyGraphData
|
||||||
);
|
);
|
||||||
|
@ -35,7 +35,7 @@ describe('wasm loader tests', () => {
|
|||||||
db,
|
db,
|
||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{},
|
{ rpcSupportsBlockHashParam: true },
|
||||||
filePath,
|
filePath,
|
||||||
dummyGraphData
|
dummyGraphData
|
||||||
);
|
);
|
||||||
@ -113,7 +113,7 @@ describe('wasm loader tests', () => {
|
|||||||
db,
|
db,
|
||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{},
|
{ rpcSupportsBlockHashParam: true },
|
||||||
module,
|
module,
|
||||||
dummyGraphData
|
dummyGraphData
|
||||||
);
|
);
|
||||||
|
@ -47,8 +47,9 @@ export interface GraphData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Context {
|
export interface Context {
|
||||||
block?: Block
|
rpcSupportsBlockHashParam: boolean;
|
||||||
contractAddress?: string
|
block?: Block;
|
||||||
|
contractAddress?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const log = debug('vulcanize:graph-node');
|
const log = debug('vulcanize:graph-node');
|
||||||
@ -173,10 +174,21 @@ export const instantiate = async (
|
|||||||
functionParams = await Promise.all(functionParamsPromise);
|
functionParams = await Promise.all(functionParamsPromise);
|
||||||
|
|
||||||
assert(context.block);
|
assert(context.block);
|
||||||
|
let result: any;
|
||||||
|
|
||||||
// TODO: Check for function overloading.
|
// TODO: Check for function overloading.
|
||||||
console.time(`time:loader#ethereum.call-${functionName}`);
|
console.time(`time:loader#ethereum.call-${functionName}`);
|
||||||
let result = await contract[functionName](...functionParams, { blockTag: context.block.blockHash });
|
if (context.rpcSupportsBlockHashParam) {
|
||||||
|
result = await contract[functionName](
|
||||||
|
...functionParams,
|
||||||
|
{ blockTag: context.block.blockHash }
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
result = await contract[functionName](
|
||||||
|
...functionParams,
|
||||||
|
{ blockTag: BigNumber.from(context.block.blockNumber).toHexString() }
|
||||||
|
);
|
||||||
|
}
|
||||||
console.timeEnd(`time:loader#ethereum.call-${functionName}`);
|
console.timeEnd(`time:loader#ethereum.call-${functionName}`);
|
||||||
|
|
||||||
// Using function signature does not work.
|
// Using function signature does not work.
|
||||||
|
@ -44,7 +44,7 @@ describe('numbers wasm tests', () => {
|
|||||||
db,
|
db,
|
||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{},
|
{ rpcSupportsBlockHashParam: true },
|
||||||
filePath,
|
filePath,
|
||||||
dummyGraphData
|
dummyGraphData
|
||||||
);
|
);
|
||||||
|
@ -52,6 +52,7 @@ xdescribe('storage-call wasm tests', () => {
|
|||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{
|
{
|
||||||
|
rpcSupportsBlockHashParam: true,
|
||||||
block: dummyEventData.block,
|
block: dummyEventData.block,
|
||||||
contractAddress
|
contractAddress
|
||||||
},
|
},
|
||||||
|
@ -33,7 +33,7 @@ describe('typeConversion wasm tests', () => {
|
|||||||
db,
|
db,
|
||||||
indexer,
|
indexer,
|
||||||
provider,
|
provider,
|
||||||
{},
|
{ rpcSupportsBlockHashParam: true },
|
||||||
filePath,
|
filePath,
|
||||||
dummyGraphData
|
dummyGraphData
|
||||||
);
|
);
|
||||||
|
@ -52,7 +52,7 @@ export class GraphWatcher {
|
|||||||
_dataSourceMap: { [key: string]: DataSource } = {};
|
_dataSourceMap: { [key: string]: DataSource } = {};
|
||||||
_transactionsMap: Map<string, Transaction> = new Map();
|
_transactionsMap: Map<string, Transaction> = new Map();
|
||||||
|
|
||||||
_context: Context = {};
|
_context: Context;
|
||||||
|
|
||||||
constructor (database: GraphDatabase, ethClient: EthClient, ethProvider: providers.BaseProvider, serverConfig: ServerConfig) {
|
constructor (database: GraphDatabase, ethClient: EthClient, ethProvider: providers.BaseProvider, serverConfig: ServerConfig) {
|
||||||
this._database = database;
|
this._database = database;
|
||||||
@ -60,6 +60,10 @@ export class GraphWatcher {
|
|||||||
this._ethProvider = ethProvider;
|
this._ethProvider = ethProvider;
|
||||||
this._subgraphPath = serverConfig.subgraphPath;
|
this._subgraphPath = serverConfig.subgraphPath;
|
||||||
this._wasmRestartBlocksInterval = serverConfig.wasmRestartBlocksInterval;
|
this._wasmRestartBlocksInterval = serverConfig.wasmRestartBlocksInterval;
|
||||||
|
|
||||||
|
this._context = {
|
||||||
|
rpcSupportsBlockHashParam: Boolean(serverConfig.rpcSupportsBlockHashParam)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async init () {
|
async init () {
|
||||||
|
@ -166,7 +166,7 @@ export class EthClient implements EthClientInterface {
|
|||||||
Extra: rawBlock.extraData,
|
Extra: rawBlock.extraData,
|
||||||
MixDigest: rawBlock.mixHash,
|
MixDigest: rawBlock.mixHash,
|
||||||
Nonce: BigInt(rawBlock.nonce),
|
Nonce: BigInt(rawBlock.nonce),
|
||||||
BaseFee: BigInt(rawBlock.baseFeePerGas)
|
BaseFee: rawBlock.baseFeePerGas ?? BigInt(rawBlock.baseFeePerGas)
|
||||||
};
|
};
|
||||||
|
|
||||||
const rlpData = encodeHeader(header);
|
const rlpData = encodeHeader(header);
|
||||||
|
@ -221,6 +221,7 @@ export interface ServerConfig {
|
|||||||
|
|
||||||
p2p: P2PConfig;
|
p2p: P2PConfig;
|
||||||
|
|
||||||
|
// TODO: Move flag to config upstream.ethServer
|
||||||
// Flag to specify whether RPC endpoint supports block hash as block tag parameter
|
// Flag to specify whether RPC endpoint supports block hash as block tag parameter
|
||||||
// https://ethereum.org/en/developers/docs/apis/json-rpc/#default-block
|
// https://ethereum.org/en/developers/docs/apis/json-rpc/#default-block
|
||||||
rpcSupportsBlockHashParam: boolean;
|
rpcSupportsBlockHashParam: boolean;
|
||||||
|
@ -151,7 +151,12 @@ export const getContractEntitiesMap = (dataSources: any[]): Map<string, string[]
|
|||||||
// Populate contractEntitiesMap using data sources from subgraph
|
// Populate contractEntitiesMap using data sources from subgraph
|
||||||
dataSources.forEach((dataSource: any) => {
|
dataSources.forEach((dataSource: any) => {
|
||||||
const { source: { address: contractAddress }, mapping: { entities } } = dataSource;
|
const { source: { address: contractAddress }, mapping: { entities } } = dataSource;
|
||||||
contractEntitiesMap.set(ethers.utils.getAddress(contractAddress), entities as string[]);
|
|
||||||
|
// TODO: Handle template data source
|
||||||
|
// TODO: Avoid mapping subgraph entities to contract address in watcher state
|
||||||
|
if (contractAddress) {
|
||||||
|
contractEntitiesMap.set(ethers.utils.getAddress(contractAddress), entities as string[]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return contractEntitiesMap;
|
return contractEntitiesMap;
|
||||||
|
@ -550,7 +550,7 @@ export const toEntityValue = async (instanceExports: any, entityInstance: any, d
|
|||||||
// Check if the entity property is nullable.
|
// Check if the entity property is nullable.
|
||||||
// No need to set the property if the value is null as well.
|
// No need to set the property if the value is null as well.
|
||||||
if (isNullable && value === null) {
|
if (isNullable && value === null) {
|
||||||
return;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const entityValue = await formatEntityValue(instanceExports, subgraphValue, type, value, isArray);
|
const entityValue = await formatEntityValue(instanceExports, subgraphValue, type, value, isArray);
|
||||||
|
@ -52,7 +52,7 @@ export interface StateStatus {
|
|||||||
|
|
||||||
export type ResultState = {
|
export type ResultState = {
|
||||||
block: {
|
block: {
|
||||||
cid: string;
|
cid: string | null;
|
||||||
hash: string;
|
hash: string;
|
||||||
number: number;
|
number: number;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
@ -66,7 +66,7 @@ export type ResultState = {
|
|||||||
|
|
||||||
export type ResultEvent = {
|
export type ResultEvent = {
|
||||||
block: {
|
block: {
|
||||||
cid: string;
|
cid: string | null;
|
||||||
hash: string;
|
hash: string;
|
||||||
number: number;
|
number: number;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
|
@ -20,7 +20,7 @@ export interface StateDataMeta {
|
|||||||
},
|
},
|
||||||
ethBlock: {
|
ethBlock: {
|
||||||
cid: {
|
cid: {
|
||||||
'/': string
|
'/': string | null
|
||||||
},
|
},
|
||||||
num: number
|
num: number
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ export enum StateKind {
|
|||||||
|
|
||||||
export interface BlockProgressInterface {
|
export interface BlockProgressInterface {
|
||||||
id: number;
|
id: number;
|
||||||
cid: string;
|
cid: string | null;
|
||||||
blockHash: string;
|
blockHash: string;
|
||||||
parentHash: string;
|
parentHash: string;
|
||||||
blockNumber: number;
|
blockNumber: number;
|
||||||
|
Loading…
Reference in New Issue
Block a user