envio 3.6.1 → 3.7.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/index.d.ts +197 -9
- package/package.json +6 -6
- package/src/Batch.res +64 -25
- package/src/Batch.res.mjs +69 -46
- package/src/ChainFetching.res +13 -17
- package/src/ChainFetching.res.mjs +9 -14
- package/src/ChainState.res +160 -119
- package/src/ChainState.res.mjs +75 -46
- package/src/ChainState.resi +15 -12
- package/src/Config.res +9 -2
- package/src/Config.res.mjs +4 -4
- package/src/Core.res +5 -0
- package/src/Ecosystem.res +0 -1
- package/src/Envio.res +16 -3
- package/src/EventConfigBuilder.res +155 -40
- package/src/EventConfigBuilder.res.mjs +76 -24
- package/src/EventProcessing.res +4 -8
- package/src/EventProcessing.res.mjs +4 -4
- package/src/EventUtils.res +3 -47
- package/src/FetchState.res +124 -104
- package/src/FetchState.res.mjs +116 -100
- package/src/HandlerRegister.res +108 -2
- package/src/HandlerRegister.res.mjs +59 -10
- package/src/HandlerRegister.resi +4 -0
- package/src/Internal.res +84 -24
- package/src/Internal.res.mjs +33 -2
- package/src/LazyLoader.res +12 -11
- package/src/LazyLoader.res.mjs +13 -7
- package/src/Main.res +22 -9
- package/src/Main.res.mjs +18 -5
- package/src/MemoryStorage.res +724 -0
- package/src/MemoryStorage.res.mjs +601 -0
- package/src/PgStorage.res +18 -7
- package/src/PgStorage.res.mjs +14 -11
- package/src/ReorgDetection.res +0 -222
- package/src/ReorgDetection.res.mjs +0 -163
- package/src/Rollback.res +14 -15
- package/src/Rollback.res.mjs +4 -5
- package/src/SimulateItems.res +2 -2
- package/src/Utils.res +3 -0
- package/src/bindings/ClickHouse.res +16 -11
- package/src/bindings/ClickHouse.res.mjs +10 -10
- package/src/bindings/Vitest.res +1 -1
- package/src/sources/BlockStore.res +115 -5
- package/src/sources/BlockStore.res.mjs +25 -0
- package/src/sources/Evm.res +0 -1
- package/src/sources/Evm.res.mjs +0 -1
- package/src/sources/EvmHyperSyncSource.res +19 -84
- package/src/sources/EvmHyperSyncSource.res.mjs +24 -60
- package/src/sources/Fuel.res +24 -4
- package/src/sources/Fuel.res.mjs +23 -3
- package/src/sources/FuelHyperSync.res +8 -3
- package/src/sources/FuelHyperSync.res.mjs +5 -4
- package/src/sources/FuelHyperSync.resi +3 -1
- package/src/sources/FuelHyperSyncClient.res +7 -10
- package/src/sources/FuelHyperSyncSource.res +18 -45
- package/src/sources/FuelHyperSyncSource.res.mjs +18 -35
- package/src/sources/HyperSync.res +49 -229
- package/src/sources/HyperSync.res.mjs +74 -191
- package/src/sources/HyperSync.resi +11 -35
- package/src/sources/HyperSyncClient.res +9 -79
- package/src/sources/HyperSyncClient.res.mjs +2 -6
- package/src/sources/RequestStat.res +5 -0
- package/src/sources/RequestStat.res.mjs +2 -0
- package/src/sources/RpcSource.res +149 -43
- package/src/sources/RpcSource.res.mjs +104 -41
- package/src/sources/SimulateSource.res +8 -5
- package/src/sources/SimulateSource.res.mjs +6 -6
- package/src/sources/Source.res +89 -16
- package/src/sources/Source.res.mjs +50 -1
- package/src/sources/SourceManager.res +255 -50
- package/src/sources/SourceManager.res.mjs +149 -55
- package/src/sources/SourceManager.resi +2 -6
- package/src/sources/Svm.res +0 -7
- package/src/sources/Svm.res.mjs +0 -8
- package/src/sources/SvmHyperSyncClient.res +21 -16
- package/src/sources/SvmHyperSyncClient.res.mjs +3 -4
- package/src/sources/SvmHyperSyncSource.res +25 -117
- package/src/sources/SvmHyperSyncSource.res.mjs +8 -121
- package/svm.schema.json +3 -2
|
@@ -10,17 +10,6 @@ type options = {
|
|
|
10
10
|
addressStore: AddressStore.t,
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
// Synthesize a stable logIndex for an SVM instruction so the FetchState
|
|
14
|
-
// ordering machinery (which compares by `(blockNumber, logIndex)`) sorts
|
|
15
|
-
// instructions deterministically within a slot. The bit packing fits inside
|
|
16
|
-
// JS's 53-bit safe-integer range: transactionIndex ≤ ~10k per slot,
|
|
17
|
-
// instruction position ≤ 1000 per tx, depth ≤ ~10. Outer-only instructions
|
|
18
|
-
// land at `tx * 65536`; inner ones append depth-weighted offsets.
|
|
19
|
-
let synthLogIndex = (~transactionIndex, ~instructionAddress) => {
|
|
20
|
-
let addrSum = instructionAddress->Array.reduce(0, (acc, n) => acc * 1024 + n + 1)
|
|
21
|
-
transactionIndex * 65536 + addrSum
|
|
22
|
-
}
|
|
23
|
-
|
|
24
13
|
// Parse the Rust-decoded instruction (args/accounts arrive as JSON strings to
|
|
25
14
|
// side-step napi-rs's lack of native JSON passthrough) into the public shape.
|
|
26
15
|
let parseDecoded = (
|
|
@@ -68,7 +57,14 @@ let toSvmInstruction = (
|
|
|
68
57
|
}
|
|
69
58
|
|
|
70
59
|
let make = (
|
|
71
|
-
{
|
|
60
|
+
{
|
|
61
|
+
chainId,
|
|
62
|
+
endpointUrl,
|
|
63
|
+
apiToken,
|
|
64
|
+
onEventRegistrations,
|
|
65
|
+
clientTimeoutMillis,
|
|
66
|
+
addressStore,
|
|
67
|
+
}: options,
|
|
72
68
|
): t => {
|
|
73
69
|
let name = "SvmHyperSync"
|
|
74
70
|
|
|
@@ -112,6 +108,9 @@ let make = (
|
|
|
112
108
|
~addressSet,
|
|
113
109
|
) catch {
|
|
114
110
|
| exn =>
|
|
111
|
+
// A rate limit or a replica behind the head is recoverable and has its own
|
|
112
|
+
// backoff and failover, so it must not be buried in a generic retry.
|
|
113
|
+
HyperSync.reraiseIfRecoverable(exn)
|
|
115
114
|
throw(
|
|
116
115
|
Source.GetItemsError(
|
|
117
116
|
Source.FailedGettingItems({
|
|
@@ -133,17 +132,6 @@ let make = (
|
|
|
133
132
|
|
|
134
133
|
let parsingRef = Performance.now()
|
|
135
134
|
|
|
136
|
-
// Per-slot blockTime lookup from the response's `blocks` table, for the
|
|
137
|
-
// batch's `latestFetchedBlockTimestamp`. Slots without a block row (rare;
|
|
138
|
-
// usually skipped slots) fall back to `None`.
|
|
139
|
-
let blockTimeBySlot = Dict.make()
|
|
140
|
-
resp.blocks->Array.forEach(b => {
|
|
141
|
-
switch b.blockTime {
|
|
142
|
-
| Some(t) => blockTimeBySlot->Dict.set(b.slot->Int.toString, t)
|
|
143
|
-
| None => ()
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
|
|
147
135
|
let parsedQueueItems = resp.items->Array.map(item => {
|
|
148
136
|
// Routing happened in Rust; the item references its registration by
|
|
149
137
|
// chain-scoped index.
|
|
@@ -161,10 +149,13 @@ let make = (
|
|
|
161
149
|
onEventRegistration,
|
|
162
150
|
chainId,
|
|
163
151
|
blockNumber: item.slot,
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
152
|
+
// A slot orders by `(transactionIndex, instructionAddress)` — the
|
|
153
|
+
// transaction, then the instruction's position in its CPI tree. Both
|
|
154
|
+
// ride the item so the buffer comparator can order on the pair
|
|
155
|
+
// directly; no single integer can hold it (Solana allows a CPI depth
|
|
156
|
+
// of 5, which needs more bits than a JS integer is exact to).
|
|
157
|
+
logIndex: item.transactionIndex,
|
|
158
|
+
orderPath: item.instructionAddress,
|
|
168
159
|
// The parent transaction is materialised from the store at batch prep.
|
|
169
160
|
transactionIndex: item.transactionIndex,
|
|
170
161
|
payload: payload->(Utils.magic: Envio.svmInstruction => Internal.eventPayload),
|
|
@@ -173,112 +164,29 @@ let make = (
|
|
|
173
164
|
|
|
174
165
|
let parsingTimeElapsed = parsingRef->Performance.secondsSince
|
|
175
166
|
let highestSlot = resp.nextSlot - 1
|
|
176
|
-
let latestBlockTime =
|
|
177
|
-
blockTimeBySlot
|
|
178
|
-
->Utils.Dict.dangerouslyGetNonOption(highestSlot->Int.toString)
|
|
179
|
-
->Option.getOr(0)
|
|
180
|
-
|
|
181
|
-
// Best-effort (slot, blockhash) pairs from the blocks the server returned
|
|
182
|
-
// for this range. Gaps (skipped slots, or slots without matched data) are
|
|
183
|
-
// fine — reorg detection only compares hashes for slots it has observed.
|
|
184
|
-
let blockHashes = resp.blocks->Array.map((b): ReorgDetection.blockData => {
|
|
185
|
-
blockNumber: b.slot,
|
|
186
|
-
blockHash: b.blockhash,
|
|
187
|
-
})
|
|
188
167
|
|
|
189
168
|
let totalTimeElapsed = totalTimeRef->Performance.secondsSince
|
|
190
169
|
|
|
191
170
|
{
|
|
192
|
-
latestFetchedBlockTimestamp: latestBlockTime,
|
|
193
171
|
parsedQueueItems,
|
|
194
172
|
// Raw transactions kept in Rust; materialised (selected fields) at batch prep.
|
|
195
173
|
transactionStore: Some(transactionStore),
|
|
196
174
|
// Raw blocks kept in Rust; materialised onto the payload at batch prep.
|
|
197
|
-
|
|
175
|
+
// Their (slot, blockhash) pairs also drive reorg detection on merge.
|
|
176
|
+
blockStore,
|
|
198
177
|
latestFetchedBlockNumber: highestSlot,
|
|
199
178
|
stats: {totalTimeElapsed, parsingTimeElapsed, pageFetchTime},
|
|
200
179
|
knownHeight,
|
|
201
|
-
blockHashes,
|
|
202
180
|
fromBlockQueried: fromBlock,
|
|
203
181
|
requestStats,
|
|
204
182
|
}
|
|
205
183
|
}
|
|
206
184
|
|
|
207
|
-
//
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
let requestStats = []
|
|
213
|
-
let fromRef = ref(fromSlot)
|
|
214
|
-
let keepGoing = ref(true)
|
|
215
|
-
while keepGoing.contents {
|
|
216
|
-
let query: SvmHyperSyncClient.query = {
|
|
217
|
-
fromSlot: fromRef.contents,
|
|
218
|
-
toSlot: toSlot + 1,
|
|
219
|
-
includeAllBlocks: true,
|
|
220
|
-
fields: {block: [Slot, Blockhash, BlockTime]},
|
|
221
|
-
maxNumBlocks: 1000,
|
|
222
|
-
}
|
|
223
|
-
let timerRef = Performance.now()
|
|
224
|
-
// Block-only query; the store pages are empty.
|
|
225
|
-
let (resp, _, _) = await client.get(~query)
|
|
226
|
-
requestStats
|
|
227
|
-
->Array.push({Source.method: "getBlockHashes", seconds: timerRef->Performance.secondsSince})
|
|
228
|
-
->ignore
|
|
229
|
-
resp.data.blocks->Array.forEach(b =>
|
|
230
|
-
blockDatas
|
|
231
|
-
->Array.push({
|
|
232
|
-
ReorgDetection.blockNumber: b.slot,
|
|
233
|
-
blockHash: b.blockhash,
|
|
234
|
-
blockTimestamp: b.blockTime->Option.getOr(0),
|
|
235
|
-
})
|
|
236
|
-
->ignore
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
// `nextSlot` is the (exclusive) resume cursor. Stop once it passes the
|
|
240
|
-
// range, or fails to advance — the latter guards against an infinite loop.
|
|
241
|
-
if resp.nextSlot > toSlot || resp.nextSlot <= fromRef.contents {
|
|
242
|
-
keepGoing := false
|
|
243
|
-
} else {
|
|
244
|
-
fromRef := resp.nextSlot
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
(blockDatas, requestStats)
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
let getBlockHashes = async (~blockNumbers, ~logger as _) =>
|
|
251
|
-
switch blockNumbers->Array.get(0) {
|
|
252
|
-
| None => {Source.result: Ok([]), requestStats: []}
|
|
253
|
-
| Some(firstSlot) =>
|
|
254
|
-
try {
|
|
255
|
-
let minSlot = ref(firstSlot)
|
|
256
|
-
let maxSlot = ref(firstSlot)
|
|
257
|
-
let requested = Utils.Set.make()
|
|
258
|
-
blockNumbers->Array.forEach(slot => {
|
|
259
|
-
if slot < minSlot.contents {
|
|
260
|
-
minSlot := slot
|
|
261
|
-
}
|
|
262
|
-
if slot > maxSlot.contents {
|
|
263
|
-
maxSlot := slot
|
|
264
|
-
}
|
|
265
|
-
requested->Utils.Set.add(slot)->ignore
|
|
266
|
-
})
|
|
267
|
-
let (blockDatas, requestStats) = await queryBlockDataRange(
|
|
268
|
-
~fromSlot=minSlot.contents,
|
|
269
|
-
~toSlot=maxSlot.contents,
|
|
270
|
-
)
|
|
271
|
-
// Keep one entry per requested slot; drop duplicates and unrelated slots.
|
|
272
|
-
{
|
|
273
|
-
Source.result: Ok(
|
|
274
|
-
blockDatas->Array.filter(data => requested->Utils.Set.delete(data.blockNumber)),
|
|
275
|
-
),
|
|
276
|
-
requestStats,
|
|
277
|
-
}
|
|
278
|
-
} catch {
|
|
279
|
-
| exn => {Source.result: Error(exn), requestStats: []}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
185
|
+
// Called through the client rather than passed as a value: the client is a
|
|
186
|
+
// napi class, so a detached method reference loses the instance it belongs to.
|
|
187
|
+
let getBlockHashes = HyperSync.makeGetBlockHashes(
|
|
188
|
+
~query=(~blockNumbers) => client.getBlockHashes(~blockNumbers),
|
|
189
|
+
)
|
|
282
190
|
|
|
283
191
|
{
|
|
284
192
|
name,
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Source from "./Source.res.mjs";
|
|
4
|
+
import * as HyperSync from "./HyperSync.res.mjs";
|
|
4
5
|
import * as Performance from "../bindings/Performance.res.mjs";
|
|
5
|
-
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
6
6
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
7
7
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
8
8
|
import * as SvmHyperSyncClient from "./SvmHyperSyncClient.res.mjs";
|
|
9
9
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
10
10
|
|
|
11
|
-
function synthLogIndex(transactionIndex, instructionAddress) {
|
|
12
|
-
let addrSum = Stdlib_Array.reduce(instructionAddress, 0, (acc, n) => ((acc << 10) + n | 0) + 1 | 0);
|
|
13
|
-
return (transactionIndex << 16) + addrSum | 0;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
11
|
function parseDecoded(d) {
|
|
17
12
|
let args;
|
|
18
13
|
try {
|
|
@@ -58,7 +53,7 @@ function toSvmInstruction(item, programName, instructionName) {
|
|
|
58
53
|
function make(param) {
|
|
59
54
|
let onEventRegistrations = param.onEventRegistrations;
|
|
60
55
|
let chainId = param.chainId;
|
|
61
|
-
let client = SvmHyperSyncClient.make(param.endpointUrl, param.apiToken, param.clientTimeoutMillis, undefined, undefined,
|
|
56
|
+
let client = SvmHyperSyncClient.make(param.endpointUrl, param.apiToken, param.clientTimeoutMillis, undefined, undefined, SvmHyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations), param.addressStore);
|
|
62
57
|
let getItemsOrThrow = async (fromBlock, toBlock, addressSet, knownHeight, param, selection, itemsTarget, retry, param$1) => {
|
|
63
58
|
let totalTimeRef = Performance.now();
|
|
64
59
|
let pageFetchRef = Performance.now();
|
|
@@ -76,6 +71,7 @@ function make(param) {
|
|
|
76
71
|
match = await client.getEventItems(query, addressSet);
|
|
77
72
|
} catch (raw_exn) {
|
|
78
73
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
74
|
+
HyperSync.reraiseIfRecoverable(exn);
|
|
79
75
|
throw {
|
|
80
76
|
RE_EXN_ID: Source.GetItemsError,
|
|
81
77
|
_1: {
|
|
@@ -98,14 +94,6 @@ function make(param) {
|
|
|
98
94
|
seconds: pageFetchTime
|
|
99
95
|
}];
|
|
100
96
|
let parsingRef = Performance.now();
|
|
101
|
-
let blockTimeBySlot = {};
|
|
102
|
-
resp.blocks.forEach(b => {
|
|
103
|
-
let t = b.blockTime;
|
|
104
|
-
if (t !== undefined) {
|
|
105
|
-
blockTimeBySlot[b.slot.toString()] = t;
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
97
|
let parsedQueueItems = resp.items.map(item => {
|
|
110
98
|
let onEventRegistration = onEventRegistrations[item.onEventRegistrationIndex];
|
|
111
99
|
let eventConfig = onEventRegistration.eventConfig;
|
|
@@ -115,28 +103,22 @@ function make(param) {
|
|
|
115
103
|
onEventRegistration: onEventRegistration,
|
|
116
104
|
chainId: chainId,
|
|
117
105
|
blockNumber: item.slot,
|
|
118
|
-
logIndex:
|
|
106
|
+
logIndex: item.transactionIndex,
|
|
107
|
+
orderPath: item.instructionAddress,
|
|
119
108
|
transactionIndex: item.transactionIndex,
|
|
120
109
|
payload: payload
|
|
121
110
|
};
|
|
122
111
|
});
|
|
123
112
|
let parsingTimeElapsed = Performance.secondsSince(parsingRef);
|
|
124
113
|
let highestSlot = resp.nextSlot - 1 | 0;
|
|
125
|
-
let latestBlockTime = Stdlib_Option.getOr(blockTimeBySlot[highestSlot.toString()], 0);
|
|
126
|
-
let blockHashes = resp.blocks.map(b => ({
|
|
127
|
-
blockHash: b.blockhash,
|
|
128
|
-
blockNumber: b.slot
|
|
129
|
-
}));
|
|
130
114
|
let totalTimeElapsed = Performance.secondsSince(totalTimeRef);
|
|
131
115
|
return {
|
|
132
116
|
knownHeight: knownHeight,
|
|
133
|
-
blockHashes: blockHashes,
|
|
134
117
|
parsedQueueItems: parsedQueueItems,
|
|
135
118
|
transactionStore: Primitive_option.some(match[1]),
|
|
136
|
-
blockStore:
|
|
119
|
+
blockStore: match[2],
|
|
137
120
|
fromBlockQueried: fromBlock,
|
|
138
121
|
latestFetchedBlockNumber: highestSlot,
|
|
139
|
-
latestFetchedBlockTimestamp: latestBlockTime,
|
|
140
122
|
stats: {
|
|
141
123
|
"total time elapsed (s)": totalTimeElapsed,
|
|
142
124
|
"parsing time (s)": parsingTimeElapsed,
|
|
@@ -145,101 +127,7 @@ function make(param) {
|
|
|
145
127
|
requestStats: requestStats
|
|
146
128
|
};
|
|
147
129
|
};
|
|
148
|
-
let
|
|
149
|
-
let blockDatas = [];
|
|
150
|
-
let requestStats = [];
|
|
151
|
-
let fromRef = fromSlot;
|
|
152
|
-
let keepGoing = true;
|
|
153
|
-
while (keepGoing) {
|
|
154
|
-
let query_toSlot = toSlot + 1 | 0;
|
|
155
|
-
let query_includeAllBlocks = true;
|
|
156
|
-
let query_fields = {
|
|
157
|
-
block: [
|
|
158
|
-
"slot",
|
|
159
|
-
"blockhash",
|
|
160
|
-
"block_time"
|
|
161
|
-
]
|
|
162
|
-
};
|
|
163
|
-
let query_maxNumBlocks = 1000;
|
|
164
|
-
let query = {
|
|
165
|
-
fromSlot: fromRef,
|
|
166
|
-
toSlot: query_toSlot,
|
|
167
|
-
includeAllBlocks: query_includeAllBlocks,
|
|
168
|
-
fields: query_fields,
|
|
169
|
-
maxNumBlocks: query_maxNumBlocks
|
|
170
|
-
};
|
|
171
|
-
let timerRef = Performance.now();
|
|
172
|
-
let match = await client.get(query);
|
|
173
|
-
let resp = match[0];
|
|
174
|
-
requestStats.push({
|
|
175
|
-
method: "getBlockHashes",
|
|
176
|
-
seconds: Performance.secondsSince(timerRef)
|
|
177
|
-
});
|
|
178
|
-
resp.data.blocks.forEach(b => {
|
|
179
|
-
blockDatas.push({
|
|
180
|
-
blockHash: b.blockhash,
|
|
181
|
-
blockNumber: b.slot,
|
|
182
|
-
blockTimestamp: Stdlib_Option.getOr(b.blockTime, 0)
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
if (resp.nextSlot > toSlot || resp.nextSlot <= fromRef) {
|
|
186
|
-
keepGoing = false;
|
|
187
|
-
} else {
|
|
188
|
-
fromRef = resp.nextSlot;
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
return [
|
|
192
|
-
blockDatas,
|
|
193
|
-
requestStats
|
|
194
|
-
];
|
|
195
|
-
};
|
|
196
|
-
let getBlockHashes = async (blockNumbers, param) => {
|
|
197
|
-
let firstSlot = blockNumbers[0];
|
|
198
|
-
if (firstSlot === undefined) {
|
|
199
|
-
return {
|
|
200
|
-
result: {
|
|
201
|
-
TAG: "Ok",
|
|
202
|
-
_0: []
|
|
203
|
-
},
|
|
204
|
-
requestStats: []
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
try {
|
|
208
|
-
let minSlot = {
|
|
209
|
-
contents: firstSlot
|
|
210
|
-
};
|
|
211
|
-
let maxSlot = {
|
|
212
|
-
contents: firstSlot
|
|
213
|
-
};
|
|
214
|
-
let requested = new Set();
|
|
215
|
-
blockNumbers.forEach(slot => {
|
|
216
|
-
if (slot < minSlot.contents) {
|
|
217
|
-
minSlot.contents = slot;
|
|
218
|
-
}
|
|
219
|
-
if (slot > maxSlot.contents) {
|
|
220
|
-
maxSlot.contents = slot;
|
|
221
|
-
}
|
|
222
|
-
requested.add(slot);
|
|
223
|
-
});
|
|
224
|
-
let match = await queryBlockDataRange(minSlot.contents, maxSlot.contents);
|
|
225
|
-
return {
|
|
226
|
-
result: {
|
|
227
|
-
TAG: "Ok",
|
|
228
|
-
_0: match[0].filter(data => requested.delete(data.blockNumber))
|
|
229
|
-
},
|
|
230
|
-
requestStats: match[1]
|
|
231
|
-
};
|
|
232
|
-
} catch (raw_exn) {
|
|
233
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
234
|
-
return {
|
|
235
|
-
result: {
|
|
236
|
-
TAG: "Error",
|
|
237
|
-
_0: exn
|
|
238
|
-
},
|
|
239
|
-
requestStats: []
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
};
|
|
130
|
+
let getBlockHashes = HyperSync.makeGetBlockHashes(blockNumbers => client.getBlockHashes(blockNumbers));
|
|
243
131
|
return {
|
|
244
132
|
name: "SvmHyperSync",
|
|
245
133
|
sourceFor: "Sync",
|
|
@@ -264,9 +152,8 @@ function make(param) {
|
|
|
264
152
|
}
|
|
265
153
|
|
|
266
154
|
export {
|
|
267
|
-
synthLogIndex,
|
|
268
155
|
parseDecoded,
|
|
269
156
|
toSvmInstruction,
|
|
270
157
|
make,
|
|
271
158
|
}
|
|
272
|
-
/*
|
|
159
|
+
/* Source Not a pure module */
|
package/svm.schema.json
CHANGED
|
@@ -511,7 +511,7 @@
|
|
|
511
511
|
"type": "string",
|
|
512
512
|
"enum": [
|
|
513
513
|
"transactionIndex",
|
|
514
|
-
"
|
|
514
|
+
"signature",
|
|
515
515
|
"feePayer",
|
|
516
516
|
"success",
|
|
517
517
|
"err",
|
|
@@ -519,7 +519,8 @@
|
|
|
519
519
|
"computeUnitsConsumed",
|
|
520
520
|
"accountKeys",
|
|
521
521
|
"recentBlockhash",
|
|
522
|
-
"version"
|
|
522
|
+
"version",
|
|
523
|
+
"allSignatures"
|
|
523
524
|
]
|
|
524
525
|
},
|
|
525
526
|
"SvmBlockField": {
|