@subql/node-ethereum 1.10.1-3 → 2.0.1-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.
- package/CHANGELOG.md +65 -0
- package/README.md +3 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/configure/SubqueryProject.d.ts +9 -11
- package/dist/configure/SubqueryProject.js +19 -9
- package/dist/configure/SubqueryProject.js.map +1 -1
- package/dist/configure/configure.module.js +5 -7
- package/dist/configure/configure.module.js.map +1 -1
- package/dist/ethereum/api.connection.d.ts +11 -0
- package/dist/ethereum/api.connection.js +27 -0
- package/dist/ethereum/api.connection.js.map +1 -0
- package/dist/ethereum/api.ethereum.d.ts +18 -5
- package/dist/ethereum/api.ethereum.js +138 -43
- package/dist/ethereum/api.ethereum.js.map +1 -1
- package/dist/ethereum/api.service.ethereum.d.ts +11 -3
- package/dist/ethereum/api.service.ethereum.js +68 -18
- package/dist/ethereum/api.service.ethereum.js.map +1 -1
- package/dist/ethereum/api.service.ethereum.test.d.ts +1 -0
- package/dist/ethereum/api.service.ethereum.test.js +73 -0
- package/dist/ethereum/api.service.ethereum.test.js.map +1 -0
- package/dist/ethereum/block.ethereum.d.ts +1 -1
- package/dist/ethereum/block.ethereum.js +10 -12
- package/dist/ethereum/block.ethereum.js.map +1 -1
- package/dist/ethereum/ethers/json-rpc-batch-provider.d.ts +21 -0
- package/dist/ethereum/ethers/json-rpc-batch-provider.js +114 -0
- package/dist/ethereum/ethers/json-rpc-batch-provider.js.map +1 -0
- package/dist/ethereum/ethers/json-rpc-provider.d.ts +7 -0
- package/dist/ethereum/ethers/json-rpc-provider.js +68 -0
- package/dist/ethereum/ethers/json-rpc-provider.js.map +1 -0
- package/dist/ethereum/ethers/web/_version.d.ts +1 -0
- package/dist/ethereum/ethers/web/_version.js +6 -0
- package/dist/ethereum/ethers/web/_version.js.map +1 -0
- package/dist/ethereum/ethers/web/geturl.d.ts +3 -0
- package/dist/ethereum/ethers/web/geturl.js +116 -0
- package/dist/ethereum/ethers/web/geturl.js.map +1 -0
- package/dist/ethereum/ethers/web/index.d.ts +49 -0
- package/dist/ethereum/ethers/web/index.js +437 -0
- package/dist/ethereum/ethers/web/index.js.map +1 -0
- package/dist/ethereum/ethers/web/types.d.ts +26 -0
- package/dist/ethereum/ethers/web/types.js +4 -0
- package/dist/ethereum/ethers/web/types.js.map +1 -0
- package/dist/ethereum/safe-api.d.ts +34 -0
- package/dist/ethereum/safe-api.js +114 -0
- package/dist/ethereum/safe-api.js.map +1 -0
- package/dist/ethereum/utils.ethereum.d.ts +1 -1
- package/dist/ethereum/utils.ethereum.js +22 -87
- package/dist/ethereum/utils.ethereum.js.map +1 -1
- package/dist/indexer/blockDispatcher/block-dispatcher.service.d.ts +17 -0
- package/dist/indexer/blockDispatcher/block-dispatcher.service.js +55 -0
- package/dist/indexer/blockDispatcher/block-dispatcher.service.js.map +1 -0
- package/dist/indexer/blockDispatcher/ethereum-block-dispatcher.d.ts +4 -0
- package/dist/indexer/blockDispatcher/ethereum-block-dispatcher.js +5 -0
- package/dist/indexer/blockDispatcher/ethereum-block-dispatcher.js.map +1 -0
- package/dist/indexer/blockDispatcher/index.d.ts +4 -0
- package/dist/indexer/blockDispatcher/index.js +10 -0
- package/dist/indexer/blockDispatcher/index.js.map +1 -0
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.d.ts +15 -0
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js +88 -0
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js.map +1 -0
- package/dist/indexer/dictionary.service.d.ts +1 -0
- package/dist/indexer/dictionary.service.js +22 -2
- package/dist/indexer/dictionary.service.js.map +1 -1
- package/dist/indexer/ds-processor.service.d.ts +1 -1
- package/dist/indexer/ds-processor.service.js +4 -0
- package/dist/indexer/ds-processor.service.js.map +1 -1
- package/dist/indexer/dynamic-ds.service.d.ts +3 -19
- package/dist/indexer/dynamic-ds.service.js +20 -72
- package/dist/indexer/dynamic-ds.service.js.map +1 -1
- package/dist/indexer/fetch.module.js +40 -12
- package/dist/indexer/fetch.module.js.map +1 -1
- package/dist/indexer/fetch.service.d.ts +16 -7
- package/dist/indexer/fetch.service.js +188 -78
- package/dist/indexer/fetch.service.js.map +1 -1
- package/dist/indexer/indexer.manager.d.ts +11 -17
- package/dist/indexer/indexer.manager.js +68 -71
- package/dist/indexer/indexer.manager.js.map +1 -1
- package/dist/indexer/indexer.module.js +32 -8
- package/dist/indexer/indexer.module.js.map +1 -1
- package/dist/indexer/project.service.d.ts +11 -8
- package/dist/indexer/project.service.js +76 -82
- package/dist/indexer/project.service.js.map +1 -1
- package/dist/indexer/sandbox.service.js +11 -2
- package/dist/indexer/sandbox.service.js.map +1 -1
- package/dist/indexer/types.d.ts +2 -1
- package/dist/indexer/types.js.map +1 -1
- package/dist/indexer/unfinalizedBlocks.service.d.ts +36 -0
- package/dist/indexer/unfinalizedBlocks.service.js +197 -0
- package/dist/indexer/unfinalizedBlocks.service.js.map +1 -0
- package/dist/indexer/unfinalizedBlocks.spec.d.ts +1 -0
- package/dist/indexer/unfinalizedBlocks.spec.js +195 -0
- package/dist/indexer/unfinalizedBlocks.spec.js.map +1 -0
- package/dist/indexer/worker/worker.d.ts +22 -6
- package/dist/indexer/worker/worker.js +16 -3
- package/dist/indexer/worker/worker.js.map +1 -1
- package/dist/indexer/worker/worker.service.d.ts +10 -6
- package/dist/indexer/worker/worker.service.js +23 -10
- package/dist/indexer/worker/worker.service.js.map +1 -1
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.d.ts +11 -0
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.js +32 -0
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.js.map +1 -0
- package/dist/init.js +2 -2
- package/dist/init.js.map +1 -1
- package/dist/main.js +6 -1
- package/dist/main.js.map +1 -1
- package/dist/meta/meta.module.js +8 -0
- package/dist/meta/meta.module.js.map +1 -1
- package/dist/meta/meta.service.d.ts +18 -3
- package/dist/meta/meta.service.js +89 -5
- package/dist/meta/meta.service.js.map +1 -1
- package/dist/subcommands/forceClean.service.d.ts +3 -1
- package/dist/subcommands/forceClean.service.js +30 -6
- package/dist/subcommands/forceClean.service.js.map +1 -1
- package/dist/subcommands/reindex.init.js +6 -1
- package/dist/subcommands/reindex.init.js.map +1 -1
- package/dist/subcommands/reindex.module.js +20 -1
- package/dist/subcommands/reindex.module.js.map +1 -1
- package/dist/subcommands/reindex.service.d.ts +7 -3
- package/dist/subcommands/reindex.service.js +44 -50
- package/dist/subcommands/reindex.service.js.map +1 -1
- package/dist/subcommands/testing.init.d.ts +1 -0
- package/dist/subcommands/testing.init.js +34 -0
- package/dist/subcommands/testing.init.js.map +1 -0
- package/dist/subcommands/testing.module.d.ts +4 -0
- package/dist/subcommands/testing.module.js +77 -0
- package/dist/subcommands/testing.module.js.map +1 -0
- package/dist/subcommands/testing.service.d.ts +9 -0
- package/dist/subcommands/testing.service.js +43 -0
- package/dist/subcommands/testing.service.js.map +1 -0
- package/dist/utils/project.d.ts +3 -0
- package/dist/utils/project.js +45 -1
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/reindex.d.ts +6 -0
- package/dist/utils/reindex.js +48 -0
- package/dist/utils/reindex.js.map +1 -0
- package/dist/utils/string.js +10 -2
- package/dist/utils/string.js.map +1 -1
- package/dist/yargs.d.ts +97 -49
- package/dist/yargs.js +130 -69
- package/dist/yargs.js.map +1 -1
- package/package.json +13 -11
- package/dist/indexer/worker/block-dispatcher.service.d.ts +0 -69
- package/dist/indexer/worker/block-dispatcher.service.js +0 -356
- package/dist/indexer/worker/block-dispatcher.service.js.map +0 -1
|
@@ -26,19 +26,34 @@ const utils_ethereum_1 = require("../ethereum/utils.ethereum");
|
|
|
26
26
|
const string_1 = require("../utils/string");
|
|
27
27
|
const dictionary_service_1 = require("./dictionary.service");
|
|
28
28
|
const dynamic_ds_service_1 = require("./dynamic-ds.service");
|
|
29
|
+
const unfinalizedBlocks_service_1 = require("./unfinalizedBlocks.service");
|
|
29
30
|
const logger = (0, node_core_1.getLogger)('fetch');
|
|
30
31
|
let BLOCK_TIME_VARIANCE = 5000;
|
|
31
32
|
const DICTIONARY_MAX_QUERY_SIZE = 10000;
|
|
32
33
|
const CHECK_MEMORY_INTERVAL = 60000;
|
|
33
34
|
const MINIMUM_BATCH_SIZE = 5;
|
|
34
35
|
const INTERVAL_PERCENT = 0.9;
|
|
35
|
-
|
|
36
|
+
const QUERY_ADDRESS_LIMIT = 50;
|
|
37
|
+
function eventFilterToQueryEntry(filter, dsOptions) {
|
|
36
38
|
const conditions = [];
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
if (Array.isArray(dsOptions)) {
|
|
40
|
+
const addresses = dsOptions.map((option) => option.address).filter(Boolean);
|
|
41
|
+
if (addresses.length !== 0 && addresses.length <= QUERY_ADDRESS_LIMIT) {
|
|
42
|
+
conditions.push({
|
|
43
|
+
field: 'address',
|
|
44
|
+
value: addresses,
|
|
45
|
+
matcher: 'inInsensitive',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
if (dsOptions === null || dsOptions === void 0 ? void 0 : dsOptions.address) {
|
|
51
|
+
conditions.push({
|
|
52
|
+
field: 'address',
|
|
53
|
+
value: dsOptions.address.toLowerCase(),
|
|
54
|
+
// matcher: 'equals',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
42
57
|
}
|
|
43
58
|
if (filter.topics) {
|
|
44
59
|
for (let i = 0; i < Math.min(filter.topics.length, 4); i++) {
|
|
@@ -47,7 +62,11 @@ function eventFilterToQueryEntry(filter) {
|
|
|
47
62
|
continue;
|
|
48
63
|
}
|
|
49
64
|
const field = `topics${i}`;
|
|
50
|
-
conditions.push({
|
|
65
|
+
conditions.push({
|
|
66
|
+
field,
|
|
67
|
+
value: (0, string_1.eventToTopic)(topic),
|
|
68
|
+
matcher: 'equalTo',
|
|
69
|
+
});
|
|
51
70
|
}
|
|
52
71
|
}
|
|
53
72
|
return {
|
|
@@ -73,6 +92,7 @@ function callFilterToQueryEntry(filter) {
|
|
|
73
92
|
conditions.push({
|
|
74
93
|
field: 'func',
|
|
75
94
|
value: (0, string_1.functionToSighash)(filter.function),
|
|
95
|
+
matcher: 'equalTo',
|
|
76
96
|
});
|
|
77
97
|
}
|
|
78
98
|
return {
|
|
@@ -81,16 +101,19 @@ function callFilterToQueryEntry(filter) {
|
|
|
81
101
|
};
|
|
82
102
|
}
|
|
83
103
|
let FetchService = class FetchService {
|
|
84
|
-
constructor(apiService, nodeConfig, project, blockDispatcher, dictionaryService, dynamicDsService, eventEmitter, schedulerRegistry) {
|
|
104
|
+
constructor(apiService, nodeConfig, project, blockDispatcher, dictionaryService, dynamicDsService, unfinalizedBlocksService, eventEmitter, schedulerRegistry) {
|
|
85
105
|
this.apiService = apiService;
|
|
86
106
|
this.nodeConfig = nodeConfig;
|
|
87
107
|
this.project = project;
|
|
88
108
|
this.blockDispatcher = blockDispatcher;
|
|
89
109
|
this.dictionaryService = dictionaryService;
|
|
90
110
|
this.dynamicDsService = dynamicDsService;
|
|
111
|
+
this.unfinalizedBlocksService = unfinalizedBlocksService;
|
|
91
112
|
this.eventEmitter = eventEmitter;
|
|
92
113
|
this.schedulerRegistry = schedulerRegistry;
|
|
93
114
|
this.isShutdown = false;
|
|
115
|
+
this.dictionaryMetaValid = false;
|
|
116
|
+
this.bypassBlocks = [];
|
|
94
117
|
this.batchSizeScale = 1;
|
|
95
118
|
}
|
|
96
119
|
onApplicationShutdown() {
|
|
@@ -103,41 +126,50 @@ let FetchService = class FetchService {
|
|
|
103
126
|
this.templateDynamicDatasouces =
|
|
104
127
|
await this.dynamicDsService.getDynamicDatasources();
|
|
105
128
|
}
|
|
106
|
-
|
|
107
|
-
|
|
129
|
+
buildDictionaryQueryEntries(startBlock) {
|
|
130
|
+
var _a;
|
|
108
131
|
const queryEntries = [];
|
|
109
|
-
const
|
|
110
|
-
|
|
132
|
+
const groupdDynamicDs = Object.values((0, lodash_1.groupBy)(this.templateDynamicDatasouces, (ds) => ds.name)).map((grouped) => {
|
|
133
|
+
const options = grouped.map((ds) => ds.options);
|
|
134
|
+
const ref = grouped[0];
|
|
135
|
+
return Object.assign(Object.assign({}, ref), { groupedOptions: options });
|
|
136
|
+
});
|
|
137
|
+
// Only run the ds that is equal or less than startBlock
|
|
138
|
+
// sort array from lowest ds.startBlock to highest
|
|
139
|
+
const filteredDs = this.project.dataSources
|
|
140
|
+
.concat(groupdDynamicDs)
|
|
141
|
+
.filter((ds) => ds.startBlock <= startBlock)
|
|
142
|
+
.sort((a, b) => a.startBlock - b.startBlock);
|
|
143
|
+
for (const ds of filteredDs) {
|
|
111
144
|
for (const handler of ds.mapping.handlers) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
filterList = filterList.filter((f) => f);
|
|
115
|
-
if (!filterList.length)
|
|
145
|
+
// No filters, cant use dictionary
|
|
146
|
+
if (!handler.filter)
|
|
116
147
|
return [];
|
|
117
148
|
switch (handler.kind) {
|
|
118
149
|
case common_ethereum_1.EthereumHandlerKind.Block:
|
|
119
150
|
return [];
|
|
120
151
|
case common_ethereum_1.EthereumHandlerKind.Call: {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
152
|
+
const filter = handler.filter;
|
|
153
|
+
if (filter.from !== undefined ||
|
|
154
|
+
filter.to !== undefined ||
|
|
155
|
+
filter.function) {
|
|
156
|
+
queryEntries.push(callFilterToQueryEntry(filter));
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
return [];
|
|
130
160
|
}
|
|
131
161
|
break;
|
|
132
162
|
}
|
|
133
163
|
case common_ethereum_1.EthereumHandlerKind.Event: {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
164
|
+
const filter = handler.filter;
|
|
165
|
+
if (ds.groupedOptions) {
|
|
166
|
+
queryEntries.push(eventFilterToQueryEntry(filter, ds.groupedOptions));
|
|
167
|
+
}
|
|
168
|
+
else if (((_a = ds.options) === null || _a === void 0 ? void 0 : _a.address) || filter.topics) {
|
|
169
|
+
queryEntries.push(eventFilterToQueryEntry(filter, ds.options));
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
return [];
|
|
141
173
|
}
|
|
142
174
|
break;
|
|
143
175
|
}
|
|
@@ -148,13 +180,19 @@ let FetchService = class FetchService {
|
|
|
148
180
|
return (0, lodash_1.uniqBy)(queryEntries, (item) => `${item.entity}|${JSON.stringify((0, lodash_1.sortBy)(item.conditions, (c) => c.field))}`);
|
|
149
181
|
}
|
|
150
182
|
updateDictionary() {
|
|
183
|
+
this.dictionaryService.buildDictionaryEntryMap(this.project.dataSources.concat(this.templateDynamicDatasouces), this.buildDictionaryQueryEntries.bind(this));
|
|
184
|
+
}
|
|
185
|
+
get useDictionary() {
|
|
151
186
|
var _a;
|
|
152
|
-
this.
|
|
153
|
-
|
|
154
|
-
!!((_a = this.
|
|
155
|
-
!!this.project.network.dictionary;
|
|
187
|
+
return (!!this.project.network.dictionary &&
|
|
188
|
+
this.dictionaryMetaValid &&
|
|
189
|
+
!!this.dictionaryService.getDictionaryQueryEntries((_a = this.blockDispatcher.latestBufferedHeight) !== null && _a !== void 0 ? _a : Math.min(...this.project.dataSources.map((ds) => ds.startBlock))).length);
|
|
156
190
|
}
|
|
157
191
|
async init(startHeight) {
|
|
192
|
+
var _a;
|
|
193
|
+
if (((_a = this.project.network) === null || _a === void 0 ? void 0 : _a.bypassBlocks) !== undefined) {
|
|
194
|
+
this.bypassBlocks = (0, node_core_1.transformBypassBlocks)(this.project.network.bypassBlocks).filter((blk) => blk >= startHeight);
|
|
195
|
+
}
|
|
158
196
|
if (this.api) {
|
|
159
197
|
const CHAIN_INTERVAL = (0, utils_ethereum_1.calcInterval)(this.api) * INTERVAL_PERCENT;
|
|
160
198
|
BLOCK_TIME_VARIANCE = Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);
|
|
@@ -162,14 +200,23 @@ let FetchService = class FetchService {
|
|
|
162
200
|
}
|
|
163
201
|
await this.syncDynamicDatascourcesFromMeta();
|
|
164
202
|
this.updateDictionary();
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
203
|
+
// Call metadata here, other network should align with this
|
|
204
|
+
// For substrate, we might use the specVersion metadata in future if we have same error handling as in node-core
|
|
205
|
+
const metadata = await this.dictionaryService.getMetadata();
|
|
206
|
+
if (this.project.network.dictionary) {
|
|
207
|
+
this.evmChainId = await this.dictionaryService.getEvmChainId();
|
|
208
|
+
}
|
|
209
|
+
const dictionaryValid = this.dictionaryValidation(metadata);
|
|
210
|
+
await Promise.all([this.getFinalizedBlockHead(), this.getBestBlockHead()]);
|
|
170
211
|
await this.blockDispatcher.init(this.resetForNewDs.bind(this));
|
|
171
212
|
void this.startLoop(startHeight);
|
|
172
213
|
}
|
|
214
|
+
getUseDictionary() {
|
|
215
|
+
return this.useDictionary;
|
|
216
|
+
}
|
|
217
|
+
getLatestFinalizedHeight() {
|
|
218
|
+
return this.latestFinalizedHeight;
|
|
219
|
+
}
|
|
173
220
|
checkBatchScale() {
|
|
174
221
|
if (this.nodeConfig['scale-batch-size']) {
|
|
175
222
|
const scale = (0, node_core_1.checkMemoryUsage)(this.batchSizeScale, this.nodeConfig);
|
|
@@ -185,15 +232,22 @@ let FetchService = class FetchService {
|
|
|
185
232
|
}
|
|
186
233
|
try {
|
|
187
234
|
const currentFinalizedHeight = await this.api.getFinalizedBlockHeight();
|
|
235
|
+
logger.debug(`finalized:${currentFinalizedHeight.toString()}`);
|
|
236
|
+
const finalizedHeader = await this.api.getBlockByHeightOrHash(currentFinalizedHeight);
|
|
188
237
|
if (this.latestFinalizedHeight !== currentFinalizedHeight) {
|
|
189
238
|
this.latestFinalizedHeight = currentFinalizedHeight;
|
|
190
|
-
this.
|
|
191
|
-
|
|
192
|
-
|
|
239
|
+
this.unfinalizedBlocksService.registerFinalizedBlock(finalizedHeader);
|
|
240
|
+
if (!this.nodeConfig.unfinalizedBlocks) {
|
|
241
|
+
if (!this.nodeConfig.unfinalizedBlocks) {
|
|
242
|
+
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockTarget, {
|
|
243
|
+
height: this.latestFinalizedHeight,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
193
247
|
}
|
|
194
248
|
}
|
|
195
249
|
catch (e) {
|
|
196
|
-
logger.
|
|
250
|
+
logger.warn(e, `Having a problem when get finalized block`);
|
|
197
251
|
}
|
|
198
252
|
}
|
|
199
253
|
async getBestBlockHead() {
|
|
@@ -202,16 +256,22 @@ let FetchService = class FetchService {
|
|
|
202
256
|
return;
|
|
203
257
|
}
|
|
204
258
|
try {
|
|
205
|
-
const currentBestHeight = await this.api.
|
|
259
|
+
const currentBestHeight = await this.api.getBestBlockHeight();
|
|
260
|
+
logger.debug(`best:${currentBestHeight.toString()}`);
|
|
206
261
|
if (this.latestBestHeight !== currentBestHeight) {
|
|
207
262
|
this.latestBestHeight = currentBestHeight;
|
|
208
263
|
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockBest, {
|
|
209
264
|
height: this.latestBestHeight,
|
|
210
265
|
});
|
|
266
|
+
if (this.nodeConfig.unfinalizedBlocks) {
|
|
267
|
+
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockTarget, {
|
|
268
|
+
height: this.latestBestHeight,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
211
271
|
}
|
|
212
272
|
}
|
|
213
273
|
catch (e) {
|
|
214
|
-
logger.
|
|
274
|
+
logger.warn(e, `Having a problem when get best block`);
|
|
215
275
|
}
|
|
216
276
|
}
|
|
217
277
|
async startLoop(initBlockHeight) {
|
|
@@ -256,19 +316,31 @@ let FetchService = class FetchService {
|
|
|
256
316
|
? this.blockDispatcher.latestBufferedHeight + 1
|
|
257
317
|
: initBlockHeight;
|
|
258
318
|
};
|
|
319
|
+
if (this.useDictionary &&
|
|
320
|
+
this.dictionaryService.startHeight > getStartBlockHeight()) {
|
|
321
|
+
logger.warn(`Dictionary start height ${this.dictionaryService.startHeight} is beyond indexing height ${getStartBlockHeight()}, skipping dictionary for now`);
|
|
322
|
+
}
|
|
259
323
|
while (!this.isShutdown) {
|
|
260
324
|
startBlockHeight = getStartBlockHeight();
|
|
261
|
-
scaledBatchSize =
|
|
325
|
+
scaledBatchSize = this.blockDispatcher.smartBatchSize;
|
|
326
|
+
if (scaledBatchSize === 0) {
|
|
327
|
+
await (0, node_core_1.waitForBatchSize)(this.blockDispatcher.minimumHeapLimit);
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
const latestHeight = this.nodeConfig.unfinalizedBlocks
|
|
331
|
+
? this.latestBestHeight
|
|
332
|
+
: this.latestFinalizedHeight;
|
|
262
333
|
if (this.blockDispatcher.freeSize < scaledBatchSize ||
|
|
263
|
-
startBlockHeight >
|
|
334
|
+
startBlockHeight > latestHeight) {
|
|
264
335
|
await (0, node_core_1.delay)(1);
|
|
265
336
|
continue;
|
|
266
337
|
}
|
|
267
|
-
if (this.useDictionary
|
|
338
|
+
if (this.useDictionary &&
|
|
339
|
+
startBlockHeight >= this.dictionaryService.startHeight) {
|
|
268
340
|
const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;
|
|
269
341
|
const moduloBlocks = this.getModuloBlocks(startBlockHeight, queryEndBlock);
|
|
270
342
|
try {
|
|
271
|
-
const dictionary = await this.dictionaryService.
|
|
343
|
+
const dictionary = await this.dictionaryService.scopedDictionaryEntries(startBlockHeight, queryEndBlock, scaledBatchSize);
|
|
272
344
|
if (startBlockHeight !== getStartBlockHeight()) {
|
|
273
345
|
logger.debug(`Queue was reset for new DS, discarding dictionary query result`);
|
|
274
346
|
continue;
|
|
@@ -281,12 +353,13 @@ let FetchService = class FetchService {
|
|
|
281
353
|
.sort((a, b) => a - b);
|
|
282
354
|
if (batchBlocks.length === 0) {
|
|
283
355
|
// There we're no blocks in this query range, we can set a new height we're up to
|
|
284
|
-
this.blockDispatcher.
|
|
356
|
+
await this.blockDispatcher.enqueueBlocks([], Math.min(queryEndBlock - 1, dictionary._metadata.lastProcessedHeight));
|
|
285
357
|
}
|
|
286
358
|
else {
|
|
287
359
|
const maxBlockSize = Math.min(batchBlocks.length, this.blockDispatcher.freeSize);
|
|
288
|
-
|
|
289
|
-
this.
|
|
360
|
+
const enqueuingBlocks = batchBlocks.slice(0, maxBlockSize);
|
|
361
|
+
const cleanedBatchBlocks = this.filteredBlockBatch(enqueuingBlocks);
|
|
362
|
+
await this.blockDispatcher.enqueueBlocks(cleanedBatchBlocks, this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks));
|
|
290
363
|
}
|
|
291
364
|
continue; // skip nextBlockRange() way
|
|
292
365
|
}
|
|
@@ -298,37 +371,67 @@ let FetchService = class FetchService {
|
|
|
298
371
|
}
|
|
299
372
|
}
|
|
300
373
|
const endHeight = this.nextEndBlockHeight(startBlockHeight, scaledBatchSize);
|
|
301
|
-
|
|
302
|
-
this.
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
374
|
+
const enqueuingBlocks = handlers.length && this.getModulos().length === handlers.length
|
|
375
|
+
? this.getEnqueuedModuloBlocks(startBlockHeight)
|
|
376
|
+
: (0, lodash_1.range)(startBlockHeight, endHeight + 1);
|
|
377
|
+
const cleanedBatchBlocks = this.filteredBlockBatch(enqueuingBlocks);
|
|
378
|
+
await this.blockDispatcher.enqueueBlocks(cleanedBatchBlocks, this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks));
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
getLatestBufferHeight(cleanedBatchBlocks, rawBatchBlocks) {
|
|
382
|
+
return Math.max(...cleanedBatchBlocks, ...rawBatchBlocks);
|
|
383
|
+
}
|
|
384
|
+
filteredBlockBatch(currentBatchBlocks) {
|
|
385
|
+
if (!this.bypassBlocks.length || !currentBatchBlocks) {
|
|
386
|
+
return currentBatchBlocks;
|
|
387
|
+
}
|
|
388
|
+
const cleanedBatch = (0, node_core_1.cleanedBatchBlocks)(this.bypassBlocks, currentBatchBlocks);
|
|
389
|
+
const pollutedBlocks = this.bypassBlocks.filter((b) => b < Math.max(...currentBatchBlocks));
|
|
390
|
+
if (pollutedBlocks.length) {
|
|
391
|
+
logger.info(`Bypassing blocks: ${pollutedBlocks}`);
|
|
307
392
|
}
|
|
393
|
+
this.bypassBlocks = (0, lodash_1.without)(this.bypassBlocks, ...pollutedBlocks);
|
|
394
|
+
return cleanedBatch;
|
|
308
395
|
}
|
|
309
396
|
nextEndBlockHeight(startBlockHeight, scaledBatchSize) {
|
|
310
397
|
let endBlockHeight = startBlockHeight + scaledBatchSize - 1;
|
|
311
398
|
if (endBlockHeight > this.latestFinalizedHeight) {
|
|
312
|
-
|
|
399
|
+
if (this.nodeConfig.unfinalizedBlocks) {
|
|
400
|
+
if (endBlockHeight >= this.latestBestHeight) {
|
|
401
|
+
endBlockHeight = this.latestBestHeight;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
endBlockHeight = this.latestFinalizedHeight;
|
|
406
|
+
}
|
|
313
407
|
}
|
|
314
408
|
return endBlockHeight;
|
|
315
409
|
}
|
|
316
|
-
dictionaryValidation(
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
410
|
+
dictionaryValidation(dictionary, startBlockHeight) {
|
|
411
|
+
const validate = () => {
|
|
412
|
+
if (dictionary !== undefined) {
|
|
413
|
+
const { _metadata: metaData } = dictionary;
|
|
414
|
+
if (metaData.genesisHash !== this.api.getGenesisHash() &&
|
|
415
|
+
this.evmChainId !== this.api.getChainId().toString()) {
|
|
416
|
+
logger.error('The dictionary that you have specified does not match the chain you are indexing, it will be ignored. Please update your project manifest to reference the correct dictionary');
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
if (startBlockHeight !== undefined &&
|
|
420
|
+
metaData.lastProcessedHeight < startBlockHeight) {
|
|
421
|
+
logger.warn(`Dictionary indexed block is behind current indexing block height`);
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
return true;
|
|
425
|
+
}
|
|
329
426
|
return false;
|
|
330
|
-
}
|
|
331
|
-
|
|
427
|
+
};
|
|
428
|
+
const valid = validate();
|
|
429
|
+
this.dictionaryMetaValid = valid;
|
|
430
|
+
this.eventEmitter.emit(node_core_1.IndexerEvent.UsingDictionary, {
|
|
431
|
+
value: Number(this.useDictionary),
|
|
432
|
+
});
|
|
433
|
+
this.eventEmitter.emit(node_core_1.IndexerEvent.SkipDictionary);
|
|
434
|
+
return valid;
|
|
332
435
|
}
|
|
333
436
|
async resetForNewDs(blockHeight) {
|
|
334
437
|
await this.syncDynamicDatascourcesFromMeta();
|
|
@@ -336,6 +439,11 @@ let FetchService = class FetchService {
|
|
|
336
439
|
this.updateDictionary();
|
|
337
440
|
this.blockDispatcher.flushQueue(blockHeight);
|
|
338
441
|
}
|
|
442
|
+
async resetForIncorrectBestBlock(blockHeight) {
|
|
443
|
+
await this.syncDynamicDatascourcesFromMeta();
|
|
444
|
+
this.updateDictionary();
|
|
445
|
+
this.blockDispatcher.flushQueue(blockHeight);
|
|
446
|
+
}
|
|
339
447
|
};
|
|
340
448
|
__decorate([
|
|
341
449
|
(0, schedule_1.Interval)(CHECK_MEMORY_INTERVAL),
|
|
@@ -344,24 +452,26 @@ __decorate([
|
|
|
344
452
|
__metadata("design:returntype", void 0)
|
|
345
453
|
], FetchService.prototype, "checkBatchScale", null);
|
|
346
454
|
__decorate([
|
|
347
|
-
(0, schedule_1.Interval)(BLOCK_TIME_VARIANCE
|
|
455
|
+
(0, schedule_1.Interval)(BLOCK_TIME_VARIANCE),
|
|
348
456
|
__metadata("design:type", Function),
|
|
349
457
|
__metadata("design:paramtypes", []),
|
|
350
458
|
__metadata("design:returntype", Promise)
|
|
351
459
|
], FetchService.prototype, "getFinalizedBlockHead", null);
|
|
352
460
|
__decorate([
|
|
353
|
-
(0, schedule_1.Interval)(BLOCK_TIME_VARIANCE
|
|
461
|
+
(0, schedule_1.Interval)(BLOCK_TIME_VARIANCE),
|
|
354
462
|
__metadata("design:type", Function),
|
|
355
463
|
__metadata("design:paramtypes", []),
|
|
356
464
|
__metadata("design:returntype", Promise)
|
|
357
465
|
], FetchService.prototype, "getBestBlockHead", null);
|
|
358
466
|
FetchService = __decorate([
|
|
359
467
|
(0, common_1.Injectable)(),
|
|
468
|
+
__param(2, (0, common_1.Inject)('ISubqueryProject')),
|
|
360
469
|
__param(3, (0, common_1.Inject)('IBlockDispatcher')),
|
|
361
470
|
__metadata("design:paramtypes", [node_core_1.ApiService,
|
|
362
471
|
node_core_1.NodeConfig,
|
|
363
472
|
SubqueryProject_1.SubqueryProject, Object, dictionary_service_1.DictionaryService,
|
|
364
473
|
dynamic_ds_service_1.DynamicDsService,
|
|
474
|
+
unfinalizedBlocks_service_1.UnfinalizedBlocksService,
|
|
365
475
|
event_emitter_1.EventEmitter2,
|
|
366
476
|
schedule_1.SchedulerRegistry])
|
|
367
477
|
], FetchService);
|
|
@@ -1 +1 @@
|
|
|
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, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { Interval, SchedulerRegistry } from '@nestjs/schedule';\nimport {\n isCustomDs,\n EthereumHandlerKind,\n SubqlHandlerFilter,\n} from '@subql/common-ethereum';\nimport {\n ApiService,\n Dictionary,\n checkMemoryUsage,\n delay,\n getLogger,\n IndexerEvent,\n NodeConfig,\n} from '@subql/node-core';\nimport {\n DictionaryQueryEntry,\n ApiWrapper,\n EthereumLogFilter,\n EthereumTransactionFilter,\n} from '@subql/types-ethereum';\nimport { range, sortBy, uniqBy } from 'lodash';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { calcInterval } from '../ethereum/utils.ethereum';\nimport { eventToTopic, functionToSighash } from '../utils/string';\nimport { DictionaryService } from './dictionary.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { IBlockDispatcher } from './worker/block-dispatcher.service';\n\nconst logger = getLogger('fetch');\nlet BLOCK_TIME_VARIANCE = 5000;\nconst DICTIONARY_MAX_QUERY_SIZE = 10000;\nconst CHECK_MEMORY_INTERVAL = 60000;\nconst MINIMUM_BATCH_SIZE = 5;\nconst INTERVAL_PERCENT = 0.9;\n\nfunction eventFilterToQueryEntry(\n filter: EthereumLogFilter,\n): DictionaryQueryEntry {\n const conditions = [];\n if (filter.address) {\n conditions.push({\n field: 'address',\n value: filter.address.toLowerCase(),\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({ field, value: eventToTopic(topic) });\n }\n }\n return {\n entity: 'evmLogs',\n conditions,\n };\n}\n\nfunction callFilterToQueryEntry(\n filter: EthereumTransactionFilter,\n): DictionaryQueryEntry {\n const conditions = [];\n if (filter.from) {\n conditions.push({\n field: 'from',\n value: filter.from.toLowerCase(),\n });\n }\n if (filter.to) {\n conditions.push({\n field: 'to',\n value: filter.to.toLowerCase(),\n });\n }\n if (filter.function) {\n conditions.push({\n field: 'func',\n value: functionToSighash(filter.function),\n });\n }\n return {\n entity: 'evmTransactions',\n conditions,\n };\n}\n\n@Injectable()\nexport class FetchService implements OnApplicationShutdown {\n private latestBestHeight: number;\n private latestFinalizedHeight: number;\n private isShutdown = false;\n private useDictionary: boolean;\n private dictionaryQueryEntries?: DictionaryQueryEntry[];\n private batchSizeScale: number;\n private templateDynamicDatasouces: SubqlProjectDs[];\n\n constructor(\n private apiService: ApiService,\n private nodeConfig: NodeConfig,\n private project: SubqueryProject,\n @Inject('IBlockDispatcher') private blockDispatcher: IBlockDispatcher,\n private dictionaryService: DictionaryService,\n private dynamicDsService: DynamicDsService,\n private eventEmitter: EventEmitter2,\n private schedulerRegistry: SchedulerRegistry,\n ) {\n this.batchSizeScale = 1;\n }\n\n onApplicationShutdown(): void {\n this.isShutdown = true;\n }\n\n get api(): ApiWrapper {\n return this.apiService.api;\n }\n\n async syncDynamicDatascourcesFromMeta(): Promise<void> {\n this.templateDynamicDatasouces =\n await this.dynamicDsService.getDynamicDatasources();\n }\n\n // TODO: if custom ds doesn't support dictionary, use baseFilter, if yes, let\n getDictionaryQueryEntries(): DictionaryQueryEntry[] {\n const queryEntries: DictionaryQueryEntry[] = [];\n\n const dataSources = this.project.dataSources;\n for (const ds of dataSources.concat(this.templateDynamicDatasouces)) {\n for (const handler of ds.mapping.handlers) {\n let filterList: SubqlHandlerFilter[];\n filterList = [handler.filter];\n filterList = filterList.filter((f) => f);\n if (!filterList.length) return [];\n switch (handler.kind) {\n case EthereumHandlerKind.Block:\n return [];\n case EthereumHandlerKind.Call: {\n for (const filter of filterList 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 }\n break;\n }\n case EthereumHandlerKind.Event: {\n for (const filter of filterList as EthereumLogFilter[]) {\n if (filter.address || filter.topics) {\n queryEntries.push(eventFilterToQueryEntry(filter));\n } else {\n return [];\n }\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 updateDictionary(): void {\n this.dictionaryQueryEntries = this.getDictionaryQueryEntries();\n this.useDictionary =\n !!this.dictionaryQueryEntries?.length &&\n !!this.project.network.dictionary;\n }\n\n async init(startHeight: number): Promise<void> {\n if (this.api) {\n const CHAIN_INTERVAL = calcInterval(this.api) * INTERVAL_PERCENT;\n\n BLOCK_TIME_VARIANCE = Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);\n\n this.schedulerRegistry.addInterval(\n 'getLatestBlockHead',\n setInterval(() => void this.getBestBlockHead(), BLOCK_TIME_VARIANCE),\n );\n }\n await this.syncDynamicDatascourcesFromMeta();\n this.updateDictionary();\n this.eventEmitter.emit(IndexerEvent.UsingDictionary, {\n value: Number(this.useDictionary),\n });\n await this.getFinalizedBlockHead();\n await this.getBestBlockHead();\n\n await this.blockDispatcher.init(this.resetForNewDs.bind(this));\n\n void this.startLoop(startHeight);\n }\n\n @Interval(CHECK_MEMORY_INTERVAL)\n checkBatchScale(): void {\n if (this.nodeConfig['scale-batch-size']) {\n const scale = checkMemoryUsage(this.batchSizeScale, this.nodeConfig);\n\n if (this.batchSizeScale !== scale) {\n this.batchSizeScale = scale;\n }\n }\n }\n\n @Interval(BLOCK_TIME_VARIANCE * 1000)\n async getFinalizedBlockHead(): Promise<void> {\n if (!this.api) {\n logger.debug(`Skip fetch finalized block until API is ready`);\n return;\n }\n try {\n const currentFinalizedHeight = await this.api.getFinalizedBlockHeight();\n if (this.latestFinalizedHeight !== currentFinalizedHeight) {\n this.latestFinalizedHeight = currentFinalizedHeight;\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestFinalizedHeight,\n });\n }\n } catch (e) {\n logger.error(e, `Having a problem when get finalized block`);\n }\n }\n\n @Interval(BLOCK_TIME_VARIANCE * 1000)\n async getBestBlockHead(): Promise<void> {\n if (!this.api) {\n logger.debug(`Skip fetch best block until API is ready`);\n return;\n }\n try {\n const currentBestHeight = await this.api.getLastHeight();\n if (this.latestBestHeight !== currentBestHeight) {\n this.latestBestHeight = currentBestHeight;\n this.eventEmitter.emit(IndexerEvent.BlockBest, {\n height: this.latestBestHeight,\n });\n }\n } catch (e) {\n logger.error(e, `Having a problem when get best block`);\n }\n }\n\n async startLoop(initBlockHeight: number): Promise<void> {\n await this.fillNextBlockBuffer(initBlockHeight);\n }\n\n 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 getModuloBlocks(startHeight: number, endHeight: number): number[] {\n const modulos = this.getModulos();\n const moduloBlocks: number[] = [];\n for (let i = startHeight; i < endHeight; i++) {\n if (modulos.find((m) => i % m === 0)) {\n moduloBlocks.push(i);\n }\n }\n return moduloBlocks;\n }\n\n getEnqueuedModuloBlocks(startBlockHeight: number): number[] {\n return this.getModuloBlocks(\n startBlockHeight,\n this.nodeConfig.batchSize * Math.max(...this.getModulos()) +\n startBlockHeight,\n ).slice(0, this.nodeConfig.batchSize);\n }\n\n async fillNextBlockBuffer(initBlockHeight: number): Promise<void> {\n let startBlockHeight: number;\n let scaledBatchSize: number;\n const handlers = [].concat(\n ...this.project.dataSources.map((ds) => ds.mapping.handlers),\n );\n\n const getStartBlockHeight = (): number => {\n return this.blockDispatcher.latestBufferedHeight\n ? this.blockDispatcher.latestBufferedHeight + 1\n : initBlockHeight;\n };\n\n while (!this.isShutdown) {\n startBlockHeight = getStartBlockHeight();\n\n scaledBatchSize = Math.max(\n Math.round(this.batchSizeScale * this.nodeConfig.batchSize),\n Math.min(MINIMUM_BATCH_SIZE, this.nodeConfig.batchSize * 3),\n );\n if (\n this.blockDispatcher.freeSize < scaledBatchSize ||\n startBlockHeight > this.latestFinalizedHeight\n ) {\n await delay(1);\n continue;\n }\n if (this.useDictionary) {\n const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;\n const moduloBlocks = this.getModuloBlocks(\n startBlockHeight,\n queryEndBlock,\n );\n try {\n const dictionary = await this.dictionaryService.getDictionary(\n startBlockHeight,\n queryEndBlock,\n scaledBatchSize,\n this.dictionaryQueryEntries,\n );\n\n if (startBlockHeight !== getStartBlockHeight()) {\n logger.debug(\n `Queue was reset for new DS, discarding dictionary query result`,\n );\n continue;\n }\n\n if (\n dictionary &&\n this.dictionaryValidation(dictionary, startBlockHeight)\n ) {\n let { batchBlocks } = dictionary;\n\n batchBlocks = batchBlocks\n .concat(moduloBlocks)\n .sort((a, b) => a - b);\n if (batchBlocks.length === 0) {\n // There we're no blocks in this query range, we can set a new height we're up to\n this.blockDispatcher.latestBufferedHeight = Math.min(\n queryEndBlock - 1,\n dictionary._metadata.lastProcessedHeight,\n );\n } else {\n const maxBlockSize = Math.min(\n batchBlocks.length,\n this.blockDispatcher.freeSize,\n );\n batchBlocks = batchBlocks.slice(0, maxBlockSize);\n this.blockDispatcher.enqueueBlocks(batchBlocks);\n }\n continue; // skip nextBlockRange() way\n }\n // else use this.nextBlockRange()\n } catch (e) {\n logger.debug(`Fetch dictionary stopped: ${e.message}`);\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n }\n }\n const endHeight = this.nextEndBlockHeight(\n startBlockHeight,\n scaledBatchSize,\n );\n\n if (this.getModulos().length === handlers.length) {\n this.blockDispatcher.enqueueBlocks(\n this.getEnqueuedModuloBlocks(startBlockHeight),\n );\n } else {\n this.blockDispatcher.enqueueBlocks(\n range(startBlockHeight, endHeight + 1),\n );\n }\n }\n }\n\n private nextEndBlockHeight(\n startBlockHeight: number,\n scaledBatchSize: number,\n ): number {\n let endBlockHeight = startBlockHeight + scaledBatchSize - 1;\n\n if (endBlockHeight > this.latestFinalizedHeight) {\n endBlockHeight = this.latestFinalizedHeight;\n }\n return endBlockHeight;\n }\n\n private dictionaryValidation(\n { _metadata: metaData }: Dictionary,\n startBlockHeight: number,\n ): boolean {\n if (metaData.genesisHash !== this.api.getGenesisHash()) {\n logger.error(\n 'The dictionary that you have specified does not match the chain you are indexing, it will be ignored. Please update your project manifest to reference the correct dictionary',\n );\n this.useDictionary = false;\n this.eventEmitter.emit(IndexerEvent.UsingDictionary, {\n value: Number(this.useDictionary),\n });\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n return false;\n }\n if (metaData.lastProcessedHeight < startBlockHeight) {\n logger.warn(\n `Dictionary indexed block is behind current indexing block height`,\n );\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n return false;\n }\n return true;\n }\n\n async resetForNewDs(blockHeight: number): Promise<void> {\n await this.syncDynamicDatascourcesFromMeta();\n this.dynamicDsService.deleteTempDsRecords(blockHeight);\n this.updateDictionary();\n this.blockDispatcher.flushQueue(blockHeight);\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, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { Interval, SchedulerRegistry } from '@nestjs/schedule';\n\nimport {\n isCustomDs,\n EthereumHandlerKind,\n EthereumLogFilter,\n SubqlEthereumProcessorOptions,\n EthereumTransactionFilter,\n} from '@subql/common-ethereum';\nimport {\n ApiService,\n cleanedBatchBlocks,\n checkMemoryUsage,\n delay,\n getLogger,\n IndexerEvent,\n NodeConfig,\n transformBypassBlocks,\n waitForBatchSize,\n} from '@subql/node-core';\nimport {\n ApiWrapper,\n DictionaryQueryCondition,\n DictionaryQueryEntry,\n} from '@subql/types-ethereum';\nimport { MetaData } from '@subql/utils';\nimport { groupBy, range, sortBy, uniqBy, without } from 'lodash';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { calcInterval } from '../ethereum/utils.ethereum';\nimport { eventToTopic, functionToSighash } from '../utils/string';\nimport { IEthereumBlockDispatcher } from './blockDispatcher';\nimport { DictionaryService } from './dictionary.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { UnfinalizedBlocksService } from './unfinalizedBlocks.service';\n\nconst logger = getLogger('fetch');\nlet BLOCK_TIME_VARIANCE = 5000;\nconst DICTIONARY_MAX_QUERY_SIZE = 10000;\nconst CHECK_MEMORY_INTERVAL = 60000;\nconst MINIMUM_BATCH_SIZE = 5;\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: 'inInsensitive',\n });\n }\n } else {\n if (dsOptions?.address) {\n conditions.push({\n field: 'address',\n value: dsOptions.address.toLowerCase(),\n // matcher: 'equals',\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 });\n }\n if (filter.to) {\n conditions.push({\n field: 'to',\n value: filter.to.toLowerCase(),\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 implements OnApplicationShutdown {\n private latestBestHeight: number;\n private latestFinalizedHeight: number;\n private isShutdown = false;\n private batchSizeScale: number;\n private templateDynamicDatasouces: SubqlProjectDs[];\n private dictionaryMetaValid = false;\n private evmChainId: string;\n private bypassBlocks: number[] = [];\n\n constructor(\n private apiService: ApiService,\n private nodeConfig: NodeConfig,\n @Inject('ISubqueryProject') private project: SubqueryProject,\n @Inject('IBlockDispatcher')\n private blockDispatcher: IEthereumBlockDispatcher,\n private dictionaryService: DictionaryService,\n private dynamicDsService: DynamicDsService,\n private unfinalizedBlocksService: UnfinalizedBlocksService,\n private eventEmitter: EventEmitter2,\n private schedulerRegistry: SchedulerRegistry,\n ) {\n this.batchSizeScale = 1;\n }\n\n onApplicationShutdown(): void {\n this.isShutdown = true;\n }\n\n get api(): ApiWrapper {\n return this.apiService.api;\n }\n\n async syncDynamicDatascourcesFromMeta(): Promise<void> {\n this.templateDynamicDatasouces =\n await this.dynamicDsService.getDynamicDatasources();\n }\n\n buildDictionaryQueryEntries(startBlock: number): DictionaryQueryEntry[] {\n const queryEntries: DictionaryQueryEntry[] = [];\n\n type GroupedSubqlProjectDs = SubqlProjectDs & {\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 updateDictionary(): void {\n this.dictionaryService.buildDictionaryEntryMap<SubqlProjectDs>(\n this.project.dataSources.concat(this.templateDynamicDatasouces),\n this.buildDictionaryQueryEntries.bind(this),\n );\n }\n\n private get useDictionary(): boolean {\n return (\n !!this.project.network.dictionary &&\n this.dictionaryMetaValid &&\n !!this.dictionaryService.getDictionaryQueryEntries(\n this.blockDispatcher.latestBufferedHeight ??\n Math.min(...this.project.dataSources.map((ds) => ds.startBlock)),\n ).length\n );\n }\n\n async init(startHeight: number): Promise<void> {\n if (this.project.network?.bypassBlocks !== undefined) {\n this.bypassBlocks = transformBypassBlocks(\n this.project.network.bypassBlocks,\n ).filter((blk) => blk >= startHeight);\n }\n if (this.api) {\n const CHAIN_INTERVAL = calcInterval(this.api) * INTERVAL_PERCENT;\n\n BLOCK_TIME_VARIANCE = Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);\n\n this.schedulerRegistry.addInterval(\n 'getLatestBlockHead',\n setInterval(() => void this.getBestBlockHead(), BLOCK_TIME_VARIANCE),\n );\n }\n await this.syncDynamicDatascourcesFromMeta();\n\n this.updateDictionary();\n // Call metadata here, other network should align with this\n // For substrate, we might use the specVersion metadata in future if we have same error handling as in node-core\n const metadata = await this.dictionaryService.getMetadata();\n if (this.project.network.dictionary) {\n this.evmChainId = await this.dictionaryService.getEvmChainId();\n }\n const dictionaryValid = this.dictionaryValidation(metadata);\n\n await Promise.all([this.getFinalizedBlockHead(), this.getBestBlockHead()]);\n\n await this.blockDispatcher.init(this.resetForNewDs.bind(this));\n void this.startLoop(startHeight);\n }\n\n getUseDictionary(): boolean {\n return this.useDictionary;\n }\n\n getLatestFinalizedHeight(): number {\n return this.latestFinalizedHeight;\n }\n\n @Interval(CHECK_MEMORY_INTERVAL)\n checkBatchScale(): void {\n if (this.nodeConfig['scale-batch-size']) {\n const scale = checkMemoryUsage(this.batchSizeScale, this.nodeConfig);\n\n if (this.batchSizeScale !== scale) {\n this.batchSizeScale = scale;\n }\n }\n }\n\n @Interval(BLOCK_TIME_VARIANCE)\n async getFinalizedBlockHead(): Promise<void> {\n if (!this.api) {\n logger.debug(`Skip fetch finalized block until API is ready`);\n return;\n }\n try {\n const currentFinalizedHeight = await this.api.getFinalizedBlockHeight();\n logger.debug(`finalized:${currentFinalizedHeight.toString()}`);\n const finalizedHeader = await this.api.getBlockByHeightOrHash(\n currentFinalizedHeight,\n );\n if (this.latestFinalizedHeight !== currentFinalizedHeight) {\n this.latestFinalizedHeight = currentFinalizedHeight;\n this.unfinalizedBlocksService.registerFinalizedBlock(finalizedHeader);\n if (!this.nodeConfig.unfinalizedBlocks) {\n if (!this.nodeConfig.unfinalizedBlocks) {\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestFinalizedHeight,\n });\n }\n }\n }\n } catch (e) {\n logger.warn(e, `Having a problem when get finalized block`);\n }\n }\n\n @Interval(BLOCK_TIME_VARIANCE)\n async getBestBlockHead(): Promise<void> {\n if (!this.api) {\n logger.debug(`Skip fetch best block until API is ready`);\n return;\n }\n try {\n const currentBestHeight = await this.api.getBestBlockHeight();\n logger.debug(`best:${currentBestHeight.toString()}`);\n if (this.latestBestHeight !== currentBestHeight) {\n this.latestBestHeight = currentBestHeight;\n this.eventEmitter.emit(IndexerEvent.BlockBest, {\n height: this.latestBestHeight,\n });\n\n if (this.nodeConfig.unfinalizedBlocks) {\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestBestHeight,\n });\n }\n }\n } catch (e) {\n logger.warn(e, `Having a problem when get best block`);\n }\n }\n private async startLoop(initBlockHeight: number): Promise<void> {\n await this.fillNextBlockBuffer(initBlockHeight);\n }\n\n 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 getModuloBlocks(startHeight: number, endHeight: number): number[] {\n const modulos = this.getModulos();\n const moduloBlocks: number[] = [];\n for (let i = startHeight; i < endHeight; i++) {\n if (modulos.find((m) => i % m === 0)) {\n moduloBlocks.push(i);\n }\n }\n return moduloBlocks;\n }\n\n getEnqueuedModuloBlocks(startBlockHeight: number): number[] {\n return this.getModuloBlocks(\n startBlockHeight,\n this.nodeConfig.batchSize * Math.max(...this.getModulos()) +\n startBlockHeight,\n ).slice(0, this.nodeConfig.batchSize);\n }\n\n async fillNextBlockBuffer(initBlockHeight: number): Promise<void> {\n let startBlockHeight: number;\n let scaledBatchSize: number;\n const handlers = [].concat(\n ...this.project.dataSources.map((ds) => ds.mapping.handlers),\n );\n\n const getStartBlockHeight = (): number => {\n return this.blockDispatcher.latestBufferedHeight\n ? this.blockDispatcher.latestBufferedHeight + 1\n : initBlockHeight;\n };\n\n if (\n this.useDictionary &&\n this.dictionaryService.startHeight > getStartBlockHeight()\n ) {\n logger.warn(\n `Dictionary start height ${\n this.dictionaryService.startHeight\n } is beyond indexing height ${getStartBlockHeight()}, skipping dictionary for now`,\n );\n }\n\n while (!this.isShutdown) {\n startBlockHeight = getStartBlockHeight();\n\n scaledBatchSize = this.blockDispatcher.smartBatchSize;\n\n if (scaledBatchSize === 0) {\n await waitForBatchSize(this.blockDispatcher.minimumHeapLimit);\n continue;\n }\n\n const latestHeight = this.nodeConfig.unfinalizedBlocks\n ? this.latestBestHeight\n : this.latestFinalizedHeight;\n\n if (\n this.blockDispatcher.freeSize < scaledBatchSize ||\n startBlockHeight > latestHeight\n ) {\n await delay(1);\n continue;\n }\n\n if (\n this.useDictionary &&\n startBlockHeight >= this.dictionaryService.startHeight\n ) {\n const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;\n const moduloBlocks = this.getModuloBlocks(\n startBlockHeight,\n queryEndBlock,\n );\n\n try {\n const dictionary =\n await this.dictionaryService.scopedDictionaryEntries(\n startBlockHeight,\n queryEndBlock,\n scaledBatchSize,\n );\n\n if (startBlockHeight !== getStartBlockHeight()) {\n logger.debug(\n `Queue was reset for new DS, discarding dictionary query result`,\n );\n continue;\n }\n\n if (\n dictionary &&\n this.dictionaryValidation(dictionary, startBlockHeight)\n ) {\n let { batchBlocks } = dictionary;\n\n batchBlocks = batchBlocks\n .concat(moduloBlocks)\n .sort((a, b) => a - b);\n if (batchBlocks.length === 0) {\n // There we're no blocks in this query range, we can set a new height we're up to\n await this.blockDispatcher.enqueueBlocks(\n [],\n Math.min(\n queryEndBlock - 1,\n dictionary._metadata.lastProcessedHeight,\n ),\n );\n } else {\n const maxBlockSize = Math.min(\n batchBlocks.length,\n this.blockDispatcher.freeSize,\n );\n const enqueuingBlocks = batchBlocks.slice(0, maxBlockSize);\n const cleanedBatchBlocks =\n this.filteredBlockBatch(enqueuingBlocks);\n await this.blockDispatcher.enqueueBlocks(\n cleanedBatchBlocks,\n this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks),\n );\n }\n continue; // skip nextBlockRange() way\n }\n // else use this.nextBlockRange()\n } catch (e) {\n logger.debug(`Fetch dictionary stopped: ${e.message}`);\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n }\n }\n\n const endHeight = this.nextEndBlockHeight(\n startBlockHeight,\n scaledBatchSize,\n );\n\n const enqueuingBlocks =\n handlers.length && this.getModulos().length === handlers.length\n ? this.getEnqueuedModuloBlocks(startBlockHeight)\n : range(startBlockHeight, endHeight + 1);\n\n const cleanedBatchBlocks = this.filteredBlockBatch(enqueuingBlocks);\n await this.blockDispatcher.enqueueBlocks(\n cleanedBatchBlocks,\n this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks),\n );\n }\n }\n\n private getLatestBufferHeight(\n cleanedBatchBlocks: number[],\n rawBatchBlocks: number[],\n ): number {\n return Math.max(...cleanedBatchBlocks, ...rawBatchBlocks);\n }\n private filteredBlockBatch(currentBatchBlocks: number[]): number[] {\n if (!this.bypassBlocks.length || !currentBatchBlocks) {\n return currentBatchBlocks;\n }\n\n const cleanedBatch = cleanedBatchBlocks(\n this.bypassBlocks,\n currentBatchBlocks,\n );\n\n const pollutedBlocks = this.bypassBlocks.filter(\n (b) => b < Math.max(...currentBatchBlocks),\n );\n if (pollutedBlocks.length) {\n logger.info(`Bypassing blocks: ${pollutedBlocks}`);\n }\n this.bypassBlocks = without(this.bypassBlocks, ...pollutedBlocks);\n return cleanedBatch;\n }\n\n private nextEndBlockHeight(\n startBlockHeight: number,\n scaledBatchSize: number,\n ): number {\n let endBlockHeight = startBlockHeight + scaledBatchSize - 1;\n\n if (endBlockHeight > this.latestFinalizedHeight) {\n if (this.nodeConfig.unfinalizedBlocks) {\n if (endBlockHeight >= this.latestBestHeight) {\n endBlockHeight = this.latestBestHeight;\n }\n } else {\n endBlockHeight = this.latestFinalizedHeight;\n }\n }\n return endBlockHeight;\n }\n\n private dictionaryValidation(\n dictionary: { _metadata: MetaData },\n startBlockHeight?: number,\n ): boolean {\n const validate = (): boolean => {\n if (dictionary !== undefined) {\n const { _metadata: metaData } = dictionary;\n\n if (\n metaData.genesisHash !== this.api.getGenesisHash() &&\n this.evmChainId !== this.api.getChainId().toString()\n ) {\n logger.error(\n 'The dictionary that you have specified does not match the chain you are indexing, it will be ignored. Please update your project manifest to reference the correct dictionary',\n );\n return false;\n }\n\n if (\n startBlockHeight !== undefined &&\n metaData.lastProcessedHeight < startBlockHeight\n ) {\n logger.warn(\n `Dictionary indexed block is behind current indexing block height`,\n );\n return false;\n }\n return true;\n }\n return false;\n };\n\n const valid = validate();\n\n this.dictionaryMetaValid = valid;\n this.eventEmitter.emit(IndexerEvent.UsingDictionary, {\n value: Number(this.useDictionary),\n });\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n\n return valid;\n }\n\n async resetForNewDs(blockHeight: number): Promise<void> {\n await this.syncDynamicDatascourcesFromMeta();\n this.dynamicDsService.deleteTempDsRecords(blockHeight);\n this.updateDictionary();\n this.blockDispatcher.flushQueue(blockHeight);\n }\n async resetForIncorrectBestBlock(blockHeight: number): Promise<void> {\n await this.syncDynamicDatascourcesFromMeta();\n this.updateDictionary();\n this.blockDispatcher.flushQueue(blockHeight);\n }\n}\n"]}
|
|
@@ -1,34 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NodeConfig, ProcessBlockResponse, ApiService, IIndexerManager } from '@subql/node-core';
|
|
2
2
|
import { EthereumBlockWrapper } from '@subql/types-ethereum';
|
|
3
|
-
import {
|
|
4
|
-
import { SubqueryProject } from '../configure/SubqueryProject';
|
|
3
|
+
import { SubqlProjectDs } from '../configure/SubqueryProject';
|
|
5
4
|
import { DsProcessorService } from './ds-processor.service';
|
|
6
5
|
import { DynamicDsService } from './dynamic-ds.service';
|
|
7
6
|
import { ProjectService } from './project.service';
|
|
8
7
|
import { SandboxService } from './sandbox.service';
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
import { UnfinalizedBlocksService } from './unfinalizedBlocks.service';
|
|
9
|
+
export declare class IndexerManager implements IIndexerManager<EthereumBlockWrapper, SubqlProjectDs> {
|
|
11
10
|
private apiService;
|
|
12
|
-
private poiService;
|
|
13
|
-
private sequelize;
|
|
14
|
-
private project;
|
|
15
11
|
private nodeConfig;
|
|
16
12
|
private sandboxService;
|
|
17
|
-
private dynamicDsService;
|
|
18
13
|
private dsProcessorService;
|
|
14
|
+
private dynamicDsService;
|
|
15
|
+
private unfinalizedBlocksService;
|
|
19
16
|
private projectService;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
constructor(storeService: StoreService, apiService: ApiService, poiService: PoiService, sequelize: Sequelize, project: SubqueryProject, nodeConfig: NodeConfig, sandboxService: SandboxService, dynamicDsService: DynamicDsService, dsProcessorService: DsProcessorService, projectService: ProjectService);
|
|
23
|
-
indexBlock(blockContent: EthereumBlockWrapper): Promise<{
|
|
24
|
-
dynamicDsCreated: boolean;
|
|
25
|
-
operationHash: Uint8Array;
|
|
26
|
-
}>;
|
|
17
|
+
constructor(apiService: ApiService, nodeConfig: NodeConfig, sandboxService: SandboxService, dsProcessorService: DsProcessorService, dynamicDsService: DynamicDsService, unfinalizedBlocksService: UnfinalizedBlocksService, projectService: ProjectService);
|
|
18
|
+
indexBlock(blockContent: EthereumBlockWrapper, dataSources: SubqlProjectDs[]): Promise<ProcessBlockResponse>;
|
|
27
19
|
start(): Promise<void>;
|
|
20
|
+
private processUnfinalizedBlocks;
|
|
28
21
|
private filterDataSources;
|
|
22
|
+
private assertDataSources;
|
|
29
23
|
private indexBlockData;
|
|
30
24
|
private indexBlockContent;
|
|
31
|
-
private
|
|
25
|
+
private indexTransaction;
|
|
32
26
|
private indexEvent;
|
|
33
27
|
private indexData;
|
|
34
28
|
private filterCustomDsHandlers;
|