univo 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs
CHANGED
|
@@ -4,8 +4,8 @@ import open from 'open';
|
|
|
4
4
|
import { config } from 'dotenv';
|
|
5
5
|
import { WebSocket } from 'partysocket';
|
|
6
6
|
import { defineCommand, runMain } from 'citty';
|
|
7
|
-
import { h as http } from './shared/univo.
|
|
8
|
-
import { c as createLogger, v as version, n as name } from './shared/univo.
|
|
7
|
+
import { h as http } from './shared/univo.DObJAnN6.mjs';
|
|
8
|
+
import { c as createLogger, v as version, n as name } from './shared/univo.BCKcG-WP.mjs';
|
|
9
9
|
|
|
10
10
|
const log = createLogger({ quiet: false });
|
|
11
11
|
const dev = defineCommand({
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as viem from 'viem';
|
|
2
|
-
import { g as getException, c as createException, a as catchException, l as local } from './shared/univo.
|
|
3
|
-
import { c as createLogger, d as decompress, b as decoder, r as retry, v as version, e as normalizeHex, a as isHexEqual, f as compress } from './shared/univo.
|
|
2
|
+
import { g as getException, c as createException, a as catchException, l as local } from './shared/univo.DObJAnN6.mjs';
|
|
3
|
+
import { c as createLogger, d as decompress, b as decoder, r as retry, v as version, e as normalizeHex, a as isHexEqual, f as compress } from './shared/univo.BCKcG-WP.mjs';
|
|
4
4
|
import { AdapterError } from './metadata/adapters.mjs';
|
|
5
5
|
import 'ws';
|
|
6
6
|
import 'partysocket';
|
|
@@ -94,6 +94,7 @@ function createServer(opts) {
|
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
const SUPPORTED_TRANSACTION_TYPES = /* @__PURE__ */ new Set([0n, 1n, 2n, 3n, 4n]);
|
|
97
98
|
function matchFilter(block, filter) {
|
|
98
99
|
if (!chainValid(block, filter)) return false;
|
|
99
100
|
if (!toBlockValid(block, filter)) return false;
|
|
@@ -139,58 +140,54 @@ function defineIndexer(opts) {
|
|
|
139
140
|
const eventsGroupedByStorageMap = /* @__PURE__ */ new Map();
|
|
140
141
|
const allActions = [];
|
|
141
142
|
async function getBlockFromChain(head) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (typeof head.parent_hash === "string") {
|
|
153
|
-
if (!isHexEqual(head.parent_hash, block.eth_getBlockByNumber.parentHash)) {
|
|
154
|
-
throw new Error("Method `eth_getBlockByNumber` returned unexpected parent hash");
|
|
155
|
-
}
|
|
143
|
+
return await retry(() => retry_getBlockFromChain(head), 2);
|
|
144
|
+
}
|
|
145
|
+
async function retry_getBlockFromChain(head) {
|
|
146
|
+
const block = await opts.getBlock({ chain: head.chain, number: head.number });
|
|
147
|
+
if (block === null) {
|
|
148
|
+
throw new Error("Provided `getBlock` function returned null");
|
|
149
|
+
}
|
|
150
|
+
if (typeof head.hash === "string") {
|
|
151
|
+
if (!isHexEqual(head.hash, block.eth_getBlockByNumber.hash)) {
|
|
152
|
+
throw new Error("Block returned unexpected block hash");
|
|
156
153
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
verifyTransactionIndicies(block);
|
|
162
|
-
verifyTransactionGasUsage(block);
|
|
163
|
-
return block;
|
|
164
|
-
} catch (error) {
|
|
165
|
-
if (error instanceof Error) {
|
|
166
|
-
log.error(`Failed to load block: ${error.message}`);
|
|
154
|
+
}
|
|
155
|
+
if (typeof head.parent_hash === "string") {
|
|
156
|
+
if (!isHexEqual(head.parent_hash, block.eth_getBlockByNumber.parentHash)) {
|
|
157
|
+
throw new Error("Block returned unexpected parent hash");
|
|
167
158
|
}
|
|
168
|
-
throw error;
|
|
169
159
|
}
|
|
160
|
+
verifyBlockHashes(block);
|
|
161
|
+
verifyLogIndicies(block);
|
|
162
|
+
verifyReceiptsRoot(block);
|
|
163
|
+
verifyTransactionsRoot(block);
|
|
164
|
+
verifyTransactionIndicies(block);
|
|
165
|
+
verifyTransactionGasUsage(block);
|
|
166
|
+
return block;
|
|
170
167
|
}
|
|
171
168
|
function verifyBlockHashes(block) {
|
|
172
169
|
const blockHash = block.eth_getBlockByNumber.hash;
|
|
173
170
|
const transactions = block.eth_getBlockByNumber.transactions;
|
|
174
171
|
for (const transaction of transactions) {
|
|
175
172
|
if (!isHexEqual(blockHash, transaction.blockHash)) {
|
|
176
|
-
throw new Error("
|
|
173
|
+
throw new Error("Block returned transaction with unexpected block hash");
|
|
177
174
|
}
|
|
178
175
|
}
|
|
179
176
|
for (const receipt of block.eth_getBlockReceipts) {
|
|
180
177
|
if (!isHexEqual(block.eth_getBlockByNumber.hash, receipt.blockHash)) {
|
|
181
|
-
throw new Error("
|
|
178
|
+
throw new Error("Block returned receipt with unexpected block hash");
|
|
182
179
|
}
|
|
183
180
|
const transactionIndex = viem.hexToNumber(receipt.transactionIndex);
|
|
184
181
|
const transaction = transactions[transactionIndex];
|
|
185
182
|
if (transaction === void 0 || !isHexEqual(transaction.hash, receipt.transactionHash)) {
|
|
186
|
-
throw new Error("
|
|
183
|
+
throw new Error("Block returned receipt with unexpected transaction hash");
|
|
187
184
|
}
|
|
188
185
|
for (const entry of receipt.logs) {
|
|
189
186
|
if (!isHexEqual(blockHash, entry.blockHash)) {
|
|
190
|
-
throw new Error("
|
|
187
|
+
throw new Error("Block returned log with unexpected block hash");
|
|
191
188
|
}
|
|
192
189
|
if (!isHexEqual(receipt.transactionHash, entry.transactionHash)) {
|
|
193
|
-
throw new Error("
|
|
190
|
+
throw new Error("Block returned log with unexpected transaction hash");
|
|
194
191
|
}
|
|
195
192
|
}
|
|
196
193
|
}
|
|
@@ -200,7 +197,7 @@ function defineIndexer(opts) {
|
|
|
200
197
|
for (const receipt of block.eth_getBlockReceipts) {
|
|
201
198
|
for (const entry of receipt.logs) {
|
|
202
199
|
if (viem.hexToBigInt(entry.logIndex) !== expectedLogIndex) {
|
|
203
|
-
throw new Error("
|
|
200
|
+
throw new Error("Block returned non-contiguous log indices");
|
|
204
201
|
}
|
|
205
202
|
expectedLogIndex++;
|
|
206
203
|
}
|
|
@@ -209,7 +206,7 @@ function defineIndexer(opts) {
|
|
|
209
206
|
function verifyReceiptsRoot(block) {
|
|
210
207
|
const receiptsRoot = calculateTrieRoot(block.eth_getBlockReceipts.map(serializeReceipt));
|
|
211
208
|
if (!isHexEqual(block.eth_getBlockByNumber.receiptsRoot, receiptsRoot)) {
|
|
212
|
-
throw new Error("
|
|
209
|
+
throw new Error("Block returned receipts that do not match the block receipts root");
|
|
213
210
|
}
|
|
214
211
|
}
|
|
215
212
|
function calculateTrieRoot(values) {
|
|
@@ -284,41 +281,53 @@ function defineIndexer(opts) {
|
|
|
284
281
|
return type === 0n ? encoded : viem.concatBytes([Uint8Array.of(Number(type)), encoded]);
|
|
285
282
|
}
|
|
286
283
|
function verifyTransactionsRoot(block) {
|
|
287
|
-
const
|
|
288
|
-
|
|
284
|
+
const unsupportedTxs = block.eth_getBlockByNumber.transactions.filter((tx) => {
|
|
285
|
+
return !SUPPORTED_TRANSACTION_TYPES.has(viem.hexToBigInt(tx.type));
|
|
286
|
+
});
|
|
287
|
+
for (const tx of unsupportedTxs) {
|
|
288
|
+
log.warn(`Encountered unsupported tx type for ${tx.hash} on ${block.eth_chainId}`);
|
|
289
|
+
}
|
|
290
|
+
if (unsupportedTxs.length > 0) {
|
|
291
|
+
return log.warn("Unable to verify block `transactionsRoot` because of unsupported tx type");
|
|
292
|
+
}
|
|
293
|
+
const transactions = block.eth_getBlockByNumber.transactions.map((tx) => {
|
|
294
|
+
const { input, ...formatted } = viem.formatTransaction(tx);
|
|
295
|
+
if (formatted.type === "legacy" && (formatted.v === 27n || formatted.v === 28n)) {
|
|
296
|
+
formatted.chainId = void 0;
|
|
297
|
+
}
|
|
289
298
|
const signature = formatted.type === "legacy" ? { r: formatted.r, s: formatted.s, v: formatted.v } : { r: formatted.r, s: formatted.s, yParity: formatted.yParity };
|
|
290
299
|
const serialized = viem.serializeTransaction(
|
|
291
300
|
{ ...formatted, data: input },
|
|
292
301
|
//
|
|
293
302
|
signature
|
|
294
303
|
);
|
|
295
|
-
if (!isHexEqual(
|
|
296
|
-
throw new Error(
|
|
304
|
+
if (!isHexEqual(tx.hash, viem.keccak256(serialized))) {
|
|
305
|
+
throw new Error(`Transaction ${tx.hash} failed serialization check`);
|
|
297
306
|
}
|
|
298
307
|
return viem.hexToBytes(serialized);
|
|
299
308
|
});
|
|
300
309
|
const transactionsRoot = calculateTrieRoot(transactions);
|
|
301
310
|
if (!isHexEqual(block.eth_getBlockByNumber.transactionsRoot, transactionsRoot)) {
|
|
302
|
-
throw new Error("
|
|
311
|
+
throw new Error("Block returned transactions that do not match the block transactions root");
|
|
303
312
|
}
|
|
304
313
|
}
|
|
305
314
|
function verifyTransactionIndicies(block) {
|
|
306
315
|
const receipts = block.eth_getBlockReceipts;
|
|
307
316
|
const transactions = block.eth_getBlockByNumber.transactions;
|
|
308
317
|
if (transactions.length !== receipts.length) {
|
|
309
|
-
throw new Error("
|
|
318
|
+
throw new Error("Block returned different transaction counts");
|
|
310
319
|
}
|
|
311
320
|
for (let index = 0; index < transactions.length; index++) {
|
|
312
321
|
const expectedIndex = BigInt(index);
|
|
313
322
|
if (viem.hexToBigInt(transactions[index].transactionIndex) !== expectedIndex) {
|
|
314
|
-
throw new Error("
|
|
323
|
+
throw new Error("Block returned non-contiguous transaction indices");
|
|
315
324
|
}
|
|
316
325
|
if (viem.hexToBigInt(receipts[index].transactionIndex) !== expectedIndex) {
|
|
317
|
-
throw new Error("
|
|
326
|
+
throw new Error("Block returned non-contiguous transaction indices");
|
|
318
327
|
}
|
|
319
328
|
for (const entry of receipts[index].logs) {
|
|
320
329
|
if (viem.hexToBigInt(entry.transactionIndex) !== expectedIndex) {
|
|
321
|
-
throw new Error("
|
|
330
|
+
throw new Error("Block returned log with unexpected transaction index");
|
|
322
331
|
}
|
|
323
332
|
}
|
|
324
333
|
}
|
|
@@ -327,20 +336,20 @@ function defineIndexer(opts) {
|
|
|
327
336
|
const gasLimit = viem.hexToBigInt(block.eth_getBlockByNumber.gasLimit);
|
|
328
337
|
const blockGasUsed = viem.hexToBigInt(block.eth_getBlockByNumber.gasUsed);
|
|
329
338
|
if (blockGasUsed > gasLimit) {
|
|
330
|
-
throw new Error("
|
|
339
|
+
throw new Error("Block returned gas used greater than the block gas limit");
|
|
331
340
|
}
|
|
332
341
|
let cumulativeGasUsed = 0n;
|
|
333
342
|
for (const receipt of block.eth_getBlockReceipts) {
|
|
334
343
|
cumulativeGasUsed += viem.hexToBigInt(receipt.gasUsed);
|
|
335
344
|
if (viem.hexToBigInt(receipt.cumulativeGasUsed) !== cumulativeGasUsed) {
|
|
336
|
-
throw new Error("
|
|
345
|
+
throw new Error("Block returned inconsistent cumulative gas used");
|
|
337
346
|
}
|
|
338
347
|
if (cumulativeGasUsed > gasLimit) {
|
|
339
|
-
throw new Error("
|
|
348
|
+
throw new Error("Block returned cumulative gas used greater than the block gas limit");
|
|
340
349
|
}
|
|
341
350
|
}
|
|
342
351
|
if (cumulativeGasUsed !== blockGasUsed) {
|
|
343
|
-
throw new Error("
|
|
352
|
+
throw new Error("Block returned inconsistent gas used");
|
|
344
353
|
}
|
|
345
354
|
}
|
|
346
355
|
async function getOrInitManifest(chain) {
|
package/dist/realtime.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { hexToNumber } from 'viem';
|
|
2
|
-
import { c as createLogger, i as iife, m as mutex, r as retry, a as isHexEqual } from './shared/univo.
|
|
2
|
+
import { c as createLogger, i as iife, m as mutex, r as retry, a as isHexEqual } from './shared/univo.BCKcG-WP.mjs';
|
|
3
3
|
|
|
4
4
|
function defineBlockchain(opts) {
|
|
5
5
|
const log = createLogger({ quiet: opts.quiet });
|
|
@@ -122,7 +122,7 @@ function realtime(opts) {
|
|
|
122
122
|
await retry(
|
|
123
123
|
() => opts.indexer.request({ method: "public_deleteReorganisedHead", params: [{ chain, ...head }] }),
|
|
124
124
|
//
|
|
125
|
-
|
|
125
|
+
2
|
|
126
126
|
);
|
|
127
127
|
log.debug("Delivered reorganised head");
|
|
128
128
|
} catch (error) {
|
|
@@ -152,7 +152,7 @@ function realtime(opts) {
|
|
|
152
152
|
log.debug("Indexer finalized");
|
|
153
153
|
} catch (error) {
|
|
154
154
|
if (error instanceof Error) {
|
|
155
|
-
log.warn(`Failed to finalize ${error.message}`);
|
|
155
|
+
log.warn(`Failed to finalize: ${error.message}`);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ws from 'ws';
|
|
2
2
|
import { WebSocket } from 'partysocket';
|
|
3
|
-
import { f as compress, g as raise, c as createLogger, m as mutex } from './univo.
|
|
3
|
+
import { f as compress, g as raise, c as createLogger, m as mutex } from './univo.BCKcG-WP.mjs';
|
|
4
4
|
|
|
5
5
|
function createException(message) {
|
|
6
6
|
return `univo:${message}`;
|
package/dist/transport.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import 'ws';
|
|
2
2
|
import 'partysocket';
|
|
3
|
-
export { h as http, l as local, w as wss } from './shared/univo.
|
|
4
|
-
import './shared/univo.
|
|
3
|
+
export { h as http, l as local, w as wss } from './shared/univo.DObJAnN6.mjs';
|
|
4
|
+
import './shared/univo.BCKcG-WP.mjs';
|