@subsquid/batch-processor 0.0.0 → 1.0.0-portal-api.d887ad
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/lib/database.d.ts +6 -6
- package/lib/database.d.ts.map +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/lib/run.d.ts +4 -5
- package/lib/run.d.ts.map +1 -1
- package/lib/run.js +132 -49
- package/lib/run.js.map +1 -1
- package/lib/util.js +4 -5
- package/lib/util.js.map +1 -1
- package/package.json +6 -5
- package/src/database.ts +8 -7
- package/src/index.ts +0 -1
- package/src/run.ts +160 -68
- package/lib/datasource.d.ts +0 -8
- package/lib/datasource.d.ts.map +0 -1
- package/lib/datasource.js +0 -3
- package/lib/datasource.js.map +0 -1
- package/src/datasource.ts +0 -9
package/lib/database.d.ts
CHANGED
|
@@ -10,9 +10,12 @@ export interface FinalTxInfo {
|
|
|
10
10
|
}
|
|
11
11
|
export interface FinalDatabase<S> {
|
|
12
12
|
supportsHotBlocks?: false;
|
|
13
|
-
connect(): Promise<
|
|
13
|
+
connect(): Promise<FinalDatabaseState>;
|
|
14
|
+
getState?(): Promise<FinalDatabaseState>;
|
|
14
15
|
transact(info: FinalTxInfo, cb: (store: S) => Promise<void>): Promise<void>;
|
|
15
16
|
}
|
|
17
|
+
export interface FinalDatabaseState extends HashAndHeight {
|
|
18
|
+
}
|
|
16
19
|
export interface HotTxInfo {
|
|
17
20
|
finalizedHead: HashAndHeight;
|
|
18
21
|
baseHead: HashAndHeight;
|
|
@@ -21,12 +24,9 @@ export interface HotTxInfo {
|
|
|
21
24
|
export interface HotDatabase<S> {
|
|
22
25
|
supportsHotBlocks: true;
|
|
23
26
|
connect(): Promise<HotDatabaseState>;
|
|
27
|
+
getState(): Promise<HotDatabaseState>;
|
|
24
28
|
transact(info: FinalTxInfo, cb: (store: S) => Promise<void>): Promise<void>;
|
|
25
|
-
|
|
26
|
-
* @deprecated
|
|
27
|
-
*/
|
|
28
|
-
transactHot(info: HotTxInfo, cb: (store: S, block: HashAndHeight) => Promise<void>): Promise<void>;
|
|
29
|
-
transactHot2?(info: HotTxInfo, cb: (store: S, blockSliceStart: number, blockSliceEnd: number) => Promise<void>): Promise<void>;
|
|
29
|
+
transactHot2(info: HotTxInfo, cb: (store: S, blockSliceStart: number, blockSliceEnd: number) => Promise<void>): Promise<void>;
|
|
30
30
|
}
|
|
31
31
|
export interface HotDatabaseState extends HashAndHeight {
|
|
32
32
|
top: HashAndHeight[];
|
package/lib/database.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;AAG3D,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,aAAa,CAAA;IACvB,QAAQ,EAAE,aAAa,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;CACnB;AAGD,MAAM,WAAW,aAAa,CAAC,CAAC;IAC5B,iBAAiB,CAAC,EAAE,KAAK,CAAA;IACzB,OAAO,IAAI,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;AAG3D,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,aAAa,CAAA;IACvB,QAAQ,EAAE,aAAa,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;CACnB;AAGD,MAAM,WAAW,aAAa,CAAC,CAAC;IAC5B,iBAAiB,CAAC,EAAE,KAAK,CAAA;IACzB,OAAO,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACtC,QAAQ,CAAC,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACxC,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9E;AAGD,MAAM,WAAW,kBAAmB,SAAQ,aAAa;CAAG;AAG5D,MAAM,WAAW,SAAS;IACtB,aAAa,EAAE,aAAa,CAAA;IAC5B,QAAQ,EAAE,aAAa,CAAA;IACvB,SAAS,EAAE,aAAa,EAAE,CAAA;CAC7B;AAGD,MAAM,WAAW,WAAW,CAAC,CAAC;IAC1B,iBAAiB,EAAE,IAAI,CAAA;IACvB,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACpC,QAAQ,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACrC,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE3E,YAAY,CACR,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAChF,OAAO,CAAC,IAAI,CAAC,CAAA;CACnB;AAGD,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACnD,GAAG,EAAE,aAAa,EAAE,CAAA;CACvB;AAGD,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACf"}
|
package/lib/index.d.ts
CHANGED
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,OAAO,CAAA"}
|
package/lib/index.js
CHANGED
|
@@ -15,6 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./database"), exports);
|
|
18
|
-
__exportStar(require("./datasource"), exports);
|
|
19
18
|
__exportStar(require("./run"), exports);
|
|
20
19
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA0B;AAC1B
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA0B;AAC1B,wCAAqB"}
|
package/lib/run.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Database
|
|
2
|
-
import { DataSource } from '
|
|
1
|
+
import { Database } from './database';
|
|
2
|
+
import { DataSource, BlockRef } from '@subsquid/util-internal-data-source';
|
|
3
3
|
export interface DataHandlerContext<Block, Store> {
|
|
4
4
|
/**
|
|
5
5
|
* Storage interface provided by the database
|
|
@@ -14,8 +14,8 @@ export interface DataHandlerContext<Block, Store> {
|
|
|
14
14
|
*/
|
|
15
15
|
isHead: boolean;
|
|
16
16
|
}
|
|
17
|
-
interface BlockBase {
|
|
18
|
-
header:
|
|
17
|
+
export interface BlockBase {
|
|
18
|
+
header: BlockRef;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Run data processing.
|
|
@@ -32,5 +32,4 @@ interface BlockBase {
|
|
|
32
32
|
* @param dataHandler - The data handler, see {@link DataHandlerContext} for an API available to the handler.
|
|
33
33
|
*/
|
|
34
34
|
export declare function run<Block extends BlockBase, Store>(src: DataSource<Block>, db: Database<Store>, dataHandler: (ctx: DataHandlerContext<Block, Store>) => Promise<void>): void;
|
|
35
|
-
export {};
|
|
36
35
|
//# sourceMappingURL=run.d.ts.map
|
package/lib/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,QAAQ,EAAmB,MAAM,YAAY,CAAA;AAEpE,OAAO,EAAC,UAAU,EAAmB,QAAQ,EAAC,MAAM,qCAAqC,CAAA;AAMzF,MAAM,WAAW,kBAAkB,CAAC,KAAK,EAAE,KAAK;IAC5C;;OAEG;IACH,KAAK,EAAE,KAAK,CAAA;IACZ;;OAEG;IACH,MAAM,EAAE,KAAK,EAAE,CAAA;IACf;;OAEG;IACH,MAAM,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,SAAS;IACtB,MAAM,EAAE,QAAQ,CAAA;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,GAAG,CAAC,KAAK,SAAS,SAAS,EAAE,KAAK,EAC9C,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,EACtB,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EACnB,WAAW,EAAE,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GACtE,IAAI,CASN"}
|
package/lib/run.js
CHANGED
|
@@ -22,13 +22,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.run =
|
|
29
|
+
exports.run = run;
|
|
27
30
|
const logger_1 = require("@subsquid/logger");
|
|
28
31
|
const util_internal_1 = require("@subsquid/util-internal");
|
|
29
32
|
const util_internal_prometheus_server_1 = require("@subsquid/util-internal-prometheus-server");
|
|
30
33
|
const prom = __importStar(require("prom-client"));
|
|
31
34
|
const metrics_1 = require("./metrics");
|
|
35
|
+
const util_internal_data_source_1 = require("@subsquid/util-internal-data-source");
|
|
36
|
+
const assert_1 = __importDefault(require("assert"));
|
|
32
37
|
const util_1 = require("./util");
|
|
33
38
|
const log = (0, logger_1.createLogger)('sqd:batch-processor');
|
|
34
39
|
/**
|
|
@@ -48,11 +53,10 @@ const log = (0, logger_1.createLogger)('sqd:batch-processor');
|
|
|
48
53
|
function run(src, db, dataHandler) {
|
|
49
54
|
(0, util_internal_1.runProgram)(() => {
|
|
50
55
|
return new Processor(src, db, dataHandler).run();
|
|
51
|
-
}, err => {
|
|
56
|
+
}, (err) => {
|
|
52
57
|
log.fatal(err);
|
|
53
58
|
});
|
|
54
59
|
}
|
|
55
|
-
exports.run = run;
|
|
56
60
|
class Processor {
|
|
57
61
|
constructor(src, db, handler) {
|
|
58
62
|
this.src = src;
|
|
@@ -60,32 +64,73 @@ class Processor {
|
|
|
60
64
|
this.handler = handler;
|
|
61
65
|
this.metrics = new metrics_1.Metrics();
|
|
62
66
|
this.hasStatusNews = false;
|
|
63
|
-
this.chainHeight = new util_internal_1.Throttler(() => this.src.
|
|
67
|
+
this.chainHeight = new util_internal_1.Throttler(() => this.src.getHead()?.then((r) => r?.number ?? -1), 30000);
|
|
64
68
|
}
|
|
65
69
|
async run() {
|
|
66
|
-
let
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
let finalizedHead;
|
|
71
|
+
let head;
|
|
72
|
+
if (this.db.supportsHotBlocks) {
|
|
73
|
+
let state = await this.db.connect();
|
|
74
|
+
finalizedHead = state;
|
|
75
|
+
head = (0, util_internal_1.last)([state, ...state.top]);
|
|
69
76
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
else {
|
|
78
|
+
finalizedHead = head = await this.db.connect();
|
|
79
|
+
}
|
|
80
|
+
if (head.height >= 0) {
|
|
81
|
+
log.info(`last processed block was ${head.height}`);
|
|
82
|
+
await this.assertWeAreOnTheSameChain(finalizedHead);
|
|
83
|
+
}
|
|
84
|
+
await this.initMetrics(head.height);
|
|
85
|
+
while (true) {
|
|
86
|
+
try {
|
|
87
|
+
let prevBlockNumber = head.height;
|
|
88
|
+
let prevBlockHash = head.height < 0 ? undefined : head.hash;
|
|
89
|
+
let stream = this.src.getStream({
|
|
90
|
+
range: { from: prevBlockNumber + 1 },
|
|
91
|
+
parentHash: prevBlockHash,
|
|
92
|
+
});
|
|
93
|
+
for await (let data of stream) {
|
|
94
|
+
let finalizedHead = data.finalizedHead == null
|
|
95
|
+
? { height: -1, hash: '0x' }
|
|
96
|
+
: {
|
|
97
|
+
height: data.finalizedHead.number,
|
|
98
|
+
hash: data.finalizedHead.hash,
|
|
99
|
+
};
|
|
100
|
+
head = await this.processBatch(head, finalizedHead, data.blocks);
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
if ((0, util_internal_data_source_1.isForkException)(e) && this.db.supportsHotBlocks) {
|
|
106
|
+
let state = await this.db.getState();
|
|
107
|
+
let forkBase = await computeForkBase(state, e.prevBlocks);
|
|
108
|
+
if (forkBase == null) {
|
|
109
|
+
// rollback all blocks
|
|
110
|
+
head = { height: -1, hash: '0x' };
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
head = forkBase;
|
|
114
|
+
}
|
|
115
|
+
log.info(`navigating a fork on a common base ${(0, util_1.formatHead)(head)}`);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
throw e;
|
|
119
|
+
}
|
|
75
120
|
}
|
|
76
121
|
}
|
|
77
122
|
this.reportFinalStatus();
|
|
78
123
|
}
|
|
79
124
|
async assertWeAreOnTheSameChain(state) {
|
|
80
|
-
if (state.height < 0)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
125
|
+
// if (state.height < 0) return
|
|
126
|
+
// let hash = await this.src.getBlockHash(state.number)
|
|
127
|
+
// if (state.hash === hash) return
|
|
128
|
+
// throw new Error(
|
|
129
|
+
// `already indexed block ${formatHead(state)} was not found on chain`
|
|
130
|
+
// )
|
|
86
131
|
}
|
|
87
132
|
async initMetrics(state) {
|
|
88
|
-
|
|
133
|
+
this.updateProgressMetrics(await this.chainHeight.get(), state);
|
|
89
134
|
let port = process.env.PROCESSOR_PROMETHEUS_PORT || process.env.PROMETHEUS_PORT;
|
|
90
135
|
if (port == null)
|
|
91
136
|
return;
|
|
@@ -94,48 +139,57 @@ class Processor {
|
|
|
94
139
|
let server = await (0, util_internal_prometheus_server_1.createPrometheusServer)(prom.register, port);
|
|
95
140
|
log.info(`prometheus metrics are served on port ${server.port}`);
|
|
96
141
|
}
|
|
97
|
-
updateProgressMetrics(chainHeight,
|
|
142
|
+
updateProgressMetrics(chainHeight, indexerHeight, time) {
|
|
98
143
|
this.metrics.setChainHeight(chainHeight);
|
|
99
|
-
this.metrics.setLastProcessedBlock(
|
|
144
|
+
this.metrics.setLastProcessedBlock(indexerHeight);
|
|
100
145
|
let left;
|
|
101
146
|
let processed;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
from: this.metrics.getLastProcessedBlock() + 1,
|
|
105
|
-
to: this.metrics.getChainHeight()
|
|
106
|
-
});
|
|
107
|
-
processed = this.src.getBlocksCountInRange({
|
|
108
|
-
from: 0,
|
|
109
|
-
to: this.metrics.getChainHeight()
|
|
110
|
-
}) - left;
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
left = this.metrics.getChainHeight() - this.metrics.getLastProcessedBlock();
|
|
114
|
-
processed = this.metrics.getLastProcessedBlock();
|
|
115
|
-
}
|
|
147
|
+
left = this.metrics.getChainHeight() - this.metrics.getLastProcessedBlock();
|
|
148
|
+
processed = this.metrics.getLastProcessedBlock();
|
|
116
149
|
this.metrics.updateProgress(processed, left, time);
|
|
117
150
|
}
|
|
118
|
-
async processBatch(prevHead, blocks) {
|
|
151
|
+
async processBatch(prevHead, finalizedHead, blocks) {
|
|
119
152
|
let chainHeight = await this.chainHeight.get();
|
|
153
|
+
let lastBlock = (0, util_internal_1.maybeLast)(blocks);
|
|
154
|
+
if (lastBlock == null)
|
|
155
|
+
return prevHead;
|
|
120
156
|
let nextHead = {
|
|
121
|
-
hash:
|
|
122
|
-
height:
|
|
157
|
+
hash: lastBlock.header.hash,
|
|
158
|
+
height: lastBlock.header.number,
|
|
123
159
|
};
|
|
124
160
|
let isOnTop = nextHead.height >= chainHeight;
|
|
125
161
|
let mappingStartTime = process.hrtime.bigint();
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
162
|
+
if (this.db.supportsHotBlocks) {
|
|
163
|
+
await this.db.transactHot2({
|
|
164
|
+
finalizedHead,
|
|
165
|
+
baseHead: prevHead,
|
|
166
|
+
newBlocks: blocks.map((b) => ({
|
|
167
|
+
hash: b.header.hash,
|
|
168
|
+
height: b.header.number,
|
|
169
|
+
})),
|
|
170
|
+
}, (store, start, end) => {
|
|
171
|
+
return this.handler({
|
|
172
|
+
store,
|
|
173
|
+
blocks: blocks.slice(start, end),
|
|
174
|
+
isHead: isOnTop,
|
|
175
|
+
});
|
|
135
176
|
});
|
|
136
|
-
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
await this.db.transact({
|
|
180
|
+
prevHead,
|
|
181
|
+
nextHead,
|
|
182
|
+
isOnTop,
|
|
183
|
+
}, (store) => {
|
|
184
|
+
return this.handler({
|
|
185
|
+
store,
|
|
186
|
+
blocks,
|
|
187
|
+
isHead: isOnTop,
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
}
|
|
137
191
|
let mappingEndTime = process.hrtime.bigint();
|
|
138
|
-
this.updateProgressMetrics(chainHeight, nextHead, mappingEndTime);
|
|
192
|
+
this.updateProgressMetrics(chainHeight, nextHead.height, mappingEndTime);
|
|
139
193
|
this.metrics.registerBatch(blocks.length, (0, util_1.getItemsCount)(blocks), mappingStartTime, mappingEndTime);
|
|
140
194
|
this.reportStatus();
|
|
141
195
|
return nextHead;
|
|
@@ -165,4 +219,33 @@ class Processor {
|
|
|
165
219
|
}
|
|
166
220
|
}
|
|
167
221
|
}
|
|
222
|
+
async function computeForkBase(state, forked, finalizedHead) {
|
|
223
|
+
(0, assert_1.default)(forked?.length);
|
|
224
|
+
let tail = forked.slice();
|
|
225
|
+
let commited = state.top;
|
|
226
|
+
if (commited.length > 0) {
|
|
227
|
+
for (let i = commited.length - 1; i >= 0; i--) {
|
|
228
|
+
let h = commited[i];
|
|
229
|
+
while (tail.length > 0 && (0, util_internal_1.last)(tail).number > h.height) {
|
|
230
|
+
tail.pop();
|
|
231
|
+
}
|
|
232
|
+
if (tail.length == 0)
|
|
233
|
+
return h;
|
|
234
|
+
let t = (0, util_internal_1.last)(tail);
|
|
235
|
+
if (t.number == h.height && t.hash == h.hash)
|
|
236
|
+
return h;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
if (forked[0].number > state.height)
|
|
241
|
+
return state;
|
|
242
|
+
let headOnChain = forked.find((b) => b.number == state.height);
|
|
243
|
+
if (headOnChain == null || headOnChain.hash !== state.hash) {
|
|
244
|
+
if (finalizedHead && finalizedHead.number >= state.height) {
|
|
245
|
+
throw new Error(`finalized block ${(0, util_1.formatHead)(state)} was not found on chain`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return state;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
168
251
|
//# sourceMappingURL=run.js.map
|
package/lib/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|
package/lib/util.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.timeInterval = timeInterval;
|
|
4
|
+
exports.getItemsCount = getItemsCount;
|
|
5
|
+
exports.formatHead = formatHead;
|
|
6
|
+
exports.shortHash = shortHash;
|
|
4
7
|
function timeInterval(seconds) {
|
|
5
8
|
if (seconds < 60) {
|
|
6
9
|
return Math.round(seconds) + 's';
|
|
@@ -13,7 +16,6 @@ function timeInterval(seconds) {
|
|
|
13
16
|
minutes = minutes - hours * 60;
|
|
14
17
|
return hours + 'h ' + minutes + 'm';
|
|
15
18
|
}
|
|
16
|
-
exports.timeInterval = timeInterval;
|
|
17
19
|
function getItemsCount(blocks) {
|
|
18
20
|
let count = 0;
|
|
19
21
|
for (let block of blocks) {
|
|
@@ -26,11 +28,9 @@ function getItemsCount(blocks) {
|
|
|
26
28
|
}
|
|
27
29
|
return count;
|
|
28
30
|
}
|
|
29
|
-
exports.getItemsCount = getItemsCount;
|
|
30
31
|
function formatHead(head) {
|
|
31
32
|
return `${head.height}#${shortHash(head.hash)}`;
|
|
32
33
|
}
|
|
33
|
-
exports.formatHead = formatHead;
|
|
34
34
|
function shortHash(hash) {
|
|
35
35
|
if (hash.startsWith('0x')) {
|
|
36
36
|
return hash.slice(2, 7);
|
|
@@ -39,5 +39,4 @@ function shortHash(hash) {
|
|
|
39
39
|
return hash.slice(0, 5);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
exports.shortHash = shortHash;
|
|
43
42
|
//# sourceMappingURL=util.js.map
|
package/lib/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;AAGA,oCAWC;AAGD,sCAWC;AAGD,gCAEC;AAGD,8BAMC;AAvCD,SAAgB,YAAY,CAAC,OAAe;IACxC,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,GAAG,CAAA;IACpC,CAAC;IACD,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAC,EAAE,CAAC,CAAA;IACnC,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;QACf,OAAQ,OAAO,GAAC,GAAG,CAAA;IACvB,CAAC;IACD,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAA;IACpC,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,EAAE,CAAA;IAC9B,OAAO,KAAK,GAAG,IAAI,GAAG,OAAO,GAAG,GAAG,CAAA;AACvC,CAAC;AAGD,SAAgB,aAAa,CAAC,MAAa;IACvC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;QACvB,KAAK,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;YACpB,IAAI,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;YACpB,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,KAAK,IAAI,GAAG,CAAC,MAAM,CAAA;YACvB,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAA;AAChB,CAAC;AAGD,SAAgB,UAAU,CAAC,IAAmB;IAC1C,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;AACnD,CAAC;AAGD,SAAgB,SAAS,CAAC,IAAY;IAClC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC3B,CAAC;SAAM,CAAC;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC3B,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@subsquid/batch-processor",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "1.0.0-portal-api.d887ad",
|
|
4
4
|
"description": "ETL processor",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"repository": "git@github.com:subsquid/squid.git",
|
|
@@ -14,16 +14,17 @@
|
|
|
14
14
|
],
|
|
15
15
|
"main": "lib/index.js",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@subsquid/logger": "
|
|
18
|
-
"@subsquid/util-internal": "
|
|
17
|
+
"@subsquid/logger": "1.5.0-portal-api.d887ad",
|
|
18
|
+
"@subsquid/util-internal": "3.3.0-portal-api.d887ad",
|
|
19
19
|
"@subsquid/util-internal-counters": "^1.3.2",
|
|
20
20
|
"@subsquid/util-internal-prometheus-server": "^1.3.0",
|
|
21
21
|
"@subsquid/util-internal-range": "^0.3.0",
|
|
22
|
-
"prom-client": "^14.2.0"
|
|
22
|
+
"prom-client": "^14.2.0",
|
|
23
|
+
"@subsquid/util-internal-data-source": "^0.0.0"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@types/node": "^18.18.14",
|
|
26
|
-
"typescript": "
|
|
27
|
+
"typescript": "5.5.4"
|
|
27
28
|
},
|
|
28
29
|
"scripts": {
|
|
29
30
|
"build": "rm -rf lib && tsc"
|
package/src/database.ts
CHANGED
|
@@ -14,11 +14,15 @@ export interface FinalTxInfo {
|
|
|
14
14
|
|
|
15
15
|
export interface FinalDatabase<S> {
|
|
16
16
|
supportsHotBlocks?: false
|
|
17
|
-
connect(): Promise<
|
|
17
|
+
connect(): Promise<FinalDatabaseState>
|
|
18
|
+
getState?(): Promise<FinalDatabaseState>
|
|
18
19
|
transact(info: FinalTxInfo, cb: (store: S) => Promise<void>): Promise<void>
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
|
|
23
|
+
export interface FinalDatabaseState extends HashAndHeight {}
|
|
24
|
+
|
|
25
|
+
|
|
22
26
|
export interface HotTxInfo {
|
|
23
27
|
finalizedHead: HashAndHeight
|
|
24
28
|
baseHead: HashAndHeight
|
|
@@ -29,13 +33,10 @@ export interface HotTxInfo {
|
|
|
29
33
|
export interface HotDatabase<S> {
|
|
30
34
|
supportsHotBlocks: true
|
|
31
35
|
connect(): Promise<HotDatabaseState>
|
|
36
|
+
getState(): Promise<HotDatabaseState>
|
|
32
37
|
transact(info: FinalTxInfo, cb: (store: S) => Promise<void>): Promise<void>
|
|
33
|
-
/**
|
|
34
|
-
* @deprecated
|
|
35
|
-
*/
|
|
36
|
-
transactHot(info: HotTxInfo, cb: (store: S, block: HashAndHeight) => Promise<void>): Promise<void>
|
|
37
38
|
|
|
38
|
-
transactHot2
|
|
39
|
+
transactHot2(
|
|
39
40
|
info: HotTxInfo,
|
|
40
41
|
cb: (store: S, blockSliceStart: number, blockSliceEnd: number) => Promise<void>
|
|
41
42
|
): Promise<void>
|
|
@@ -50,4 +51,4 @@ export interface HotDatabaseState extends HashAndHeight {
|
|
|
50
51
|
export interface HashAndHeight {
|
|
51
52
|
height: number
|
|
52
53
|
hash: string
|
|
53
|
-
}
|
|
54
|
+
}
|
package/src/index.ts
CHANGED
package/src/run.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import {createLogger} from '@subsquid/logger'
|
|
2
|
-
import {last, runProgram, Throttler} from '@subsquid/util-internal'
|
|
2
|
+
import {last, maybeLast, runProgram, Throttler} from '@subsquid/util-internal'
|
|
3
3
|
import {createPrometheusServer} from '@subsquid/util-internal-prometheus-server'
|
|
4
4
|
import * as prom from 'prom-client'
|
|
5
|
-
import {Database,
|
|
6
|
-
import {DataSource} from './datasource'
|
|
5
|
+
import {HashAndHeight, Database, HotDatabaseState} from './database'
|
|
7
6
|
import {Metrics} from './metrics'
|
|
7
|
+
import {DataSource, isForkException, BlockRef} from '@subsquid/util-internal-data-source'
|
|
8
|
+
import assert from 'assert'
|
|
8
9
|
import {formatHead, getItemsCount} from './util'
|
|
9
10
|
|
|
10
|
-
|
|
11
11
|
const log = createLogger('sqd:batch-processor')
|
|
12
12
|
|
|
13
|
-
|
|
14
13
|
export interface DataHandlerContext<Block, Store> {
|
|
15
14
|
/**
|
|
16
15
|
* Storage interface provided by the database
|
|
@@ -26,12 +25,10 @@ export interface DataHandlerContext<Block, Store> {
|
|
|
26
25
|
isHead: boolean
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
header: HashAndHeight
|
|
28
|
+
export interface BlockBase {
|
|
29
|
+
header: BlockRef
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
|
|
35
32
|
/**
|
|
36
33
|
* Run data processing.
|
|
37
34
|
*
|
|
@@ -51,14 +48,16 @@ export function run<Block extends BlockBase, Store>(
|
|
|
51
48
|
db: Database<Store>,
|
|
52
49
|
dataHandler: (ctx: DataHandlerContext<Block, Store>) => Promise<void>
|
|
53
50
|
): void {
|
|
54
|
-
runProgram(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
runProgram(
|
|
52
|
+
() => {
|
|
53
|
+
return new Processor(src, db, dataHandler).run()
|
|
54
|
+
},
|
|
55
|
+
(err) => {
|
|
56
|
+
log.fatal(err)
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
|
|
62
61
|
class Processor<B extends BlockBase, S> {
|
|
63
62
|
private metrics = new Metrics()
|
|
64
63
|
private chainHeight: Throttler<number>
|
|
@@ -70,21 +69,64 @@ class Processor<B extends BlockBase, S> {
|
|
|
70
69
|
private db: Database<S>,
|
|
71
70
|
private handler: (ctx: DataHandlerContext<B, S>) => Promise<void>
|
|
72
71
|
) {
|
|
73
|
-
this.chainHeight = new Throttler(() => this.src.
|
|
72
|
+
this.chainHeight = new Throttler(() => this.src.getHead()?.then((r) => r?.number ?? -1), 30_000)
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
async run(): Promise<void> {
|
|
77
|
-
let
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
let finalizedHead: HashAndHeight
|
|
77
|
+
let head: HashAndHeight
|
|
78
|
+
if (this.db.supportsHotBlocks) {
|
|
79
|
+
let state = await this.db.connect()
|
|
80
|
+
finalizedHead = state
|
|
81
|
+
head = last([state, ...state.top])
|
|
82
|
+
} else {
|
|
83
|
+
finalizedHead = head = await this.db.connect()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (head.height >= 0) {
|
|
87
|
+
log.info(`last processed block was ${head.height}`)
|
|
88
|
+
await this.assertWeAreOnTheSameChain(finalizedHead)
|
|
80
89
|
}
|
|
81
90
|
|
|
82
|
-
await this.
|
|
83
|
-
await this.initMetrics(state)
|
|
91
|
+
await this.initMetrics(head.height)
|
|
84
92
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
93
|
+
while (true) {
|
|
94
|
+
try {
|
|
95
|
+
let prevBlockNumber = head.height
|
|
96
|
+
let prevBlockHash = head.height < 0 ? undefined : head.hash
|
|
97
|
+
|
|
98
|
+
let stream = this.src.getStream({
|
|
99
|
+
range: {from: prevBlockNumber + 1},
|
|
100
|
+
parentHash: prevBlockHash,
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
for await (let data of stream) {
|
|
104
|
+
let finalizedHead: HashAndHeight =
|
|
105
|
+
data.finalizedHead == null
|
|
106
|
+
? {height: -1, hash: '0x'}
|
|
107
|
+
: {
|
|
108
|
+
height: data.finalizedHead.number,
|
|
109
|
+
hash: data.finalizedHead.hash,
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
head = await this.processBatch(head, finalizedHead, data.blocks)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
break
|
|
116
|
+
} catch (e) {
|
|
117
|
+
if (isForkException(e) && this.db.supportsHotBlocks) {
|
|
118
|
+
let state = await this.db.getState()
|
|
119
|
+
let forkBase = await computeForkBase(state, e.prevBlocks)
|
|
120
|
+
if (forkBase == null) {
|
|
121
|
+
// rollback all blocks
|
|
122
|
+
head = {height: -1, hash: '0x'}
|
|
123
|
+
} else {
|
|
124
|
+
head = forkBase
|
|
125
|
+
}
|
|
126
|
+
log.info(`navigating a fork on a common base ${formatHead(head)}`)
|
|
127
|
+
} else {
|
|
128
|
+
throw e
|
|
129
|
+
}
|
|
88
130
|
}
|
|
89
131
|
}
|
|
90
132
|
|
|
@@ -92,16 +134,16 @@ class Processor<B extends BlockBase, S> {
|
|
|
92
134
|
}
|
|
93
135
|
|
|
94
136
|
private async assertWeAreOnTheSameChain(state: HashAndHeight): Promise<void> {
|
|
95
|
-
if (state.height < 0) return
|
|
96
|
-
let hash = await this.src.getBlockHash(state.
|
|
97
|
-
if (state.hash === hash) return
|
|
98
|
-
throw new Error(
|
|
99
|
-
|
|
100
|
-
)
|
|
137
|
+
// if (state.height < 0) return
|
|
138
|
+
// let hash = await this.src.getBlockHash(state.number)
|
|
139
|
+
// if (state.hash === hash) return
|
|
140
|
+
// throw new Error(
|
|
141
|
+
// `already indexed block ${formatHead(state)} was not found on chain`
|
|
142
|
+
// )
|
|
101
143
|
}
|
|
102
144
|
|
|
103
|
-
private async initMetrics(state:
|
|
104
|
-
|
|
145
|
+
private async initMetrics(state: number): Promise<void> {
|
|
146
|
+
this.updateProgressMetrics(await this.chainHeight.get(), state)
|
|
105
147
|
let port = process.env.PROCESSOR_PROMETHEUS_PORT || process.env.PROMETHEUS_PORT
|
|
106
148
|
if (port == null) return
|
|
107
149
|
prom.collectDefaultMetrics()
|
|
@@ -110,60 +152,74 @@ class Processor<B extends BlockBase, S> {
|
|
|
110
152
|
log.info(`prometheus metrics are served on port ${server.port}`)
|
|
111
153
|
}
|
|
112
154
|
|
|
113
|
-
private updateProgressMetrics(chainHeight: number,
|
|
155
|
+
private updateProgressMetrics(chainHeight: number, indexerHeight: number, time?: bigint): void {
|
|
114
156
|
this.metrics.setChainHeight(chainHeight)
|
|
115
|
-
this.metrics.setLastProcessedBlock(
|
|
157
|
+
this.metrics.setLastProcessedBlock(indexerHeight)
|
|
116
158
|
let left: number
|
|
117
159
|
let processed: number
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
from: this.metrics.getLastProcessedBlock() + 1,
|
|
121
|
-
to: this.metrics.getChainHeight()
|
|
122
|
-
})
|
|
123
|
-
processed = this.src.getBlocksCountInRange({
|
|
124
|
-
from: 0,
|
|
125
|
-
to: this.metrics.getChainHeight()
|
|
126
|
-
}) - left
|
|
127
|
-
} else {
|
|
128
|
-
left = this.metrics.getChainHeight() - this.metrics.getLastProcessedBlock()
|
|
129
|
-
processed = this.metrics.getLastProcessedBlock()
|
|
130
|
-
}
|
|
160
|
+
left = this.metrics.getChainHeight() - this.metrics.getLastProcessedBlock()
|
|
161
|
+
processed = this.metrics.getLastProcessedBlock()
|
|
131
162
|
this.metrics.updateProgress(processed, left, time)
|
|
132
163
|
}
|
|
133
164
|
|
|
134
|
-
private async processBatch(
|
|
165
|
+
private async processBatch(
|
|
166
|
+
prevHead: HashAndHeight,
|
|
167
|
+
finalizedHead: HashAndHeight,
|
|
168
|
+
blocks: B[]
|
|
169
|
+
): Promise<HashAndHeight> {
|
|
135
170
|
let chainHeight = await this.chainHeight.get()
|
|
136
171
|
|
|
172
|
+
let lastBlock = maybeLast(blocks)
|
|
173
|
+
if (lastBlock == null) return prevHead
|
|
174
|
+
|
|
137
175
|
let nextHead = {
|
|
138
|
-
hash:
|
|
139
|
-
height:
|
|
176
|
+
hash: lastBlock.header.hash,
|
|
177
|
+
height: lastBlock.header.number,
|
|
140
178
|
}
|
|
141
179
|
|
|
142
180
|
let isOnTop = nextHead.height >= chainHeight
|
|
143
181
|
|
|
144
182
|
let mappingStartTime = process.hrtime.bigint()
|
|
145
183
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
184
|
+
if (this.db.supportsHotBlocks) {
|
|
185
|
+
await this.db.transactHot2(
|
|
186
|
+
{
|
|
187
|
+
finalizedHead,
|
|
188
|
+
baseHead: prevHead,
|
|
189
|
+
newBlocks: blocks.map((b) => ({
|
|
190
|
+
hash: b.header.hash,
|
|
191
|
+
height: b.header.number,
|
|
192
|
+
})),
|
|
193
|
+
},
|
|
194
|
+
(store, start, end) => {
|
|
195
|
+
return this.handler({
|
|
196
|
+
store,
|
|
197
|
+
blocks: blocks.slice(start, end),
|
|
198
|
+
isHead: isOnTop,
|
|
199
|
+
})
|
|
200
|
+
}
|
|
201
|
+
)
|
|
202
|
+
} else {
|
|
203
|
+
await this.db.transact(
|
|
204
|
+
{
|
|
205
|
+
prevHead,
|
|
206
|
+
nextHead,
|
|
207
|
+
isOnTop,
|
|
208
|
+
},
|
|
209
|
+
(store) => {
|
|
210
|
+
return this.handler({
|
|
211
|
+
store,
|
|
212
|
+
blocks,
|
|
213
|
+
isHead: isOnTop,
|
|
214
|
+
})
|
|
215
|
+
}
|
|
216
|
+
)
|
|
217
|
+
}
|
|
157
218
|
|
|
158
219
|
let mappingEndTime = process.hrtime.bigint()
|
|
159
220
|
|
|
160
|
-
this.updateProgressMetrics(chainHeight, nextHead, mappingEndTime)
|
|
161
|
-
this.metrics.registerBatch(
|
|
162
|
-
blocks.length,
|
|
163
|
-
getItemsCount(blocks),
|
|
164
|
-
mappingStartTime,
|
|
165
|
-
mappingEndTime
|
|
166
|
-
)
|
|
221
|
+
this.updateProgressMetrics(chainHeight, nextHead.height, mappingEndTime)
|
|
222
|
+
this.metrics.registerBatch(blocks.length, getItemsCount(blocks), mappingStartTime, mappingEndTime)
|
|
167
223
|
|
|
168
224
|
this.reportStatus()
|
|
169
225
|
|
|
@@ -195,3 +251,39 @@ class Processor<B extends BlockBase, S> {
|
|
|
195
251
|
}
|
|
196
252
|
}
|
|
197
253
|
}
|
|
254
|
+
|
|
255
|
+
async function computeForkBase(
|
|
256
|
+
state: HotDatabaseState,
|
|
257
|
+
forked: BlockRef[],
|
|
258
|
+
finalizedHead?: BlockRef
|
|
259
|
+
): Promise<HashAndHeight | undefined> {
|
|
260
|
+
assert(forked?.length)
|
|
261
|
+
let tail = forked.slice()
|
|
262
|
+
|
|
263
|
+
let commited = state.top
|
|
264
|
+
if (commited.length > 0) {
|
|
265
|
+
for (let i = commited.length - 1; i >= 0; i--) {
|
|
266
|
+
let h = commited[i]
|
|
267
|
+
|
|
268
|
+
while (tail.length > 0 && last(tail).number > h.height) {
|
|
269
|
+
tail.pop()
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (tail.length == 0) return h
|
|
273
|
+
|
|
274
|
+
let t = last(tail)
|
|
275
|
+
if (t.number == h.height && t.hash == h.hash) return h
|
|
276
|
+
}
|
|
277
|
+
} else {
|
|
278
|
+
if (forked[0].number > state.height) return state
|
|
279
|
+
|
|
280
|
+
let headOnChain = forked.find((b) => b.number == state.height)
|
|
281
|
+
if (headOnChain == null || headOnChain.hash !== state.hash) {
|
|
282
|
+
if (finalizedHead && finalizedHead.number >= state.height) {
|
|
283
|
+
throw new Error(`finalized block ${formatHead(state)} was not found on chain`)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return state
|
|
288
|
+
}
|
|
289
|
+
}
|
package/lib/datasource.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { FiniteRange } from '@subsquid/util-internal-range';
|
|
2
|
-
export interface DataSource<B> {
|
|
3
|
-
getFinalizedHeight(): Promise<number>;
|
|
4
|
-
getBlockHash(height: number): Promise<string | undefined>;
|
|
5
|
-
getBlockStream(fromBlock?: number): AsyncIterable<B[]>;
|
|
6
|
-
getBlocksCountInRange?(range: FiniteRange): number;
|
|
7
|
-
}
|
|
8
|
-
//# sourceMappingURL=datasource.d.ts.map
|
package/lib/datasource.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"datasource.d.ts","sourceRoot":"","sources":["../src/datasource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,+BAA+B,CAAA;AAG9D,MAAM,WAAW,UAAU,CAAC,CAAC;IACzB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACrC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACzD,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC,EAAE,CAAC,CAAA;IACtD,qBAAqB,CAAC,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAA;CACrD"}
|
package/lib/datasource.js
DELETED
package/lib/datasource.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"datasource.js","sourceRoot":"","sources":["../src/datasource.ts"],"names":[],"mappings":""}
|
package/src/datasource.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type {FiniteRange} from '@subsquid/util-internal-range'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export interface DataSource<B> {
|
|
5
|
-
getFinalizedHeight(): Promise<number>
|
|
6
|
-
getBlockHash(height: number): Promise<string | undefined>
|
|
7
|
-
getBlockStream(fromBlock?: number): AsyncIterable<B[]>
|
|
8
|
-
getBlocksCountInRange?(range: FiniteRange): number
|
|
9
|
-
}
|