-
-
Notifications
You must be signed in to change notification settings - Fork 439
Expand file tree
/
Copy pathsingleThread.ts
More file actions
89 lines (75 loc) · 2.72 KB
/
singleThread.ts
File metadata and controls
89 lines (75 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import {PublicKey, Signature, aggregatePublicKeys, aggregateSignatures, verify} from "@chainsafe/lodestar-z/blst";
import {ISignatureSet, Index2PubkeyCache} from "@lodestar/state-transition";
import {Metrics} from "../../metrics/index.js";
import {IBlsVerifier} from "./interface.js";
import {verifySignatureSetsMaybeBatch} from "./maybeBatch.js";
import {getAggregatedPubkey, getAggregatedPubkeysCount} from "./utils.js";
export class BlsSingleThreadVerifier implements IBlsVerifier {
private readonly metrics: Metrics | null;
private readonly index2pubkey: Index2PubkeyCache;
constructor({metrics = null, index2pubkey}: {metrics: Metrics | null; index2pubkey: Index2PubkeyCache}) {
this.metrics = metrics;
this.index2pubkey = index2pubkey;
}
async verifySignatureSets(sets: ISignatureSet[]): Promise<boolean> {
this.metrics?.bls.aggregatedPubkeys.inc(getAggregatedPubkeysCount(sets));
const setsAggregated = sets.map((set) => ({
publicKey: getAggregatedPubkey(set, this.index2pubkey, this.metrics),
message: set.signingRoot,
signature: set.signature,
}));
// Count time after aggregating
const timer = this.metrics?.blsThreadPool.mainThreadDurationInThreadPool.startTimer();
const isValid = verifySignatureSetsMaybeBatch(setsAggregated);
// Don't use a try/catch, only count run without exceptions
if (timer) {
timer();
}
return isValid;
}
async verifySignatureSetsSameMessage(
sets: {publicKey: PublicKey; signature: Uint8Array}[],
message: Uint8Array
): Promise<boolean[]> {
const timer = this.metrics?.blsThreadPool.mainThreadDurationInThreadPool.startTimer();
const pubkey = aggregatePublicKeys(sets.map((set) => set.publicKey));
let isAllValid = true;
// validate signature = true
const signatures = sets.map((set) => {
try {
return Signature.fromBytes(set.signature, true);
} catch (_) {
// at least one set has malformed signature
isAllValid = false;
return null;
}
});
if (isAllValid) {
const signature = aggregateSignatures(signatures as Signature[]);
isAllValid = verify(message, pubkey, signature);
}
let result: boolean[];
if (isAllValid) {
result = sets.map(() => true);
} else {
result = sets.map((set, i) => {
const sig = signatures[i];
if (sig === null) {
return false;
}
return verify(message, set.publicKey, sig);
});
}
if (timer) {
timer();
}
return result;
}
async close(): Promise<void> {
// nothing to do
}
canAcceptWork(): boolean {
// Since sigs are verified blocking the main thread, there's no mechanism to throttle
return true;
}
}