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:
Nabarun Gogoi 2023-10-25 11:04:12 +05:30 committed by GitHub
parent e8d8476bef
commit 07887c160e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 61 additions and 23 deletions

View File

@ -14,7 +14,7 @@ columns:
columnType: PrimaryGeneratedColumn
- name: cid
pgType: varchar
tsType: string
tsType: string | null
columnType: Column
columnOptions:
- option: nullable

View File

@ -12,9 +12,6 @@ columns:
pgType: integer
tsType: number
columnType: Column
columnOptions:
- option: nullable
value: true
imports:
- toImport:
- Entity

View File

@ -538,6 +538,8 @@ export class Entity {
option: 'nullable',
value: 'true'
});
columnObject.tsType = `${tsType} | null`;
}
entityObject.columns.push(columnObject);

View File

@ -30,6 +30,9 @@
# Use -1 for skipping check on block range.
maxEventsBlockRange = 1000
# Flag to specify whether RPC endpoint supports block hash as block tag parameter
rpcSupportsBlockHashParam = true
# GQL cache settings
[server.gqlCache]
enabled = true

View File

@ -116,7 +116,15 @@
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
yarn job-runner

View File

@ -71,6 +71,7 @@ xdescribe('call handler in mapping code', () => {
indexer,
provider,
{
rpcSupportsBlockHashParam: true,
block: dummyEventData.block,
contractAddress: dummyGraphData.dataSource.address
},

View File

@ -33,7 +33,7 @@ describe('crypto host api', () => {
db,
indexer,
provider,
{},
{ rpcSupportsBlockHashParam: true },
filePath,
dummyGraphData
);

View File

@ -90,6 +90,7 @@ xdescribe('eden wasm loader tests', async () => {
indexer,
provider,
{
rpcSupportsBlockHashParam: true,
block: dummyEventData.block,
contractAddress
},
@ -210,6 +211,7 @@ xdescribe('eden wasm loader tests', async () => {
indexer,
provider,
{
rpcSupportsBlockHashParam: true,
block: dummyEventData.block,
contractAddress
},
@ -328,6 +330,7 @@ xdescribe('eden wasm loader tests', async () => {
indexer,
provider,
{
rpcSupportsBlockHashParam: true,
block: dummyEventData.block,
contractAddress
},

View File

@ -33,7 +33,7 @@ describe('ethereum ABI encode decode', () => {
db,
indexer,
provider,
{},
{ rpcSupportsBlockHashParam: true },
filePath,
dummyGraphData
);

View File

@ -51,6 +51,7 @@ xdescribe('eth-call wasm tests', () => {
indexer,
provider,
{
rpcSupportsBlockHashParam: true,
block: dummyEventData.block,
contractAddress
},

View File

@ -31,7 +31,7 @@ describe('json host api', () => {
db,
indexer,
provider,
{},
{ rpcSupportsBlockHashParam: true },
filePath,
dummyGraphData
);

View File

@ -35,7 +35,7 @@ describe('wasm loader tests', () => {
db,
indexer,
provider,
{},
{ rpcSupportsBlockHashParam: true },
filePath,
dummyGraphData
);
@ -113,7 +113,7 @@ describe('wasm loader tests', () => {
db,
indexer,
provider,
{},
{ rpcSupportsBlockHashParam: true },
module,
dummyGraphData
);

View File

@ -47,8 +47,9 @@ export interface GraphData {
}
export interface Context {
block?: Block
contractAddress?: string
rpcSupportsBlockHashParam: boolean;
block?: Block;
contractAddress?: string;
}
const log = debug('vulcanize:graph-node');
@ -173,10 +174,21 @@ export const instantiate = async (
functionParams = await Promise.all(functionParamsPromise);
assert(context.block);
let result: any;
// TODO: Check for function overloading.
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}`);
// Using function signature does not work.

View File

@ -44,7 +44,7 @@ describe('numbers wasm tests', () => {
db,
indexer,
provider,
{},
{ rpcSupportsBlockHashParam: true },
filePath,
dummyGraphData
);

View File

@ -52,6 +52,7 @@ xdescribe('storage-call wasm tests', () => {
indexer,
provider,
{
rpcSupportsBlockHashParam: true,
block: dummyEventData.block,
contractAddress
},

View File

@ -33,7 +33,7 @@ describe('typeConversion wasm tests', () => {
db,
indexer,
provider,
{},
{ rpcSupportsBlockHashParam: true },
filePath,
dummyGraphData
);

View File

@ -52,7 +52,7 @@ export class GraphWatcher {
_dataSourceMap: { [key: string]: DataSource } = {};
_transactionsMap: Map<string, Transaction> = new Map();
_context: Context = {};
_context: Context;
constructor (database: GraphDatabase, ethClient: EthClient, ethProvider: providers.BaseProvider, serverConfig: ServerConfig) {
this._database = database;
@ -60,6 +60,10 @@ export class GraphWatcher {
this._ethProvider = ethProvider;
this._subgraphPath = serverConfig.subgraphPath;
this._wasmRestartBlocksInterval = serverConfig.wasmRestartBlocksInterval;
this._context = {
rpcSupportsBlockHashParam: Boolean(serverConfig.rpcSupportsBlockHashParam)
};
}
async init () {

View File

@ -166,7 +166,7 @@ export class EthClient implements EthClientInterface {
Extra: rawBlock.extraData,
MixDigest: rawBlock.mixHash,
Nonce: BigInt(rawBlock.nonce),
BaseFee: BigInt(rawBlock.baseFeePerGas)
BaseFee: rawBlock.baseFeePerGas ?? BigInt(rawBlock.baseFeePerGas)
};
const rlpData = encodeHeader(header);

View File

@ -221,6 +221,7 @@ export interface ServerConfig {
p2p: P2PConfig;
// TODO: Move flag to config upstream.ethServer
// Flag to specify whether RPC endpoint supports block hash as block tag parameter
// https://ethereum.org/en/developers/docs/apis/json-rpc/#default-block
rpcSupportsBlockHashParam: boolean;

View File

@ -151,7 +151,12 @@ export const getContractEntitiesMap = (dataSources: any[]): Map<string, string[]
// Populate contractEntitiesMap using data sources from subgraph
dataSources.forEach((dataSource: any) => {
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;

View File

@ -550,7 +550,7 @@ export const toEntityValue = async (instanceExports: any, entityInstance: any, d
// Check if the entity property is nullable.
// No need to set the property if the value is null as well.
if (isNullable && value === null) {
return;
return value;
}
const entityValue = await formatEntityValue(instanceExports, subgraphValue, type, value, isArray);

View File

@ -52,7 +52,7 @@ export interface StateStatus {
export type ResultState = {
block: {
cid: string;
cid: string | null;
hash: string;
number: number;
timestamp: number;
@ -66,7 +66,7 @@ export type ResultState = {
export type ResultEvent = {
block: {
cid: string;
cid: string | null;
hash: string;
number: number;
timestamp: number;

View File

@ -20,7 +20,7 @@ export interface StateDataMeta {
},
ethBlock: {
cid: {
'/': string
'/': string | null
},
num: number
}

View File

@ -19,7 +19,7 @@ export enum StateKind {
export interface BlockProgressInterface {
id: number;
cid: string;
cid: string | null;
blockHash: string;
parentHash: string;
blockNumber: number;