@obolnetwork/obol-sdk 2.11.13 → 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 +702 -212
- package/dist/browser/src/index.js.map +1 -1
- package/dist/cjs/src/blsUtils.js +3843 -0
- package/dist/cjs/src/blsUtils.js.map +1 -0
- package/dist/cjs/src/index.js +790 -299
- 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 +3840 -0
- package/dist/cjs/src/verification/lockWorker.js.map +1 -0
- package/dist/cjs/src/verification/parallelPool.js +4185 -0
- package/dist/cjs/src/verification/parallelPool.js.map +1 -0
- package/dist/esm/src/blsUtils.js +21 -0
- package/dist/esm/src/blsUtils.js.map +1 -0
- package/dist/esm/src/chunk-5ASVONSJ.js +10242 -0
- package/dist/esm/src/chunk-5ASVONSJ.js.map +1 -0
- package/dist/esm/src/chunk-LOSYOJC3.js +4370 -0
- package/dist/esm/src/chunk-LOSYOJC3.js.map +1 -0
- 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 +215 -14508
- 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 +55 -0
- package/dist/esm/src/verification/lockWorker.js.map +1 -0
- package/dist/esm/src/verification/parallelPool.js +16 -0
- package/dist/esm/src/verification/parallelPool.js.map +1 -0
- package/dist/types/src/blsUtils.d.ts +5 -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 +26 -7
- package/dist/types/src/verification/lockWorker.d.ts +18 -0
- package/dist/types/src/verification/parallelPool.d.ts +11 -0
- package/dist/types/test/verification/parallelPool.spec.d.ts +1 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -21,6 +21,12 @@ var __spreadValues = (a, b) => {
|
|
|
21
21
|
return a;
|
|
22
22
|
};
|
|
23
23
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
25
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
26
|
+
}) : x)(function(x) {
|
|
27
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
28
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
29
|
+
});
|
|
24
30
|
var __export = (target, all) => {
|
|
25
31
|
for (var name2 in all)
|
|
26
32
|
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
@@ -92,7 +98,7 @@ import { v4 as uuidv4 } from "uuid";
|
|
|
92
98
|
// package.json
|
|
93
99
|
var package_default = {
|
|
94
100
|
name: "@obolnetwork/obol-sdk",
|
|
95
|
-
version: "2.
|
|
101
|
+
version: "2.12.1",
|
|
96
102
|
description: "A package for creating Distributed Validators using the Obol API.",
|
|
97
103
|
bugs: {
|
|
98
104
|
url: "https://github.com/obolnetwork/obol-sdk/issues"
|
|
@@ -576,9 +582,22 @@ var UnsupportedChainError = class _UnsupportedChainError extends Error {
|
|
|
576
582
|
Object.setPrototypeOf(this, _UnsupportedChainError.prototype);
|
|
577
583
|
}
|
|
578
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
|
+
};
|
|
579
598
|
|
|
580
599
|
// src/verification/common.ts
|
|
581
|
-
import { fromHexString as
|
|
600
|
+
import { fromHexString as fromHexString6 } from "@chainsafe/ssz";
|
|
582
601
|
import elliptic from "elliptic";
|
|
583
602
|
import * as semver from "semver";
|
|
584
603
|
|
|
@@ -705,9 +724,12 @@ import {
|
|
|
705
724
|
ByteVectorType as ByteVectorType2,
|
|
706
725
|
ContainerType as ContainerType2,
|
|
707
726
|
ListCompositeType,
|
|
708
|
-
fromHexString
|
|
727
|
+
fromHexString as fromHexString2
|
|
709
728
|
} from "@chainsafe/ssz";
|
|
710
729
|
|
|
730
|
+
// src/verification/parallelPool.ts
|
|
731
|
+
import { fromHexString } from "@chainsafe/ssz";
|
|
732
|
+
|
|
711
733
|
// node_modules/@noble/curves/node_modules/@noble/hashes/utils.js
|
|
712
734
|
function isBytes(a) {
|
|
713
735
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
@@ -5133,6 +5155,12 @@ function blsVerify(pubkey, message2, signature) {
|
|
|
5133
5155
|
return false;
|
|
5134
5156
|
}
|
|
5135
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
|
+
}
|
|
5136
5164
|
function blsVerifyAggregate(pubkeys, message2, signature) {
|
|
5137
5165
|
try {
|
|
5138
5166
|
return ls.verify(
|
|
@@ -5144,6 +5172,13 @@ function blsVerifyAggregate(pubkeys, message2, signature) {
|
|
|
5144
5172
|
return false;
|
|
5145
5173
|
}
|
|
5146
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
|
+
}
|
|
5147
5182
|
function blsVerifyMultiple(pubkeys, messages, signature) {
|
|
5148
5183
|
try {
|
|
5149
5184
|
if (pubkeys.length !== messages.length) return false;
|
|
@@ -5159,6 +5194,373 @@ function blsVerifyMultiple(pubkeys, messages, signature) {
|
|
|
5159
5194
|
function blsAggregateSignatures(signatures) {
|
|
5160
5195
|
return ls.Signature.toBytes(ls.aggregateSignatures(signatures));
|
|
5161
5196
|
}
|
|
5197
|
+
function lagrangeCoeffAtZero(shareIndex, indices) {
|
|
5198
|
+
const { Fr } = bls12_381.fields;
|
|
5199
|
+
let num = BigInt(1);
|
|
5200
|
+
let den = BigInt(1);
|
|
5201
|
+
for (const j of indices) {
|
|
5202
|
+
if (j === shareIndex) continue;
|
|
5203
|
+
num = Fr.mul(num, Fr.neg(j));
|
|
5204
|
+
den = Fr.mul(den, Fr.sub(shareIndex, j));
|
|
5205
|
+
}
|
|
5206
|
+
return Fr.mul(num, Fr.inv(den));
|
|
5207
|
+
}
|
|
5208
|
+
function blsRecoverWithIndices(shares, indices) {
|
|
5209
|
+
try {
|
|
5210
|
+
let recovered = bls12_381.G1.Point.ZERO;
|
|
5211
|
+
for (let i = 0; i < shares.length; i++) {
|
|
5212
|
+
const point = bls12_381.G1.Point.fromBytes(shares[i]);
|
|
5213
|
+
const coeff = lagrangeCoeffAtZero(indices[i], indices);
|
|
5214
|
+
recovered = recovered.add(point.multiply(coeff));
|
|
5215
|
+
}
|
|
5216
|
+
return recovered.toBytes();
|
|
5217
|
+
} catch (e) {
|
|
5218
|
+
return null;
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5221
|
+
function blsRecoverDistributedPubkeyFromShares(pubshares, threshold) {
|
|
5222
|
+
if (threshold <= 0 || pubshares.length < threshold) return null;
|
|
5223
|
+
const selected = pubshares.slice(0, threshold);
|
|
5224
|
+
const indices = selected.map((_, i) => BigInt(i + 1));
|
|
5225
|
+
return blsRecoverWithIndices(selected, indices);
|
|
5226
|
+
}
|
|
5227
|
+
function blsVerifyExtraShares(pubshares, threshold, distributedPubkey) {
|
|
5228
|
+
if (threshold <= 0 || pubshares.length < threshold) return false;
|
|
5229
|
+
try {
|
|
5230
|
+
const baseShares = pubshares.slice(0, threshold - 1);
|
|
5231
|
+
const baseIndices = baseShares.map((_, i) => BigInt(i + 1));
|
|
5232
|
+
for (let i = threshold; i < pubshares.length; i++) {
|
|
5233
|
+
const shares = [...baseShares, pubshares[i]];
|
|
5234
|
+
const indices = [...baseIndices, BigInt(i + 1)];
|
|
5235
|
+
const recovered = blsRecoverWithIndices(shares, indices);
|
|
5236
|
+
if (!recovered || recovered.length !== distributedPubkey.length || !recovered.every((b, j) => b === distributedPubkey[j])) {
|
|
5237
|
+
return false;
|
|
5238
|
+
}
|
|
5239
|
+
}
|
|
5240
|
+
return true;
|
|
5241
|
+
} catch (e) {
|
|
5242
|
+
return false;
|
|
5243
|
+
}
|
|
5244
|
+
}
|
|
5245
|
+
|
|
5246
|
+
// src/verification/parallelPool.ts
|
|
5247
|
+
var MIN_PARALLEL_VALIDATORS = 50;
|
|
5248
|
+
var MIN_PARALLEL_BATCH_PAIRS = 100;
|
|
5249
|
+
var MAX_WORKERS = 8;
|
|
5250
|
+
var MIN_VALIDATORS_PER_WORKER = 25;
|
|
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;
|
|
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
|
+
}
|
|
5261
|
+
var workerThreadsCache;
|
|
5262
|
+
var osCache;
|
|
5263
|
+
var workerPathByFile = /* @__PURE__ */ new Map();
|
|
5264
|
+
function loadWorkerThreads() {
|
|
5265
|
+
if (workerThreadsCache !== void 0) return workerThreadsCache;
|
|
5266
|
+
try {
|
|
5267
|
+
workerThreadsCache = __require("worker_threads");
|
|
5268
|
+
} catch (e) {
|
|
5269
|
+
workerThreadsCache = null;
|
|
5270
|
+
}
|
|
5271
|
+
return workerThreadsCache;
|
|
5272
|
+
}
|
|
5273
|
+
function loadOs() {
|
|
5274
|
+
if (osCache !== void 0) return osCache;
|
|
5275
|
+
try {
|
|
5276
|
+
osCache = __require("os");
|
|
5277
|
+
} catch (e) {
|
|
5278
|
+
osCache = null;
|
|
5279
|
+
}
|
|
5280
|
+
return osCache;
|
|
5281
|
+
}
|
|
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
|
+
}
|
|
5289
|
+
const path = __require("path");
|
|
5290
|
+
const fs = __require("fs");
|
|
5291
|
+
const candidates = [
|
|
5292
|
+
path.join(__dirname, filename),
|
|
5293
|
+
path.join(__dirname, "verification", filename)
|
|
5294
|
+
];
|
|
5295
|
+
try {
|
|
5296
|
+
for (const candidate of candidates) {
|
|
5297
|
+
if (fs.existsSync(candidate)) {
|
|
5298
|
+
workerPathByFile.set(filename, candidate);
|
|
5299
|
+
return candidate;
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
} catch (e) {
|
|
5303
|
+
}
|
|
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
|
+
});
|
|
5323
|
+
}
|
|
5324
|
+
function chunkArrays(arr, n) {
|
|
5325
|
+
const size = Math.ceil(arr.length / n);
|
|
5326
|
+
const out = [];
|
|
5327
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
5328
|
+
out.push(arr.slice(i, i + size));
|
|
5329
|
+
}
|
|
5330
|
+
return out;
|
|
5331
|
+
}
|
|
5332
|
+
function verifySharesSync(shares, distributedKeys, threshold) {
|
|
5333
|
+
for (let i = 0; i < shares.length; i++) {
|
|
5334
|
+
const sharesBytes = shares[i].map((s) => fromHexString(s));
|
|
5335
|
+
const dkBytes = fromHexString(distributedKeys[i]);
|
|
5336
|
+
const recovered = blsRecoverDistributedPubkeyFromShares(
|
|
5337
|
+
sharesBytes,
|
|
5338
|
+
threshold
|
|
5339
|
+
);
|
|
5340
|
+
if (!recovered) return false;
|
|
5341
|
+
if (recovered.length !== dkBytes.length) return false;
|
|
5342
|
+
for (let j = 0; j < recovered.length; j++) {
|
|
5343
|
+
if (recovered[j] !== dkBytes[j]) return false;
|
|
5344
|
+
}
|
|
5345
|
+
if (!blsVerifyExtraShares(sharesBytes, threshold, dkBytes)) {
|
|
5346
|
+
return false;
|
|
5347
|
+
}
|
|
5348
|
+
}
|
|
5349
|
+
return true;
|
|
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
|
+
}
|
|
5378
|
+
function runWorker(wt, workerFile, data) {
|
|
5379
|
+
return __async(this, null, function* () {
|
|
5380
|
+
return yield new Promise((resolve) => {
|
|
5381
|
+
let settled = false;
|
|
5382
|
+
const worker = new wt.Worker(workerFile, { workerData: data });
|
|
5383
|
+
const finish = (result) => {
|
|
5384
|
+
if (settled) return;
|
|
5385
|
+
settled = true;
|
|
5386
|
+
clearTimeout(timer);
|
|
5387
|
+
worker.terminate();
|
|
5388
|
+
resolve(result);
|
|
5389
|
+
};
|
|
5390
|
+
const timer = setTimeout(() => {
|
|
5391
|
+
finish(false);
|
|
5392
|
+
}, WORKER_TIMEOUT_MS);
|
|
5393
|
+
worker.once("message", (msg) => {
|
|
5394
|
+
finish(msg === true);
|
|
5395
|
+
});
|
|
5396
|
+
worker.once("error", () => {
|
|
5397
|
+
finish(false);
|
|
5398
|
+
});
|
|
5399
|
+
worker.once("exit", (code2) => {
|
|
5400
|
+
if (code2 !== 0) finish(false);
|
|
5401
|
+
});
|
|
5402
|
+
});
|
|
5403
|
+
});
|
|
5404
|
+
}
|
|
5405
|
+
function poolSize(itemCount, minPerWorker) {
|
|
5406
|
+
const wt = loadWorkerThreads();
|
|
5407
|
+
const os = loadOs();
|
|
5408
|
+
const workerFile = getWorkerPath("lockWorker.js");
|
|
5409
|
+
const numCpus = os ? Math.max(1, os.cpus().length) : 1;
|
|
5410
|
+
const numWorkers = Math.min(
|
|
5411
|
+
MAX_WORKERS,
|
|
5412
|
+
Math.max(1, Math.floor(itemCount / minPerWorker)),
|
|
5413
|
+
numCpus
|
|
5414
|
+
);
|
|
5415
|
+
return { numWorkers, wt, workerFile };
|
|
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
|
+
}
|
|
5429
|
+
function verifySharesBinding(shares, distributedKeys, threshold) {
|
|
5430
|
+
return __async(this, null, function* () {
|
|
5431
|
+
if (shares.length !== distributedKeys.length) return false;
|
|
5432
|
+
if (shares.length === 0) return true;
|
|
5433
|
+
const { numWorkers, wt, workerFile } = poolSize(
|
|
5434
|
+
shares.length,
|
|
5435
|
+
MIN_VALIDATORS_PER_WORKER
|
|
5436
|
+
);
|
|
5437
|
+
if (wt === null || workerFile === null || shares.length < MIN_PARALLEL_VALIDATORS || numWorkers < 2) {
|
|
5438
|
+
return verifySharesSync(shares, distributedKeys, threshold);
|
|
5439
|
+
}
|
|
5440
|
+
const shareChunks = chunkArrays(shares, numWorkers);
|
|
5441
|
+
const keyChunks = chunkArrays(distributedKeys, numWorkers);
|
|
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)
|
|
5461
|
+
);
|
|
5462
|
+
});
|
|
5463
|
+
}
|
|
5464
|
+
function verifyBatchParallel(pubkeys, messages, signatures) {
|
|
5465
|
+
return __async(this, null, function* () {
|
|
5466
|
+
if (pubkeys.length !== messages.length || pubkeys.length !== signatures.length) {
|
|
5467
|
+
return false;
|
|
5468
|
+
}
|
|
5469
|
+
if (pubkeys.length === 0) return true;
|
|
5470
|
+
const { numWorkers, wt, workerFile } = poolSize(
|
|
5471
|
+
pubkeys.length,
|
|
5472
|
+
MIN_PAIRS_PER_WORKER
|
|
5473
|
+
);
|
|
5474
|
+
if (wt === null || workerFile === null || pubkeys.length < MIN_PARALLEL_BATCH_PAIRS || numWorkers < 2) {
|
|
5475
|
+
return blsVerifyMultiple(
|
|
5476
|
+
pubkeys,
|
|
5477
|
+
messages,
|
|
5478
|
+
blsAggregateSignatures(signatures)
|
|
5479
|
+
);
|
|
5480
|
+
}
|
|
5481
|
+
const pkChunks = chunkArrays(pubkeys, numWorkers);
|
|
5482
|
+
const msgChunks = chunkArrays(messages, numWorkers);
|
|
5483
|
+
const sigChunks = chunkArrays(signatures, numWorkers);
|
|
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
|
+
}))
|
|
5493
|
+
);
|
|
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
|
+
});
|
|
5562
|
+
});
|
|
5563
|
+
}
|
|
5162
5564
|
|
|
5163
5565
|
// src/verification/v1.6.0.ts
|
|
5164
5566
|
var clusterDefinitionContainerTypeV1X6 = (configOnly) => {
|
|
@@ -5192,29 +5594,29 @@ var hashClusterDefinitionV1X6 = (cluster, configOnly) => {
|
|
|
5192
5594
|
val.num_validators = cluster.num_validators;
|
|
5193
5595
|
val.threshold = cluster.threshold;
|
|
5194
5596
|
val.dkg_algorithm = strToUint8Array(cluster.dkg_algorithm);
|
|
5195
|
-
val.fork_version =
|
|
5597
|
+
val.fork_version = fromHexString2(cluster.fork_version);
|
|
5196
5598
|
val.operators = cluster.operators.map((operator) => {
|
|
5197
|
-
return configOnly ? { address:
|
|
5198
|
-
address:
|
|
5599
|
+
return configOnly ? { address: fromHexString2(operator.address) } : {
|
|
5600
|
+
address: fromHexString2(operator.address),
|
|
5199
5601
|
enr: strToUint8Array(operator.enr),
|
|
5200
|
-
config_signature:
|
|
5201
|
-
enr_signature:
|
|
5602
|
+
config_signature: fromHexString2(operator.config_signature),
|
|
5603
|
+
enr_signature: fromHexString2(operator.enr_signature)
|
|
5202
5604
|
};
|
|
5203
5605
|
});
|
|
5204
|
-
val.creator = configOnly ? { address:
|
|
5205
|
-
address:
|
|
5206
|
-
config_signature:
|
|
5606
|
+
val.creator = configOnly ? { address: fromHexString2(cluster.creator.address) } : {
|
|
5607
|
+
address: fromHexString2(cluster.creator.address),
|
|
5608
|
+
config_signature: fromHexString2(
|
|
5207
5609
|
cluster.creator.config_signature
|
|
5208
5610
|
)
|
|
5209
5611
|
};
|
|
5210
5612
|
val.validators = cluster.validators.map((validator) => {
|
|
5211
5613
|
return {
|
|
5212
|
-
fee_recipient_address:
|
|
5213
|
-
withdrawal_address:
|
|
5614
|
+
fee_recipient_address: fromHexString2(validator.fee_recipient_address),
|
|
5615
|
+
withdrawal_address: fromHexString2(validator.withdrawal_address)
|
|
5214
5616
|
};
|
|
5215
5617
|
});
|
|
5216
5618
|
if (!configOnly) {
|
|
5217
|
-
val.config_hash =
|
|
5619
|
+
val.config_hash = fromHexString2(cluster.config_hash);
|
|
5218
5620
|
}
|
|
5219
5621
|
return val;
|
|
5220
5622
|
};
|
|
@@ -5243,65 +5645,77 @@ var hashClusterLockV1X6 = (cluster) => {
|
|
|
5243
5645
|
(dValidator) => {
|
|
5244
5646
|
var _a6, _b2, _c, _d;
|
|
5245
5647
|
return {
|
|
5246
|
-
distributed_public_key:
|
|
5648
|
+
distributed_public_key: fromHexString2(
|
|
5247
5649
|
dValidator.distributed_public_key
|
|
5248
5650
|
),
|
|
5249
5651
|
public_shares: dValidator.public_shares.map(
|
|
5250
|
-
(publicShare) =>
|
|
5652
|
+
(publicShare) => fromHexString2(publicShare)
|
|
5251
5653
|
),
|
|
5252
|
-
pubkey:
|
|
5253
|
-
withdrawal_credentials:
|
|
5654
|
+
pubkey: fromHexString2((_a6 = dValidator.deposit_data) == null ? void 0 : _a6.pubkey),
|
|
5655
|
+
withdrawal_credentials: fromHexString2(
|
|
5254
5656
|
(_b2 = dValidator.deposit_data) == null ? void 0 : _b2.withdrawal_credentials
|
|
5255
5657
|
),
|
|
5256
5658
|
amount: parseInt((_c = dValidator.deposit_data) == null ? void 0 : _c.amount),
|
|
5257
|
-
signature:
|
|
5659
|
+
signature: fromHexString2((_d = dValidator.deposit_data) == null ? void 0 : _d.signature)
|
|
5258
5660
|
};
|
|
5259
5661
|
}
|
|
5260
5662
|
);
|
|
5261
5663
|
return "0x" + Buffer.from(lockType.hashTreeRoot(val).buffer).toString("hex");
|
|
5262
5664
|
};
|
|
5263
5665
|
var verifyDVV1X6 = (clusterLock) => __async(null, null, function* () {
|
|
5264
|
-
var _a6;
|
|
5265
5666
|
const validators = clusterLock.distributed_validators;
|
|
5667
|
+
const operatorCount = clusterLock.cluster_definition.operators.length;
|
|
5668
|
+
const threshold = clusterLock.cluster_definition.threshold;
|
|
5669
|
+
for (const validator of validators) {
|
|
5670
|
+
if (validator.public_shares.length !== operatorCount) {
|
|
5671
|
+
return false;
|
|
5672
|
+
}
|
|
5673
|
+
const uniqueShareCount = new Set(validator.public_shares).size;
|
|
5674
|
+
if (uniqueShareCount !== validator.public_shares.length) {
|
|
5675
|
+
return false;
|
|
5676
|
+
}
|
|
5677
|
+
}
|
|
5678
|
+
const allShares = validators.map((v) => v.public_shares);
|
|
5679
|
+
const allDKs = validators.map((v) => v.distributed_public_key);
|
|
5680
|
+
if (!(yield verifySharesBinding(allShares, allDKs, threshold))) {
|
|
5681
|
+
return false;
|
|
5682
|
+
}
|
|
5266
5683
|
const pubShares = [];
|
|
5267
|
-
const
|
|
5268
|
-
const builderRegistrationAndDepositDataMessages = [];
|
|
5269
|
-
const blsSignatures = [];
|
|
5684
|
+
const blsChecks = [];
|
|
5270
5685
|
for (let i = 0; i < validators.length; i++) {
|
|
5271
5686
|
const validator = validators[i];
|
|
5272
5687
|
const validatorPublicShares = validator.public_shares;
|
|
5273
5688
|
const distributedPublicKey = validator.distributed_public_key;
|
|
5274
|
-
|
|
5275
|
-
|
|
5689
|
+
if (validatorPublicShares.length !== operatorCount) {
|
|
5690
|
+
return false;
|
|
5276
5691
|
}
|
|
5277
|
-
const
|
|
5692
|
+
const normalizedShares = validatorPublicShares.map((s) => s.toLowerCase());
|
|
5693
|
+
if (new Set(normalizedShares).size !== normalizedShares.length) {
|
|
5694
|
+
return false;
|
|
5695
|
+
}
|
|
5696
|
+
const validatorPublicSharesBytes = validatorPublicShares.map(
|
|
5697
|
+
(share) => fromHexString2(share)
|
|
5698
|
+
);
|
|
5699
|
+
for (const share of validatorPublicSharesBytes) {
|
|
5700
|
+
pubShares.push(share);
|
|
5701
|
+
}
|
|
5702
|
+
const depositCheck = depositBlsCheck(
|
|
5278
5703
|
distributedPublicKey,
|
|
5279
5704
|
validator.deposit_data,
|
|
5280
5705
|
clusterLock.cluster_definition.validators[i].withdrawal_address,
|
|
5281
5706
|
clusterLock.cluster_definition.fork_version
|
|
5282
5707
|
);
|
|
5283
|
-
if (!
|
|
5284
|
-
|
|
5285
|
-
}
|
|
5286
|
-
pubKeys.push(fromHexString(validator.distributed_public_key));
|
|
5287
|
-
builderRegistrationAndDepositDataMessages.push(depositDataMsg);
|
|
5288
|
-
blsSignatures.push(
|
|
5289
|
-
fromHexString((_a6 = validator.deposit_data) == null ? void 0 : _a6.signature)
|
|
5290
|
-
);
|
|
5708
|
+
if (!depositCheck) return false;
|
|
5709
|
+
blsChecks.push(depositCheck);
|
|
5291
5710
|
}
|
|
5292
|
-
|
|
5293
|
-
if (!blsVerifyMultiple(
|
|
5294
|
-
pubKeys,
|
|
5295
|
-
builderRegistrationAndDepositDataMessages,
|
|
5296
|
-
aggregateBLSSignature
|
|
5297
|
-
)) {
|
|
5711
|
+
if (!(yield verifyBlsChecksParallel(blsChecks))) {
|
|
5298
5712
|
return false;
|
|
5299
5713
|
}
|
|
5300
|
-
if (!
|
|
5714
|
+
if (!(yield verifyAggregateParallel(
|
|
5301
5715
|
pubShares,
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
)) {
|
|
5716
|
+
fromHexString2(clusterLock.lock_hash),
|
|
5717
|
+
fromHexString2(clusterLock.signature_aggregate)
|
|
5718
|
+
))) {
|
|
5305
5719
|
return false;
|
|
5306
5720
|
}
|
|
5307
5721
|
return true;
|
|
@@ -5316,7 +5730,7 @@ import {
|
|
|
5316
5730
|
ByteVectorType as ByteVectorType3,
|
|
5317
5731
|
ContainerType as ContainerType3,
|
|
5318
5732
|
ListCompositeType as ListCompositeType2,
|
|
5319
|
-
fromHexString as
|
|
5733
|
+
fromHexString as fromHexString3
|
|
5320
5734
|
} from "@chainsafe/ssz";
|
|
5321
5735
|
var clusterDefinitionContainerTypeV1X7 = (configOnly) => {
|
|
5322
5736
|
let returnedContainerType = {
|
|
@@ -5349,29 +5763,29 @@ var hashClusterDefinitionV1X7 = (cluster, configOnly) => {
|
|
|
5349
5763
|
val.num_validators = cluster.num_validators;
|
|
5350
5764
|
val.threshold = cluster.threshold;
|
|
5351
5765
|
val.dkg_algorithm = strToUint8Array(cluster.dkg_algorithm);
|
|
5352
|
-
val.fork_version =
|
|
5766
|
+
val.fork_version = fromHexString3(cluster.fork_version);
|
|
5353
5767
|
val.operators = cluster.operators.map((operator) => {
|
|
5354
|
-
return configOnly ? { address:
|
|
5355
|
-
address:
|
|
5768
|
+
return configOnly ? { address: fromHexString3(operator.address) } : {
|
|
5769
|
+
address: fromHexString3(operator.address),
|
|
5356
5770
|
enr: strToUint8Array(operator.enr),
|
|
5357
|
-
config_signature:
|
|
5358
|
-
enr_signature:
|
|
5771
|
+
config_signature: fromHexString3(operator.config_signature),
|
|
5772
|
+
enr_signature: fromHexString3(operator.enr_signature)
|
|
5359
5773
|
};
|
|
5360
5774
|
});
|
|
5361
|
-
val.creator = configOnly ? { address:
|
|
5362
|
-
address:
|
|
5363
|
-
config_signature:
|
|
5775
|
+
val.creator = configOnly ? { address: fromHexString3(cluster.creator.address) } : {
|
|
5776
|
+
address: fromHexString3(cluster.creator.address),
|
|
5777
|
+
config_signature: fromHexString3(
|
|
5364
5778
|
cluster.creator.config_signature
|
|
5365
5779
|
)
|
|
5366
5780
|
};
|
|
5367
5781
|
val.validators = cluster.validators.map((validator) => {
|
|
5368
5782
|
return {
|
|
5369
|
-
fee_recipient_address:
|
|
5370
|
-
withdrawal_address:
|
|
5783
|
+
fee_recipient_address: fromHexString3(validator.fee_recipient_address),
|
|
5784
|
+
withdrawal_address: fromHexString3(validator.withdrawal_address)
|
|
5371
5785
|
};
|
|
5372
5786
|
});
|
|
5373
5787
|
if (!configOnly) {
|
|
5374
|
-
val.config_hash =
|
|
5788
|
+
val.config_hash = fromHexString3(cluster.config_hash);
|
|
5375
5789
|
}
|
|
5376
5790
|
return val;
|
|
5377
5791
|
};
|
|
@@ -5398,34 +5812,34 @@ var hashClusterLockV1X7 = (cluster) => {
|
|
|
5398
5812
|
(dValidator) => {
|
|
5399
5813
|
var _a6, _b2, _c, _d, _e, _f, _g, _h, _i;
|
|
5400
5814
|
return {
|
|
5401
|
-
distributed_public_key:
|
|
5815
|
+
distributed_public_key: fromHexString3(
|
|
5402
5816
|
dValidator.distributed_public_key
|
|
5403
5817
|
),
|
|
5404
5818
|
public_shares: dValidator.public_shares.map(
|
|
5405
|
-
(publicShare) =>
|
|
5819
|
+
(publicShare) => fromHexString3(publicShare)
|
|
5406
5820
|
),
|
|
5407
5821
|
deposit_data: {
|
|
5408
|
-
pubkey:
|
|
5409
|
-
withdrawal_credentials:
|
|
5822
|
+
pubkey: fromHexString3((_a6 = dValidator.deposit_data) == null ? void 0 : _a6.pubkey),
|
|
5823
|
+
withdrawal_credentials: fromHexString3(
|
|
5410
5824
|
(_b2 = dValidator.deposit_data) == null ? void 0 : _b2.withdrawal_credentials
|
|
5411
5825
|
),
|
|
5412
5826
|
amount: parseInt((_c = dValidator.deposit_data) == null ? void 0 : _c.amount),
|
|
5413
|
-
signature:
|
|
5827
|
+
signature: fromHexString3(
|
|
5414
5828
|
(_d = dValidator.deposit_data) == null ? void 0 : _d.signature
|
|
5415
5829
|
)
|
|
5416
5830
|
},
|
|
5417
5831
|
builder_registration: {
|
|
5418
5832
|
message: {
|
|
5419
|
-
fee_recipient:
|
|
5833
|
+
fee_recipient: fromHexString3(
|
|
5420
5834
|
(_e = dValidator.builder_registration) == null ? void 0 : _e.message.fee_recipient
|
|
5421
5835
|
),
|
|
5422
5836
|
gas_limit: (_f = dValidator.builder_registration) == null ? void 0 : _f.message.gas_limit,
|
|
5423
5837
|
timestamp: (_g = dValidator.builder_registration) == null ? void 0 : _g.message.timestamp,
|
|
5424
|
-
pubkey:
|
|
5838
|
+
pubkey: fromHexString3(
|
|
5425
5839
|
(_h = dValidator.builder_registration) == null ? void 0 : _h.message.pubkey
|
|
5426
5840
|
)
|
|
5427
5841
|
},
|
|
5428
|
-
signature:
|
|
5842
|
+
signature: fromHexString3(
|
|
5429
5843
|
(_i = dValidator.builder_registration) == null ? void 0 : _i.signature
|
|
5430
5844
|
)
|
|
5431
5845
|
}
|
|
@@ -5435,63 +5849,69 @@ var hashClusterLockV1X7 = (cluster) => {
|
|
|
5435
5849
|
return "0x" + Buffer.from(lockType.hashTreeRoot(val).buffer).toString("hex");
|
|
5436
5850
|
};
|
|
5437
5851
|
var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
|
|
5438
|
-
var _a6, _b2;
|
|
5439
5852
|
const validators = clusterLock.distributed_validators;
|
|
5853
|
+
const operatorCount = clusterLock.cluster_definition.operators.length;
|
|
5854
|
+
const threshold = clusterLock.cluster_definition.threshold;
|
|
5855
|
+
for (const validator of validators) {
|
|
5856
|
+
if (validator.public_shares.length !== operatorCount) {
|
|
5857
|
+
return false;
|
|
5858
|
+
}
|
|
5859
|
+
const uniqueShareCount = new Set(validator.public_shares).size;
|
|
5860
|
+
if (uniqueShareCount !== validator.public_shares.length) {
|
|
5861
|
+
return false;
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
const allShares = validators.map((v) => v.public_shares);
|
|
5865
|
+
const allDKs = validators.map((v) => v.distributed_public_key);
|
|
5866
|
+
if (!(yield verifySharesBinding(allShares, allDKs, threshold))) {
|
|
5867
|
+
return false;
|
|
5868
|
+
}
|
|
5440
5869
|
const pubShares = [];
|
|
5441
|
-
const
|
|
5442
|
-
const builderRegistrationAndDepositDataMessages = [];
|
|
5443
|
-
const blsSignatures = [];
|
|
5870
|
+
const blsChecks = [];
|
|
5444
5871
|
for (let i = 0; i < validators.length; i++) {
|
|
5445
5872
|
const validator = validators[i];
|
|
5446
5873
|
const validatorPublicShares = validator.public_shares;
|
|
5447
5874
|
const distributedPublicKey = validator.distributed_public_key;
|
|
5448
|
-
|
|
5449
|
-
|
|
5875
|
+
if (validatorPublicShares.length !== operatorCount) {
|
|
5876
|
+
return false;
|
|
5877
|
+
}
|
|
5878
|
+
const normalizedShares = validatorPublicShares.map((s) => s.toLowerCase());
|
|
5879
|
+
if (new Set(normalizedShares).size !== normalizedShares.length) {
|
|
5880
|
+
return false;
|
|
5881
|
+
}
|
|
5882
|
+
const validatorPublicSharesBytes = validatorPublicShares.map(
|
|
5883
|
+
(share) => fromHexString3(share)
|
|
5884
|
+
);
|
|
5885
|
+
for (const share of validatorPublicSharesBytes) {
|
|
5886
|
+
pubShares.push(share);
|
|
5450
5887
|
}
|
|
5451
|
-
const
|
|
5888
|
+
const depositCheck = depositBlsCheck(
|
|
5452
5889
|
distributedPublicKey,
|
|
5453
5890
|
validator.deposit_data,
|
|
5454
5891
|
clusterLock.cluster_definition.validators[i].withdrawal_address,
|
|
5455
5892
|
clusterLock.cluster_definition.fork_version
|
|
5456
5893
|
);
|
|
5457
|
-
if (!
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
pubKeys.push(fromHexString2(distributedPublicKey));
|
|
5461
|
-
builderRegistrationAndDepositDataMessages.push(depositDataMsg);
|
|
5462
|
-
blsSignatures.push(
|
|
5463
|
-
fromHexString2((_a6 = validator.deposit_data) == null ? void 0 : _a6.signature)
|
|
5464
|
-
);
|
|
5465
|
-
const { isValidBuilderRegistration, builderRegistrationMsg } = verifyBuilderRegistration(
|
|
5894
|
+
if (!depositCheck) return false;
|
|
5895
|
+
blsChecks.push(depositCheck);
|
|
5896
|
+
const builderCheck = builderBlsCheck(
|
|
5466
5897
|
validator,
|
|
5467
5898
|
clusterLock.cluster_definition.validators[i].fee_recipient_address,
|
|
5468
5899
|
clusterLock.cluster_definition.fork_version
|
|
5469
5900
|
);
|
|
5470
|
-
if (!
|
|
5471
|
-
|
|
5472
|
-
}
|
|
5473
|
-
pubKeys.push(fromHexString2(distributedPublicKey));
|
|
5474
|
-
builderRegistrationAndDepositDataMessages.push(builderRegistrationMsg);
|
|
5475
|
-
blsSignatures.push(
|
|
5476
|
-
fromHexString2((_b2 = validator.builder_registration) == null ? void 0 : _b2.signature)
|
|
5477
|
-
);
|
|
5901
|
+
if (!builderCheck) return false;
|
|
5902
|
+
blsChecks.push(builderCheck);
|
|
5478
5903
|
}
|
|
5479
|
-
|
|
5480
|
-
if (!blsVerifyMultiple(
|
|
5481
|
-
pubKeys,
|
|
5482
|
-
builderRegistrationAndDepositDataMessages,
|
|
5483
|
-
aggregateBLSSignature
|
|
5484
|
-
)) {
|
|
5904
|
+
if (!(yield verifyBlsChecksParallel(blsChecks))) {
|
|
5485
5905
|
return false;
|
|
5486
5906
|
}
|
|
5487
5907
|
if (!verifyNodeSignatures(clusterLock)) {
|
|
5488
5908
|
return false;
|
|
5489
5909
|
}
|
|
5490
|
-
if (!
|
|
5910
|
+
if (!(yield verifyAggregateParallel(
|
|
5491
5911
|
pubShares,
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
)) {
|
|
5912
|
+
fromHexString3(clusterLock.lock_hash),
|
|
5913
|
+
fromHexString3(clusterLock.signature_aggregate)
|
|
5914
|
+
))) {
|
|
5495
5915
|
return false;
|
|
5496
5916
|
}
|
|
5497
5917
|
return true;
|
|
@@ -14959,7 +15379,7 @@ import {
|
|
|
14959
15379
|
ContainerType as ContainerType4,
|
|
14960
15380
|
ListBasicType,
|
|
14961
15381
|
ListCompositeType as ListCompositeType3,
|
|
14962
|
-
fromHexString as
|
|
15382
|
+
fromHexString as fromHexString4
|
|
14963
15383
|
} from "@chainsafe/ssz";
|
|
14964
15384
|
var clusterDefinitionContainerTypeV1X8 = (configOnly) => {
|
|
14965
15385
|
let returnedContainerType = {
|
|
@@ -14996,25 +15416,25 @@ var hashClusterDefinitionV1X8 = (cluster, configOnly) => {
|
|
|
14996
15416
|
val.num_validators = cluster.num_validators;
|
|
14997
15417
|
val.threshold = cluster.threshold;
|
|
14998
15418
|
val.dkg_algorithm = strToUint8Array(cluster.dkg_algorithm);
|
|
14999
|
-
val.fork_version =
|
|
15419
|
+
val.fork_version = fromHexString4(cluster.fork_version);
|
|
15000
15420
|
val.operators = cluster.operators.map((operator) => {
|
|
15001
|
-
return configOnly ? { address:
|
|
15002
|
-
address:
|
|
15421
|
+
return configOnly ? { address: fromHexString4(operator.address) } : {
|
|
15422
|
+
address: fromHexString4(operator.address),
|
|
15003
15423
|
enr: strToUint8Array(operator.enr),
|
|
15004
|
-
config_signature:
|
|
15005
|
-
enr_signature:
|
|
15424
|
+
config_signature: fromHexString4(operator.config_signature),
|
|
15425
|
+
enr_signature: fromHexString4(operator.enr_signature)
|
|
15006
15426
|
};
|
|
15007
15427
|
});
|
|
15008
|
-
val.creator = configOnly ? { address:
|
|
15009
|
-
address:
|
|
15010
|
-
config_signature:
|
|
15428
|
+
val.creator = configOnly ? { address: fromHexString4(cluster.creator.address) } : {
|
|
15429
|
+
address: fromHexString4(cluster.creator.address),
|
|
15430
|
+
config_signature: fromHexString4(
|
|
15011
15431
|
cluster.creator.config_signature
|
|
15012
15432
|
)
|
|
15013
15433
|
};
|
|
15014
15434
|
val.validators = cluster.validators.map((validator) => {
|
|
15015
15435
|
return {
|
|
15016
|
-
fee_recipient_address:
|
|
15017
|
-
withdrawal_address:
|
|
15436
|
+
fee_recipient_address: fromHexString4(validator.fee_recipient_address),
|
|
15437
|
+
withdrawal_address: fromHexString4(validator.withdrawal_address)
|
|
15018
15438
|
};
|
|
15019
15439
|
});
|
|
15020
15440
|
if (cluster.deposit_amounts) {
|
|
@@ -15023,7 +15443,7 @@ var hashClusterDefinitionV1X8 = (cluster, configOnly) => {
|
|
|
15023
15443
|
});
|
|
15024
15444
|
}
|
|
15025
15445
|
if (!configOnly) {
|
|
15026
|
-
val.config_hash =
|
|
15446
|
+
val.config_hash = fromHexString4(cluster.config_hash);
|
|
15027
15447
|
}
|
|
15028
15448
|
return val;
|
|
15029
15449
|
};
|
|
@@ -15050,35 +15470,35 @@ var hashClusterLockV1X8 = (cluster) => {
|
|
|
15050
15470
|
(dValidator) => {
|
|
15051
15471
|
var _a6, _b2, _c, _d, _e;
|
|
15052
15472
|
return {
|
|
15053
|
-
distributed_public_key:
|
|
15473
|
+
distributed_public_key: fromHexString4(
|
|
15054
15474
|
dValidator.distributed_public_key
|
|
15055
15475
|
),
|
|
15056
15476
|
public_shares: dValidator.public_shares.map(
|
|
15057
|
-
(publicShare) =>
|
|
15477
|
+
(publicShare) => fromHexString4(publicShare)
|
|
15058
15478
|
),
|
|
15059
15479
|
// should be fixed
|
|
15060
15480
|
partial_deposit_data: dValidator.partial_deposit_data.map((depositData) => {
|
|
15061
15481
|
return {
|
|
15062
|
-
pubkey:
|
|
15063
|
-
withdrawal_credentials:
|
|
15482
|
+
pubkey: fromHexString4(depositData.pubkey),
|
|
15483
|
+
withdrawal_credentials: fromHexString4(
|
|
15064
15484
|
depositData.withdrawal_credentials
|
|
15065
15485
|
),
|
|
15066
15486
|
amount: parseInt(depositData.amount),
|
|
15067
|
-
signature:
|
|
15487
|
+
signature: fromHexString4(depositData.signature)
|
|
15068
15488
|
};
|
|
15069
15489
|
}),
|
|
15070
15490
|
builder_registration: {
|
|
15071
15491
|
message: {
|
|
15072
|
-
fee_recipient:
|
|
15492
|
+
fee_recipient: fromHexString4(
|
|
15073
15493
|
(_a6 = dValidator.builder_registration) == null ? void 0 : _a6.message.fee_recipient
|
|
15074
15494
|
),
|
|
15075
15495
|
gas_limit: (_b2 = dValidator.builder_registration) == null ? void 0 : _b2.message.gas_limit,
|
|
15076
15496
|
timestamp: (_c = dValidator.builder_registration) == null ? void 0 : _c.message.timestamp,
|
|
15077
|
-
pubkey:
|
|
15497
|
+
pubkey: fromHexString4(
|
|
15078
15498
|
(_d = dValidator.builder_registration) == null ? void 0 : _d.message.pubkey
|
|
15079
15499
|
)
|
|
15080
15500
|
},
|
|
15081
|
-
signature:
|
|
15501
|
+
signature: fromHexString4(
|
|
15082
15502
|
(_e = dValidator.builder_registration) == null ? void 0 : _e.signature
|
|
15083
15503
|
)
|
|
15084
15504
|
}
|
|
@@ -15088,18 +15508,44 @@ var hashClusterLockV1X8 = (cluster) => {
|
|
|
15088
15508
|
return "0x" + Buffer.from(lockType.hashTreeRoot(val).buffer).toString("hex");
|
|
15089
15509
|
};
|
|
15090
15510
|
var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
|
|
15091
|
-
var _a6;
|
|
15092
15511
|
const validators = clusterLock.distributed_validators;
|
|
15512
|
+
const operatorCount = clusterLock.cluster_definition.operators.length;
|
|
15513
|
+
const threshold = clusterLock.cluster_definition.threshold;
|
|
15514
|
+
for (const validator of validators) {
|
|
15515
|
+
if (validator.public_shares.length !== operatorCount) {
|
|
15516
|
+
return false;
|
|
15517
|
+
}
|
|
15518
|
+
const uniqueShareCount = new Set(validator.public_shares).size;
|
|
15519
|
+
if (uniqueShareCount !== validator.public_shares.length) {
|
|
15520
|
+
return false;
|
|
15521
|
+
}
|
|
15522
|
+
}
|
|
15523
|
+
const allShares = validators.map((v) => v.public_shares);
|
|
15524
|
+
const allDKs = validators.map((v) => v.distributed_public_key);
|
|
15525
|
+
if (!(yield verifySharesBinding(allShares, allDKs, threshold))) {
|
|
15526
|
+
return false;
|
|
15527
|
+
}
|
|
15093
15528
|
const pubShares = [];
|
|
15094
|
-
const
|
|
15095
|
-
const
|
|
15096
|
-
const
|
|
15529
|
+
const blsChecks = [];
|
|
15530
|
+
const forkVersion = clusterLock.cluster_definition.fork_version;
|
|
15531
|
+
const depositDomain = depositDomainForFork(forkVersion);
|
|
15532
|
+
const builderDomain = builderDomainForFork(forkVersion);
|
|
15097
15533
|
for (let i = 0; i < validators.length; i++) {
|
|
15098
15534
|
const validator = validators[i];
|
|
15099
15535
|
const validatorPublicShares = validator.public_shares;
|
|
15100
15536
|
const distributedPublicKey = validator.distributed_public_key;
|
|
15101
|
-
|
|
15102
|
-
|
|
15537
|
+
if (validatorPublicShares.length !== operatorCount) {
|
|
15538
|
+
return false;
|
|
15539
|
+
}
|
|
15540
|
+
const normalizedShares = validatorPublicShares.map((s) => s.toLowerCase());
|
|
15541
|
+
if (new Set(normalizedShares).size !== normalizedShares.length) {
|
|
15542
|
+
return false;
|
|
15543
|
+
}
|
|
15544
|
+
const validatorPublicSharesBytes = validatorPublicShares.map(
|
|
15545
|
+
(share) => fromHexString4(share)
|
|
15546
|
+
);
|
|
15547
|
+
for (const share of validatorPublicSharesBytes) {
|
|
15548
|
+
pubShares.push(share);
|
|
15103
15549
|
}
|
|
15104
15550
|
const depositAmounts = clusterLock.cluster_definition.deposit_amounts;
|
|
15105
15551
|
if (!!depositAmounts && depositAmounts !== null) {
|
|
@@ -15110,52 +15556,38 @@ var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
|
|
|
15110
15556
|
return false;
|
|
15111
15557
|
}
|
|
15112
15558
|
}
|
|
15113
|
-
for (const
|
|
15114
|
-
const
|
|
15115
|
-
const { isValidDepositData, depositDataMsg } = verifyDepositData(
|
|
15559
|
+
for (const depositData of validator.partial_deposit_data) {
|
|
15560
|
+
const check = depositBlsCheck(
|
|
15116
15561
|
distributedPublicKey,
|
|
15117
15562
|
depositData,
|
|
15118
15563
|
clusterLock.cluster_definition.validators[i].withdrawal_address,
|
|
15119
|
-
|
|
15120
|
-
clusterLock.cluster_definition.compounding
|
|
15564
|
+
forkVersion,
|
|
15565
|
+
clusterLock.cluster_definition.compounding,
|
|
15566
|
+
depositDomain
|
|
15121
15567
|
);
|
|
15122
|
-
if (!
|
|
15123
|
-
|
|
15124
|
-
}
|
|
15125
|
-
pubKeys.push(fromHexString3(distributedPublicKey));
|
|
15126
|
-
builderRegistrationAndDepositDataMessages.push(depositDataMsg);
|
|
15127
|
-
blsSignatures.push(fromHexString3(depositData == null ? void 0 : depositData.signature));
|
|
15568
|
+
if (!check) return false;
|
|
15569
|
+
blsChecks.push(check);
|
|
15128
15570
|
}
|
|
15129
|
-
const
|
|
15571
|
+
const builderCheck = builderBlsCheck(
|
|
15130
15572
|
validator,
|
|
15131
15573
|
clusterLock.cluster_definition.validators[i].fee_recipient_address,
|
|
15132
|
-
|
|
15133
|
-
|
|
15134
|
-
if (!isValidBuilderRegistration) {
|
|
15135
|
-
return false;
|
|
15136
|
-
}
|
|
15137
|
-
pubKeys.push(fromHexString3(distributedPublicKey));
|
|
15138
|
-
builderRegistrationAndDepositDataMessages.push(builderRegistrationMsg);
|
|
15139
|
-
blsSignatures.push(
|
|
15140
|
-
fromHexString3((_a6 = validator.builder_registration) == null ? void 0 : _a6.signature)
|
|
15574
|
+
forkVersion,
|
|
15575
|
+
builderDomain
|
|
15141
15576
|
);
|
|
15577
|
+
if (!builderCheck) return false;
|
|
15578
|
+
blsChecks.push(builderCheck);
|
|
15142
15579
|
}
|
|
15143
|
-
|
|
15144
|
-
if (!blsVerifyMultiple(
|
|
15145
|
-
pubKeys,
|
|
15146
|
-
builderRegistrationAndDepositDataMessages,
|
|
15147
|
-
aggregateBLSSignature
|
|
15148
|
-
)) {
|
|
15580
|
+
if (!(yield verifyBlsChecksParallel(blsChecks))) {
|
|
15149
15581
|
return false;
|
|
15150
15582
|
}
|
|
15151
15583
|
if (!verifyNodeSignatures(clusterLock)) {
|
|
15152
15584
|
return false;
|
|
15153
15585
|
}
|
|
15154
|
-
if (!
|
|
15586
|
+
if (!(yield verifyAggregateParallel(
|
|
15155
15587
|
pubShares,
|
|
15156
|
-
|
|
15157
|
-
|
|
15158
|
-
)) {
|
|
15588
|
+
fromHexString4(clusterLock.lock_hash),
|
|
15589
|
+
fromHexString4(clusterLock.signature_aggregate)
|
|
15590
|
+
))) {
|
|
15159
15591
|
return false;
|
|
15160
15592
|
}
|
|
15161
15593
|
return true;
|
|
@@ -15246,7 +15678,7 @@ import {
|
|
|
15246
15678
|
ContainerType as ContainerType5,
|
|
15247
15679
|
ListBasicType as ListBasicType2,
|
|
15248
15680
|
ListCompositeType as ListCompositeType4,
|
|
15249
|
-
fromHexString as
|
|
15681
|
+
fromHexString as fromHexString5,
|
|
15250
15682
|
BooleanType
|
|
15251
15683
|
} from "@chainsafe/ssz";
|
|
15252
15684
|
var clusterDefinitionContainerTypeV1X10 = (configOnly) => {
|
|
@@ -15287,25 +15719,25 @@ var hashClusterDefinitionV1X10 = (cluster, configOnly) => {
|
|
|
15287
15719
|
val.num_validators = cluster.num_validators;
|
|
15288
15720
|
val.threshold = cluster.threshold;
|
|
15289
15721
|
val.dkg_algorithm = strToUint8Array(cluster.dkg_algorithm);
|
|
15290
|
-
val.fork_version =
|
|
15722
|
+
val.fork_version = fromHexString5(cluster.fork_version);
|
|
15291
15723
|
val.operators = cluster.operators.map((operator) => {
|
|
15292
|
-
return configOnly ? { address:
|
|
15293
|
-
address:
|
|
15724
|
+
return configOnly ? { address: fromHexString5(operator.address) } : {
|
|
15725
|
+
address: fromHexString5(operator.address),
|
|
15294
15726
|
enr: strToUint8Array(operator.enr),
|
|
15295
|
-
config_signature:
|
|
15296
|
-
enr_signature:
|
|
15727
|
+
config_signature: fromHexString5(operator.config_signature),
|
|
15728
|
+
enr_signature: fromHexString5(operator.enr_signature)
|
|
15297
15729
|
};
|
|
15298
15730
|
});
|
|
15299
|
-
val.creator = configOnly ? { address:
|
|
15300
|
-
address:
|
|
15301
|
-
config_signature:
|
|
15731
|
+
val.creator = configOnly ? { address: fromHexString5(cluster.creator.address) } : {
|
|
15732
|
+
address: fromHexString5(cluster.creator.address),
|
|
15733
|
+
config_signature: fromHexString5(
|
|
15302
15734
|
cluster.creator.config_signature
|
|
15303
15735
|
)
|
|
15304
15736
|
};
|
|
15305
15737
|
val.validators = cluster.validators.map((validator) => {
|
|
15306
15738
|
return {
|
|
15307
|
-
fee_recipient_address:
|
|
15308
|
-
withdrawal_address:
|
|
15739
|
+
fee_recipient_address: fromHexString5(validator.fee_recipient_address),
|
|
15740
|
+
withdrawal_address: fromHexString5(validator.withdrawal_address)
|
|
15309
15741
|
};
|
|
15310
15742
|
});
|
|
15311
15743
|
if (cluster.deposit_amounts) {
|
|
@@ -15323,7 +15755,7 @@ var hashClusterDefinitionV1X10 = (cluster, configOnly) => {
|
|
|
15323
15755
|
val.compounding = cluster.compounding;
|
|
15324
15756
|
}
|
|
15325
15757
|
if (!configOnly) {
|
|
15326
|
-
val.config_hash =
|
|
15758
|
+
val.config_hash = fromHexString5(cluster.config_hash);
|
|
15327
15759
|
}
|
|
15328
15760
|
return val;
|
|
15329
15761
|
};
|
|
@@ -15350,35 +15782,35 @@ var hashClusterLockV1X10 = (cluster) => {
|
|
|
15350
15782
|
(dValidator) => {
|
|
15351
15783
|
var _a6, _b2, _c, _d, _e;
|
|
15352
15784
|
return {
|
|
15353
|
-
distributed_public_key:
|
|
15785
|
+
distributed_public_key: fromHexString5(
|
|
15354
15786
|
dValidator.distributed_public_key
|
|
15355
15787
|
),
|
|
15356
15788
|
public_shares: dValidator.public_shares.map(
|
|
15357
|
-
(publicShare) =>
|
|
15789
|
+
(publicShare) => fromHexString5(publicShare)
|
|
15358
15790
|
),
|
|
15359
15791
|
// should be fixed
|
|
15360
15792
|
partial_deposit_data: dValidator.partial_deposit_data.map((depositData) => {
|
|
15361
15793
|
return {
|
|
15362
|
-
pubkey:
|
|
15363
|
-
withdrawal_credentials:
|
|
15794
|
+
pubkey: fromHexString5(depositData.pubkey),
|
|
15795
|
+
withdrawal_credentials: fromHexString5(
|
|
15364
15796
|
depositData.withdrawal_credentials
|
|
15365
15797
|
),
|
|
15366
15798
|
amount: parseInt(depositData.amount),
|
|
15367
|
-
signature:
|
|
15799
|
+
signature: fromHexString5(depositData.signature)
|
|
15368
15800
|
};
|
|
15369
15801
|
}),
|
|
15370
15802
|
builder_registration: {
|
|
15371
15803
|
message: {
|
|
15372
|
-
fee_recipient:
|
|
15804
|
+
fee_recipient: fromHexString5(
|
|
15373
15805
|
(_a6 = dValidator.builder_registration) == null ? void 0 : _a6.message.fee_recipient
|
|
15374
15806
|
),
|
|
15375
15807
|
gas_limit: (_b2 = dValidator.builder_registration) == null ? void 0 : _b2.message.gas_limit,
|
|
15376
15808
|
timestamp: (_c = dValidator.builder_registration) == null ? void 0 : _c.message.timestamp,
|
|
15377
|
-
pubkey:
|
|
15809
|
+
pubkey: fromHexString5(
|
|
15378
15810
|
(_d = dValidator.builder_registration) == null ? void 0 : _d.message.pubkey
|
|
15379
15811
|
)
|
|
15380
15812
|
},
|
|
15381
|
-
signature:
|
|
15813
|
+
signature: fromHexString5(
|
|
15382
15814
|
(_e = dValidator.builder_registration) == null ? void 0 : _e.signature
|
|
15383
15815
|
)
|
|
15384
15816
|
}
|
|
@@ -15537,8 +15969,8 @@ var computeSigningRoot = (sszObjectRoot, domain) => {
|
|
|
15537
15969
|
};
|
|
15538
15970
|
var computeDepositMsgRoot = (msg) => {
|
|
15539
15971
|
const depositMsgVal = depositMessageType.defaultValue();
|
|
15540
|
-
depositMsgVal.pubkey =
|
|
15541
|
-
depositMsgVal.withdrawal_credentials =
|
|
15972
|
+
depositMsgVal.pubkey = fromHexString6(msg.pubkey);
|
|
15973
|
+
depositMsgVal.withdrawal_credentials = fromHexString6(
|
|
15542
15974
|
msg.withdrawal_credentials
|
|
15543
15975
|
);
|
|
15544
15976
|
depositMsgVal.amount = parseInt(msg.amount);
|
|
@@ -15552,16 +15984,16 @@ var computeForkDataRoot = (currentVersion, genesisValidatorsRoot) => {
|
|
|
15552
15984
|
};
|
|
15553
15985
|
var computebuilderRegistrationMsgRoot = (msg) => {
|
|
15554
15986
|
const builderRegistrationMsgVal = builderRegistrationMessageType.defaultValue();
|
|
15555
|
-
builderRegistrationMsgVal.fee_recipient =
|
|
15987
|
+
builderRegistrationMsgVal.fee_recipient = fromHexString6(msg.fee_recipient);
|
|
15556
15988
|
builderRegistrationMsgVal.gas_limit = msg.gas_limit;
|
|
15557
15989
|
builderRegistrationMsgVal.timestamp = msg.timestamp;
|
|
15558
|
-
builderRegistrationMsgVal.pubkey =
|
|
15990
|
+
builderRegistrationMsgVal.pubkey = fromHexString6(msg.pubkey);
|
|
15559
15991
|
return Buffer.from(
|
|
15560
15992
|
builderRegistrationMessageType.hashTreeRoot(builderRegistrationMsgVal).buffer
|
|
15561
15993
|
);
|
|
15562
15994
|
};
|
|
15563
|
-
var computeDomain = (domainType, lockForkVersion, genesisValidatorsRoot =
|
|
15564
|
-
const forkVersion =
|
|
15995
|
+
var computeDomain = (domainType, lockForkVersion, genesisValidatorsRoot = fromHexString6(GENESIS_VALIDATOR_ROOT)) => {
|
|
15996
|
+
const forkVersion = fromHexString6(
|
|
15565
15997
|
lockForkVersion.substring(2, lockForkVersion.length)
|
|
15566
15998
|
);
|
|
15567
15999
|
const forkDataRoot = computeForkDataRoot(forkVersion, genesisValidatorsRoot);
|
|
@@ -15570,37 +16002,62 @@ var computeDomain = (domainType, lockForkVersion, genesisValidatorsRoot = fromHe
|
|
|
15570
16002
|
domain.set(forkDataRoot.subarray(0, 28), 4);
|
|
15571
16003
|
return domain;
|
|
15572
16004
|
};
|
|
15573
|
-
var
|
|
15574
|
-
|
|
15575
|
-
|
|
15576
|
-
|
|
15577
|
-
);
|
|
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);
|
|
15578
16009
|
const withdrawalPrefix = compounding ? "0x02" : "0x01";
|
|
15579
16010
|
const expectedWithdrawalCredentials = withdrawalPrefix + "0".repeat(22) + withdrawalAddress.toLowerCase().slice(2);
|
|
15580
16011
|
if (expectedWithdrawalCredentials !== depositData.withdrawal_credentials) {
|
|
15581
|
-
return {
|
|
16012
|
+
return { valid: false, message: new Uint8Array(0) };
|
|
15582
16013
|
}
|
|
15583
16014
|
if (distributedPublicKey !== depositData.pubkey) {
|
|
15584
|
-
return {
|
|
16015
|
+
return { valid: false, message: new Uint8Array(0) };
|
|
15585
16016
|
}
|
|
15586
16017
|
const depositMessageBuffer = computeDepositMsgRoot(depositData);
|
|
15587
|
-
const
|
|
16018
|
+
const message2 = signingRoot(depositDomain, depositMessageBuffer);
|
|
15588
16019
|
if (!depositData.signature) {
|
|
15589
|
-
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 };
|
|
15590
16050
|
}
|
|
15591
16051
|
const isValidDepositData = blsVerify(
|
|
15592
|
-
|
|
15593
|
-
|
|
15594
|
-
|
|
16052
|
+
fromHexString6(depositData.pubkey),
|
|
16053
|
+
message2,
|
|
16054
|
+
fromHexString6(depositData.signature)
|
|
15595
16055
|
);
|
|
15596
|
-
return { isValidDepositData, depositDataMsg:
|
|
16056
|
+
return { isValidDepositData, depositDataMsg: message2 };
|
|
15597
16057
|
};
|
|
15598
|
-
var verifyBuilderRegistration = (validator, feeRecipientAddress, forkVersion) => {
|
|
16058
|
+
var verifyBuilderRegistration = (validator, feeRecipientAddress, forkVersion, precomputedBuilderDomain) => {
|
|
15599
16059
|
var _a6;
|
|
15600
|
-
const builderDomain = computeDomain(
|
|
15601
|
-
fromHexString5(DOMAIN_APPLICATION_BUILDER),
|
|
15602
|
-
forkVersion
|
|
15603
|
-
);
|
|
16060
|
+
const builderDomain = precomputedBuilderDomain != null ? precomputedBuilderDomain : computeDomain(fromHexString6(DOMAIN_APPLICATION_BUILDER), forkVersion);
|
|
15604
16061
|
if (validator.distributed_public_key !== ((_a6 = validator.builder_registration) == null ? void 0 : _a6.message.pubkey)) {
|
|
15605
16062
|
return {
|
|
15606
16063
|
isValidBuilderRegistration: false,
|
|
@@ -15625,6 +16082,22 @@ var verifyBuilderRegistration = (validator, feeRecipientAddress, forkVersion) =>
|
|
|
15625
16082
|
builderRegistrationMsg: builderRegistrationMessage
|
|
15626
16083
|
};
|
|
15627
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
|
+
};
|
|
15628
16101
|
var verifyNodeSignatures = (clusterLock) => {
|
|
15629
16102
|
const ec2 = new elliptic.ec("secp256k1");
|
|
15630
16103
|
const nodeSignatures = clusterLock.node_signatures;
|
|
@@ -15666,6 +16139,12 @@ var verifyLockData = (clusterLock) => __async(null, null, function* () {
|
|
|
15666
16139
|
}
|
|
15667
16140
|
return false;
|
|
15668
16141
|
});
|
|
16142
|
+
var hasUniqueDistributedKeys = (clusterLock) => {
|
|
16143
|
+
const dvKeys = clusterLock.distributed_validators.map(
|
|
16144
|
+
(v) => v.distributed_public_key.toLowerCase()
|
|
16145
|
+
);
|
|
16146
|
+
return new Set(dvKeys).size === dvKeys.length;
|
|
16147
|
+
};
|
|
15669
16148
|
var isValidClusterLock = (clusterLock, safeRpcUrl) => __async(null, null, function* () {
|
|
15670
16149
|
try {
|
|
15671
16150
|
const definitionType = definitionFlow(clusterLock.cluster_definition);
|
|
@@ -15686,6 +16165,9 @@ var isValidClusterLock = (clusterLock, safeRpcUrl) => __async(null, null, functi
|
|
|
15686
16165
|
if (clusterLockHash(clusterLock) !== clusterLock.lock_hash) {
|
|
15687
16166
|
return false;
|
|
15688
16167
|
}
|
|
16168
|
+
if (!hasUniqueDistributedKeys(clusterLock)) {
|
|
16169
|
+
return false;
|
|
16170
|
+
}
|
|
15689
16171
|
const isValidLockData = yield verifyLockData(clusterLock);
|
|
15690
16172
|
if (!isValidLockData) {
|
|
15691
16173
|
return false;
|
|
@@ -19360,7 +19842,7 @@ import * as elliptic2 from "elliptic";
|
|
|
19360
19842
|
import {
|
|
19361
19843
|
ByteVectorType as ByteVectorType7,
|
|
19362
19844
|
ContainerType as ContainerType7,
|
|
19363
|
-
fromHexString as
|
|
19845
|
+
fromHexString as fromHexString8,
|
|
19364
19846
|
ListCompositeType as ListCompositeType5,
|
|
19365
19847
|
UintNumberType as UintNumberType6
|
|
19366
19848
|
} from "@chainsafe/ssz";
|
|
@@ -19400,7 +19882,7 @@ function getGenesisValidatorsRoot(beaconNodeApiUrl) {
|
|
|
19400
19882
|
}
|
|
19401
19883
|
|
|
19402
19884
|
// src/exits/verificationHelpers.ts
|
|
19403
|
-
import { ContainerType as ContainerType6, ByteVectorType as ByteVectorType6, fromHexString as
|
|
19885
|
+
import { ContainerType as ContainerType6, ByteVectorType as ByteVectorType6, fromHexString as fromHexString7 } from "@chainsafe/ssz";
|
|
19404
19886
|
var GENESIS_VALIDATOR_ROOT_HEX_STRING = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
19405
19887
|
var ForkDataType = new ContainerType6({
|
|
19406
19888
|
currentVersion: new ByteVectorType6(4),
|
|
@@ -19417,7 +19899,7 @@ function computeForkDataRoot2(currentVersion, genesisValidatorsRoot) {
|
|
|
19417
19899
|
return Buffer.from(ForkDataType.hashTreeRoot(forkDataVal).buffer);
|
|
19418
19900
|
}
|
|
19419
19901
|
function computeDomain2(domainType, forkVersionString, genesisValidatorsRootOverride) {
|
|
19420
|
-
const forkVersionBytes =
|
|
19902
|
+
const forkVersionBytes = fromHexString7(
|
|
19421
19903
|
forkVersionString.substring(2, forkVersionString.length)
|
|
19422
19904
|
);
|
|
19423
19905
|
if (forkVersionBytes.length !== 4) {
|
|
@@ -19426,7 +19908,7 @@ function computeDomain2(domainType, forkVersionString, genesisValidatorsRootOver
|
|
|
19426
19908
|
if (domainType.length !== 4) {
|
|
19427
19909
|
throw new Error("Domain type must be 4 bytes");
|
|
19428
19910
|
}
|
|
19429
|
-
const actualGenesisValidatorsRoot = genesisValidatorsRootOverride != null ? genesisValidatorsRootOverride :
|
|
19911
|
+
const actualGenesisValidatorsRoot = genesisValidatorsRootOverride != null ? genesisValidatorsRootOverride : fromHexString7(GENESIS_VALIDATOR_ROOT_HEX_STRING.substring(2));
|
|
19430
19912
|
if (actualGenesisValidatorsRoot.length !== 32) {
|
|
19431
19913
|
throw new Error("genesisValidatorsRoot must be 32 bytes");
|
|
19432
19914
|
}
|
|
@@ -19519,7 +20001,7 @@ var Exit = class _Exit {
|
|
|
19519
20001
|
static computeExitPayloadRoot(exits) {
|
|
19520
20002
|
const sszValue = SSZPartialExitsPayloadType.defaultValue();
|
|
19521
20003
|
sszValue.partial_exits = exits.partial_exits.map((pe) => ({
|
|
19522
|
-
public_key:
|
|
20004
|
+
public_key: fromHexString8(pe.public_key),
|
|
19523
20005
|
signed_exit_message: {
|
|
19524
20006
|
message: {
|
|
19525
20007
|
epoch: _Exit.safeParseInt(pe.signed_exit_message.message.epoch),
|
|
@@ -19527,7 +20009,7 @@ var Exit = class _Exit {
|
|
|
19527
20009
|
pe.signed_exit_message.message.validator_index
|
|
19528
20010
|
)
|
|
19529
20011
|
},
|
|
19530
|
-
signature:
|
|
20012
|
+
signature: fromHexString8(pe.signed_exit_message.signature)
|
|
19531
20013
|
}
|
|
19532
20014
|
}));
|
|
19533
20015
|
sszValue.share_idx = exits.share_idx;
|
|
@@ -19577,18 +20059,18 @@ var Exit = class _Exit {
|
|
|
19577
20059
|
signedExitMessage.message
|
|
19578
20060
|
);
|
|
19579
20061
|
const exitDomain = computeDomain2(
|
|
19580
|
-
|
|
20062
|
+
fromHexString8(DOMAIN_VOLUNTARY_EXIT),
|
|
19581
20063
|
capellaForkVersionString,
|
|
19582
|
-
|
|
20064
|
+
fromHexString8(genesisValidatorsRootString)
|
|
19583
20065
|
);
|
|
19584
20066
|
const messageSigningRoot = signingRoot2(
|
|
19585
20067
|
exitDomain,
|
|
19586
20068
|
partialExitMessageBuffer
|
|
19587
20069
|
);
|
|
19588
20070
|
return blsVerify(
|
|
19589
|
-
|
|
20071
|
+
fromHexString8(publicShareKey),
|
|
19590
20072
|
messageSigningRoot,
|
|
19591
|
-
|
|
20073
|
+
fromHexString8(signedExitMessage.signature)
|
|
19592
20074
|
);
|
|
19593
20075
|
});
|
|
19594
20076
|
}
|
|
@@ -19891,7 +20373,7 @@ var Exit = class _Exit {
|
|
|
19891
20373
|
);
|
|
19892
20374
|
}
|
|
19893
20375
|
try {
|
|
19894
|
-
const sigBytes =
|
|
20376
|
+
const sigBytes = fromHexString8(cleanSigStr);
|
|
19895
20377
|
const sigIdx = parseInt(sigIdxStr, 10);
|
|
19896
20378
|
signaturesByIndex.set(sigIdx + 1, sigBytes);
|
|
19897
20379
|
} catch (err) {
|
|
@@ -20635,8 +21117,9 @@ var EOA = class {
|
|
|
20635
21117
|
// src/services.ts
|
|
20636
21118
|
var validateClusterLock = (lock, safeRpcUrl) => __async(null, null, function* () {
|
|
20637
21119
|
try {
|
|
20638
|
-
const
|
|
20639
|
-
return
|
|
21120
|
+
const inWorker = yield validateClusterLockInWorker(lock, safeRpcUrl);
|
|
21121
|
+
if (inWorker !== null) return inWorker;
|
|
21122
|
+
return yield isValidClusterLock(lock, safeRpcUrl);
|
|
20640
21123
|
} catch (err) {
|
|
20641
21124
|
throw err;
|
|
20642
21125
|
}
|
|
@@ -21235,6 +21718,7 @@ export {
|
|
|
21235
21718
|
CONFIG_VERSION,
|
|
21236
21719
|
CONFLICT_ERROR_MSG,
|
|
21237
21720
|
Client,
|
|
21721
|
+
ClusterLockValidationTimeoutError,
|
|
21238
21722
|
ConflictError,
|
|
21239
21723
|
CreatorConfigHashSigningTypes,
|
|
21240
21724
|
CreatorTypedMessage,
|
|
@@ -21275,8 +21759,13 @@ export {
|
|
|
21275
21759
|
TermsAndConditionsSigningTypes,
|
|
21276
21760
|
UnsupportedChainError,
|
|
21277
21761
|
blsVerify,
|
|
21762
|
+
builderBlsCheck,
|
|
21763
|
+
builderDomainForFork,
|
|
21278
21764
|
clusterConfigOrDefinitionHash,
|
|
21279
21765
|
clusterLockHash,
|
|
21766
|
+
depositBlsCheck,
|
|
21767
|
+
depositDomainForFork,
|
|
21768
|
+
hasUniqueDistributedKeys,
|
|
21280
21769
|
isChainSupportedForSplitters,
|
|
21281
21770
|
isValidClusterLock,
|
|
21282
21771
|
signCreatorConfigHashPayload,
|
|
@@ -21285,6 +21774,7 @@ export {
|
|
|
21285
21774
|
signingRoot,
|
|
21286
21775
|
validateAddressSignature,
|
|
21287
21776
|
validateClusterLock,
|
|
21777
|
+
validateDepositDataStructure,
|
|
21288
21778
|
validateEOASignature,
|
|
21289
21779
|
validateSmartContractSignature,
|
|
21290
21780
|
verifyBuilderRegistration,
|