@subql/node-ethereum 3.11.0 → 3.11.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/dist/.tsbuildinfo +1 -1
- package/dist/ethereum/api.connection.d.ts +4 -4
- package/dist/ethereum/api.connection.js.map +1 -1
- package/dist/ethereum/api.ethereum.d.ts +4 -3
- package/dist/ethereum/api.ethereum.js +6 -3
- package/dist/ethereum/api.ethereum.js.map +1 -1
- package/dist/ethereum/api.ethereum.test.js +13 -1
- package/dist/ethereum/api.ethereum.test.js.map +1 -1
- package/dist/ethereum/api.service.ethereum.d.ts +2 -2
- package/dist/ethereum/api.service.ethereum.js.map +1 -1
- package/dist/ethereum/block.ethereum.js +6 -2
- package/dist/ethereum/block.ethereum.js.map +1 -1
- package/dist/ethereum/utils.ethereum.d.ts +8 -1
- package/dist/ethereum/utils.ethereum.js +17 -1
- package/dist/ethereum/utils.ethereum.js.map +1 -1
- package/dist/indexer/blockDispatcher/block-dispatcher.service.d.ts +2 -3
- package/dist/indexer/blockDispatcher/block-dispatcher.service.js +1 -4
- package/dist/indexer/blockDispatcher/block-dispatcher.service.js.map +1 -1
- package/dist/indexer/blockDispatcher/ethereum-block-dispatcher.d.ts +2 -1
- package/dist/indexer/blockDispatcher/ethereum-block-dispatcher.js.map +1 -1
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.d.ts +2 -1
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js +0 -12
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js.map +1 -1
- package/dist/indexer/dictionary/ethDictionary.service.d.ts +9 -0
- package/dist/indexer/dictionary/ethDictionary.service.js +59 -0
- package/dist/indexer/dictionary/ethDictionary.service.js.map +1 -0
- package/dist/indexer/dictionary/utils.d.ts +3 -0
- package/dist/indexer/dictionary/utils.js +24 -0
- package/dist/indexer/dictionary/utils.js.map +1 -0
- package/dist/indexer/dictionary/utils.spec.js +83 -0
- package/dist/indexer/dictionary/utils.spec.js.map +1 -0
- package/dist/indexer/dictionary/v1/ethDictionaryV1.d.ts +16 -0
- package/dist/indexer/dictionary/v1/ethDictionaryV1.js +202 -0
- package/dist/indexer/dictionary/v1/ethDictionaryV1.js.map +1 -0
- package/dist/indexer/{fetch.service.spec.js → dictionary/v1/ethDictionaryV1.spec.js} +45 -23
- package/dist/indexer/dictionary/v1/ethDictionaryV1.spec.js.map +1 -0
- package/dist/indexer/dictionary/v1/index.d.ts +1 -0
- package/dist/indexer/dictionary/v1/index.js +20 -0
- package/dist/indexer/dictionary/v1/index.js.map +1 -0
- package/dist/indexer/dictionary/v2/ethDictionaryV2.d.ts +14 -0
- package/dist/indexer/dictionary/v2/ethDictionaryV2.js +188 -0
- package/dist/indexer/dictionary/v2/ethDictionaryV2.js.map +1 -0
- package/dist/indexer/dictionary/v2/ethDictionaryV2.spec.d.ts +1 -0
- package/dist/indexer/dictionary/v2/ethDictionaryV2.spec.js +232 -0
- package/dist/indexer/dictionary/v2/ethDictionaryV2.spec.js.map +1 -0
- package/dist/indexer/dictionary/v2/index.d.ts +2 -0
- package/dist/indexer/dictionary/v2/index.js +21 -0
- package/dist/indexer/dictionary/v2/index.js.map +1 -0
- package/dist/indexer/dictionary/v2/types.d.ts +75 -0
- package/dist/indexer/dictionary/v2/types.js +5 -0
- package/dist/indexer/dictionary/v2/types.js.map +1 -0
- package/dist/indexer/dictionary/v2/utils.d.ts +4 -0
- package/dist/indexer/dictionary/v2/utils.js +22 -0
- package/dist/indexer/dictionary/v2/utils.js.map +1 -0
- package/dist/indexer/dictionary/v2/utils.spec.d.ts +1 -0
- package/dist/indexer/dictionary/v2/utils.spec.js +98 -0
- package/dist/indexer/dictionary/v2/utils.spec.js.map +1 -0
- package/dist/indexer/fetch.module.js +4 -3
- package/dist/indexer/fetch.module.js.map +1 -1
- package/dist/indexer/fetch.service.d.ts +4 -14
- package/dist/indexer/fetch.service.js +4 -177
- package/dist/indexer/fetch.service.js.map +1 -1
- package/dist/indexer/indexer.manager.d.ts +5 -5
- package/dist/indexer/indexer.manager.js +3 -3
- package/dist/indexer/indexer.manager.js.map +1 -1
- package/dist/indexer/unfinalizedBlocks.service.d.ts +1 -5
- package/dist/indexer/unfinalizedBlocks.service.js +5 -21
- package/dist/indexer/unfinalizedBlocks.service.js.map +1 -1
- package/dist/indexer/worker/worker.service.d.ts +4 -4
- package/dist/indexer/worker/worker.service.js +1 -1
- package/dist/indexer/worker/worker.service.js.map +1 -1
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.d.ts +2 -2
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.js +2 -6
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.js.map +1 -1
- package/dist/subcommands/testing.service.d.ts +2 -2
- package/dist/subcommands/testing.service.js.map +1 -1
- package/package.json +8 -7
- package/dist/indexer/dictionary.service.d.ts +0 -11
- package/dist/indexer/dictionary.service.js +0 -72
- package/dist/indexer/dictionary.service.js.map +0 -1
- package/dist/indexer/dictionary.service.spec.js +0 -15
- package/dist/indexer/dictionary.service.spec.js.map +0 -1
- package/dist/indexer/fetch.service.spec.js.map +0 -1
- /package/dist/indexer/{dictionary.service.spec.d.ts → dictionary/utils.spec.d.ts} +0 -0
- /package/dist/indexer/{fetch.service.spec.d.ts → dictionary/v1/ethDictionaryV1.spec.d.ts} +0 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
const node_core_1 = require("@subql/node-core");
|
|
6
|
+
const types_ethereum_1 = require("@subql/types-ethereum");
|
|
7
|
+
const ethDictionaryV2_1 = require("./ethDictionaryV2");
|
|
8
|
+
const DEFAULT_DICTIONARY = 'http://localhost:3000/rpc/eth-mainnet';
|
|
9
|
+
const HTTP_ENDPOINT = 'https://polygon.api.onfinality.io/public';
|
|
10
|
+
const mockDs = [
|
|
11
|
+
{
|
|
12
|
+
kind: types_ethereum_1.EthereumDatasourceKind.Runtime,
|
|
13
|
+
assets: new Map(),
|
|
14
|
+
startBlock: 3678215,
|
|
15
|
+
mapping: {
|
|
16
|
+
file: './dist/index.js',
|
|
17
|
+
handlers: [
|
|
18
|
+
{
|
|
19
|
+
handler: 'handleTransaction',
|
|
20
|
+
kind: types_ethereum_1.EthereumHandlerKind.Call,
|
|
21
|
+
filter: {
|
|
22
|
+
function: 'approve(address spender, uint256 rawAmount)',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
handler: 'handleLog',
|
|
27
|
+
kind: types_ethereum_1.EthereumHandlerKind.Event,
|
|
28
|
+
filter: {
|
|
29
|
+
topics: [
|
|
30
|
+
'Transfer(address indexed from, address indexed to, uint256 amount)',
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
// tx to is null
|
|
39
|
+
const mockDs2 = [
|
|
40
|
+
{
|
|
41
|
+
kind: types_ethereum_1.EthereumDatasourceKind.Runtime,
|
|
42
|
+
assets: new Map(),
|
|
43
|
+
startBlock: 3678215,
|
|
44
|
+
mapping: {
|
|
45
|
+
file: './dist/index.js',
|
|
46
|
+
handlers: [
|
|
47
|
+
{
|
|
48
|
+
handler: 'handleTransaction',
|
|
49
|
+
kind: types_ethereum_1.EthereumHandlerKind.Call,
|
|
50
|
+
filter: {
|
|
51
|
+
to: null,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
const nodeConfig = new node_core_1.NodeConfig({
|
|
59
|
+
subquery: 'polygon-starter',
|
|
60
|
+
subqueryName: 'polygon-starter',
|
|
61
|
+
dictionaryTimeout: 10,
|
|
62
|
+
networkEndpoint: [HTTP_ENDPOINT],
|
|
63
|
+
networkDictionary: [`${DEFAULT_DICTIONARY}/polygon`],
|
|
64
|
+
});
|
|
65
|
+
function makeBlockHeightMap(mockDs) {
|
|
66
|
+
const m = new Map();
|
|
67
|
+
mockDs.forEach((ds, index, dataSources) => {
|
|
68
|
+
m.set(ds.startBlock, dataSources.slice(0, index + 1));
|
|
69
|
+
});
|
|
70
|
+
return new node_core_1.BlockHeightMap(m);
|
|
71
|
+
}
|
|
72
|
+
// enable this once dictionary v2 is online
|
|
73
|
+
describe('eth dictionary v2', () => {
|
|
74
|
+
let ethDictionaryV2;
|
|
75
|
+
let ethBlock3678215;
|
|
76
|
+
let ethBlock3678250;
|
|
77
|
+
const dsMap = makeBlockHeightMap(mockDs);
|
|
78
|
+
beforeEach(async () => {
|
|
79
|
+
ethDictionaryV2 = await ethDictionaryV2_1.EthDictionaryV2.create(DEFAULT_DICTIONARY, nodeConfig, undefined, { network: { chainId: '10' } }, '10');
|
|
80
|
+
ethDictionaryV2.updateQueriesMap(dsMap);
|
|
81
|
+
});
|
|
82
|
+
it('convert ds to v2 dictionary queries', () => {
|
|
83
|
+
//Polygon
|
|
84
|
+
const query = ethDictionaryV2.queriesMap.get(3678215);
|
|
85
|
+
expect(query.logs.length).toBe(1);
|
|
86
|
+
expect(query.transactions.length).toBe(1);
|
|
87
|
+
}, 100000);
|
|
88
|
+
it('query response match with entries', async () => {
|
|
89
|
+
//Polygon
|
|
90
|
+
const ethBlocks = (await ethDictionaryV2.getData(3678215, ethDictionaryV2._metadata.end, 2));
|
|
91
|
+
expect(ethBlocks.batchBlocks.map((b) => b.block.number)).toStrictEqual([
|
|
92
|
+
3678215, 3678250,
|
|
93
|
+
]);
|
|
94
|
+
ethBlock3678215 = ethBlocks.batchBlocks[0].block;
|
|
95
|
+
ethBlock3678250 = ethBlocks.batchBlocks[1].block;
|
|
96
|
+
expect(ethBlock3678215.number).toBe(3678215);
|
|
97
|
+
expect(ethBlock3678250.number).toBe(3678250);
|
|
98
|
+
// To match with dictionaryQueryEntries[0].func
|
|
99
|
+
expect(ethBlock3678215.transactions[0].input.indexOf('0x60806040')).toBe(0);
|
|
100
|
+
expect(ethBlock3678250.logs.length).toBe(1);
|
|
101
|
+
// This matches with dictionaryQueryEntries[0].topics
|
|
102
|
+
expect(ethBlock3678250.logs[0].topics).toContain('0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef');
|
|
103
|
+
}, 100000);
|
|
104
|
+
it('able to convert raw v2 Blocks into eth blocks when getData', async () => {
|
|
105
|
+
//Polygon
|
|
106
|
+
const ethBlocks = (await ethDictionaryV2.getData(3678215, ethDictionaryV2._metadata.end, 2));
|
|
107
|
+
expect(ethBlocks.batchBlocks[0].block.number).toStrictEqual(3678215);
|
|
108
|
+
expect(ethBlocks.lastBufferedHeight).toStrictEqual(3678250);
|
|
109
|
+
// Can include input and hash
|
|
110
|
+
// https://polygonscan.com/tx/0xb1b5f7882fa8d62d3650948c08066e928b7b5c9d607d2fe8c7e6ce57caf06774
|
|
111
|
+
expect(ethBlocks.batchBlocks[1].block.transactions[1].hash).toBe(`0xb1b5f7882fa8d62d3650948c08066e928b7b5c9d607d2fe8c7e6ce57caf06774`);
|
|
112
|
+
expect(ethBlocks.batchBlocks[1].block.transactions[1].input).toBe(`0x23b872dd000000000000000000000000244a79a2e79e8d884d9c9cc425d88f9e2ed988ca000000000000000000000000d22c4c383ce5efa0364d5fab5ce1313c24a52bda0000000000000000000000000000000000000000000000000000000000000159`);
|
|
113
|
+
// relate logs
|
|
114
|
+
// https://polygonscan.com/tx/0xb1b5f7882fa8d62d3650948c08066e928b7b5c9d607d2fe8c7e6ce57caf06774#eventlog
|
|
115
|
+
expect(ethBlocks.batchBlocks[1].block.logs[0].data).toBe(`0x`);
|
|
116
|
+
}, 500000);
|
|
117
|
+
});
|
|
118
|
+
// TODO, check this
|
|
119
|
+
it.skip('able to get transaction with field to is null', async () => {
|
|
120
|
+
const dsMap = makeBlockHeightMap(mockDs2);
|
|
121
|
+
const ethDictionaryV2 = await ethDictionaryV2_1.EthDictionaryV2.create(DEFAULT_DICTIONARY, nodeConfig, undefined, { network: { chainId: '10' } }, '10');
|
|
122
|
+
ethDictionaryV2.updateQueriesMap(dsMap);
|
|
123
|
+
const { conditions, queryEndBlock } = ethDictionaryV2.getQueryConditions(3678215, ethDictionaryV2._metadata.end);
|
|
124
|
+
expect(conditions).toBe({ transactions: [{ to: null }] });
|
|
125
|
+
const ethBlocks = (await ethDictionaryV2.getData(3678215, ethDictionaryV2._metadata.end, 2));
|
|
126
|
+
}, 50000);
|
|
127
|
+
describe('buildDictionaryV2QueryEntry', () => {
|
|
128
|
+
it('Build filter for !null', () => {
|
|
129
|
+
const ds = {
|
|
130
|
+
kind: types_ethereum_1.EthereumDatasourceKind.Runtime,
|
|
131
|
+
assets: new Map(),
|
|
132
|
+
options: {
|
|
133
|
+
abi: 'erc20',
|
|
134
|
+
address: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
|
|
135
|
+
},
|
|
136
|
+
startBlock: 1,
|
|
137
|
+
mapping: {
|
|
138
|
+
file: '',
|
|
139
|
+
handlers: [
|
|
140
|
+
{
|
|
141
|
+
handler: 'handleLog',
|
|
142
|
+
kind: types_ethereum_1.EthereumHandlerKind.Event,
|
|
143
|
+
filter: {
|
|
144
|
+
topics: [
|
|
145
|
+
'Transfer(address, address, uint256)',
|
|
146
|
+
undefined,
|
|
147
|
+
undefined,
|
|
148
|
+
'!null',
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
const result = (0, ethDictionaryV2_1.buildDictionaryV2QueryEntry)([ds]);
|
|
156
|
+
expect(result).toEqual({
|
|
157
|
+
logs: [
|
|
158
|
+
{
|
|
159
|
+
address: ['0x7ceb23fd6bc0add59e62ac25578270cff1b9f619'],
|
|
160
|
+
topics0: [
|
|
161
|
+
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
|
|
162
|
+
],
|
|
163
|
+
topics3: [],
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
it('should unique QueryEntry for duplicate dataSources', () => {
|
|
169
|
+
const ds = {
|
|
170
|
+
kind: types_ethereum_1.EthereumDatasourceKind.Runtime,
|
|
171
|
+
assets: new Map(),
|
|
172
|
+
options: {
|
|
173
|
+
abi: 'erc20',
|
|
174
|
+
address: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
|
|
175
|
+
},
|
|
176
|
+
startBlock: 1,
|
|
177
|
+
mapping: {
|
|
178
|
+
file: '',
|
|
179
|
+
handlers: [
|
|
180
|
+
{
|
|
181
|
+
handler: 'handleLog',
|
|
182
|
+
kind: types_ethereum_1.EthereumHandlerKind.Event,
|
|
183
|
+
filter: {
|
|
184
|
+
topics: ['Transfer(address, address, uint256)'],
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
handler: 'handleLogSame',
|
|
189
|
+
kind: types_ethereum_1.EthereumHandlerKind.Event,
|
|
190
|
+
filter: {
|
|
191
|
+
topics: ['Transfer(address, address, uint256)'],
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
handler: 'handleTx',
|
|
196
|
+
kind: types_ethereum_1.EthereumHandlerKind.Call,
|
|
197
|
+
filter: {
|
|
198
|
+
function: 'setminimumStakingAmount(uint256 amount)',
|
|
199
|
+
from: 'mockAddress',
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
handler: 'handleTxSame',
|
|
204
|
+
kind: types_ethereum_1.EthereumHandlerKind.Call,
|
|
205
|
+
filter: {
|
|
206
|
+
function: 'setminimumStakingAmount(uint256 amount)',
|
|
207
|
+
from: 'mockAddress',
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
const result = (0, ethDictionaryV2_1.buildDictionaryV2QueryEntry)([ds]);
|
|
214
|
+
expect(result).toEqual({
|
|
215
|
+
logs: [
|
|
216
|
+
{
|
|
217
|
+
address: ['0x7ceb23fd6bc0add59e62ac25578270cff1b9f619'],
|
|
218
|
+
topics0: [
|
|
219
|
+
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
transactions: [
|
|
224
|
+
{
|
|
225
|
+
from: ['mockaddress'],
|
|
226
|
+
function: ['0x7ef9ea98'],
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
//# sourceMappingURL=ethDictionaryV2.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ethDictionaryV2.spec.js","sourceRoot":"","sources":["../../../../src/indexer/dictionary/v2/ethDictionaryV2.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport {\n NodeConfig,\n BlockHeightMap,\n IBlock,\n DictionaryResponse,\n} from '@subql/node-core';\nimport {\n EthereumBlock,\n EthereumDatasourceKind,\n EthereumHandlerKind,\n SubqlDatasource,\n SubqlRuntimeDatasource,\n} from '@subql/types-ethereum';\nimport {\n EthereumProjectDs,\n SubqueryProject,\n} from '../../../configure/SubqueryProject';\nimport {\n buildDictionaryV2QueryEntry,\n EthDictionaryV2,\n} from './ethDictionaryV2';\n\nconst DEFAULT_DICTIONARY = 'http://localhost:3000/rpc/eth-mainnet';\n\nconst HTTP_ENDPOINT = 'https://polygon.api.onfinality.io/public';\nconst mockDs: EthereumProjectDs[] = [\n {\n kind: EthereumDatasourceKind.Runtime,\n assets: new Map(),\n startBlock: 3678215,\n mapping: {\n file: './dist/index.js',\n handlers: [\n {\n handler: 'handleTransaction',\n kind: EthereumHandlerKind.Call,\n filter: {\n function: 'approve(address spender, uint256 rawAmount)',\n },\n },\n {\n handler: 'handleLog',\n kind: EthereumHandlerKind.Event,\n filter: {\n topics: [\n 'Transfer(address indexed from, address indexed to, uint256 amount)',\n ],\n },\n },\n ],\n },\n },\n];\n\n// tx to is null\nconst mockDs2: EthereumProjectDs[] = [\n {\n kind: EthereumDatasourceKind.Runtime,\n assets: new Map(),\n startBlock: 3678215,\n mapping: {\n file: './dist/index.js',\n handlers: [\n {\n handler: 'handleTransaction',\n kind: EthereumHandlerKind.Call,\n filter: {\n to: null,\n },\n },\n ],\n },\n },\n];\n\nconst nodeConfig = new NodeConfig({\n subquery: 'polygon-starter',\n subqueryName: 'polygon-starter',\n dictionaryTimeout: 10,\n networkEndpoint: [HTTP_ENDPOINT],\n networkDictionary: [`${DEFAULT_DICTIONARY}/polygon`],\n});\n\nfunction makeBlockHeightMap(mockDs: SubqlDatasource[]): BlockHeightMap<any> {\n const m = new Map<number, any>();\n mockDs.forEach((ds, index, dataSources) => {\n m.set(ds.startBlock, dataSources.slice(0, index + 1));\n });\n return new BlockHeightMap(m);\n}\n\n// enable this once dictionary v2 is online\ndescribe('eth dictionary v2', () => {\n let ethDictionaryV2: EthDictionaryV2;\n let ethBlock3678215: EthereumBlock;\n let ethBlock3678250: EthereumBlock;\n\n const dsMap = makeBlockHeightMap(mockDs);\n\n beforeEach(async () => {\n ethDictionaryV2 = await EthDictionaryV2.create(\n DEFAULT_DICTIONARY,\n nodeConfig,\n undefined,\n { network: { chainId: '10' } } as SubqueryProject,\n '10',\n );\n\n ethDictionaryV2.updateQueriesMap(dsMap);\n });\n\n it('convert ds to v2 dictionary queries', () => {\n //Polygon\n const query = (ethDictionaryV2 as any).queriesMap.get(3678215);\n expect(query.logs.length).toBe(1);\n expect(query.transactions.length).toBe(1);\n }, 100000);\n\n it('query response match with entries', async () => {\n //Polygon\n const ethBlocks = (await ethDictionaryV2.getData(\n 3678215,\n (ethDictionaryV2 as any)._metadata.end,\n 2,\n )) as DictionaryResponse<IBlock<EthereumBlock>>;\n\n expect(ethBlocks.batchBlocks.map((b) => b.block.number)).toStrictEqual([\n 3678215, 3678250,\n ]);\n\n ethBlock3678215 = ethBlocks.batchBlocks[0].block;\n ethBlock3678250 = ethBlocks.batchBlocks[1].block;\n\n expect(ethBlock3678215.number).toBe(3678215);\n expect(ethBlock3678250.number).toBe(3678250);\n\n // To match with dictionaryQueryEntries[0].func\n expect(ethBlock3678215.transactions[0].input.indexOf('0x60806040')).toBe(0);\n\n expect(ethBlock3678250.logs.length).toBe(1);\n // This matches with dictionaryQueryEntries[0].topics\n expect(ethBlock3678250.logs[0].topics).toContain(\n '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',\n );\n }, 100000);\n\n it('able to convert raw v2 Blocks into eth blocks when getData', async () => {\n //Polygon\n const ethBlocks = (await ethDictionaryV2.getData(\n 3678215,\n (ethDictionaryV2 as any)._metadata.end,\n 2,\n )) as DictionaryResponse<IBlock<EthereumBlock>>;\n\n expect(ethBlocks.batchBlocks[0].block.number).toStrictEqual(3678215);\n expect(ethBlocks.lastBufferedHeight).toStrictEqual(3678250);\n\n // Can include input and hash\n // https://polygonscan.com/tx/0xb1b5f7882fa8d62d3650948c08066e928b7b5c9d607d2fe8c7e6ce57caf06774\n expect(ethBlocks.batchBlocks[1].block.transactions[1].hash).toBe(\n `0xb1b5f7882fa8d62d3650948c08066e928b7b5c9d607d2fe8c7e6ce57caf06774`,\n );\n expect(ethBlocks.batchBlocks[1].block.transactions[1].input).toBe(\n `0x23b872dd000000000000000000000000244a79a2e79e8d884d9c9cc425d88f9e2ed988ca000000000000000000000000d22c4c383ce5efa0364d5fab5ce1313c24a52bda0000000000000000000000000000000000000000000000000000000000000159`,\n );\n\n // relate logs\n // https://polygonscan.com/tx/0xb1b5f7882fa8d62d3650948c08066e928b7b5c9d607d2fe8c7e6ce57caf06774#eventlog\n expect(ethBlocks.batchBlocks[1].block.logs[0].data).toBe(`0x`);\n }, 500000);\n});\n\n// TODO, check this\nit.skip('able to get transaction with field to is null', async () => {\n const dsMap = makeBlockHeightMap(mockDs2);\n const ethDictionaryV2 = await EthDictionaryV2.create(\n DEFAULT_DICTIONARY,\n nodeConfig,\n undefined,\n { network: { chainId: '10' } } as SubqueryProject,\n '10',\n );\n ethDictionaryV2.updateQueriesMap(dsMap);\n\n const { conditions, queryEndBlock } = (\n ethDictionaryV2 as any\n ).getQueryConditions(3678215, (ethDictionaryV2 as any)._metadata.end);\n\n expect(conditions).toBe({ transactions: [{ to: null }] });\n const ethBlocks = (await ethDictionaryV2.getData(\n 3678215,\n (ethDictionaryV2 as any)._metadata.end,\n 2,\n )) as DictionaryResponse<IBlock<EthereumBlock>>;\n}, 50000);\n\ndescribe('buildDictionaryV2QueryEntry', () => {\n it('Build filter for !null', () => {\n const ds: SubqlRuntimeDatasource = {\n kind: EthereumDatasourceKind.Runtime,\n assets: new Map(),\n options: {\n abi: 'erc20',\n address: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',\n },\n startBlock: 1,\n mapping: {\n file: '',\n handlers: [\n {\n handler: 'handleLog',\n kind: EthereumHandlerKind.Event,\n filter: {\n topics: [\n 'Transfer(address, address, uint256)',\n undefined,\n undefined,\n '!null',\n ],\n },\n },\n ],\n },\n };\n const result = buildDictionaryV2QueryEntry([ds]);\n\n expect(result).toEqual({\n logs: [\n {\n address: ['0x7ceb23fd6bc0add59e62ac25578270cff1b9f619'],\n topics0: [\n '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',\n ],\n topics3: [],\n },\n ],\n });\n });\n\n it('should unique QueryEntry for duplicate dataSources', () => {\n const ds: SubqlRuntimeDatasource = {\n kind: EthereumDatasourceKind.Runtime,\n assets: new Map(),\n options: {\n abi: 'erc20',\n address: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',\n },\n startBlock: 1,\n mapping: {\n file: '',\n handlers: [\n {\n handler: 'handleLog',\n kind: EthereumHandlerKind.Event,\n filter: {\n topics: ['Transfer(address, address, uint256)'],\n },\n },\n {\n handler: 'handleLogSame',\n kind: EthereumHandlerKind.Event,\n filter: {\n topics: ['Transfer(address, address, uint256)'],\n },\n },\n {\n handler: 'handleTx',\n kind: EthereumHandlerKind.Call,\n filter: {\n function: 'setminimumStakingAmount(uint256 amount)',\n from: 'mockAddress',\n },\n },\n {\n handler: 'handleTxSame',\n kind: EthereumHandlerKind.Call,\n filter: {\n function: 'setminimumStakingAmount(uint256 amount)',\n from: 'mockAddress',\n },\n },\n ],\n },\n };\n const result = buildDictionaryV2QueryEntry([ds]);\n\n expect(result).toEqual({\n logs: [\n {\n address: ['0x7ceb23fd6bc0add59e62ac25578270cff1b9f619'],\n topics0: [\n '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',\n ],\n },\n ],\n transactions: [\n {\n from: ['mockaddress'],\n function: ['0x7ef9ea98'],\n },\n ],\n });\n });\n});\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
16
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
__exportStar(require("./ethDictionaryV2"), exports);
|
|
20
|
+
__exportStar(require("./types"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/indexer/dictionary/v2/index.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;;AAEnC,oDAAkC;AAClC,0CAAwB","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nexport * from './ethDictionaryV2';\nexport * from './types';\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { DictionaryV2QueryEntry } from '@subql/node-core';
|
|
2
|
+
export interface RawEthBlock {
|
|
3
|
+
header: {
|
|
4
|
+
parentHash: string;
|
|
5
|
+
sha3Uncles: string;
|
|
6
|
+
miner: string;
|
|
7
|
+
stateRoot: string;
|
|
8
|
+
transactionRoot: string;
|
|
9
|
+
receiptsRoot: string;
|
|
10
|
+
logsBloom: string;
|
|
11
|
+
difficulty: bigint;
|
|
12
|
+
number: bigint;
|
|
13
|
+
gasLimit: bigint;
|
|
14
|
+
gasUsed: bigint;
|
|
15
|
+
timestamp: bigint;
|
|
16
|
+
extraData: string;
|
|
17
|
+
mixHash: string;
|
|
18
|
+
nonce: string;
|
|
19
|
+
baseFeePerGas: bigint;
|
|
20
|
+
withdrawalsRoot: string;
|
|
21
|
+
blobGasUsed: bigint;
|
|
22
|
+
excessBlobGas: bigint;
|
|
23
|
+
parentBeaconBlockRoot: string;
|
|
24
|
+
hash: string;
|
|
25
|
+
};
|
|
26
|
+
transactions: RawEthTransaction[];
|
|
27
|
+
logs: RawEthLog[];
|
|
28
|
+
}
|
|
29
|
+
export interface RawEthTransaction {
|
|
30
|
+
type: string;
|
|
31
|
+
nonce: bigint;
|
|
32
|
+
to: string;
|
|
33
|
+
gas: bigint;
|
|
34
|
+
gasPrice: bigint;
|
|
35
|
+
maxPriorityFeePerGas: bigint;
|
|
36
|
+
maxFeePerGas: bigint;
|
|
37
|
+
value: bigint;
|
|
38
|
+
v: bigint;
|
|
39
|
+
r: string;
|
|
40
|
+
s: string;
|
|
41
|
+
input: string;
|
|
42
|
+
hash: string;
|
|
43
|
+
from: string;
|
|
44
|
+
func: string;
|
|
45
|
+
gasLimit: bigint;
|
|
46
|
+
}
|
|
47
|
+
export interface RawEthLog {
|
|
48
|
+
address: string;
|
|
49
|
+
topics: string[];
|
|
50
|
+
data: string;
|
|
51
|
+
blockNumber: bigint;
|
|
52
|
+
transactionHash: string;
|
|
53
|
+
transactionIndex: bigint;
|
|
54
|
+
blockHash: string;
|
|
55
|
+
logIndex: bigint;
|
|
56
|
+
removed: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Eth dictionary RPC request filter conditions
|
|
60
|
+
*/
|
|
61
|
+
export interface EthDictionaryV2QueryEntry extends DictionaryV2QueryEntry {
|
|
62
|
+
logs: EthDictionaryLogConditions[];
|
|
63
|
+
transactions: EthDictionaryTxConditions[];
|
|
64
|
+
}
|
|
65
|
+
export interface EthDictionaryLogConditions {
|
|
66
|
+
address?: string[];
|
|
67
|
+
topics0?: string[];
|
|
68
|
+
topics1?: string[];
|
|
69
|
+
topics2?: string[];
|
|
70
|
+
}
|
|
71
|
+
export interface EthDictionaryTxConditions {
|
|
72
|
+
to?: string[];
|
|
73
|
+
from?: string[];
|
|
74
|
+
function?: string[];
|
|
75
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/indexer/dictionary/v2/types.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { DictionaryV2QueryEntry } from '@subql/node-core';\n\nexport interface RawEthBlock {\n header: {\n parentHash: string;\n sha3Uncles: string;\n miner: string;\n stateRoot: string;\n transactionRoot: string;\n receiptsRoot: string;\n logsBloom: string;\n difficulty: bigint;\n number: bigint;\n gasLimit: bigint;\n gasUsed: bigint;\n timestamp: bigint;\n extraData: string;\n mixHash: string;\n nonce: string;\n baseFeePerGas: bigint;\n withdrawalsRoot: string;\n blobGasUsed: bigint;\n excessBlobGas: bigint;\n parentBeaconBlockRoot: string;\n hash: string;\n };\n transactions: RawEthTransaction[];\n logs: RawEthLog[];\n}\n\nexport interface RawEthTransaction {\n type: string;\n nonce: bigint;\n to: string;\n gas: bigint;\n gasPrice: bigint;\n maxPriorityFeePerGas: bigint;\n maxFeePerGas: bigint;\n value: bigint;\n v: bigint;\n r: string;\n s: string;\n input: string;\n hash: string;\n from: string;\n func: string;\n gasLimit: bigint;\n}\n\nexport interface RawEthLog {\n address: string;\n topics: string[];\n data: string;\n blockNumber: bigint;\n transactionHash: string;\n transactionIndex: bigint;\n blockHash: string;\n logIndex: bigint;\n removed: boolean;\n}\n\n/**\n * Eth dictionary RPC request filter conditions\n */\nexport interface EthDictionaryV2QueryEntry extends DictionaryV2QueryEntry {\n logs: EthDictionaryLogConditions[];\n transactions: EthDictionaryTxConditions[];\n}\n\nexport interface EthDictionaryLogConditions {\n address?: string[];\n topics0?: string[];\n topics1?: string[];\n topics2?: string[];\n}\n\nexport interface EthDictionaryTxConditions {\n to?: string[];\n from?: string[];\n function?: string[];\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.rawBlockToEthBlock = void 0;
|
|
6
|
+
const providers_1 = require("@ethersproject/providers");
|
|
7
|
+
const utils_ethereum_1 = require("../../../ethereum/utils.ethereum");
|
|
8
|
+
function rawBlockToEthBlock(block) {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
try {
|
|
11
|
+
const formatter = new providers_1.Formatter();
|
|
12
|
+
const ethBlock = (0, utils_ethereum_1.formatBlock)(Object.assign(Object.assign({}, block.header), { transactions: [] }));
|
|
13
|
+
ethBlock.logs = providers_1.Formatter.arrayOf(formatter.filterLog.bind(formatter))((_a = block.logs) !== null && _a !== void 0 ? _a : []).map((l) => (0, utils_ethereum_1.formatLog)(l, ethBlock));
|
|
14
|
+
ethBlock.transactions = ((_b = block.transactions) !== null && _b !== void 0 ? _b : []).map((tx) => (Object.assign(Object.assign({}, (0, utils_ethereum_1.formatTransaction)(tx, ethBlock)), { logs: ethBlock.logs.filter((l) => l.transactionHash === tx.hash) })));
|
|
15
|
+
return (0, utils_ethereum_1.formatBlockUtil)(ethBlock);
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
throw new Error(`Convert raw block to Eth block failed at ${block.header.number},${e.message}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.rawBlockToEthBlock = rawBlockToEthBlock;
|
|
22
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/indexer/dictionary/v2/utils.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;AAEnC,wDAAqD;AAGrD,qEAK0C;AAG1C,SAAgB,kBAAkB,CAAC,KAAkB;;IACnD,IAAI;QACF,MAAM,SAAS,GAAG,IAAI,qBAAS,EAAE,CAAC;QAElC,MAAM,QAAQ,GAAG,IAAA,4BAAW,kCACvB,KAAK,CAAC,MAAM,KACf,YAAY,EAAE,EAAE,IAChB,CAAC;QAEH,QAAQ,CAAC,IAAI,GAAG,qBAAS,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CACpE,MAAA,KAAK,CAAC,IAAI,mCAAI,EAAE,CACjB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,0BAAS,EAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAErC,QAAQ,CAAC,YAAY,GAAG,CAAC,MAAA,KAAK,CAAC,YAAY,mCAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,iCAC1D,IAAA,kCAAiB,EAAC,EAAE,EAAE,QAAQ,CAAC,KAClC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,EAAE,CAAC,IAAI,CAAC,IAEhE,CAAC,CAAC;QAEJ,OAAO,IAAA,gCAAe,EAAC,QAAQ,CAAC,CAAC;KAClC;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,IAAI,KAAK,CACb,4CAA4C,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,CAC/E,CAAC;KACH;AACH,CAAC;AAzBD,gDAyBC","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { Formatter } from '@ethersproject/providers';\nimport { IBlock } from '@subql/node-core';\nimport { EthereumBlock } from '@subql/types-ethereum';\nimport {\n formatBlock,\n formatBlockUtil,\n formatLog,\n formatTransaction,\n} from '../../../ethereum/utils.ethereum';\nimport { RawEthBlock } from './types';\n\nexport function rawBlockToEthBlock(block: RawEthBlock): IBlock<EthereumBlock> {\n try {\n const formatter = new Formatter();\n\n const ethBlock = formatBlock({\n ...block.header,\n transactions: [],\n });\n\n ethBlock.logs = Formatter.arrayOf(formatter.filterLog.bind(formatter))(\n block.logs ?? [],\n ).map((l) => formatLog(l, ethBlock));\n\n ethBlock.transactions = (block.transactions ?? []).map((tx) => ({\n ...formatTransaction(tx, ethBlock),\n logs: ethBlock.logs.filter((l) => l.transactionHash === tx.hash),\n // TODO add method for receipts\n }));\n\n return formatBlockUtil(ethBlock);\n } catch (e) {\n throw new Error(\n `Convert raw block to Eth block failed at ${block.header.number},${e.message}`,\n );\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
5
|
+
var t = {};
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
9
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
10
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
11
|
+
t[p[i]] = s[p[i]];
|
|
12
|
+
}
|
|
13
|
+
return t;
|
|
14
|
+
};
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
const eventemitter2_1 = __importDefault(require("eventemitter2"));
|
|
20
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
21
|
+
const ethereum_1 = require("../../../ethereum");
|
|
22
|
+
const utils_1 = require("./utils");
|
|
23
|
+
const DICTIONARY_URL = 'http://localhost:3000/rpc/eth-mainnet';
|
|
24
|
+
const RPC_URL = 'https://eth.llamarpc.com';
|
|
25
|
+
async function fetchDictionaryBlock() {
|
|
26
|
+
const res = await (0, node_fetch_1.default)(DICTIONARY_URL, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers: {
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
},
|
|
31
|
+
body: JSON.stringify({
|
|
32
|
+
jsonrpc: '2.0',
|
|
33
|
+
id: 1,
|
|
34
|
+
method: 'subql_filterBlocks',
|
|
35
|
+
params: [
|
|
36
|
+
{
|
|
37
|
+
fromBlock: '0x3e579e',
|
|
38
|
+
toBlock: '0x3e579e',
|
|
39
|
+
limit: '0x1',
|
|
40
|
+
blockFilter: {
|
|
41
|
+
logs: [
|
|
42
|
+
{
|
|
43
|
+
address: ['0x6f28B146804dBa2D6f944C03528A8FDbc673df2C'],
|
|
44
|
+
topics0: [
|
|
45
|
+
'0xb76d0edd90c6a07aa3ff7a222d7f5933e29c6acc660c059c97837f05c4ca1a84',
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
fieldSelector: {
|
|
51
|
+
blockHeader: true,
|
|
52
|
+
logs: {
|
|
53
|
+
transaction: true,
|
|
54
|
+
},
|
|
55
|
+
transactions: {
|
|
56
|
+
log: true,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
}),
|
|
62
|
+
});
|
|
63
|
+
return (await res.json()).result.blocks[0];
|
|
64
|
+
}
|
|
65
|
+
async function fetchRPCBlock() {
|
|
66
|
+
const api = new ethereum_1.EthereumApi(RPC_URL, 1, new eventemitter2_1.default());
|
|
67
|
+
return api.fetchBlock(4085662);
|
|
68
|
+
}
|
|
69
|
+
describe('rawBlockToEthBlock', () => {
|
|
70
|
+
it('successfully convers a block', async () => {
|
|
71
|
+
const [raw, rpcBlock] = await Promise.all([
|
|
72
|
+
fetchDictionaryBlock(),
|
|
73
|
+
fetchRPCBlock(),
|
|
74
|
+
]);
|
|
75
|
+
const block = (0, utils_1.rawBlockToEthBlock)(raw);
|
|
76
|
+
expect(block.getHeader()).toEqual({
|
|
77
|
+
blockHash: '0xde8e614cc05b483fe092fd0aff435011138c15c9ede862579074218d4aff5132',
|
|
78
|
+
blockHeight: 4085662,
|
|
79
|
+
parentHash: '0x669c7a2c66e38c144ad1e2845ec345b6ce7e2107edbdb331ab88d355982126a7',
|
|
80
|
+
});
|
|
81
|
+
expect(block.block.transactions.length).toBeGreaterThan(0);
|
|
82
|
+
expect(block.block.logs.length).toBeGreaterThan(0);
|
|
83
|
+
// Dictionry is going to return a subset of events/transactions so we base off dictionary block
|
|
84
|
+
for (const log of block.block.logs) {
|
|
85
|
+
// Remove linked types
|
|
86
|
+
const { block: _1, transaction: _2 } = log, logRest = __rest(log, ["block", "transaction"]);
|
|
87
|
+
const _a = rpcBlock.block.logs[log.logIndex], { block: _3, transaction: _4 } = _a, rpcLogRest = __rest(_a, ["block", "transaction"]);
|
|
88
|
+
expect(JSON.stringify(logRest)).toEqual(JSON.stringify(rpcLogRest));
|
|
89
|
+
}
|
|
90
|
+
for (const tx of block.block.transactions) {
|
|
91
|
+
// Cast to any to remove toJSON which results in different key order
|
|
92
|
+
const _b = tx, { logs: _1, receipt: _3, toJSON: _5 } = _b, txRest = __rest(_b, ["logs", "receipt", "toJSON"]);
|
|
93
|
+
const _c = rpcBlock.block.transactions[Number(tx.transactionIndex)], { logs: _2, receipt: _4, toJSON: _6 } = _c, rpcTxRest = __rest(_c, ["logs", "receipt", "toJSON"]);
|
|
94
|
+
expect(txRest).toEqual(rpcTxRest);
|
|
95
|
+
}
|
|
96
|
+
}, 15000);
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=utils.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.spec.js","sourceRoot":"","sources":["../../../../src/indexer/dictionary/v2/utils.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { IBlock } from '@subql/node-core';\nimport { EthereumBlock } from '@subql/types-ethereum';\nimport EventEmitter2 from 'eventemitter2';\nimport fetch from 'node-fetch';\nimport { EthereumApi } from '../../../ethereum';\nimport { RawEthBlock } from './types';\nimport { rawBlockToEthBlock } from './utils';\n\nconst DICTIONARY_URL = 'http://localhost:3000/rpc/eth-mainnet';\nconst RPC_URL = 'https://eth.llamarpc.com';\n\nasync function fetchDictionaryBlock(): Promise<RawEthBlock> {\n const res = await fetch(DICTIONARY_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'subql_filterBlocks',\n params: [\n {\n fromBlock: '0x3e579e',\n toBlock: '0x3e579e',\n limit: '0x1',\n blockFilter: {\n logs: [\n {\n address: ['0x6f28B146804dBa2D6f944C03528A8FDbc673df2C'],\n topics0: [\n '0xb76d0edd90c6a07aa3ff7a222d7f5933e29c6acc660c059c97837f05c4ca1a84',\n ],\n },\n ],\n },\n fieldSelector: {\n blockHeader: true,\n logs: {\n transaction: true,\n },\n transactions: {\n log: true,\n },\n },\n },\n ],\n }),\n });\n\n return (await res.json()).result.blocks[0];\n}\n\nasync function fetchRPCBlock(): Promise<IBlock<EthereumBlock>> {\n const api = new EthereumApi(RPC_URL, 1, new EventEmitter2());\n\n return api.fetchBlock(4085662);\n}\n\ndescribe('rawBlockToEthBlock', () => {\n it('successfully convers a block', async () => {\n const [raw, rpcBlock] = await Promise.all([\n fetchDictionaryBlock(),\n fetchRPCBlock(),\n ]);\n\n const block = rawBlockToEthBlock(raw);\n\n expect(block.getHeader()).toEqual({\n blockHash:\n '0xde8e614cc05b483fe092fd0aff435011138c15c9ede862579074218d4aff5132',\n blockHeight: 4085662,\n parentHash:\n '0x669c7a2c66e38c144ad1e2845ec345b6ce7e2107edbdb331ab88d355982126a7',\n });\n\n expect(block.block.transactions.length).toBeGreaterThan(0);\n expect(block.block.logs.length).toBeGreaterThan(0);\n\n // Dictionry is going to return a subset of events/transactions so we base off dictionary block\n for (const log of block.block.logs) {\n // Remove linked types\n const { block: _1, transaction: _2, ...logRest } = log;\n const {\n block: _3,\n transaction: _4,\n ...rpcLogRest\n } = rpcBlock.block.logs[log.logIndex];\n expect(JSON.stringify(logRest)).toEqual(JSON.stringify(rpcLogRest));\n }\n\n for (const tx of block.block.transactions) {\n // Cast to any to remove toJSON which results in different key order\n const { logs: _1, receipt: _3, toJSON: _5, ...txRest } = tx as any;\n const {\n logs: _2,\n receipt: _4,\n toJSON: _6,\n ...rpcTxRest\n } = rpcBlock.block.transactions[Number(tx.transactionIndex)] as any;\n\n expect(txRest).toEqual(rpcTxRest);\n }\n }, 15000);\n});\n"]}
|
|
@@ -14,7 +14,7 @@ const event_emitter_1 = require("@nestjs/event-emitter");
|
|
|
14
14
|
const node_core_1 = require("@subql/node-core");
|
|
15
15
|
const api_service_ethereum_1 = require("../ethereum/api.service.ethereum");
|
|
16
16
|
const blockDispatcher_1 = require("./blockDispatcher");
|
|
17
|
-
const
|
|
17
|
+
const ethDictionary_service_1 = require("./dictionary/ethDictionary.service");
|
|
18
18
|
const ds_processor_service_1 = require("./ds-processor.service");
|
|
19
19
|
const dynamic_ds_service_1 = require("./dynamic-ds.service");
|
|
20
20
|
const fetch_service_1 = require("./fetch.service");
|
|
@@ -30,6 +30,7 @@ FetchModule = __decorate([
|
|
|
30
30
|
node_core_1.InMemoryCacheService,
|
|
31
31
|
node_core_1.StoreService,
|
|
32
32
|
node_core_1.StoreCacheService,
|
|
33
|
+
api_service_ethereum_1.EthereumApiService,
|
|
33
34
|
{
|
|
34
35
|
provide: node_core_1.ApiService,
|
|
35
36
|
useFactory: async (project, connectionPoolService, eventEmitter, nodeConfig) => {
|
|
@@ -89,9 +90,9 @@ FetchModule = __decorate([
|
|
|
89
90
|
node_core_1.IndexingBenchmarkService,
|
|
90
91
|
node_core_1.PoiBenchmarkService,
|
|
91
92
|
{
|
|
92
|
-
provide:
|
|
93
|
+
provide: ethDictionary_service_1.EthDictionaryService,
|
|
93
94
|
useFactory: async (project, nodeConfig, eventEmitter) => {
|
|
94
|
-
const dictionaryService =
|
|
95
|
+
const dictionaryService = new ethDictionary_service_1.EthDictionaryService(project, nodeConfig, eventEmitter);
|
|
95
96
|
return dictionaryService;
|
|
96
97
|
},
|
|
97
98
|
inject: ['ISubqueryProject', node_core_1.NodeConfig, event_emitter_1.EventEmitter2],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.module.js","sourceRoot":"","sources":["../../src/indexer/fetch.module.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;AAEnC,2CAAwC;AACxC,yDAAsD;AACtD,gDAc0B;AAG1B,2EAAsE;AACtE,uDAG2B;AAC3B,
|
|
1
|
+
{"version":3,"file":"fetch.module.js","sourceRoot":"","sources":["../../src/indexer/fetch.module.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { Module } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport {\n PoiBenchmarkService,\n IndexingBenchmarkService,\n StoreService,\n PoiService,\n ApiService,\n NodeConfig,\n ConnectionPoolService,\n ConnectionPoolStateManager,\n SmartBatchService,\n StoreCacheService,\n IProjectUpgradeService,\n PoiSyncService,\n InMemoryCacheService,\n} from '@subql/node-core';\nimport { SubqueryProject } from '../configure/SubqueryProject';\nimport { EthereumApiConnection } from '../ethereum/api.connection';\nimport { EthereumApiService } from '../ethereum/api.service.ethereum';\nimport {\n BlockDispatcherService,\n WorkerBlockDispatcherService,\n} from './blockDispatcher';\nimport { EthDictionaryService } from './dictionary/ethDictionary.service';\nimport { DsProcessorService } from './ds-processor.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { FetchService } from './fetch.service';\nimport { IndexerManager } from './indexer.manager';\nimport { ProjectService } from './project.service';\nimport { SandboxService } from './sandbox.service';\nimport { UnfinalizedBlocksService } from './unfinalizedBlocks.service';\n\n@Module({\n providers: [\n InMemoryCacheService,\n StoreService,\n StoreCacheService,\n EthereumApiService,\n {\n provide: ApiService,\n useFactory: async (\n project: SubqueryProject,\n connectionPoolService: ConnectionPoolService<EthereumApiConnection>,\n eventEmitter: EventEmitter2,\n nodeConfig: NodeConfig,\n ) => {\n const apiService = new EthereumApiService(\n project,\n connectionPoolService,\n eventEmitter,\n nodeConfig,\n );\n await apiService.init();\n return apiService;\n },\n inject: [\n 'ISubqueryProject',\n ConnectionPoolService,\n EventEmitter2,\n NodeConfig,\n ],\n },\n IndexerManager,\n ConnectionPoolStateManager,\n ConnectionPoolService,\n {\n provide: SmartBatchService,\n useFactory: (nodeConfig: NodeConfig) => {\n return new SmartBatchService(nodeConfig.batchSize);\n },\n inject: [NodeConfig],\n },\n {\n provide: SmartBatchService,\n useFactory: (nodeConfig: NodeConfig) => {\n return new SmartBatchService(nodeConfig.batchSize);\n },\n inject: [NodeConfig],\n },\n {\n provide: 'IBlockDispatcher',\n useFactory: (\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n projectService: ProjectService,\n projectUpgradeService: IProjectUpgradeService,\n apiService: EthereumApiService,\n indexerManager: IndexerManager,\n smartBatchService: SmartBatchService,\n cacheService: InMemoryCacheService,\n storeService: StoreService,\n storeCacheService: StoreCacheService,\n poiSyncService: PoiSyncService,\n project: SubqueryProject,\n dynamicDsService: DynamicDsService,\n unfinalizedBlocks: UnfinalizedBlocksService,\n connectionPoolState: ConnectionPoolStateManager<EthereumApiConnection>,\n ) =>\n nodeConfig.workers !== undefined\n ? new WorkerBlockDispatcherService(\n nodeConfig,\n eventEmitter,\n projectService,\n projectUpgradeService,\n smartBatchService,\n cacheService,\n storeService,\n storeCacheService,\n poiSyncService,\n project,\n dynamicDsService,\n unfinalizedBlocks,\n connectionPoolState,\n )\n : new BlockDispatcherService(\n apiService,\n nodeConfig,\n indexerManager,\n eventEmitter,\n projectService,\n projectUpgradeService,\n smartBatchService,\n storeService,\n storeCacheService,\n poiSyncService,\n project,\n dynamicDsService,\n ),\n inject: [\n NodeConfig,\n EventEmitter2,\n 'IProjectService',\n 'IProjectUpgradeService',\n ApiService,\n IndexerManager,\n SmartBatchService,\n InMemoryCacheService,\n StoreService,\n StoreCacheService,\n PoiSyncService,\n 'ISubqueryProject',\n DynamicDsService,\n UnfinalizedBlocksService,\n ConnectionPoolStateManager,\n ],\n },\n FetchService,\n ConnectionPoolService,\n IndexingBenchmarkService,\n PoiBenchmarkService,\n {\n provide: EthDictionaryService,\n useFactory: async (\n project: SubqueryProject,\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n // eslint-disable-next-line @typescript-eslint/require-await\n ) => {\n const dictionaryService = new EthDictionaryService(\n project,\n nodeConfig,\n eventEmitter,\n );\n return dictionaryService;\n },\n inject: ['ISubqueryProject', NodeConfig, EventEmitter2],\n },\n SandboxService,\n DsProcessorService,\n DynamicDsService,\n PoiService,\n PoiSyncService,\n {\n useClass: ProjectService,\n provide: 'IProjectService',\n },\n UnfinalizedBlocksService,\n ],\n exports: [StoreService, StoreCacheService],\n})\nexport class FetchModule {}\n"]}
|