@subsquid/batch-processor 0.1.0 → 0.2.0-portal-api.493495
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 +4 -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 -4
- package/lib/run.d.ts.map +1 -1
- package/lib/run.js +171 -41
- package/lib/run.js.map +1 -1
- package/lib/util.d.ts +2 -2
- package/lib/util.d.ts.map +1 -1
- package/lib/util.js +1 -1
- package/lib/util.js.map +1 -1
- package/package.json +4 -2
- package/src/database.ts +6 -7
- package/src/index.ts +0 -1
- package/src/run.ts +202 -56
- package/src/util.ts +3 -2
- 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,11 @@ export interface FinalTxInfo {
|
|
|
10
10
|
}
|
|
11
11
|
export interface FinalDatabase<S> {
|
|
12
12
|
supportsHotBlocks?: false;
|
|
13
|
-
connect(): Promise<
|
|
13
|
+
connect(): Promise<FinalDatabaseState>;
|
|
14
14
|
transact(info: FinalTxInfo, cb: (store: S) => Promise<void>): Promise<void>;
|
|
15
15
|
}
|
|
16
|
+
export interface FinalDatabaseState extends HashAndHeight {
|
|
17
|
+
}
|
|
16
18
|
export interface HotTxInfo {
|
|
17
19
|
finalizedHead: HashAndHeight;
|
|
18
20
|
baseHead: HashAndHeight;
|
|
@@ -22,11 +24,7 @@ export interface HotDatabase<S> {
|
|
|
22
24
|
supportsHotBlocks: true;
|
|
23
25
|
connect(): Promise<HotDatabaseState>;
|
|
24
26
|
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>;
|
|
27
|
+
transactHot2(info: HotTxInfo, cb: (store: S, blockSliceStart: number, blockSliceEnd: number) => Promise<void>): Promise<void>;
|
|
30
28
|
}
|
|
31
29
|
export interface HotDatabaseState extends HashAndHeight {
|
|
32
30
|
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,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,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,6 +1,6 @@
|
|
|
1
|
+
import { Database } from './database';
|
|
2
|
+
import { DataSource, BlockRef } from '@subsquid/util-internal-data-source';
|
|
1
3
|
import { PrometheusServer } from '@subsquid/util-internal-processor-tools';
|
|
2
|
-
import { Database, HashAndHeight } from './database';
|
|
3
|
-
import { DataSource } from './datasource';
|
|
4
4
|
export { PrometheusServer };
|
|
5
5
|
export interface DataHandlerContext<Block, Store> {
|
|
6
6
|
/**
|
|
@@ -16,8 +16,8 @@ export interface DataHandlerContext<Block, Store> {
|
|
|
16
16
|
*/
|
|
17
17
|
isHead: boolean;
|
|
18
18
|
}
|
|
19
|
-
interface BlockBase {
|
|
20
|
-
header:
|
|
19
|
+
export interface BlockBase {
|
|
20
|
+
header: BlockRef;
|
|
21
21
|
}
|
|
22
22
|
interface RunOptions {
|
|
23
23
|
prometheus?: PrometheusServer;
|
package/lib/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,QAAQ,EAAC,MAAM,YAAY,CAAA;AAClD,OAAO,EAAC,UAAU,EAAmB,QAAQ,EAAkB,MAAM,qCAAqC,CAAA;AAE1G,OAAO,EAAC,gBAAgB,EAAgB,MAAM,yCAAyC,CAAA;AAIvF,OAAO,EAAC,gBAAgB,EAAC,CAAA;AAKzB,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;AAGD,MAAM,WAAW,SAAS;IACtB,MAAM,EAAE,QAAQ,CAAA;CACnB;AASD,UAAU,UAAU;IAChB,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAChC;AAGD;;;;;;;;;;;;;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,EACrE,IAAI,CAAC,EAAE,UAAU,GAClB,IAAI,CAMN"}
|
package/lib/run.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.PrometheusServer = void 0;
|
|
4
7
|
exports.run = run;
|
|
5
8
|
const logger_1 = require("@subsquid/logger");
|
|
6
9
|
const util_internal_1 = require("@subsquid/util-internal");
|
|
10
|
+
const util_internal_data_source_1 = require("@subsquid/util-internal-data-source");
|
|
11
|
+
const assert_1 = __importDefault(require("assert"));
|
|
7
12
|
const util_internal_processor_tools_1 = require("@subsquid/util-internal-processor-tools");
|
|
8
13
|
Object.defineProperty(exports, "PrometheusServer", { enumerable: true, get: function () { return util_internal_processor_tools_1.PrometheusServer; } });
|
|
9
14
|
const util_1 = require("./util");
|
|
@@ -37,32 +42,63 @@ class Processor {
|
|
|
37
42
|
this.opts = opts;
|
|
38
43
|
this.hasStatusNews = false;
|
|
39
44
|
this.metrics = new util_internal_processor_tools_1.RunnerMetrics(src.getBlocksCountInRange?.bind(src) ?? ((range) => Math.max(0, range.to - range.from + 1)));
|
|
40
|
-
this.chainHeight = new util_internal_1.Throttler(() => this.src.getFinalizedHeight(), 30000);
|
|
41
45
|
}
|
|
42
46
|
async run() {
|
|
43
|
-
let
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
let getHead = this.db.supportsHotBlocks ? this.src.getHead.bind(this.src) : this.src.getFinalizedHead.bind(this.src);
|
|
48
|
+
let chainHeight = new util_internal_1.Throttler(() => getHead()?.then((r) => r?.number ?? -1), 10000);
|
|
49
|
+
let state = {
|
|
50
|
+
finalizedHead: undefined,
|
|
51
|
+
unfinalizedHeads: [],
|
|
52
|
+
};
|
|
53
|
+
if (this.db.supportsHotBlocks) {
|
|
54
|
+
let dbState = await this.db.connect();
|
|
55
|
+
state.finalizedHead = dbState.height < 0 ? undefined : toBlockRef(dbState);
|
|
56
|
+
state.unfinalizedHeads = dbState.top.map(toBlockRef);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
let dbState = await this.db.connect();
|
|
60
|
+
state.finalizedHead = dbState.height < 0 ? undefined : toBlockRef(dbState);
|
|
61
|
+
}
|
|
62
|
+
let head = getStateHead(state);
|
|
63
|
+
if (head != null) {
|
|
64
|
+
log.info(`last processed block was ${head.number}`);
|
|
65
|
+
}
|
|
66
|
+
await this.initMetrics(head?.number ?? -1, await chainHeight.get());
|
|
67
|
+
while (true) {
|
|
68
|
+
let getStream = this.db.supportsHotBlocks
|
|
69
|
+
? this.src.getStream.bind(this.src)
|
|
70
|
+
: this.src.getFinalizedStream.bind(this.src);
|
|
71
|
+
head = getStateHead(state);
|
|
72
|
+
try {
|
|
73
|
+
for await (let data of getStream({ after: head })) {
|
|
74
|
+
state = await this.processBatch(state, data, await chainHeight.get());
|
|
75
|
+
}
|
|
76
|
+
break; // Stream completed successfully, exit loop
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
if (!(0, util_internal_data_source_1.isForkException)(e) || !this.db.supportsHotBlocks)
|
|
80
|
+
throw e;
|
|
81
|
+
// Handle fork and continue loop to retry
|
|
82
|
+
let chain = state.finalizedHead
|
|
83
|
+
? [state.finalizedHead, ...state.unfinalizedHeads]
|
|
84
|
+
: state.unfinalizedHeads;
|
|
85
|
+
let rollbackIndex = findRollbackIndex(chain, e.previousBlocks);
|
|
86
|
+
if (rollbackIndex === -1) {
|
|
87
|
+
if (state.finalizedHead != null)
|
|
88
|
+
throw new Error('Unable to process fork');
|
|
89
|
+
state.unfinalizedHeads = [];
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const rollbackHead = chain[rollbackIndex];
|
|
93
|
+
log.info(`navigating a fork on a common base ${(0, util_1.formatHead)(rollbackHead)}`);
|
|
94
|
+
state.unfinalizedHeads = chain.slice(1, rollbackIndex + 1);
|
|
95
|
+
}
|
|
52
96
|
}
|
|
53
97
|
}
|
|
54
98
|
this.reportFinalStatus();
|
|
55
99
|
}
|
|
56
|
-
async
|
|
57
|
-
|
|
58
|
-
return;
|
|
59
|
-
let hash = await this.src.getBlockHash(state.height);
|
|
60
|
-
if (state.hash === hash)
|
|
61
|
-
return;
|
|
62
|
-
throw new Error(`already indexed block ${(0, util_1.formatHead)(state)} was not found on chain`);
|
|
63
|
-
}
|
|
64
|
-
async initMetrics(state) {
|
|
65
|
-
this.updateProgressMetrics(await this.chainHeight.get(), state);
|
|
100
|
+
async initMetrics(state, chainHeight) {
|
|
101
|
+
this.updateProgressMetrics(chainHeight, state);
|
|
66
102
|
let port = process.env.PROCESSOR_PROMETHEUS_PORT || process.env.PROMETHEUS_PORT;
|
|
67
103
|
let prometheusServer;
|
|
68
104
|
if (this.opts?.prometheus != null) {
|
|
@@ -78,35 +114,87 @@ class Processor {
|
|
|
78
114
|
let listening = await prometheusServer.serve();
|
|
79
115
|
log.info(`prometheus metrics are served on port ${listening.port}`);
|
|
80
116
|
}
|
|
81
|
-
updateProgressMetrics(chainHeight,
|
|
117
|
+
updateProgressMetrics(chainHeight, indexerHeight, time) {
|
|
82
118
|
this.metrics.setChainHeight(chainHeight);
|
|
83
|
-
this.metrics.setLastProcessedBlock(
|
|
119
|
+
this.metrics.setLastProcessedBlock(indexerHeight);
|
|
84
120
|
this.metrics.updateProgress(time);
|
|
85
121
|
}
|
|
86
|
-
async processBatch(
|
|
87
|
-
let
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
122
|
+
async processBatch(state, data, chainHeight) {
|
|
123
|
+
let { blocks, finalizedHead: finalizedHeadData } = data;
|
|
124
|
+
if (blocks.length === 0)
|
|
125
|
+
return state;
|
|
126
|
+
let prevHead = getStateHead(state);
|
|
127
|
+
// Validate data continuity
|
|
128
|
+
if (prevHead && prevHead.number >= blocks[0].header.number) {
|
|
129
|
+
throw new Error('Data is not continuous');
|
|
130
|
+
}
|
|
131
|
+
if (finalizedHeadData != null && state.finalizedHead != null && finalizedHeadData.number <= state.finalizedHead.number) {
|
|
132
|
+
finalizedHeadData = state.finalizedHead;
|
|
133
|
+
}
|
|
134
|
+
let unfinalizedIndex = 0;
|
|
135
|
+
if (finalizedHeadData != null) {
|
|
136
|
+
unfinalizedIndex = blocks.findIndex((b) => b.header.number > finalizedHeadData.number);
|
|
137
|
+
}
|
|
138
|
+
let nextHead = (0, util_internal_1.last)(blocks).header;
|
|
139
|
+
let isOnTop = nextHead.number >= chainHeight;
|
|
93
140
|
let mappingStartTime = process.hrtime.bigint();
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
141
|
+
if (this.db.supportsHotBlocks) {
|
|
142
|
+
let finalizedRef;
|
|
143
|
+
if (unfinalizedIndex < 0) {
|
|
144
|
+
finalizedRef = blocks[blocks.length - 1].header;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
finalizedRef = blocks[unfinalizedIndex - 1]?.header;
|
|
148
|
+
if (finalizedHeadData != null) {
|
|
149
|
+
finalizedRef = { hash: finalizedHeadData.hash, number: finalizedHeadData.number };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
let finalizedHead = maxBlockRef(finalizedRef, state.finalizedHead);
|
|
153
|
+
await this.db.transactHot2({
|
|
154
|
+
finalizedHead: toHashAndHeight(finalizedHead),
|
|
155
|
+
baseHead: toHashAndHeight(prevHead),
|
|
156
|
+
newBlocks: blocks.map((b) => toHashAndHeight(b.header)),
|
|
157
|
+
}, (store, start, end) => {
|
|
158
|
+
return this.handler({
|
|
159
|
+
store,
|
|
160
|
+
blocks: (start === 0 && end === blocks.length) ? blocks : blocks.slice(start, end),
|
|
161
|
+
isHead: isOnTop,
|
|
162
|
+
});
|
|
103
163
|
});
|
|
104
|
-
|
|
164
|
+
if (finalizedHead) {
|
|
165
|
+
state.finalizedHead = finalizedHead;
|
|
166
|
+
}
|
|
167
|
+
if (state.finalizedHead) {
|
|
168
|
+
let idx = state.unfinalizedHeads.findIndex((h) => h.number > state.finalizedHead.number);
|
|
169
|
+
state.unfinalizedHeads = idx < 0 ? [] : state.unfinalizedHeads.slice(idx);
|
|
170
|
+
}
|
|
171
|
+
if (unfinalizedIndex >= 0) {
|
|
172
|
+
for (let i = unfinalizedIndex; i < blocks.length; i++) {
|
|
173
|
+
state.unfinalizedHeads.push({ number: blocks[i].header.number, hash: blocks[i].header.hash });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
(0, assert_1.default)(unfinalizedIndex < 0, 'non-hot database received unfinalized blocks');
|
|
179
|
+
await this.db.transact({
|
|
180
|
+
prevHead: prevHead ? toHashAndHeight(prevHead) : { height: -1, hash: '0x' },
|
|
181
|
+
nextHead: toHashAndHeight(nextHead),
|
|
182
|
+
isOnTop,
|
|
183
|
+
}, (store) => {
|
|
184
|
+
return this.handler({
|
|
185
|
+
store,
|
|
186
|
+
blocks,
|
|
187
|
+
isHead: isOnTop,
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
state.finalizedHead = { number: nextHead.number, hash: nextHead.hash };
|
|
191
|
+
state.unfinalizedHeads = [];
|
|
192
|
+
}
|
|
105
193
|
let mappingEndTime = process.hrtime.bigint();
|
|
106
|
-
this.updateProgressMetrics(chainHeight, nextHead, mappingEndTime);
|
|
194
|
+
this.updateProgressMetrics(chainHeight, nextHead.number, mappingEndTime);
|
|
107
195
|
this.metrics.registerBatch(blocks.length, (0, util_1.getItemsCount)(blocks), mappingStartTime, mappingEndTime);
|
|
108
196
|
this.reportStatus();
|
|
109
|
-
return
|
|
197
|
+
return state;
|
|
110
198
|
}
|
|
111
199
|
reportStatus() {
|
|
112
200
|
if (this.statusReportTimer == null) {
|
|
@@ -133,4 +221,46 @@ class Processor {
|
|
|
133
221
|
}
|
|
134
222
|
}
|
|
135
223
|
}
|
|
224
|
+
function findRollbackIndex(currentChain, forkChain) {
|
|
225
|
+
let currentIndex = 0;
|
|
226
|
+
let forkIndex = 0;
|
|
227
|
+
let lastCommonIndex = -1;
|
|
228
|
+
while (currentIndex < currentChain.length && forkIndex < forkChain.length) {
|
|
229
|
+
const currentBlock = currentChain[currentIndex];
|
|
230
|
+
const forkBlock = forkChain[forkIndex];
|
|
231
|
+
if (currentBlock.number > forkBlock.number) {
|
|
232
|
+
forkIndex++;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (currentBlock.number < forkBlock.number) {
|
|
236
|
+
currentIndex++;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (currentBlock.hash !== forkBlock.hash) {
|
|
240
|
+
return lastCommonIndex;
|
|
241
|
+
}
|
|
242
|
+
lastCommonIndex = currentIndex;
|
|
243
|
+
currentIndex++;
|
|
244
|
+
forkIndex++;
|
|
245
|
+
}
|
|
246
|
+
return lastCommonIndex;
|
|
247
|
+
}
|
|
248
|
+
function toHashAndHeight(ref) {
|
|
249
|
+
if (ref == null)
|
|
250
|
+
return { height: -1, hash: '0x' };
|
|
251
|
+
return { height: ref.number, hash: ref.hash };
|
|
252
|
+
}
|
|
253
|
+
function toBlockRef(hashAndHeight) {
|
|
254
|
+
return { number: hashAndHeight.height, hash: hashAndHeight.hash };
|
|
255
|
+
}
|
|
256
|
+
function getStateHead(state) {
|
|
257
|
+
return (0, util_internal_1.maybeLast)(state.unfinalizedHeads) ?? state.finalizedHead;
|
|
258
|
+
}
|
|
259
|
+
function maxBlockRef(a, b) {
|
|
260
|
+
if (a == null)
|
|
261
|
+
return b;
|
|
262
|
+
if (b == null)
|
|
263
|
+
return a;
|
|
264
|
+
return a.number >= b.number ? a : b;
|
|
265
|
+
}
|
|
136
266
|
//# 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":";;;;;;AA4DA,kBAWC;AAvED,6CAA6C;AAC7C,2DAA8E;AAE9E,mFAA0G;AAC1G,oDAA2B;AAC3B,2FAAuF;AAI/E,iGAJA,gDAAgB,OAIA;AAHxB,iCAAgD;AAMhD,MAAM,GAAG,GAAG,IAAA,qBAAY,EAAC,qBAAqB,CAAC,CAAA;AAkC/C;;;;;;;;;;;;;GAaG;AACH,SAAgB,GAAG,CACf,GAAsB,EACtB,EAAmB,EACnB,WAAqE,EACrE,IAAiB;IAEjB,IAAA,0BAAU,EAAC,GAAG,EAAE;QACR,OAAO,IAAI,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAA;IAC9D,CAAC,EAAE,GAAG,CAAC,EAAE;QACD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACtB,CAAC,CAAC,CAAA;AACN,CAAC;AAED,MAAM,SAAS;IAKX,YACY,GAAkB,EAClB,EAAe,EACf,OAAyD,EAChD,IAAiB;QAH1B,QAAG,GAAH,GAAG,CAAe;QAClB,OAAE,GAAF,EAAE,CAAa;QACf,YAAO,GAAP,OAAO,CAAkD;QAChD,SAAI,GAAJ,IAAI,CAAa;QAN9B,kBAAa,GAAG,KAAK,CAAA;QAQzB,IAAI,CAAC,OAAO,GAAG,IAAI,6CAAa,CAC5B,GAAG,CAAC,qBAAqB,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAC9F,CAAA;IACL,CAAC;IAED,KAAK,CAAC,GAAG;QACL,IAAI,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACpH,IAAI,WAAW,GAAG,IAAI,yBAAS,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,KAAM,CAAC,CAAA;QAEtF,IAAI,KAAK,GAAmB;YACxB,aAAa,EAAE,SAAS;YACxB,gBAAgB,EAAE,EAAE;SACvB,CAAA;QACD,IAAI,IAAI,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC;YAC5B,IAAI,OAAO,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAA;YACrC,KAAK,CAAC,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;YAC1E,KAAK,CAAC,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QACxD,CAAC;aAAM,CAAC;YACJ,IAAI,OAAO,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAA;YACrC,KAAK,CAAC,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QAC9E,CAAC;QAED,IAAI,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;QAC9B,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,4BAA4B,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;QACvD,CAAC;QACD,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC,EAAE,MAAM,WAAW,CAAC,GAAG,EAAE,CAAC,CAAA;QAEnE,OAAO,IAAI,EAAE,CAAC;YACV,IAAI,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,iBAAiB;gBACrC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBACnC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAEhD,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;YAC1B,IAAI,CAAC;gBACD,IAAI,KAAK,EAAE,IAAI,IAAI,IAAI,SAAS,CAAC,EAAC,KAAK,EAAE,IAAI,EAAC,CAAC,EAAE,CAAC;oBAC9C,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC,GAAG,EAAE,CAAC,CAAA;gBACzE,CAAC;gBACD,MAAK,CAAC,2CAA2C;YACrD,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,IAAI,CAAC,IAAA,2CAAe,EAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,iBAAiB;oBAAE,MAAM,CAAC,CAAA;gBAE9D,yCAAyC;gBACzC,IAAI,KAAK,GAAG,KAAK,CAAC,aAAa;oBAC3B,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,KAAK,CAAC,gBAAgB,CAAC;oBAClD,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAA;gBAC5B,IAAI,aAAa,GAAG,iBAAiB,CAAC,KAAK,EAAE,CAAC,CAAC,cAAc,CAAC,CAAA;gBAC9D,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC;oBACvB,IAAI,KAAK,CAAC,aAAa,IAAI,IAAI;wBAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;oBAC1E,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAA;gBAC/B,CAAC;qBAAM,CAAC;oBACJ,MAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC,CAAA;oBACzC,GAAG,CAAC,IAAI,CAAC,sCAAsC,IAAA,iBAAU,EAAC,YAAY,CAAC,EAAE,CAAC,CAAA;oBAE1E,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,GAAG,CAAC,CAAC,CAAA;gBAC9D,CAAC;YACL,CAAC;QACL,CAAC;QAED,IAAI,CAAC,iBAAiB,EAAE,CAAA;IAC5B,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,KAAa,EAAE,WAAmB;QACxD,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;QAC9C,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAA;QAE/E,IAAI,gBAA8C,CAAA;QAClD,IAAI,IAAI,CAAC,IAAI,EAAE,UAAU,IAAI,IAAI,EAAE,CAAC;YAChC,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAA;QAC3C,CAAC;aAAM,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACtB,gBAAgB,GAAG,IAAI,gDAAgB,EAAE,CAAA;YACzC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAClC,CAAC;QACD,IAAI,gBAAgB,IAAI,IAAI;YAAE,OAAM;QAEpC,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC/C,IAAI,SAAS,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE,CAAA;QAC9C,GAAG,CAAC,IAAI,CAAC,yCAAyC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAA;IACvE,CAAC;IAEO,qBAAqB,CAAC,WAAmB,EAAE,aAAqB,EAAE,IAAa;QACnF,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;QACxC,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAA;QACjD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;IACrC,CAAC;IAEO,KAAK,CAAC,YAAY,CACtB,KAAqB,EACrB,IAAmB,EACnB,WAAmB;QAEnB,IAAI,EAAC,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAC,GAAG,IAAI,CAAA;QAErD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QAErC,IAAI,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;QAElC,2BAA2B;QAC3B,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;QAC7C,CAAC;QAED,IAAI,iBAAiB,IAAI,IAAI,IAAI,KAAK,CAAC,aAAa,IAAI,IAAI,IAAI,iBAAiB,CAAC,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YACrH,iBAAiB,GAAG,KAAK,CAAC,aAAa,CAAA;QAC3C,CAAC;QAED,IAAI,gBAAgB,GAAG,CAAC,CAAA;QACxB,IAAI,iBAAiB,IAAI,IAAI,EAAE,CAAC;YAC5B,gBAAgB,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,iBAAkB,CAAC,MAAM,CAAC,CAAA;QAC3F,CAAC;QAED,IAAI,QAAQ,GAAG,IAAA,oBAAI,EAAC,MAAM,CAAC,CAAC,MAAM,CAAA;QAClC,IAAI,OAAO,GAAG,QAAQ,CAAC,MAAM,IAAI,WAAW,CAAA;QAE5C,IAAI,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAA;QAE9C,IAAI,IAAI,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC;YAC5B,IAAI,YAAkC,CAAA;YACtC,IAAI,gBAAgB,GAAG,CAAC,EAAE,CAAC;gBACvB,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAA;YACnD,CAAC;iBAAM,CAAC;gBACJ,YAAY,GAAG,MAAM,CAAC,gBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,CAAA;gBACnD,IAAI,iBAAiB,IAAI,IAAI,EAAE,CAAC;oBAC5B,YAAY,GAAG,EAAC,IAAI,EAAE,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,CAAC,MAAM,EAAC,CAAA;gBACnF,CAAC;YACL,CAAC;YACD,IAAI,aAAa,GAAG,WAAW,CAAC,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC,CAAA;YAClE,MAAM,IAAI,CAAC,EAAE,CAAC,YAAY,CACtB;gBACI,aAAa,EAAE,eAAe,CAAC,aAAa,CAAC;gBAC7C,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;gBACnC,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;aAC1D,EACD,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAClB,OAAO,IAAI,CAAC,OAAO,CAAC;oBAChB,KAAK;oBACL,MAAM,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC;oBAClF,MAAM,EAAE,OAAO;iBAClB,CAAC,CAAA;YACN,CAAC,CACJ,CAAA;YAED,IAAI,aAAa,EAAE,CAAC;gBAChB,KAAK,CAAC,aAAa,GAAG,aAAa,CAAA;YACvC,CAAC;YACD,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;gBACtB,IAAI,GAAG,GAAG,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,aAAc,CAAC,MAAM,CAAC,CAAA;gBACzF,KAAK,CAAC,gBAAgB,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC7E,CAAC;YACD,IAAI,gBAAgB,IAAI,CAAC,EAAE,CAAC;gBACxB,KAAK,IAAI,CAAC,GAAG,gBAAgB,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACpD,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAC,CAAC,CAAA;gBAC/F,CAAC;YACL,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,IAAA,gBAAM,EAAC,gBAAgB,GAAG,CAAC,EAAE,8CAA8C,CAAC,CAAA;YAE5E,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAClB;gBACI,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAC,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAC;gBACzE,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;gBACnC,OAAO;aACV,EACD,CAAC,KAAK,EAAE,EAAE;gBACN,OAAO,IAAI,CAAC,OAAO,CAAC;oBAChB,KAAK;oBACL,MAAM;oBACN,MAAM,EAAE,OAAO;iBAClB,CAAC,CAAA;YACN,CAAC,CACJ,CAAA;YAED,KAAK,CAAC,aAAa,GAAG,EAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAC,CAAA;YACpE,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAA;QAC/B,CAAC;QAED,IAAI,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAA;QAE5C,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;QACxE,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,IAAA,oBAAa,EAAC,MAAM,CAAC,EAAE,gBAAgB,EAAE,cAAc,CAAC,CAAA;QAElG,IAAI,CAAC,YAAY,EAAE,CAAA;QAEnB,OAAO,KAAK,CAAA;IAChB,CAAC;IAEO,YAAY;QAChB,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,EAAE,CAAC;YACjC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;YACtC,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC,GAAG,EAAE;gBACrC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAA;gBAClC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;oBACrB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAA;oBAC1B,IAAI,CAAC,YAAY,EAAE,CAAA;gBACvB,CAAC;YACL,CAAC,EAAE,IAAK,CAAC,CAAA;QACb,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QAC7B,CAAC;IACL,CAAC;IAEO,iBAAiB;QACrB,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,EAAE,CAAC;YACjC,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QACxC,CAAC;QACD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAA;YAC1B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;QAC1C,CAAC;IACL,CAAC;CACJ;AAED,SAAS,iBAAiB,CAAC,YAAwB,EAAE,SAAqB;IACtE,IAAI,YAAY,GAAG,CAAC,CAAA;IACpB,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,IAAI,eAAe,GAAG,CAAC,CAAC,CAAA;IAExB,OAAO,YAAY,GAAG,YAAY,CAAC,MAAM,IAAI,SAAS,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;QACxE,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,CAAC,CAAA;QAC/C,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;QAEtC,IAAI,YAAY,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;YACzC,SAAS,EAAE,CAAA;YACX,SAAQ;QACZ,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;YACzC,YAAY,EAAE,CAAA;YACd,SAAQ;QACZ,CAAC;QAED,IAAI,YAAY,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YACvC,OAAO,eAAe,CAAA;QAC1B,CAAC;QAED,eAAe,GAAG,YAAY,CAAA;QAC9B,YAAY,EAAE,CAAA;QACd,SAAS,EAAE,CAAA;IACf,CAAC;IAED,OAAO,eAAe,CAAA;AAC1B,CAAC;AAED,SAAS,eAAe,CAAC,GAAyB;IAC9C,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,EAAC,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAC,CAAA;IAChD,OAAO,EAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAC,CAAA;AAC/C,CAAC;AAED,SAAS,UAAU,CAAC,aAA4B;IAC5C,OAAO,EAAC,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,EAAC,CAAA;AACnE,CAAC;AAED,SAAS,YAAY,CAAC,KAAqB;IACvC,OAAO,IAAA,yBAAS,EAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,KAAK,CAAC,aAAa,CAAA;AACnE,CAAC;AAED,SAAS,WAAW,CAAC,CAAuB,EAAE,CAAuB;IACjE,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,CAAC,CAAA;IACvB,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,CAAC,CAAA;IACvB,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACvC,CAAC"}
|
package/lib/util.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BlockRef } from '@subsquid/util-internal-data-source';
|
|
2
2
|
export declare function timeInterval(seconds: number): string;
|
|
3
3
|
export declare function getItemsCount(blocks: any[]): number;
|
|
4
|
-
export declare function formatHead(head:
|
|
4
|
+
export declare function formatHead(head: BlockRef): string;
|
|
5
5
|
export declare function shortHash(hash: string): string;
|
|
6
6
|
//# sourceMappingURL=util.d.ts.map
|
package/lib/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qCAAqC,CAAA;AAIjE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAWpD;AAGD,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,CAWnD;AAGD,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEjD;AAGD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM9C"}
|
package/lib/util.js
CHANGED
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":";;AAIA,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,IAAc;IACrC,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.
|
|
3
|
+
"version": "0.2.0-portal-api.493495",
|
|
4
4
|
"description": "ETL processor",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"repository": "git@github.com:subsquid/squid-sdk.git",
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
"@subsquid/util-internal": "^3.2.0",
|
|
19
19
|
"@subsquid/util-internal-processor-tools": "^4.4.0",
|
|
20
20
|
"@subsquid/util-internal-counters": "^1.3.2",
|
|
21
|
-
"@subsquid/util-internal-
|
|
21
|
+
"@subsquid/util-internal-prometheus-server": "^1.3.0",
|
|
22
|
+
"@subsquid/util-internal-range": "^0.3.0",
|
|
23
|
+
"@subsquid/util-internal-data-source": "0.0.1-portal-api.493495"
|
|
22
24
|
},
|
|
23
25
|
"devDependencies": {
|
|
24
26
|
"@types/node": "^18.18.14",
|
package/src/database.ts
CHANGED
|
@@ -14,11 +14,14 @@ export interface FinalTxInfo {
|
|
|
14
14
|
|
|
15
15
|
export interface FinalDatabase<S> {
|
|
16
16
|
supportsHotBlocks?: false
|
|
17
|
-
connect(): Promise<
|
|
17
|
+
connect(): Promise<FinalDatabaseState>
|
|
18
18
|
transact(info: FinalTxInfo, cb: (store: S) => Promise<void>): Promise<void>
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
export interface FinalDatabaseState extends HashAndHeight {}
|
|
23
|
+
|
|
24
|
+
|
|
22
25
|
export interface HotTxInfo {
|
|
23
26
|
finalizedHead: HashAndHeight
|
|
24
27
|
baseHead: HashAndHeight
|
|
@@ -30,12 +33,8 @@ export interface HotDatabase<S> {
|
|
|
30
33
|
supportsHotBlocks: true
|
|
31
34
|
connect(): Promise<HotDatabaseState>
|
|
32
35
|
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
36
|
|
|
38
|
-
transactHot2
|
|
37
|
+
transactHot2(
|
|
39
38
|
info: HotTxInfo,
|
|
40
39
|
cb: (store: S, blockSliceStart: number, blockSliceEnd: number) => Promise<void>
|
|
41
40
|
): Promise<void>
|
|
@@ -50,4 +49,4 @@ export interface HotDatabaseState extends HashAndHeight {
|
|
|
50
49
|
export interface HashAndHeight {
|
|
51
50
|
height: number
|
|
52
51
|
hash: string
|
|
53
|
-
}
|
|
52
|
+
}
|
package/src/index.ts
CHANGED
package/src/run.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
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
|
+
import {HashAndHeight, Database} from './database'
|
|
4
|
+
import {DataSource, isForkException, BlockRef, type BlockBatch} from '@subsquid/util-internal-data-source'
|
|
5
|
+
import assert from 'assert'
|
|
3
6
|
import {PrometheusServer, RunnerMetrics} from '@subsquid/util-internal-processor-tools'
|
|
4
|
-
import {Database, HashAndHeight} from './database'
|
|
5
|
-
import {DataSource} from './datasource'
|
|
6
7
|
import {formatHead, getItemsCount} from './util'
|
|
7
8
|
|
|
9
|
+
|
|
8
10
|
export {PrometheusServer}
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
const log = createLogger('sqd:batch-processor')
|
|
12
14
|
|
|
13
|
-
|
|
14
15
|
export interface DataHandlerContext<Block, Store> {
|
|
15
16
|
/**
|
|
16
17
|
* Storage interface provided by the database
|
|
@@ -27,10 +28,17 @@ export interface DataHandlerContext<Block, Store> {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
interface BlockBase {
|
|
31
|
-
header:
|
|
31
|
+
export interface BlockBase {
|
|
32
|
+
header: BlockRef
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
|
|
36
|
+
interface ProcessorState {
|
|
37
|
+
finalizedHead: BlockRef | undefined
|
|
38
|
+
unfinalizedHeads: BlockRef[]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
34
42
|
interface RunOptions {
|
|
35
43
|
prometheus?: PrometheusServer
|
|
36
44
|
}
|
|
@@ -63,10 +71,8 @@ export function run<Block extends BlockBase, Store>(
|
|
|
63
71
|
})
|
|
64
72
|
}
|
|
65
73
|
|
|
66
|
-
|
|
67
74
|
class Processor<B extends BlockBase, S> {
|
|
68
75
|
private metrics: RunnerMetrics
|
|
69
|
-
private chainHeight: Throttler<number>
|
|
70
76
|
private statusReportTimer?: any
|
|
71
77
|
private hasStatusNews = false
|
|
72
78
|
|
|
@@ -79,38 +85,67 @@ class Processor<B extends BlockBase, S> {
|
|
|
79
85
|
this.metrics = new RunnerMetrics(
|
|
80
86
|
src.getBlocksCountInRange?.bind(src) ?? ((range) => Math.max(0, range.to - range.from + 1)),
|
|
81
87
|
)
|
|
82
|
-
this.chainHeight = new Throttler(() => this.src.getFinalizedHeight(), 30_000)
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
async run(): Promise<void> {
|
|
86
|
-
let
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
let getHead = this.db.supportsHotBlocks ? this.src.getHead.bind(this.src) : this.src.getFinalizedHead.bind(this.src)
|
|
92
|
+
let chainHeight = new Throttler(() => getHead()?.then((r) => r?.number ?? -1), 10_000)
|
|
93
|
+
|
|
94
|
+
let state: ProcessorState = {
|
|
95
|
+
finalizedHead: undefined,
|
|
96
|
+
unfinalizedHeads: [],
|
|
97
|
+
}
|
|
98
|
+
if (this.db.supportsHotBlocks) {
|
|
99
|
+
let dbState = await this.db.connect()
|
|
100
|
+
state.finalizedHead = dbState.height < 0 ? undefined : toBlockRef(dbState)
|
|
101
|
+
state.unfinalizedHeads = dbState.top.map(toBlockRef)
|
|
102
|
+
} else {
|
|
103
|
+
let dbState = await this.db.connect()
|
|
104
|
+
state.finalizedHead = dbState.height < 0 ? undefined : toBlockRef(dbState)
|
|
89
105
|
}
|
|
90
106
|
|
|
91
|
-
|
|
92
|
-
|
|
107
|
+
let head = getStateHead(state)
|
|
108
|
+
if (head != null) {
|
|
109
|
+
log.info(`last processed block was ${head.number}`)
|
|
110
|
+
}
|
|
111
|
+
await this.initMetrics(head?.number ?? -1, await chainHeight.get())
|
|
93
112
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
113
|
+
while (true) {
|
|
114
|
+
let getStream = this.db.supportsHotBlocks
|
|
115
|
+
? this.src.getStream.bind(this.src)
|
|
116
|
+
: this.src.getFinalizedStream.bind(this.src)
|
|
117
|
+
|
|
118
|
+
head = getStateHead(state)
|
|
119
|
+
try {
|
|
120
|
+
for await (let data of getStream({after: head})) {
|
|
121
|
+
state = await this.processBatch(state, data, await chainHeight.get())
|
|
122
|
+
}
|
|
123
|
+
break // Stream completed successfully, exit loop
|
|
124
|
+
} catch (e) {
|
|
125
|
+
if (!isForkException(e) || !this.db.supportsHotBlocks) throw e
|
|
126
|
+
|
|
127
|
+
// Handle fork and continue loop to retry
|
|
128
|
+
let chain = state.finalizedHead
|
|
129
|
+
? [state.finalizedHead, ...state.unfinalizedHeads]
|
|
130
|
+
: state.unfinalizedHeads
|
|
131
|
+
let rollbackIndex = findRollbackIndex(chain, e.previousBlocks)
|
|
132
|
+
if (rollbackIndex === -1) {
|
|
133
|
+
if (state.finalizedHead != null) throw new Error('Unable to process fork')
|
|
134
|
+
state.unfinalizedHeads = []
|
|
135
|
+
} else {
|
|
136
|
+
const rollbackHead = chain[rollbackIndex]
|
|
137
|
+
log.info(`navigating a fork on a common base ${formatHead(rollbackHead)}`)
|
|
138
|
+
|
|
139
|
+
state.unfinalizedHeads = chain.slice(1, rollbackIndex + 1)
|
|
140
|
+
}
|
|
97
141
|
}
|
|
98
142
|
}
|
|
99
143
|
|
|
100
144
|
this.reportFinalStatus()
|
|
101
145
|
}
|
|
102
146
|
|
|
103
|
-
private async
|
|
104
|
-
|
|
105
|
-
let hash = await this.src.getBlockHash(state.height)
|
|
106
|
-
if (state.hash === hash) return
|
|
107
|
-
throw new Error(
|
|
108
|
-
`already indexed block ${formatHead(state)} was not found on chain`
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private async initMetrics(state: HashAndHeight): Promise<void> {
|
|
113
|
-
this.updateProgressMetrics(await this.chainHeight.get(), state)
|
|
147
|
+
private async initMetrics(state: number, chainHeight: number): Promise<void> {
|
|
148
|
+
this.updateProgressMetrics(chainHeight, state)
|
|
114
149
|
let port = process.env.PROCESSOR_PROMETHEUS_PORT || process.env.PROMETHEUS_PORT
|
|
115
150
|
|
|
116
151
|
let prometheusServer: PrometheusServer | undefined
|
|
@@ -127,49 +162,110 @@ class Processor<B extends BlockBase, S> {
|
|
|
127
162
|
log.info(`prometheus metrics are served on port ${listening.port}`)
|
|
128
163
|
}
|
|
129
164
|
|
|
130
|
-
private updateProgressMetrics(chainHeight: number,
|
|
165
|
+
private updateProgressMetrics(chainHeight: number, indexerHeight: number, time?: bigint): void {
|
|
131
166
|
this.metrics.setChainHeight(chainHeight)
|
|
132
|
-
this.metrics.setLastProcessedBlock(
|
|
167
|
+
this.metrics.setLastProcessedBlock(indexerHeight)
|
|
133
168
|
this.metrics.updateProgress(time)
|
|
134
169
|
}
|
|
135
170
|
|
|
136
|
-
private async processBatch(
|
|
137
|
-
|
|
171
|
+
private async processBatch(
|
|
172
|
+
state: ProcessorState,
|
|
173
|
+
data: BlockBatch<B>,
|
|
174
|
+
chainHeight: number
|
|
175
|
+
): Promise<ProcessorState> {
|
|
176
|
+
let {blocks, finalizedHead: finalizedHeadData} = data
|
|
177
|
+
|
|
178
|
+
if (blocks.length === 0) return state
|
|
179
|
+
|
|
180
|
+
let prevHead = getStateHead(state)
|
|
181
|
+
|
|
182
|
+
// Validate data continuity
|
|
183
|
+
if (prevHead && prevHead.number >= blocks[0].header.number) {
|
|
184
|
+
throw new Error('Data is not continuous')
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (finalizedHeadData != null && state.finalizedHead != null && finalizedHeadData.number <= state.finalizedHead.number) {
|
|
188
|
+
finalizedHeadData = state.finalizedHead
|
|
189
|
+
}
|
|
138
190
|
|
|
139
|
-
let
|
|
140
|
-
|
|
141
|
-
|
|
191
|
+
let unfinalizedIndex = 0
|
|
192
|
+
if (finalizedHeadData != null) {
|
|
193
|
+
unfinalizedIndex = blocks.findIndex((b) => b.header.number > finalizedHeadData!.number)
|
|
142
194
|
}
|
|
143
195
|
|
|
144
|
-
let
|
|
196
|
+
let nextHead = last(blocks).header
|
|
197
|
+
let isOnTop = nextHead.number >= chainHeight
|
|
145
198
|
|
|
146
199
|
let mappingStartTime = process.hrtime.bigint()
|
|
147
200
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
201
|
+
if (this.db.supportsHotBlocks) {
|
|
202
|
+
let finalizedRef: BlockRef | undefined
|
|
203
|
+
if (unfinalizedIndex < 0) {
|
|
204
|
+
finalizedRef = blocks[blocks.length - 1].header
|
|
205
|
+
} else {
|
|
206
|
+
finalizedRef = blocks[unfinalizedIndex - 1]?.header
|
|
207
|
+
if (finalizedHeadData != null) {
|
|
208
|
+
finalizedRef = {hash: finalizedHeadData.hash, number: finalizedHeadData.number}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
let finalizedHead = maxBlockRef(finalizedRef, state.finalizedHead)
|
|
212
|
+
await this.db.transactHot2(
|
|
213
|
+
{
|
|
214
|
+
finalizedHead: toHashAndHeight(finalizedHead),
|
|
215
|
+
baseHead: toHashAndHeight(prevHead),
|
|
216
|
+
newBlocks: blocks.map((b) => toHashAndHeight(b.header)),
|
|
217
|
+
},
|
|
218
|
+
(store, start, end) => {
|
|
219
|
+
return this.handler({
|
|
220
|
+
store,
|
|
221
|
+
blocks: (start === 0 && end === blocks.length) ? blocks : blocks.slice(start, end),
|
|
222
|
+
isHead: isOnTop,
|
|
223
|
+
})
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
if (finalizedHead) {
|
|
228
|
+
state.finalizedHead = finalizedHead
|
|
229
|
+
}
|
|
230
|
+
if (state.finalizedHead) {
|
|
231
|
+
let idx = state.unfinalizedHeads.findIndex((h) => h.number > state.finalizedHead!.number)
|
|
232
|
+
state.unfinalizedHeads = idx < 0 ? [] : state.unfinalizedHeads.slice(idx)
|
|
233
|
+
}
|
|
234
|
+
if (unfinalizedIndex >= 0) {
|
|
235
|
+
for (let i = unfinalizedIndex; i < blocks.length; i++) {
|
|
236
|
+
state.unfinalizedHeads.push({number: blocks[i].header.number, hash: blocks[i].header.hash})
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
} else {
|
|
240
|
+
assert(unfinalizedIndex < 0, 'non-hot database received unfinalized blocks')
|
|
241
|
+
|
|
242
|
+
await this.db.transact(
|
|
243
|
+
{
|
|
244
|
+
prevHead: prevHead ? toHashAndHeight(prevHead) : {height: -1, hash: '0x'},
|
|
245
|
+
nextHead: toHashAndHeight(nextHead),
|
|
246
|
+
isOnTop,
|
|
247
|
+
},
|
|
248
|
+
(store) => {
|
|
249
|
+
return this.handler({
|
|
250
|
+
store,
|
|
251
|
+
blocks,
|
|
252
|
+
isHead: isOnTop,
|
|
253
|
+
})
|
|
254
|
+
}
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
state.finalizedHead = {number: nextHead.number, hash: nextHead.hash}
|
|
258
|
+
state.unfinalizedHeads = []
|
|
259
|
+
}
|
|
159
260
|
|
|
160
261
|
let mappingEndTime = process.hrtime.bigint()
|
|
161
262
|
|
|
162
|
-
this.updateProgressMetrics(chainHeight, nextHead, mappingEndTime)
|
|
163
|
-
this.metrics.registerBatch(
|
|
164
|
-
blocks.length,
|
|
165
|
-
getItemsCount(blocks),
|
|
166
|
-
mappingStartTime,
|
|
167
|
-
mappingEndTime
|
|
168
|
-
)
|
|
263
|
+
this.updateProgressMetrics(chainHeight, nextHead.number, mappingEndTime)
|
|
264
|
+
this.metrics.registerBatch(blocks.length, getItemsCount(blocks), mappingStartTime, mappingEndTime)
|
|
169
265
|
|
|
170
266
|
this.reportStatus()
|
|
171
267
|
|
|
172
|
-
return
|
|
268
|
+
return state
|
|
173
269
|
}
|
|
174
270
|
|
|
175
271
|
private reportStatus(): void {
|
|
@@ -181,7 +277,7 @@ class Processor<B extends BlockBase, S> {
|
|
|
181
277
|
this.hasStatusNews = false
|
|
182
278
|
this.reportStatus()
|
|
183
279
|
}
|
|
184
|
-
},
|
|
280
|
+
}, 5_000)
|
|
185
281
|
} else {
|
|
186
282
|
this.hasStatusNews = true
|
|
187
283
|
}
|
|
@@ -197,3 +293,53 @@ class Processor<B extends BlockBase, S> {
|
|
|
197
293
|
}
|
|
198
294
|
}
|
|
199
295
|
}
|
|
296
|
+
|
|
297
|
+
function findRollbackIndex(currentChain: BlockRef[], forkChain: BlockRef[]): number {
|
|
298
|
+
let currentIndex = 0
|
|
299
|
+
let forkIndex = 0
|
|
300
|
+
let lastCommonIndex = -1
|
|
301
|
+
|
|
302
|
+
while (currentIndex < currentChain.length && forkIndex < forkChain.length) {
|
|
303
|
+
const currentBlock = currentChain[currentIndex]
|
|
304
|
+
const forkBlock = forkChain[forkIndex]
|
|
305
|
+
|
|
306
|
+
if (currentBlock.number > forkBlock.number) {
|
|
307
|
+
forkIndex++
|
|
308
|
+
continue
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (currentBlock.number < forkBlock.number) {
|
|
312
|
+
currentIndex++
|
|
313
|
+
continue
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (currentBlock.hash !== forkBlock.hash) {
|
|
317
|
+
return lastCommonIndex
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
lastCommonIndex = currentIndex
|
|
321
|
+
currentIndex++
|
|
322
|
+
forkIndex++
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return lastCommonIndex
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function toHashAndHeight(ref: BlockRef | undefined): HashAndHeight {
|
|
329
|
+
if (ref == null) return {height: -1, hash: '0x'}
|
|
330
|
+
return {height: ref.number, hash: ref.hash}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function toBlockRef(hashAndHeight: HashAndHeight): BlockRef {
|
|
334
|
+
return {number: hashAndHeight.height, hash: hashAndHeight.hash}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function getStateHead(state: ProcessorState): BlockRef | undefined {
|
|
338
|
+
return maybeLast(state.unfinalizedHeads) ?? state.finalizedHead
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function maxBlockRef(a: BlockRef | undefined, b: BlockRef | undefined): BlockRef | undefined {
|
|
342
|
+
if (a == null) return b
|
|
343
|
+
if (b == null) return a
|
|
344
|
+
return a.number >= b.number ? a : b
|
|
345
|
+
}
|
package/src/util.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type {BlockRef} from '@subsquid/util-internal-data-source'
|
|
1
2
|
import {HashAndHeight} from './database'
|
|
2
3
|
|
|
3
4
|
|
|
@@ -29,8 +30,8 @@ export function getItemsCount(blocks: any[]): number {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
export function formatHead(head:
|
|
33
|
-
return `${head.
|
|
33
|
+
export function formatHead(head: BlockRef): string {
|
|
34
|
+
return `${head.number}#${shortHash(head.hash)}`
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
|
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
|
-
}
|