@subql/node-ethereum 2.5.4-1 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  import { EventEmitter2 } from '@nestjs/event-emitter';
2
2
  import { SchedulerRegistry } from '@nestjs/schedule';
3
+ import { SubqlEthereumProcessorOptions } from '@subql/common-ethereum';
3
4
  import { NodeConfig, BaseFetchService } from '@subql/node-core';
4
5
  import { DictionaryQueryEntry } from '@subql/types';
5
6
  import { SubqlDatasource } from '@subql/types-ethereum';
@@ -11,6 +12,10 @@ import { DictionaryService } from './dictionary.service';
11
12
  import { DsProcessorService } from './ds-processor.service';
12
13
  import { DynamicDsService } from './dynamic-ds.service';
13
14
  import { UnfinalizedBlocksService } from './unfinalizedBlocks.service';
15
+ type GroupedSubqlProjectDs = SubqlDatasource & {
16
+ groupedOptions?: SubqlEthereumProcessorOptions[];
17
+ };
18
+ export declare function buildDictionaryQueryEntries(dataSources: GroupedSubqlProjectDs[], startBlock: number): DictionaryQueryEntry[];
14
19
  export declare class FetchService extends BaseFetchService<EthereumApiService, SubqlDatasource, IEthereumBlockDispatcher, DictionaryService> {
15
20
  private unfinalizedBlocksService;
16
21
  constructor(apiService: EthereumApiService, nodeConfig: NodeConfig, project: SubqueryProject, blockDispatcher: IEthereumBlockDispatcher, dictionaryService: DictionaryService, dsProcessorService: DsProcessorService, dynamicDsService: DynamicDsService, unfinalizedBlocksService: UnfinalizedBlocksService, eventEmitter: EventEmitter2, schedulerRegistry: SchedulerRegistry);
@@ -25,3 +30,4 @@ export declare class FetchService extends BaseFetchService<EthereumApiService, S
25
30
  protected validatateDictionaryMeta(metaData: MetaData): Promise<boolean>;
26
31
  protected preLoopHook(): Promise<void>;
27
32
  }
33
+ export {};
@@ -14,7 +14,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
14
14
  return function (target, key) { decorator(target, key, paramIndex); }
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.FetchService = void 0;
17
+ exports.FetchService = exports.buildDictionaryQueryEntries = void 0;
18
18
  const common_1 = require("@nestjs/common");
19
19
  const event_emitter_1 = require("@nestjs/event-emitter");
20
20
  const schedule_1 = require("@nestjs/schedule");
@@ -88,6 +88,13 @@ function callFilterToQueryEntry(filter) {
88
88
  matcher: 'equalTo',
89
89
  });
90
90
  }
91
+ else if (filter.to === null) {
92
+ conditions.push({
93
+ field: 'to',
94
+ value: true,
95
+ matcher: 'isNull',
96
+ });
97
+ }
91
98
  if (filter.function) {
92
99
  conditions.push({
93
100
  field: 'func',
@@ -100,6 +107,54 @@ function callFilterToQueryEntry(filter) {
100
107
  conditions,
101
108
  };
102
109
  }
110
+ function buildDictionaryQueryEntries(dataSources, startBlock) {
111
+ var _a;
112
+ const queryEntries = [];
113
+ // Only run the ds that is equal or less than startBlock
114
+ // sort array from lowest ds.startBlock to highest
115
+ const filteredDs = dataSources
116
+ .filter((ds) => ds.startBlock <= startBlock)
117
+ .sort((a, b) => a.startBlock - b.startBlock);
118
+ for (const ds of filteredDs) {
119
+ for (const handler of ds.mapping.handlers) {
120
+ // No filters, cant use dictionary
121
+ if (!handler.filter)
122
+ return [];
123
+ switch (handler.kind) {
124
+ case common_ethereum_1.EthereumHandlerKind.Block:
125
+ return [];
126
+ case common_ethereum_1.EthereumHandlerKind.Call: {
127
+ const filter = handler.filter;
128
+ if (filter.from !== undefined ||
129
+ filter.to !== undefined ||
130
+ filter.function) {
131
+ queryEntries.push(callFilterToQueryEntry(filter));
132
+ }
133
+ else {
134
+ return [];
135
+ }
136
+ break;
137
+ }
138
+ case common_ethereum_1.EthereumHandlerKind.Event: {
139
+ const filter = handler.filter;
140
+ if (ds.groupedOptions) {
141
+ queryEntries.push(eventFilterToQueryEntry(filter, ds.groupedOptions));
142
+ }
143
+ else if (((_a = ds.options) === null || _a === void 0 ? void 0 : _a.address) || filter.topics) {
144
+ queryEntries.push(eventFilterToQueryEntry(filter, ds.options));
145
+ }
146
+ else {
147
+ return [];
148
+ }
149
+ break;
150
+ }
151
+ default:
152
+ }
153
+ }
154
+ }
155
+ return (0, lodash_1.uniqBy)(queryEntries, (item) => `${item.entity}|${JSON.stringify((0, lodash_1.sortBy)(item.conditions, (c) => c.field))}`);
156
+ }
157
+ exports.buildDictionaryQueryEntries = buildDictionaryQueryEntries;
103
158
  let FetchService = class FetchService extends node_core_1.BaseFetchService {
104
159
  constructor(apiService, nodeConfig, project, blockDispatcher, dictionaryService, dsProcessorService, dynamicDsService, unfinalizedBlocksService, eventEmitter, schedulerRegistry) {
105
160
  super(apiService, nodeConfig, project, blockDispatcher, dictionaryService, dsProcessorService, dynamicDsService, eventEmitter, schedulerRegistry);
@@ -109,8 +164,6 @@ let FetchService = class FetchService extends node_core_1.BaseFetchService {
109
164
  return this.apiService.unsafeApi;
110
165
  }
111
166
  buildDictionaryQueryEntries(startBlock) {
112
- var _a;
113
- const queryEntries = [];
114
167
  const groupdDynamicDs = Object.values((0, lodash_1.groupBy)(this.templateDynamicDatasouces, (ds) => ds.name)).map((grouped) => {
115
168
  const options = grouped.map((ds) => ds.options);
116
169
  const ref = grouped[0];
@@ -118,48 +171,8 @@ let FetchService = class FetchService extends node_core_1.BaseFetchService {
118
171
  });
119
172
  // Only run the ds that is equal or less than startBlock
120
173
  // sort array from lowest ds.startBlock to highest
121
- const filteredDs = this.project.dataSources
122
- .concat(groupdDynamicDs)
123
- .filter((ds) => ds.startBlock <= startBlock)
124
- .sort((a, b) => a.startBlock - b.startBlock);
125
- for (const ds of filteredDs) {
126
- for (const handler of ds.mapping.handlers) {
127
- // No filters, cant use dictionary
128
- if (!handler.filter)
129
- return [];
130
- switch (handler.kind) {
131
- case common_ethereum_1.EthereumHandlerKind.Block:
132
- return [];
133
- case common_ethereum_1.EthereumHandlerKind.Call: {
134
- const filter = handler.filter;
135
- if (filter.from !== undefined ||
136
- filter.to !== undefined ||
137
- filter.function) {
138
- queryEntries.push(callFilterToQueryEntry(filter));
139
- }
140
- else {
141
- return [];
142
- }
143
- break;
144
- }
145
- case common_ethereum_1.EthereumHandlerKind.Event: {
146
- const filter = handler.filter;
147
- if (ds.groupedOptions) {
148
- queryEntries.push(eventFilterToQueryEntry(filter, ds.groupedOptions));
149
- }
150
- else if (((_a = ds.options) === null || _a === void 0 ? void 0 : _a.address) || filter.topics) {
151
- queryEntries.push(eventFilterToQueryEntry(filter, ds.options));
152
- }
153
- else {
154
- return [];
155
- }
156
- break;
157
- }
158
- default:
159
- }
160
- }
161
- }
162
- return (0, lodash_1.uniqBy)(queryEntries, (item) => `${item.entity}|${JSON.stringify((0, lodash_1.sortBy)(item.conditions, (c) => c.field))}`);
174
+ const filteredDs = this.project.dataSources.concat(groupdDynamicDs);
175
+ return buildDictionaryQueryEntries(filteredDs, startBlock);
163
176
  }
164
177
  async getFinalizedHeight() {
165
178
  const block = await this.api.getFinalizedBlock();
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.service.js","sourceRoot":"","sources":["../../src/indexer/fetch.service.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;;;;;;;AAEtC,2CAAoD;AACpD,yDAAsD;AACtD,+CAAqD;AAErD,4DAMgC;AAChC,gDAAgE;AAIhE,mCAAiD;AACjD,kEAA+E;AAC/E,0CAA8D;AAE9D,+DAA0D;AAC1D,4CAAkE;AAElE,6DAAyD;AACzD,iEAA4D;AAC5D,6DAAwD;AACxD,2EAGqC;AAErC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAEjC,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B,SAAS,uBAAuB,CAC9B,MAAyB,EACzB,SAA0E;IAE1E,MAAM,UAAU,GAA+B,EAAE,CAAC;IAElD,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;QAC5B,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE5E,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,IAAI,mBAAmB,EAAE;YACrE,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;SACJ;KACF;SAAM;QACL,IAAI,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,OAAO,EAAE;YACtB,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE;gBACtC,OAAO,EAAE,SAAS;aACnB,CAAC,CAAC;SACJ;KACF;IACD,IAAI,MAAM,CAAC,MAAM,EAAE;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,KAAK,EAAE;gBACV,SAAS;aACV;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC;YAC3B,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK;gBACL,KAAK,EAAE,IAAA,qBAAY,EAAC,KAAK,CAAC;gBAC1B,OAAO,EAAE,SAAS;aACnB,CAAC,CAAC;SACJ;KACF;IACD,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,UAAU;KACX,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,MAAiC;IAEjC,MAAM,UAAU,GAA+B,EAAE,CAAC;IAClD,IAAI,MAAM,CAAC,IAAI,EAAE;QACf,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE;YAChC,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;KACJ;IACD,IAAI,MAAM,CAAC,EAAE,EAAE;QACb,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE;YAC9B,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;KACJ;IACD,IAAI,MAAM,CAAC,QAAQ,EAAE;QACnB,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,IAAA,0BAAiB,EAAC,MAAM,CAAC,QAAQ,CAAC;YACzC,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;KACJ;IACD,OAAO;QACL,MAAM,EAAE,iBAAiB;QACzB,UAAU;KACX,CAAC;AACJ,CAAC;AAGM,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,4BAKjC;IACC,YACE,UAA8B,EAC9B,UAAsB,EACM,OAAwB,EAEpD,eAAyC,EACzC,iBAAoC,EACpC,kBAAsC,EACtC,gBAAkC,EAC1B,wBAAkD,EAC1D,YAA2B,EAC3B,iBAAoC;QAEpC,KAAK,CACH,UAAU,EACV,UAAU,EACV,OAAO,EACP,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,CAClB,CAAC;QAdM,6BAAwB,GAAxB,wBAAwB,CAA0B;IAe5D,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;IACnC,CAAC;IAED,2BAA2B,CAAC,UAAkB;;QAC5C,MAAM,YAAY,GAA2B,EAAE,CAAC;QAMhD,MAAM,eAAe,GAA4B,MAAM,CAAC,MAAM,CAC5D,IAAA,gBAAO,EAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CACzD,CAAC,GAAG,CAAC,CAAC,OAAyB,EAAE,EAAE;YAClC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAEvB,uCACK,GAAG,KACN,cAAc,EAAE,OAAO,IACvB;QACJ,CAAC,CAAC,CAAC;QAEH,wDAAwD;QACxD,kDAAkD;QAClD,MAAM,UAAU,GAA4B,IAAI,CAAC,OAAO,CAAC,WAAW;aACjE,MAAM,CAAC,eAAe,CAAC;aACvB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,IAAI,UAAU,CAAC;aAC3C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;QAE/C,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE;YAC3B,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACzC,kCAAkC;gBAClC,IAAI,CAAC,OAAO,CAAC,MAAM;oBAAE,OAAO,EAAE,CAAC;gBAE/B,QAAQ,OAAO,CAAC,IAAI,EAAE;oBACpB,KAAK,qCAAmB,CAAC,KAAK;wBAC5B,OAAO,EAAE,CAAC;oBACZ,KAAK,qCAAmB,CAAC,IAAI,CAAC,CAAC;wBAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAmC,CAAC;wBAC3D,IACE,MAAM,CAAC,IAAI,KAAK,SAAS;4BACzB,MAAM,CAAC,EAAE,KAAK,SAAS;4BACvB,MAAM,CAAC,QAAQ,EACf;4BACA,YAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;yBACnD;6BAAM;4BACL,OAAO,EAAE,CAAC;yBACX;wBACD,MAAM;qBACP;oBACD,KAAK,qCAAmB,CAAC,KAAK,CAAC,CAAC;wBAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,MAA2B,CAAC;wBACnD,IAAI,EAAE,CAAC,cAAc,EAAE;4BACrB,YAAY,CAAC,IAAI,CACf,uBAAuB,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,CACnD,CAAC;yBACH;6BAAM,IAAI,CAAA,MAAA,EAAE,CAAC,OAAO,0CAAE,OAAO,KAAI,MAAM,CAAC,MAAM,EAAE;4BAC/C,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;yBAChE;6BAAM;4BACL,OAAO,EAAE,CAAC;yBACX;wBACD,MAAM;qBACP;oBACD,QAAQ;iBACT;aACF;SACF;QAED,OAAO,IAAA,eAAM,EACX,YAAY,EACZ,CAAC,IAAI,EAAE,EAAE,CACP,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAC9B,IAAA,eAAM,EAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CACxC,EAAE,CACN,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,kBAAkB;QAChC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAEjD,MAAM,MAAM,GAAG,IAAA,yCAAa,EAAC,KAAK,CAAC,CAAC;QAEpC,IAAI,CAAC,wBAAwB,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,WAAW,CAAC;IAC5B,CAAC;IAES,KAAK,CAAC,aAAa;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;IACvC,CAAC;IAED,4DAA4D;IAClD,KAAK,CAAC,gBAAgB;QAC9B,MAAM,cAAc,GAAG,IAAA,6BAAY,EAAC,IAAI,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC;QAEjE,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC;IACvD,CAAC;IAES,KAAK,CAAC,UAAU;QACxB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IAES,UAAU;QAClB,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;YACzC,IAAI,IAAA,4BAAU,EAAC,EAAE,CAAC,EAAE;gBAClB,SAAS;aACV;YACD,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACzC,IACE,OAAO,CAAC,IAAI,KAAK,qCAAmB,CAAC,KAAK;oBAC1C,OAAO,CAAC,MAAM;oBACd,OAAO,CAAC,MAAM,CAAC,MAAM,EACrB;oBACA,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;iBACrC;aACF;SACF;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAES,KAAK,CAAC,mBAAmB;QACjC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,CAAC;IAES,KAAK,CAAC,wBAAwB,CACtC,QAAkB;QAElB,OAAO,OAAO,CAAC,OAAO;QACpB,yBAAyB;QACzB,QAAQ,CAAC,WAAW,KAAK,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE;YAChD,6BAA6B;YAC7B,QAAQ,CAAC,WAAW,KAAK,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAC1D,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,WAAW;QACzB,4CAA4C;QAC5C,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF,CAAA;AA5KY,YAAY;IADxB,IAAA,mBAAU,GAAE;IAUR,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;IAC1B,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCAHf,6BAAkB;QAClB,sBAAU;QACe,iCAAe,UAGjC,sCAAiB;QAChB,yCAAkB;QACpB,qCAAgB;QACA,oDAAwB;QAC5C,6BAAa;QACR,4BAAiB;GAjB3B,YAAY,CA4KxB;AA5KY,oCAAY","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Inject, Injectable } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { SchedulerRegistry } from '@nestjs/schedule';\n\nimport {\n isCustomDs,\n EthereumHandlerKind,\n EthereumLogFilter,\n SubqlEthereumProcessorOptions,\n EthereumTransactionFilter,\n} from '@subql/common-ethereum';\nimport { NodeConfig, BaseFetchService } from '@subql/node-core';\nimport { DictionaryQueryCondition, DictionaryQueryEntry } from '@subql/types';\nimport { SubqlDatasource } from '@subql/types-ethereum';\nimport { MetaData } from '@subql/utils';\nimport { groupBy, sortBy, uniqBy } from 'lodash';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { EthereumApi, EthereumApiService } from '../ethereum';\nimport SafeEthProvider from '../ethereum/safe-api';\nimport { calcInterval } from '../ethereum/utils.ethereum';\nimport { eventToTopic, functionToSighash } from '../utils/string';\nimport { IEthereumBlockDispatcher } from './blockDispatcher';\nimport { DictionaryService } from './dictionary.service';\nimport { DsProcessorService } from './ds-processor.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport {\n blockToHeader,\n UnfinalizedBlocksService,\n} from './unfinalizedBlocks.service';\n\nconst BLOCK_TIME_VARIANCE = 5000;\n\nconst INTERVAL_PERCENT = 0.9;\nconst QUERY_ADDRESS_LIMIT = 50;\n\nfunction eventFilterToQueryEntry(\n filter: EthereumLogFilter,\n dsOptions: SubqlEthereumProcessorOptions | SubqlEthereumProcessorOptions[],\n): DictionaryQueryEntry {\n const conditions: DictionaryQueryCondition[] = [];\n\n if (Array.isArray(dsOptions)) {\n const addresses = dsOptions.map((option) => option.address).filter(Boolean);\n\n if (addresses.length !== 0 && addresses.length <= QUERY_ADDRESS_LIMIT) {\n conditions.push({\n field: 'address',\n value: addresses,\n matcher: 'in',\n });\n }\n } else {\n if (dsOptions?.address) {\n conditions.push({\n field: 'address',\n value: dsOptions.address.toLowerCase(),\n matcher: 'equalTo',\n });\n }\n }\n if (filter.topics) {\n for (let i = 0; i < Math.min(filter.topics.length, 4); i++) {\n const topic = filter.topics[i];\n if (!topic) {\n continue;\n }\n const field = `topics${i}`;\n conditions.push({\n field,\n value: eventToTopic(topic),\n matcher: 'equalTo',\n });\n }\n }\n return {\n entity: 'evmLogs',\n conditions,\n };\n}\n\nfunction callFilterToQueryEntry(\n filter: EthereumTransactionFilter,\n): DictionaryQueryEntry {\n const conditions: DictionaryQueryCondition[] = [];\n if (filter.from) {\n conditions.push({\n field: 'from',\n value: filter.from.toLowerCase(),\n matcher: 'equalTo',\n });\n }\n if (filter.to) {\n conditions.push({\n field: 'to',\n value: filter.to.toLowerCase(),\n matcher: 'equalTo',\n });\n }\n if (filter.function) {\n conditions.push({\n field: 'func',\n value: functionToSighash(filter.function),\n matcher: 'equalTo',\n });\n }\n return {\n entity: 'evmTransactions',\n conditions,\n };\n}\n\n@Injectable()\nexport class FetchService extends BaseFetchService<\n EthereumApiService,\n SubqlDatasource,\n IEthereumBlockDispatcher,\n DictionaryService\n> {\n constructor(\n apiService: EthereumApiService,\n nodeConfig: NodeConfig,\n @Inject('ISubqueryProject') project: SubqueryProject,\n @Inject('IBlockDispatcher')\n blockDispatcher: IEthereumBlockDispatcher,\n dictionaryService: DictionaryService,\n dsProcessorService: DsProcessorService,\n dynamicDsService: DynamicDsService,\n private unfinalizedBlocksService: UnfinalizedBlocksService,\n eventEmitter: EventEmitter2,\n schedulerRegistry: SchedulerRegistry,\n ) {\n super(\n apiService,\n nodeConfig,\n project,\n blockDispatcher,\n dictionaryService,\n dsProcessorService,\n dynamicDsService,\n eventEmitter,\n schedulerRegistry,\n );\n }\n\n get api(): EthereumApi {\n return this.apiService.unsafeApi;\n }\n\n buildDictionaryQueryEntries(startBlock: number): DictionaryQueryEntry[] {\n const queryEntries: DictionaryQueryEntry[] = [];\n\n type GroupedSubqlProjectDs = SubqlDatasource & {\n groupedOptions?: SubqlEthereumProcessorOptions[];\n };\n\n const groupdDynamicDs: GroupedSubqlProjectDs[] = Object.values(\n groupBy(this.templateDynamicDatasouces, (ds) => ds.name),\n ).map((grouped: SubqlProjectDs[]) => {\n const options = grouped.map((ds) => ds.options);\n const ref = grouped[0];\n\n return {\n ...ref,\n groupedOptions: options,\n };\n });\n\n // Only run the ds that is equal or less than startBlock\n // sort array from lowest ds.startBlock to highest\n const filteredDs: GroupedSubqlProjectDs[] = this.project.dataSources\n .concat(groupdDynamicDs)\n .filter((ds) => ds.startBlock <= startBlock)\n .sort((a, b) => a.startBlock - b.startBlock);\n\n for (const ds of filteredDs) {\n for (const handler of ds.mapping.handlers) {\n // No filters, cant use dictionary\n if (!handler.filter) return [];\n\n switch (handler.kind) {\n case EthereumHandlerKind.Block:\n return [];\n case EthereumHandlerKind.Call: {\n const filter = handler.filter as EthereumTransactionFilter;\n if (\n filter.from !== undefined ||\n filter.to !== undefined ||\n filter.function\n ) {\n queryEntries.push(callFilterToQueryEntry(filter));\n } else {\n return [];\n }\n break;\n }\n case EthereumHandlerKind.Event: {\n const filter = handler.filter as EthereumLogFilter;\n if (ds.groupedOptions) {\n queryEntries.push(\n eventFilterToQueryEntry(filter, ds.groupedOptions),\n );\n } else if (ds.options?.address || filter.topics) {\n queryEntries.push(eventFilterToQueryEntry(filter, ds.options));\n } else {\n return [];\n }\n break;\n }\n default:\n }\n }\n }\n\n return uniqBy(\n queryEntries,\n (item) =>\n `${item.entity}|${JSON.stringify(\n sortBy(item.conditions, (c) => c.field),\n )}`,\n );\n }\n\n protected async getFinalizedHeight(): Promise<number> {\n const block = await this.api.getFinalizedBlock();\n\n const header = blockToHeader(block);\n\n this.unfinalizedBlocksService.registerFinalizedBlock(header);\n return header.blockHeight;\n }\n\n protected async getBestHeight(): Promise<number> {\n return this.api.getBestBlockHeight();\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n protected async getChainInterval(): Promise<number> {\n const CHAIN_INTERVAL = calcInterval(this.api) * INTERVAL_PERCENT;\n\n return Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);\n }\n\n protected async getChainId(): Promise<string> {\n return Promise.resolve(this.api.getChainId().toString());\n }\n\n protected getModulos(): number[] {\n const modulos: number[] = [];\n for (const ds of this.project.dataSources) {\n if (isCustomDs(ds)) {\n continue;\n }\n for (const handler of ds.mapping.handlers) {\n if (\n handler.kind === EthereumHandlerKind.Block &&\n handler.filter &&\n handler.filter.modulo\n ) {\n modulos.push(handler.filter.modulo);\n }\n }\n }\n return modulos;\n }\n\n protected async initBlockDispatcher(): Promise<void> {\n await this.blockDispatcher.init(this.resetForNewDs.bind(this));\n }\n\n protected async validatateDictionaryMeta(\n metaData: MetaData,\n ): Promise<boolean> {\n return Promise.resolve(\n // When alias is not used\n metaData.genesisHash !== this.api.getGenesisHash() &&\n // Case when an alias is used\n metaData.genesisHash !== this.dictionaryService.chainId,\n );\n }\n\n protected async preLoopHook(): Promise<void> {\n // Ethereum doesn't need to do anything here\n return Promise.resolve();\n }\n}\n"]}
1
+ {"version":3,"file":"fetch.service.js","sourceRoot":"","sources":["../../src/indexer/fetch.service.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Inject, Injectable } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { SchedulerRegistry } from '@nestjs/schedule';\n\nimport {\n isCustomDs,\n EthereumHandlerKind,\n EthereumLogFilter,\n SubqlEthereumProcessorOptions,\n EthereumTransactionFilter,\n} from '@subql/common-ethereum';\nimport { NodeConfig, BaseFetchService } from '@subql/node-core';\nimport { DictionaryQueryCondition, DictionaryQueryEntry } from '@subql/types';\nimport { SubqlDatasource } from '@subql/types-ethereum';\nimport { MetaData } from '@subql/utils';\nimport { groupBy, sortBy, uniqBy } from 'lodash';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { EthereumApi, EthereumApiService } from '../ethereum';\nimport SafeEthProvider from '../ethereum/safe-api';\nimport { calcInterval } from '../ethereum/utils.ethereum';\nimport { eventToTopic, functionToSighash } from '../utils/string';\nimport { IEthereumBlockDispatcher } from './blockDispatcher';\nimport { DictionaryService } from './dictionary.service';\nimport { DsProcessorService } from './ds-processor.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport {\n blockToHeader,\n UnfinalizedBlocksService,\n} from './unfinalizedBlocks.service';\n\nconst BLOCK_TIME_VARIANCE = 5000;\n\nconst INTERVAL_PERCENT = 0.9;\nconst QUERY_ADDRESS_LIMIT = 50;\n\nfunction eventFilterToQueryEntry(\n filter: EthereumLogFilter,\n dsOptions: SubqlEthereumProcessorOptions | SubqlEthereumProcessorOptions[],\n): DictionaryQueryEntry {\n const conditions: DictionaryQueryCondition[] = [];\n\n if (Array.isArray(dsOptions)) {\n const addresses = dsOptions.map((option) => option.address).filter(Boolean);\n\n if (addresses.length !== 0 && addresses.length <= QUERY_ADDRESS_LIMIT) {\n conditions.push({\n field: 'address',\n value: addresses,\n matcher: 'in',\n });\n }\n } else {\n if (dsOptions?.address) {\n conditions.push({\n field: 'address',\n value: dsOptions.address.toLowerCase(),\n matcher: 'equalTo',\n });\n }\n }\n if (filter.topics) {\n for (let i = 0; i < Math.min(filter.topics.length, 4); i++) {\n const topic = filter.topics[i];\n if (!topic) {\n continue;\n }\n const field = `topics${i}`;\n conditions.push({\n field,\n value: eventToTopic(topic),\n matcher: 'equalTo',\n });\n }\n }\n return {\n entity: 'evmLogs',\n conditions,\n };\n}\n\nfunction callFilterToQueryEntry(\n filter: EthereumTransactionFilter,\n): DictionaryQueryEntry {\n const conditions: DictionaryQueryCondition[] = [];\n if (filter.from) {\n conditions.push({\n field: 'from',\n value: filter.from.toLowerCase(),\n matcher: 'equalTo',\n });\n }\n if (filter.to) {\n conditions.push({\n field: 'to',\n value: filter.to.toLowerCase(),\n matcher: 'equalTo',\n });\n } else if (filter.to === null) {\n conditions.push({\n field: 'to',\n value: true as any, // TODO update types to allow boolean\n matcher: 'isNull',\n });\n }\n if (filter.function) {\n conditions.push({\n field: 'func',\n value: functionToSighash(filter.function),\n matcher: 'equalTo',\n });\n }\n return {\n entity: 'evmTransactions',\n conditions,\n };\n}\n\ntype GroupedSubqlProjectDs = SubqlDatasource & {\n groupedOptions?: SubqlEthereumProcessorOptions[];\n};\nexport function buildDictionaryQueryEntries(\n dataSources: GroupedSubqlProjectDs[],\n startBlock: number,\n): DictionaryQueryEntry[] {\n const queryEntries: DictionaryQueryEntry[] = [];\n\n // Only run the ds that is equal or less than startBlock\n // sort array from lowest ds.startBlock to highest\n const filteredDs = dataSources\n .filter((ds) => ds.startBlock <= startBlock)\n .sort((a, b) => a.startBlock - b.startBlock);\n\n for (const ds of filteredDs) {\n for (const handler of ds.mapping.handlers) {\n // No filters, cant use dictionary\n if (!handler.filter) return [];\n\n switch (handler.kind) {\n case EthereumHandlerKind.Block:\n return [];\n case EthereumHandlerKind.Call: {\n const filter = handler.filter as EthereumTransactionFilter;\n if (\n filter.from !== undefined ||\n filter.to !== undefined ||\n filter.function\n ) {\n queryEntries.push(callFilterToQueryEntry(filter));\n } else {\n return [];\n }\n break;\n }\n case EthereumHandlerKind.Event: {\n const filter = handler.filter as EthereumLogFilter;\n if (ds.groupedOptions) {\n queryEntries.push(\n eventFilterToQueryEntry(filter, ds.groupedOptions),\n );\n } else if (ds.options?.address || filter.topics) {\n queryEntries.push(eventFilterToQueryEntry(filter, ds.options));\n } else {\n return [];\n }\n break;\n }\n default:\n }\n }\n }\n\n return uniqBy(\n queryEntries,\n (item) =>\n `${item.entity}|${JSON.stringify(\n sortBy(item.conditions, (c) => c.field),\n )}`,\n );\n}\n\n@Injectable()\nexport class FetchService extends BaseFetchService<\n EthereumApiService,\n SubqlDatasource,\n IEthereumBlockDispatcher,\n DictionaryService\n> {\n constructor(\n apiService: EthereumApiService,\n nodeConfig: NodeConfig,\n @Inject('ISubqueryProject') project: SubqueryProject,\n @Inject('IBlockDispatcher')\n blockDispatcher: IEthereumBlockDispatcher,\n dictionaryService: DictionaryService,\n dsProcessorService: DsProcessorService,\n dynamicDsService: DynamicDsService,\n private unfinalizedBlocksService: UnfinalizedBlocksService,\n eventEmitter: EventEmitter2,\n schedulerRegistry: SchedulerRegistry,\n ) {\n super(\n apiService,\n nodeConfig,\n project,\n blockDispatcher,\n dictionaryService,\n dsProcessorService,\n dynamicDsService,\n eventEmitter,\n schedulerRegistry,\n );\n }\n\n get api(): EthereumApi {\n return this.apiService.unsafeApi;\n }\n\n buildDictionaryQueryEntries(startBlock: number): DictionaryQueryEntry[] {\n const groupdDynamicDs: GroupedSubqlProjectDs[] = Object.values(\n groupBy(this.templateDynamicDatasouces, (ds) => ds.name),\n ).map((grouped: SubqlProjectDs[]) => {\n const options = grouped.map((ds) => ds.options);\n const ref = grouped[0];\n\n return {\n ...ref,\n groupedOptions: options,\n };\n });\n\n // Only run the ds that is equal or less than startBlock\n // sort array from lowest ds.startBlock to highest\n const filteredDs: GroupedSubqlProjectDs[] =\n this.project.dataSources.concat(groupdDynamicDs);\n\n return buildDictionaryQueryEntries(filteredDs, startBlock);\n }\n\n protected async getFinalizedHeight(): Promise<number> {\n const block = await this.api.getFinalizedBlock();\n\n const header = blockToHeader(block);\n\n this.unfinalizedBlocksService.registerFinalizedBlock(header);\n return header.blockHeight;\n }\n\n protected async getBestHeight(): Promise<number> {\n return this.api.getBestBlockHeight();\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n protected async getChainInterval(): Promise<number> {\n const CHAIN_INTERVAL = calcInterval(this.api) * INTERVAL_PERCENT;\n\n return Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);\n }\n\n protected async getChainId(): Promise<string> {\n return Promise.resolve(this.api.getChainId().toString());\n }\n\n protected getModulos(): number[] {\n const modulos: number[] = [];\n for (const ds of this.project.dataSources) {\n if (isCustomDs(ds)) {\n continue;\n }\n for (const handler of ds.mapping.handlers) {\n if (\n handler.kind === EthereumHandlerKind.Block &&\n handler.filter &&\n handler.filter.modulo\n ) {\n modulos.push(handler.filter.modulo);\n }\n }\n }\n return modulos;\n }\n\n protected async initBlockDispatcher(): Promise<void> {\n await this.blockDispatcher.init(this.resetForNewDs.bind(this));\n }\n\n protected async validatateDictionaryMeta(\n metaData: MetaData,\n ): Promise<boolean> {\n return Promise.resolve(\n // When alias is not used\n metaData.genesisHash !== this.api.getGenesisHash() &&\n // Case when an alias is used\n metaData.genesisHash !== this.dictionaryService.chainId,\n );\n }\n\n protected async preLoopHook(): Promise<void> {\n // Ethereum doesn't need to do anything here\n return Promise.resolve();\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ // Copyright 2020-2022 OnFinality Limited authors & contributors
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ const types_ethereum_1 = require("@subql/types-ethereum");
6
+ const fetch_service_1 = require("./fetch.service");
7
+ describe('Dictioanry queries', () => {
8
+ describe('Transaction filters', () => {
9
+ it('Build a filter for contract creation transactions', () => {
10
+ const ds = {
11
+ kind: types_ethereum_1.EthereumDatasourceKind.Runtime,
12
+ assets: new Map(),
13
+ startBlock: 1,
14
+ mapping: {
15
+ file: '',
16
+ handlers: [
17
+ {
18
+ handler: 'handleTransaction',
19
+ kind: types_ethereum_1.EthereumHandlerKind.Call,
20
+ filter: {
21
+ to: null,
22
+ },
23
+ },
24
+ ],
25
+ },
26
+ };
27
+ const result = (0, fetch_service_1.buildDictionaryQueryEntries)([ds], 1);
28
+ expect(result).toEqual([
29
+ {
30
+ entity: 'evmTransactions',
31
+ conditions: [{ field: 'to', matcher: 'isNull', value: true }],
32
+ },
33
+ ]);
34
+ });
35
+ });
36
+ });
37
+ //# sourceMappingURL=fetch.service.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.service.spec.js","sourceRoot":"","sources":["../../src/indexer/fetch.service.spec.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;AAEtC,0DAI+B;AAC/B,mDAA8D;AAE9D,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,EAAE,GAA2B;gBACjC,IAAI,EAAE,uCAAsB,CAAC,OAAO;gBACpC,MAAM,EAAE,IAAI,GAAG,EAAE;gBACjB,UAAU,EAAE,CAAC;gBACb,OAAO,EAAE;oBACP,IAAI,EAAE,EAAE;oBACR,QAAQ,EAAE;wBACR;4BACE,OAAO,EAAE,mBAAmB;4BAC5B,IAAI,EAAE,oCAAmB,CAAC,IAAI;4BAC9B,MAAM,EAAE;gCACN,EAAE,EAAE,IAAI;6BACT;yBACF;qBACF;iBACF;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,IAAA,2CAA2B,EAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAEpD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB;oBACE,MAAM,EAAE,iBAAiB;oBACzB,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;iBAC9D;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n EthereumDatasourceKind,\n EthereumHandlerKind,\n SubqlRuntimeDatasource,\n} from '@subql/types-ethereum';\nimport { buildDictionaryQueryEntries } from './fetch.service';\n\ndescribe('Dictioanry queries', () => {\n describe('Transaction filters', () => {\n it('Build a filter for contract creation transactions', () => {\n const ds: SubqlRuntimeDatasource = {\n kind: EthereumDatasourceKind.Runtime,\n assets: new Map(),\n startBlock: 1,\n mapping: {\n file: '',\n handlers: [\n {\n handler: 'handleTransaction',\n kind: EthereumHandlerKind.Call,\n filter: {\n to: null,\n },\n },\n ],\n },\n };\n\n const result = buildDictionaryQueryEntries([ds], 1);\n\n expect(result).toEqual([\n {\n entity: 'evmTransactions',\n conditions: [{ field: 'to', matcher: 'isNull', value: true }],\n },\n ]);\n });\n });\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@subql/node-ethereum",
3
- "version": "2.5.4-1",
3
+ "version": "2.6.0",
4
4
  "description": "",
5
5
  "author": "Ian He",
6
6
  "license": "Apache-2.0",
@@ -25,7 +25,7 @@
25
25
  "@nestjs/platform-express": "^8.2.6",
26
26
  "@nestjs/schedule": "^1.0.2",
27
27
  "@subql/common": "^2.2.1",
28
- "@subql/common-ethereum": "2.1.3-0",
28
+ "@subql/common-ethereum": "2.1.3",
29
29
  "@subql/node-core": "^2.5.0",
30
30
  "@subql/testing": "^2.0.0",
31
31
  "@subql/types": "^2.1.2",
@@ -67,6 +67,5 @@
67
67
  "files": [
68
68
  "/dist",
69
69
  "/bin"
70
- ],
71
- "stableVersion": "2.5.4-0"
70
+ ]
72
71
  }