@obolnetwork/obol-sdk 2.12.0 → 2.12.1
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/browser/src/index.js +315 -136
- package/dist/browser/src/index.js.map +1 -1
- package/dist/cjs/src/blsUtils.js +19 -2
- package/dist/cjs/src/blsUtils.js.map +1 -1
- package/dist/cjs/src/index.js +321 -136
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/cjs/src/verification/clusterLockValidationWorker.js +14696 -0
- package/dist/cjs/src/verification/clusterLockValidationWorker.js.map +1 -0
- package/dist/cjs/src/verification/lockWorker.js +13 -1
- package/dist/cjs/src/verification/lockWorker.js.map +1 -1
- package/dist/cjs/src/verification/parallelPool.js +228 -35
- package/dist/cjs/src/verification/parallelPool.js.map +1 -1
- package/dist/esm/src/blsUtils.js +7 -3
- package/dist/esm/src/chunk-5ASVONSJ.js +10242 -0
- package/dist/esm/src/chunk-5ASVONSJ.js.map +1 -0
- package/dist/esm/src/{chunk-267HIPEB.js → chunk-LOSYOJC3.js} +16 -1
- package/dist/esm/src/{chunk-267HIPEB.js.map → chunk-LOSYOJC3.js.map} +1 -1
- package/dist/esm/src/chunk-RYTIXFRX.js +382 -0
- package/dist/esm/src/chunk-RYTIXFRX.js.map +1 -0
- package/dist/esm/src/index.js +213 -10340
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/verification/clusterLockValidationWorker.js +18 -0
- package/dist/esm/src/verification/clusterLockValidationWorker.js.map +1 -0
- package/dist/esm/src/verification/lockWorker.js +7 -2
- package/dist/esm/src/verification/lockWorker.js.map +1 -1
- package/dist/esm/src/verification/parallelPool.js +8 -2
- package/dist/types/src/blsUtils.d.ts +3 -0
- package/dist/types/src/errors.d.ts +13 -0
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/services.d.ts +4 -1
- package/dist/types/src/types.d.ts +6 -0
- package/dist/types/src/verification/clusterLockValidationWorker.d.ts +1 -0
- package/dist/types/src/verification/common.d.ts +17 -7
- package/dist/types/src/verification/lockWorker.d.ts +7 -2
- package/dist/types/src/verification/parallelPool.d.ts +9 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/esm/src/chunk-OYZHSNKR.js +0 -186
- package/dist/esm/src/chunk-OYZHSNKR.js.map +0 -1
|
@@ -98,7 +98,7 @@ import { v4 as uuidv4 } from "uuid";
|
|
|
98
98
|
// package.json
|
|
99
99
|
var package_default = {
|
|
100
100
|
name: "@obolnetwork/obol-sdk",
|
|
101
|
-
version: "2.12.
|
|
101
|
+
version: "2.12.1",
|
|
102
102
|
description: "A package for creating Distributed Validators using the Obol API.",
|
|
103
103
|
bugs: {
|
|
104
104
|
url: "https://github.com/obolnetwork/obol-sdk/issues"
|
|
@@ -582,6 +582,19 @@ var UnsupportedChainError = class _UnsupportedChainError extends Error {
|
|
|
582
582
|
Object.setPrototypeOf(this, _UnsupportedChainError.prototype);
|
|
583
583
|
}
|
|
584
584
|
};
|
|
585
|
+
var ClusterLockValidationTimeoutError = class _ClusterLockValidationTimeoutError extends Error {
|
|
586
|
+
/**
|
|
587
|
+
* @param timeoutMs - Same value as SDK whole-lock validation worker timeout.
|
|
588
|
+
*/
|
|
589
|
+
constructor(timeoutMs) {
|
|
590
|
+
super(
|
|
591
|
+
`Cluster lock validation exceeded worker time limit (${timeoutMs} ms). Retry later; this does not imply invalid lock data.`
|
|
592
|
+
);
|
|
593
|
+
this.timeoutMs = timeoutMs;
|
|
594
|
+
this.name = "ClusterLockValidationTimeoutError";
|
|
595
|
+
Object.setPrototypeOf(this, _ClusterLockValidationTimeoutError.prototype);
|
|
596
|
+
}
|
|
597
|
+
};
|
|
585
598
|
|
|
586
599
|
// src/verification/common.ts
|
|
587
600
|
import { fromHexString as fromHexString6 } from "@chainsafe/ssz";
|
|
@@ -714,6 +727,9 @@ import {
|
|
|
714
727
|
fromHexString as fromHexString2
|
|
715
728
|
} from "@chainsafe/ssz";
|
|
716
729
|
|
|
730
|
+
// src/verification/parallelPool.ts
|
|
731
|
+
import { fromHexString } from "@chainsafe/ssz";
|
|
732
|
+
|
|
717
733
|
// node_modules/@noble/curves/node_modules/@noble/hashes/utils.js
|
|
718
734
|
function isBytes(a) {
|
|
719
735
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
@@ -5139,6 +5155,12 @@ function blsVerify(pubkey, message2, signature) {
|
|
|
5139
5155
|
return false;
|
|
5140
5156
|
}
|
|
5141
5157
|
}
|
|
5158
|
+
function blsAggregatePublicKeys(pubkeys) {
|
|
5159
|
+
if (pubkeys.length === 0) {
|
|
5160
|
+
throw new Error("cannot aggregate empty pubkey set");
|
|
5161
|
+
}
|
|
5162
|
+
return ls.aggregatePublicKeys(pubkeys).toBytes();
|
|
5163
|
+
}
|
|
5142
5164
|
function blsVerifyAggregate(pubkeys, message2, signature) {
|
|
5143
5165
|
try {
|
|
5144
5166
|
return ls.verify(
|
|
@@ -5150,6 +5172,13 @@ function blsVerifyAggregate(pubkeys, message2, signature) {
|
|
|
5150
5172
|
return false;
|
|
5151
5173
|
}
|
|
5152
5174
|
}
|
|
5175
|
+
function blsVerifyWithAggregatedPubkey(aggregatedPubkey, message2, signature) {
|
|
5176
|
+
try {
|
|
5177
|
+
return ls.verify(signature, ls.hash(message2, ETH2_DST), aggregatedPubkey);
|
|
5178
|
+
} catch (e) {
|
|
5179
|
+
return false;
|
|
5180
|
+
}
|
|
5181
|
+
}
|
|
5153
5182
|
function blsVerifyMultiple(pubkeys, messages, signature) {
|
|
5154
5183
|
try {
|
|
5155
5184
|
if (pubkeys.length !== messages.length) return false;
|
|
@@ -5215,16 +5244,23 @@ function blsVerifyExtraShares(pubshares, threshold, distributedPubkey) {
|
|
|
5215
5244
|
}
|
|
5216
5245
|
|
|
5217
5246
|
// src/verification/parallelPool.ts
|
|
5218
|
-
import { fromHexString } from "@chainsafe/ssz";
|
|
5219
5247
|
var MIN_PARALLEL_VALIDATORS = 50;
|
|
5220
5248
|
var MIN_PARALLEL_BATCH_PAIRS = 100;
|
|
5221
5249
|
var MAX_WORKERS = 8;
|
|
5222
5250
|
var MIN_VALIDATORS_PER_WORKER = 25;
|
|
5223
5251
|
var MIN_PAIRS_PER_WORKER = 50;
|
|
5252
|
+
var MIN_PARALLEL_AGGREGATE_KEYS = 400;
|
|
5253
|
+
var MIN_KEYS_PER_WORKER_AGG = 100;
|
|
5254
|
+
var MIN_VALIDATORS_FOR_VALIDATION_WORKER = 50;
|
|
5255
|
+
var VALIDATION_WORKER_TIMEOUT_MS = 12e4;
|
|
5224
5256
|
var WORKER_TIMEOUT_MS = 6e4;
|
|
5257
|
+
var MAX_CONCURRENT_WORKERS_CAP = 8;
|
|
5258
|
+
function maxConcurrentWorkers(numWorkers) {
|
|
5259
|
+
return Math.min(numWorkers, MAX_CONCURRENT_WORKERS_CAP);
|
|
5260
|
+
}
|
|
5225
5261
|
var workerThreadsCache;
|
|
5226
5262
|
var osCache;
|
|
5227
|
-
var
|
|
5263
|
+
var workerPathByFile = /* @__PURE__ */ new Map();
|
|
5228
5264
|
function loadWorkerThreads() {
|
|
5229
5265
|
if (workerThreadsCache !== void 0) return workerThreadsCache;
|
|
5230
5266
|
try {
|
|
@@ -5243,18 +5279,47 @@ function loadOs() {
|
|
|
5243
5279
|
}
|
|
5244
5280
|
return osCache;
|
|
5245
5281
|
}
|
|
5246
|
-
function getWorkerPath() {
|
|
5247
|
-
|
|
5248
|
-
if (
|
|
5282
|
+
function getWorkerPath(filename) {
|
|
5283
|
+
const cached = workerPathByFile.get(filename);
|
|
5284
|
+
if (cached !== void 0) return cached;
|
|
5285
|
+
if (typeof __dirname === "undefined") {
|
|
5286
|
+
workerPathByFile.set(filename, null);
|
|
5287
|
+
return null;
|
|
5288
|
+
}
|
|
5249
5289
|
const path = __require("path");
|
|
5250
|
-
const
|
|
5290
|
+
const fs = __require("fs");
|
|
5291
|
+
const candidates = [
|
|
5292
|
+
path.join(__dirname, filename),
|
|
5293
|
+
path.join(__dirname, "verification", filename)
|
|
5294
|
+
];
|
|
5251
5295
|
try {
|
|
5252
|
-
const
|
|
5253
|
-
|
|
5296
|
+
for (const candidate of candidates) {
|
|
5297
|
+
if (fs.existsSync(candidate)) {
|
|
5298
|
+
workerPathByFile.set(filename, candidate);
|
|
5299
|
+
return candidate;
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5254
5302
|
} catch (e) {
|
|
5255
|
-
return workerPathCache = null;
|
|
5256
5303
|
}
|
|
5257
|
-
|
|
5304
|
+
workerPathByFile.set(filename, null);
|
|
5305
|
+
return null;
|
|
5306
|
+
}
|
|
5307
|
+
function mapWithConcurrency(items, concurrency, fn) {
|
|
5308
|
+
return __async(this, null, function* () {
|
|
5309
|
+
const results = new Array(items.length);
|
|
5310
|
+
let next = 0;
|
|
5311
|
+
const runners = Array.from(
|
|
5312
|
+
{ length: Math.min(concurrency, items.length) },
|
|
5313
|
+
() => __async(null, null, function* () {
|
|
5314
|
+
while (next < items.length) {
|
|
5315
|
+
const i = next++;
|
|
5316
|
+
results[i] = yield fn(items[i], i);
|
|
5317
|
+
}
|
|
5318
|
+
})
|
|
5319
|
+
);
|
|
5320
|
+
yield Promise.all(runners);
|
|
5321
|
+
return results;
|
|
5322
|
+
});
|
|
5258
5323
|
}
|
|
5259
5324
|
function chunkArrays(arr, n) {
|
|
5260
5325
|
const size = Math.ceil(arr.length / n);
|
|
@@ -5283,6 +5348,33 @@ function verifySharesSync(shares, distributedKeys, threshold) {
|
|
|
5283
5348
|
}
|
|
5284
5349
|
return true;
|
|
5285
5350
|
}
|
|
5351
|
+
function runWorkerAggregatePubkeys(wt, workerFile, data) {
|
|
5352
|
+
return __async(this, null, function* () {
|
|
5353
|
+
return yield new Promise((resolve) => {
|
|
5354
|
+
let settled = false;
|
|
5355
|
+
const worker = new wt.Worker(workerFile, { workerData: data });
|
|
5356
|
+
const finish = (result) => {
|
|
5357
|
+
if (settled) return;
|
|
5358
|
+
settled = true;
|
|
5359
|
+
clearTimeout(timer);
|
|
5360
|
+
worker.terminate();
|
|
5361
|
+
resolve(result);
|
|
5362
|
+
};
|
|
5363
|
+
const timer = setTimeout(() => {
|
|
5364
|
+
finish(null);
|
|
5365
|
+
}, WORKER_TIMEOUT_MS);
|
|
5366
|
+
worker.once("message", (msg) => {
|
|
5367
|
+
finish(msg instanceof Uint8Array ? msg : null);
|
|
5368
|
+
});
|
|
5369
|
+
worker.once("error", () => {
|
|
5370
|
+
finish(null);
|
|
5371
|
+
});
|
|
5372
|
+
worker.once("exit", (code2) => {
|
|
5373
|
+
if (code2 !== 0) finish(null);
|
|
5374
|
+
});
|
|
5375
|
+
});
|
|
5376
|
+
});
|
|
5377
|
+
}
|
|
5286
5378
|
function runWorker(wt, workerFile, data) {
|
|
5287
5379
|
return __async(this, null, function* () {
|
|
5288
5380
|
return yield new Promise((resolve) => {
|
|
@@ -5313,8 +5405,8 @@ function runWorker(wt, workerFile, data) {
|
|
|
5313
5405
|
function poolSize(itemCount, minPerWorker) {
|
|
5314
5406
|
const wt = loadWorkerThreads();
|
|
5315
5407
|
const os = loadOs();
|
|
5316
|
-
const workerFile = getWorkerPath();
|
|
5317
|
-
const numCpus = os ? os.cpus().length : 1;
|
|
5408
|
+
const workerFile = getWorkerPath("lockWorker.js");
|
|
5409
|
+
const numCpus = os ? Math.max(1, os.cpus().length) : 1;
|
|
5318
5410
|
const numWorkers = Math.min(
|
|
5319
5411
|
MAX_WORKERS,
|
|
5320
5412
|
Math.max(1, Math.floor(itemCount / minPerWorker)),
|
|
@@ -5322,6 +5414,18 @@ function poolSize(itemCount, minPerWorker) {
|
|
|
5322
5414
|
);
|
|
5323
5415
|
return { numWorkers, wt, workerFile };
|
|
5324
5416
|
}
|
|
5417
|
+
function runWorkerChunks(wt, workerFile, chunks) {
|
|
5418
|
+
return __async(this, null, function* () {
|
|
5419
|
+
const results = yield mapWithConcurrency(
|
|
5420
|
+
chunks,
|
|
5421
|
+
maxConcurrentWorkers(chunks.length),
|
|
5422
|
+
(data) => __async(null, null, function* () {
|
|
5423
|
+
return yield runWorker(wt, workerFile, data);
|
|
5424
|
+
})
|
|
5425
|
+
);
|
|
5426
|
+
return results.every(Boolean);
|
|
5427
|
+
});
|
|
5428
|
+
}
|
|
5325
5429
|
function verifySharesBinding(shares, distributedKeys, threshold) {
|
|
5326
5430
|
return __async(this, null, function* () {
|
|
5327
5431
|
if (shares.length !== distributedKeys.length) return false;
|
|
@@ -5335,19 +5439,26 @@ function verifySharesBinding(shares, distributedKeys, threshold) {
|
|
|
5335
5439
|
}
|
|
5336
5440
|
const shareChunks = chunkArrays(shares, numWorkers);
|
|
5337
5441
|
const keyChunks = chunkArrays(distributedKeys, numWorkers);
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5442
|
+
return yield runWorkerChunks(
|
|
5443
|
+
wt,
|
|
5444
|
+
workerFile,
|
|
5445
|
+
shareChunks.map((chunk, i) => ({
|
|
5446
|
+
mode: "shareBinding",
|
|
5447
|
+
shares: chunk,
|
|
5448
|
+
distributedKeys: keyChunks[i],
|
|
5449
|
+
threshold
|
|
5450
|
+
}))
|
|
5451
|
+
);
|
|
5452
|
+
});
|
|
5453
|
+
}
|
|
5454
|
+
function verifyBlsChecksParallel(checks) {
|
|
5455
|
+
return __async(this, null, function* () {
|
|
5456
|
+
if (checks.length === 0) return true;
|
|
5457
|
+
return yield verifyBatchParallel(
|
|
5458
|
+
checks.map((c) => c.pubkey),
|
|
5459
|
+
checks.map((c) => c.message),
|
|
5460
|
+
checks.map((c) => c.signature)
|
|
5349
5461
|
);
|
|
5350
|
-
return results.every(Boolean);
|
|
5351
5462
|
});
|
|
5352
5463
|
}
|
|
5353
5464
|
function verifyBatchParallel(pubkeys, messages, signatures) {
|
|
@@ -5370,19 +5481,84 @@ function verifyBatchParallel(pubkeys, messages, signatures) {
|
|
|
5370
5481
|
const pkChunks = chunkArrays(pubkeys, numWorkers);
|
|
5371
5482
|
const msgChunks = chunkArrays(messages, numWorkers);
|
|
5372
5483
|
const sigChunks = chunkArrays(signatures, numWorkers);
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
})
|
|
5383
|
-
)
|
|
5484
|
+
return yield runWorkerChunks(
|
|
5485
|
+
wt,
|
|
5486
|
+
workerFile,
|
|
5487
|
+
pkChunks.map((pks, i) => ({
|
|
5488
|
+
mode: "verifyBatch",
|
|
5489
|
+
pubkeys: pks,
|
|
5490
|
+
messages: msgChunks[i],
|
|
5491
|
+
signatures: sigChunks[i]
|
|
5492
|
+
}))
|
|
5384
5493
|
);
|
|
5385
|
-
|
|
5494
|
+
});
|
|
5495
|
+
}
|
|
5496
|
+
function verifyAggregateParallel(pubkeys, message2, signature) {
|
|
5497
|
+
return __async(this, null, function* () {
|
|
5498
|
+
if (pubkeys.length === 0) return false;
|
|
5499
|
+
const { numWorkers, wt, workerFile } = poolSize(
|
|
5500
|
+
pubkeys.length,
|
|
5501
|
+
MIN_KEYS_PER_WORKER_AGG
|
|
5502
|
+
);
|
|
5503
|
+
if (wt === null || workerFile === null || pubkeys.length < MIN_PARALLEL_AGGREGATE_KEYS || numWorkers < 2) {
|
|
5504
|
+
return blsVerifyAggregate(pubkeys, message2, signature);
|
|
5505
|
+
}
|
|
5506
|
+
const pkChunks = chunkArrays(pubkeys, numWorkers);
|
|
5507
|
+
const partials = yield mapWithConcurrency(
|
|
5508
|
+
pkChunks,
|
|
5509
|
+
maxConcurrentWorkers(pkChunks.length),
|
|
5510
|
+
(chunk) => __async(null, null, function* () {
|
|
5511
|
+
return yield runWorkerAggregatePubkeys(wt, workerFile, {
|
|
5512
|
+
mode: "aggregatePubkeys",
|
|
5513
|
+
pubkeys: chunk
|
|
5514
|
+
});
|
|
5515
|
+
})
|
|
5516
|
+
);
|
|
5517
|
+
if (partials.some((p) => p === null)) return false;
|
|
5518
|
+
const aggregated = blsAggregatePublicKeys(partials);
|
|
5519
|
+
return blsVerifyWithAggregatedPubkey(aggregated, message2, signature);
|
|
5520
|
+
});
|
|
5521
|
+
}
|
|
5522
|
+
function validateClusterLockInWorker(lock, safeRpcUrl) {
|
|
5523
|
+
return __async(this, null, function* () {
|
|
5524
|
+
var _a6, _b2;
|
|
5525
|
+
const n = (_b2 = (_a6 = lock.distributed_validators) == null ? void 0 : _a6.length) != null ? _b2 : 0;
|
|
5526
|
+
if (n < MIN_VALIDATORS_FOR_VALIDATION_WORKER) return null;
|
|
5527
|
+
const wt = loadWorkerThreads();
|
|
5528
|
+
const workerFile = getWorkerPath("clusterLockValidationWorker.js");
|
|
5529
|
+
if (wt === null || workerFile === null) return null;
|
|
5530
|
+
return yield new Promise((resolve, reject) => {
|
|
5531
|
+
let settled = false;
|
|
5532
|
+
const worker = new wt.Worker(workerFile, {
|
|
5533
|
+
workerData: { lock, safeRpcUrl }
|
|
5534
|
+
});
|
|
5535
|
+
let timer;
|
|
5536
|
+
const finish = (result) => {
|
|
5537
|
+
if (settled) return;
|
|
5538
|
+
settled = true;
|
|
5539
|
+
clearTimeout(timer);
|
|
5540
|
+
worker.terminate();
|
|
5541
|
+
resolve(result);
|
|
5542
|
+
};
|
|
5543
|
+
timer = setTimeout(() => {
|
|
5544
|
+
if (settled) return;
|
|
5545
|
+
settled = true;
|
|
5546
|
+
clearTimeout(timer);
|
|
5547
|
+
void worker.terminate();
|
|
5548
|
+
reject(
|
|
5549
|
+
new ClusterLockValidationTimeoutError(VALIDATION_WORKER_TIMEOUT_MS)
|
|
5550
|
+
);
|
|
5551
|
+
}, VALIDATION_WORKER_TIMEOUT_MS);
|
|
5552
|
+
worker.once("message", (msg) => {
|
|
5553
|
+
finish(msg === true);
|
|
5554
|
+
});
|
|
5555
|
+
worker.once("error", () => {
|
|
5556
|
+
finish(null);
|
|
5557
|
+
});
|
|
5558
|
+
worker.once("exit", (code2) => {
|
|
5559
|
+
if (code2 !== 0) finish(null);
|
|
5560
|
+
});
|
|
5561
|
+
});
|
|
5386
5562
|
});
|
|
5387
5563
|
}
|
|
5388
5564
|
|
|
@@ -5487,7 +5663,6 @@ var hashClusterLockV1X6 = (cluster) => {
|
|
|
5487
5663
|
return "0x" + Buffer.from(lockType.hashTreeRoot(val).buffer).toString("hex");
|
|
5488
5664
|
};
|
|
5489
5665
|
var verifyDVV1X6 = (clusterLock) => __async(null, null, function* () {
|
|
5490
|
-
var _a6;
|
|
5491
5666
|
const validators = clusterLock.distributed_validators;
|
|
5492
5667
|
const operatorCount = clusterLock.cluster_definition.operators.length;
|
|
5493
5668
|
const threshold = clusterLock.cluster_definition.threshold;
|
|
@@ -5506,9 +5681,7 @@ var verifyDVV1X6 = (clusterLock) => __async(null, null, function* () {
|
|
|
5506
5681
|
return false;
|
|
5507
5682
|
}
|
|
5508
5683
|
const pubShares = [];
|
|
5509
|
-
const
|
|
5510
|
-
const builderRegistrationAndDepositDataMessages = [];
|
|
5511
|
-
const blsSignatures = [];
|
|
5684
|
+
const blsChecks = [];
|
|
5512
5685
|
for (let i = 0; i < validators.length; i++) {
|
|
5513
5686
|
const validator = validators[i];
|
|
5514
5687
|
const validatorPublicShares = validator.public_shares;
|
|
@@ -5526,33 +5699,23 @@ var verifyDVV1X6 = (clusterLock) => __async(null, null, function* () {
|
|
|
5526
5699
|
for (const share of validatorPublicSharesBytes) {
|
|
5527
5700
|
pubShares.push(share);
|
|
5528
5701
|
}
|
|
5529
|
-
const
|
|
5702
|
+
const depositCheck = depositBlsCheck(
|
|
5530
5703
|
distributedPublicKey,
|
|
5531
5704
|
validator.deposit_data,
|
|
5532
5705
|
clusterLock.cluster_definition.validators[i].withdrawal_address,
|
|
5533
5706
|
clusterLock.cluster_definition.fork_version
|
|
5534
5707
|
);
|
|
5535
|
-
if (!
|
|
5536
|
-
|
|
5537
|
-
}
|
|
5538
|
-
pubKeys.push(fromHexString2(validator.distributed_public_key));
|
|
5539
|
-
builderRegistrationAndDepositDataMessages.push(depositDataMsg);
|
|
5540
|
-
blsSignatures.push(
|
|
5541
|
-
fromHexString2((_a6 = validator.deposit_data) == null ? void 0 : _a6.signature)
|
|
5542
|
-
);
|
|
5708
|
+
if (!depositCheck) return false;
|
|
5709
|
+
blsChecks.push(depositCheck);
|
|
5543
5710
|
}
|
|
5544
|
-
if (!(yield
|
|
5545
|
-
pubKeys,
|
|
5546
|
-
builderRegistrationAndDepositDataMessages,
|
|
5547
|
-
blsSignatures
|
|
5548
|
-
))) {
|
|
5711
|
+
if (!(yield verifyBlsChecksParallel(blsChecks))) {
|
|
5549
5712
|
return false;
|
|
5550
5713
|
}
|
|
5551
|
-
if (!
|
|
5714
|
+
if (!(yield verifyAggregateParallel(
|
|
5552
5715
|
pubShares,
|
|
5553
5716
|
fromHexString2(clusterLock.lock_hash),
|
|
5554
5717
|
fromHexString2(clusterLock.signature_aggregate)
|
|
5555
|
-
)) {
|
|
5718
|
+
))) {
|
|
5556
5719
|
return false;
|
|
5557
5720
|
}
|
|
5558
5721
|
return true;
|
|
@@ -5686,7 +5849,6 @@ var hashClusterLockV1X7 = (cluster) => {
|
|
|
5686
5849
|
return "0x" + Buffer.from(lockType.hashTreeRoot(val).buffer).toString("hex");
|
|
5687
5850
|
};
|
|
5688
5851
|
var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
|
|
5689
|
-
var _a6, _b2;
|
|
5690
5852
|
const validators = clusterLock.distributed_validators;
|
|
5691
5853
|
const operatorCount = clusterLock.cluster_definition.operators.length;
|
|
5692
5854
|
const threshold = clusterLock.cluster_definition.threshold;
|
|
@@ -5705,9 +5867,7 @@ var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
|
|
|
5705
5867
|
return false;
|
|
5706
5868
|
}
|
|
5707
5869
|
const pubShares = [];
|
|
5708
|
-
const
|
|
5709
|
-
const builderRegistrationAndDepositDataMessages = [];
|
|
5710
|
-
const blsSignatures = [];
|
|
5870
|
+
const blsChecks = [];
|
|
5711
5871
|
for (let i = 0; i < validators.length; i++) {
|
|
5712
5872
|
const validator = validators[i];
|
|
5713
5873
|
const validatorPublicShares = validator.public_shares;
|
|
@@ -5725,49 +5885,33 @@ var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
|
|
|
5725
5885
|
for (const share of validatorPublicSharesBytes) {
|
|
5726
5886
|
pubShares.push(share);
|
|
5727
5887
|
}
|
|
5728
|
-
const
|
|
5888
|
+
const depositCheck = depositBlsCheck(
|
|
5729
5889
|
distributedPublicKey,
|
|
5730
5890
|
validator.deposit_data,
|
|
5731
5891
|
clusterLock.cluster_definition.validators[i].withdrawal_address,
|
|
5732
5892
|
clusterLock.cluster_definition.fork_version
|
|
5733
5893
|
);
|
|
5734
|
-
if (!
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
pubKeys.push(fromHexString3(distributedPublicKey));
|
|
5738
|
-
builderRegistrationAndDepositDataMessages.push(depositDataMsg);
|
|
5739
|
-
blsSignatures.push(
|
|
5740
|
-
fromHexString3((_a6 = validator.deposit_data) == null ? void 0 : _a6.signature)
|
|
5741
|
-
);
|
|
5742
|
-
const { isValidBuilderRegistration, builderRegistrationMsg } = verifyBuilderRegistration(
|
|
5894
|
+
if (!depositCheck) return false;
|
|
5895
|
+
blsChecks.push(depositCheck);
|
|
5896
|
+
const builderCheck = builderBlsCheck(
|
|
5743
5897
|
validator,
|
|
5744
5898
|
clusterLock.cluster_definition.validators[i].fee_recipient_address,
|
|
5745
5899
|
clusterLock.cluster_definition.fork_version
|
|
5746
5900
|
);
|
|
5747
|
-
if (!
|
|
5748
|
-
|
|
5749
|
-
}
|
|
5750
|
-
pubKeys.push(fromHexString3(distributedPublicKey));
|
|
5751
|
-
builderRegistrationAndDepositDataMessages.push(builderRegistrationMsg);
|
|
5752
|
-
blsSignatures.push(
|
|
5753
|
-
fromHexString3((_b2 = validator.builder_registration) == null ? void 0 : _b2.signature)
|
|
5754
|
-
);
|
|
5901
|
+
if (!builderCheck) return false;
|
|
5902
|
+
blsChecks.push(builderCheck);
|
|
5755
5903
|
}
|
|
5756
|
-
if (!(yield
|
|
5757
|
-
pubKeys,
|
|
5758
|
-
builderRegistrationAndDepositDataMessages,
|
|
5759
|
-
blsSignatures
|
|
5760
|
-
))) {
|
|
5904
|
+
if (!(yield verifyBlsChecksParallel(blsChecks))) {
|
|
5761
5905
|
return false;
|
|
5762
5906
|
}
|
|
5763
5907
|
if (!verifyNodeSignatures(clusterLock)) {
|
|
5764
5908
|
return false;
|
|
5765
5909
|
}
|
|
5766
|
-
if (!
|
|
5910
|
+
if (!(yield verifyAggregateParallel(
|
|
5767
5911
|
pubShares,
|
|
5768
5912
|
fromHexString3(clusterLock.lock_hash),
|
|
5769
5913
|
fromHexString3(clusterLock.signature_aggregate)
|
|
5770
|
-
)) {
|
|
5914
|
+
))) {
|
|
5771
5915
|
return false;
|
|
5772
5916
|
}
|
|
5773
5917
|
return true;
|
|
@@ -15364,7 +15508,6 @@ var hashClusterLockV1X8 = (cluster) => {
|
|
|
15364
15508
|
return "0x" + Buffer.from(lockType.hashTreeRoot(val).buffer).toString("hex");
|
|
15365
15509
|
};
|
|
15366
15510
|
var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
|
|
15367
|
-
var _a6;
|
|
15368
15511
|
const validators = clusterLock.distributed_validators;
|
|
15369
15512
|
const operatorCount = clusterLock.cluster_definition.operators.length;
|
|
15370
15513
|
const threshold = clusterLock.cluster_definition.threshold;
|
|
@@ -15383,9 +15526,10 @@ var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
|
|
|
15383
15526
|
return false;
|
|
15384
15527
|
}
|
|
15385
15528
|
const pubShares = [];
|
|
15386
|
-
const
|
|
15387
|
-
const
|
|
15388
|
-
const
|
|
15529
|
+
const blsChecks = [];
|
|
15530
|
+
const forkVersion = clusterLock.cluster_definition.fork_version;
|
|
15531
|
+
const depositDomain = depositDomainForFork(forkVersion);
|
|
15532
|
+
const builderDomain = builderDomainForFork(forkVersion);
|
|
15389
15533
|
for (let i = 0; i < validators.length; i++) {
|
|
15390
15534
|
const validator = validators[i];
|
|
15391
15535
|
const validatorPublicShares = validator.public_shares;
|
|
@@ -15412,51 +15556,38 @@ var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
|
|
|
15412
15556
|
return false;
|
|
15413
15557
|
}
|
|
15414
15558
|
}
|
|
15415
|
-
for (const
|
|
15416
|
-
const
|
|
15417
|
-
const { isValidDepositData, depositDataMsg } = verifyDepositData(
|
|
15559
|
+
for (const depositData of validator.partial_deposit_data) {
|
|
15560
|
+
const check = depositBlsCheck(
|
|
15418
15561
|
distributedPublicKey,
|
|
15419
15562
|
depositData,
|
|
15420
15563
|
clusterLock.cluster_definition.validators[i].withdrawal_address,
|
|
15421
|
-
|
|
15422
|
-
clusterLock.cluster_definition.compounding
|
|
15564
|
+
forkVersion,
|
|
15565
|
+
clusterLock.cluster_definition.compounding,
|
|
15566
|
+
depositDomain
|
|
15423
15567
|
);
|
|
15424
|
-
if (!
|
|
15425
|
-
|
|
15426
|
-
}
|
|
15427
|
-
pubKeys.push(fromHexString4(distributedPublicKey));
|
|
15428
|
-
builderRegistrationAndDepositDataMessages.push(depositDataMsg);
|
|
15429
|
-
blsSignatures.push(fromHexString4(depositData == null ? void 0 : depositData.signature));
|
|
15568
|
+
if (!check) return false;
|
|
15569
|
+
blsChecks.push(check);
|
|
15430
15570
|
}
|
|
15431
|
-
const
|
|
15571
|
+
const builderCheck = builderBlsCheck(
|
|
15432
15572
|
validator,
|
|
15433
15573
|
clusterLock.cluster_definition.validators[i].fee_recipient_address,
|
|
15434
|
-
|
|
15435
|
-
|
|
15436
|
-
if (!isValidBuilderRegistration) {
|
|
15437
|
-
return false;
|
|
15438
|
-
}
|
|
15439
|
-
pubKeys.push(fromHexString4(distributedPublicKey));
|
|
15440
|
-
builderRegistrationAndDepositDataMessages.push(builderRegistrationMsg);
|
|
15441
|
-
blsSignatures.push(
|
|
15442
|
-
fromHexString4((_a6 = validator.builder_registration) == null ? void 0 : _a6.signature)
|
|
15574
|
+
forkVersion,
|
|
15575
|
+
builderDomain
|
|
15443
15576
|
);
|
|
15577
|
+
if (!builderCheck) return false;
|
|
15578
|
+
blsChecks.push(builderCheck);
|
|
15444
15579
|
}
|
|
15445
|
-
if (!(yield
|
|
15446
|
-
pubKeys,
|
|
15447
|
-
builderRegistrationAndDepositDataMessages,
|
|
15448
|
-
blsSignatures
|
|
15449
|
-
))) {
|
|
15580
|
+
if (!(yield verifyBlsChecksParallel(blsChecks))) {
|
|
15450
15581
|
return false;
|
|
15451
15582
|
}
|
|
15452
15583
|
if (!verifyNodeSignatures(clusterLock)) {
|
|
15453
15584
|
return false;
|
|
15454
15585
|
}
|
|
15455
|
-
if (!
|
|
15586
|
+
if (!(yield verifyAggregateParallel(
|
|
15456
15587
|
pubShares,
|
|
15457
15588
|
fromHexString4(clusterLock.lock_hash),
|
|
15458
15589
|
fromHexString4(clusterLock.signature_aggregate)
|
|
15459
|
-
)) {
|
|
15590
|
+
))) {
|
|
15460
15591
|
return false;
|
|
15461
15592
|
}
|
|
15462
15593
|
return true;
|
|
@@ -15871,37 +16002,62 @@ var computeDomain = (domainType, lockForkVersion, genesisValidatorsRoot = fromHe
|
|
|
15871
16002
|
domain.set(forkDataRoot.subarray(0, 28), 4);
|
|
15872
16003
|
return domain;
|
|
15873
16004
|
};
|
|
15874
|
-
var
|
|
15875
|
-
|
|
15876
|
-
|
|
15877
|
-
|
|
15878
|
-
);
|
|
16005
|
+
var depositDomainForFork = (forkVersion) => computeDomain(fromHexString6(DOMAIN_DEPOSIT), forkVersion);
|
|
16006
|
+
var builderDomainForFork = (forkVersion) => computeDomain(fromHexString6(DOMAIN_APPLICATION_BUILDER), forkVersion);
|
|
16007
|
+
var validateDepositDataStructure = (distributedPublicKey, depositData, withdrawalAddress, forkVersion, compounding, precomputedDepositDomain) => {
|
|
16008
|
+
const depositDomain = precomputedDepositDomain != null ? precomputedDepositDomain : computeDomain(fromHexString6(DOMAIN_DEPOSIT), forkVersion);
|
|
15879
16009
|
const withdrawalPrefix = compounding ? "0x02" : "0x01";
|
|
15880
16010
|
const expectedWithdrawalCredentials = withdrawalPrefix + "0".repeat(22) + withdrawalAddress.toLowerCase().slice(2);
|
|
15881
16011
|
if (expectedWithdrawalCredentials !== depositData.withdrawal_credentials) {
|
|
15882
|
-
return {
|
|
16012
|
+
return { valid: false, message: new Uint8Array(0) };
|
|
15883
16013
|
}
|
|
15884
16014
|
if (distributedPublicKey !== depositData.pubkey) {
|
|
15885
|
-
return {
|
|
16015
|
+
return { valid: false, message: new Uint8Array(0) };
|
|
15886
16016
|
}
|
|
15887
16017
|
const depositMessageBuffer = computeDepositMsgRoot(depositData);
|
|
15888
|
-
const
|
|
16018
|
+
const message2 = signingRoot(depositDomain, depositMessageBuffer);
|
|
15889
16019
|
if (!depositData.signature) {
|
|
15890
|
-
return {
|
|
16020
|
+
return { valid: false, message: message2 };
|
|
16021
|
+
}
|
|
16022
|
+
return { valid: true, message: message2 };
|
|
16023
|
+
};
|
|
16024
|
+
var depositBlsCheck = (distributedPublicKey, depositData, withdrawalAddress, forkVersion, compounding, precomputedDepositDomain) => {
|
|
16025
|
+
const { valid, message: message2 } = validateDepositDataStructure(
|
|
16026
|
+
distributedPublicKey,
|
|
16027
|
+
depositData,
|
|
16028
|
+
withdrawalAddress,
|
|
16029
|
+
forkVersion,
|
|
16030
|
+
compounding,
|
|
16031
|
+
precomputedDepositDomain
|
|
16032
|
+
);
|
|
16033
|
+
if (!valid || !depositData.signature || !depositData.pubkey) return null;
|
|
16034
|
+
return {
|
|
16035
|
+
pubkey: fromHexString6(depositData.pubkey),
|
|
16036
|
+
message: message2,
|
|
16037
|
+
signature: fromHexString6(depositData.signature)
|
|
16038
|
+
};
|
|
16039
|
+
};
|
|
16040
|
+
var verifyDepositData = (distributedPublicKey, depositData, withdrawalAddress, forkVersion, compounding) => {
|
|
16041
|
+
const { valid, message: message2 } = validateDepositDataStructure(
|
|
16042
|
+
distributedPublicKey,
|
|
16043
|
+
depositData,
|
|
16044
|
+
withdrawalAddress,
|
|
16045
|
+
forkVersion,
|
|
16046
|
+
compounding
|
|
16047
|
+
);
|
|
16048
|
+
if (!valid || !depositData.signature || !depositData.pubkey) {
|
|
16049
|
+
return { isValidDepositData: false, depositDataMsg: message2 };
|
|
15891
16050
|
}
|
|
15892
16051
|
const isValidDepositData = blsVerify(
|
|
15893
16052
|
fromHexString6(depositData.pubkey),
|
|
15894
|
-
|
|
16053
|
+
message2,
|
|
15895
16054
|
fromHexString6(depositData.signature)
|
|
15896
16055
|
);
|
|
15897
|
-
return { isValidDepositData, depositDataMsg:
|
|
16056
|
+
return { isValidDepositData, depositDataMsg: message2 };
|
|
15898
16057
|
};
|
|
15899
|
-
var verifyBuilderRegistration = (validator, feeRecipientAddress, forkVersion) => {
|
|
16058
|
+
var verifyBuilderRegistration = (validator, feeRecipientAddress, forkVersion, precomputedBuilderDomain) => {
|
|
15900
16059
|
var _a6;
|
|
15901
|
-
const builderDomain = computeDomain(
|
|
15902
|
-
fromHexString6(DOMAIN_APPLICATION_BUILDER),
|
|
15903
|
-
forkVersion
|
|
15904
|
-
);
|
|
16060
|
+
const builderDomain = precomputedBuilderDomain != null ? precomputedBuilderDomain : computeDomain(fromHexString6(DOMAIN_APPLICATION_BUILDER), forkVersion);
|
|
15905
16061
|
if (validator.distributed_public_key !== ((_a6 = validator.builder_registration) == null ? void 0 : _a6.message.pubkey)) {
|
|
15906
16062
|
return {
|
|
15907
16063
|
isValidBuilderRegistration: false,
|
|
@@ -15926,6 +16082,22 @@ var verifyBuilderRegistration = (validator, feeRecipientAddress, forkVersion) =>
|
|
|
15926
16082
|
builderRegistrationMsg: builderRegistrationMessage
|
|
15927
16083
|
};
|
|
15928
16084
|
};
|
|
16085
|
+
var builderBlsCheck = (validator, feeRecipientAddress, forkVersion, precomputedBuilderDomain) => {
|
|
16086
|
+
var _a6;
|
|
16087
|
+
const { isValidBuilderRegistration, builderRegistrationMsg } = verifyBuilderRegistration(
|
|
16088
|
+
validator,
|
|
16089
|
+
feeRecipientAddress,
|
|
16090
|
+
forkVersion,
|
|
16091
|
+
precomputedBuilderDomain
|
|
16092
|
+
);
|
|
16093
|
+
const sig = (_a6 = validator.builder_registration) == null ? void 0 : _a6.signature;
|
|
16094
|
+
if (!isValidBuilderRegistration || !sig) return null;
|
|
16095
|
+
return {
|
|
16096
|
+
pubkey: fromHexString6(validator.distributed_public_key),
|
|
16097
|
+
message: builderRegistrationMsg,
|
|
16098
|
+
signature: fromHexString6(sig)
|
|
16099
|
+
};
|
|
16100
|
+
};
|
|
15929
16101
|
var verifyNodeSignatures = (clusterLock) => {
|
|
15930
16102
|
const ec2 = new elliptic.ec("secp256k1");
|
|
15931
16103
|
const nodeSignatures = clusterLock.node_signatures;
|
|
@@ -20945,8 +21117,9 @@ var EOA = class {
|
|
|
20945
21117
|
// src/services.ts
|
|
20946
21118
|
var validateClusterLock = (lock, safeRpcUrl) => __async(null, null, function* () {
|
|
20947
21119
|
try {
|
|
20948
|
-
const
|
|
20949
|
-
return
|
|
21120
|
+
const inWorker = yield validateClusterLockInWorker(lock, safeRpcUrl);
|
|
21121
|
+
if (inWorker !== null) return inWorker;
|
|
21122
|
+
return yield isValidClusterLock(lock, safeRpcUrl);
|
|
20950
21123
|
} catch (err) {
|
|
20951
21124
|
throw err;
|
|
20952
21125
|
}
|
|
@@ -21545,6 +21718,7 @@ export {
|
|
|
21545
21718
|
CONFIG_VERSION,
|
|
21546
21719
|
CONFLICT_ERROR_MSG,
|
|
21547
21720
|
Client,
|
|
21721
|
+
ClusterLockValidationTimeoutError,
|
|
21548
21722
|
ConflictError,
|
|
21549
21723
|
CreatorConfigHashSigningTypes,
|
|
21550
21724
|
CreatorTypedMessage,
|
|
@@ -21585,8 +21759,12 @@ export {
|
|
|
21585
21759
|
TermsAndConditionsSigningTypes,
|
|
21586
21760
|
UnsupportedChainError,
|
|
21587
21761
|
blsVerify,
|
|
21762
|
+
builderBlsCheck,
|
|
21763
|
+
builderDomainForFork,
|
|
21588
21764
|
clusterConfigOrDefinitionHash,
|
|
21589
21765
|
clusterLockHash,
|
|
21766
|
+
depositBlsCheck,
|
|
21767
|
+
depositDomainForFork,
|
|
21590
21768
|
hasUniqueDistributedKeys,
|
|
21591
21769
|
isChainSupportedForSplitters,
|
|
21592
21770
|
isValidClusterLock,
|
|
@@ -21596,6 +21774,7 @@ export {
|
|
|
21596
21774
|
signingRoot,
|
|
21597
21775
|
validateAddressSignature,
|
|
21598
21776
|
validateClusterLock,
|
|
21777
|
+
validateDepositDataStructure,
|
|
21599
21778
|
validateEOASignature,
|
|
21600
21779
|
validateSmartContractSignature,
|
|
21601
21780
|
verifyBuilderRegistration,
|