@lodestar/state-transition 1.41.0-dev.b90dff673d → 1.41.0-dev.bb16850567
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/lib/block/processVoluntaryExit.d.ts.map +1 -1
- package/lib/block/processVoluntaryExit.js +49 -47
- package/lib/block/processVoluntaryExit.js.map +1 -1
- package/lib/signatureSets/index.d.ts +2 -1
- package/lib/signatureSets/index.d.ts.map +1 -1
- package/lib/signatureSets/index.js +3 -2
- package/lib/signatureSets/index.js.map +1 -1
- package/lib/signatureSets/voluntaryExits.d.ts +7 -3
- package/lib/signatureSets/voluntaryExits.d.ts.map +1 -1
- package/lib/signatureSets/voluntaryExits.js +30 -9
- package/lib/signatureSets/voluntaryExits.js.map +1 -1
- package/package.json +8 -8
- package/src/block/processVoluntaryExit.ts +77 -54
- package/src/signatureSets/index.ts +4 -1
- package/src/signatureSets/voluntaryExits.ts +51 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processVoluntaryExit.d.ts","sourceRoot":"","sources":["../../src/block/processVoluntaryExit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"processVoluntaryExit.d.ts","sourceRoot":"","sources":["../../src/block/processVoluntaryExit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAC;AAGvC,OAAO,EAAC,yBAAyB,EAAmD,MAAM,aAAa,CAAC;AAWxG,oBAAY,qBAAqB;IAC/B,KAAK,UAAU;IACf,QAAQ,aAAa;IACrB,aAAa,mBAAmB;IAChC,UAAU,gBAAgB;IAC1B,eAAe,sBAAsB;IACrC,kBAAkB,wBAAwB;IAC1C,gBAAgB,sBAAsB;CACvC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,yBAAyB,EAChC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,EAC/C,eAAe,UAAO,GACrB,IAAI,CAkBN;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,yBAAyB,EAChC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,EAC/C,eAAe,UAAO,GACrB,qBAAqB,CAevB;AAyFD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,yBAAyB,EAChC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,EAC/C,eAAe,UAAO,GACrB,OAAO,CAET"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { PublicKey, Signature, verify } from "@chainsafe/blst";
|
|
2
1
|
import { FAR_FUTURE_EPOCH, ForkSeq } from "@lodestar/params";
|
|
3
|
-
import { ssz } from "@lodestar/types";
|
|
4
2
|
import { verifyVoluntaryExitSignature } from "../signatureSets/index.js";
|
|
3
|
+
import { BeaconStateView } from "../stateView/beaconStateView.js";
|
|
5
4
|
import { convertValidatorIndexToBuilderIndex, getPendingBalanceToWithdrawForBuilder, initiateBuilderExit, isActiveBuilder, isBuilderIndex, } from "../util/gloas.js";
|
|
6
|
-
import {
|
|
5
|
+
import { getPendingBalanceToWithdraw, isActiveValidator } from "../util/index.js";
|
|
7
6
|
import { initiateValidatorExit } from "./index.js";
|
|
8
7
|
export { VoluntaryExitValidity };
|
|
9
8
|
var VoluntaryExitValidity;
|
|
@@ -23,55 +22,61 @@ var VoluntaryExitValidity;
|
|
|
23
22
|
*/
|
|
24
23
|
export function processVoluntaryExit(fork, state, signedVoluntaryExit, verifySignature = true) {
|
|
25
24
|
const voluntaryExit = signedVoluntaryExit.message;
|
|
26
|
-
const currentEpoch = getCurrentEpoch(state);
|
|
27
|
-
// Exits must specify an epoch when they become valid; they are not valid before then
|
|
28
|
-
if (currentEpoch < voluntaryExit.epoch) {
|
|
29
|
-
throw Error(`Voluntary exit epoch ${voluntaryExit.epoch} is after current epoch ${currentEpoch}`);
|
|
30
|
-
}
|
|
31
|
-
// Check if this is a builder exit
|
|
32
|
-
if (fork >= ForkSeq.gloas && isBuilderIndex(voluntaryExit.validatorIndex)) {
|
|
33
|
-
const stateGloas = state;
|
|
34
|
-
const builderIndex = convertValidatorIndexToBuilderIndex(voluntaryExit.validatorIndex);
|
|
35
|
-
const builder = stateGloas.builders.getReadonly(builderIndex);
|
|
36
|
-
// Verify the builder is active
|
|
37
|
-
if (!isActiveBuilder(builder, state.finalizedCheckpoint.epoch)) {
|
|
38
|
-
throw Error(`Builder ${builderIndex} is not active`);
|
|
39
|
-
}
|
|
40
|
-
// Only exit builder if it has no pending withdrawals in the queue
|
|
41
|
-
if (getPendingBalanceToWithdrawForBuilder(stateGloas, builderIndex) !== 0) {
|
|
42
|
-
throw Error(`Builder ${builderIndex} has pending withdrawals`);
|
|
43
|
-
}
|
|
44
|
-
// Verify signature
|
|
45
|
-
if (verifySignature) {
|
|
46
|
-
const domain = state.config.getDomainForVoluntaryExit(state.slot);
|
|
47
|
-
const signingRoot = computeSigningRoot(ssz.phase0.VoluntaryExit, voluntaryExit, domain);
|
|
48
|
-
try {
|
|
49
|
-
const publicKey = PublicKey.fromBytes(builder.pubkey);
|
|
50
|
-
const signature = Signature.fromBytes(signedVoluntaryExit.signature, true);
|
|
51
|
-
if (!verify(signingRoot, publicKey, signature)) {
|
|
52
|
-
throw Error("BLS verify failed");
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
catch (e) {
|
|
56
|
-
throw Error(`Builder ${builderIndex} invalid exit signature reason=${e.message}`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
// Initiate builder exit
|
|
60
|
-
initiateBuilderExit(stateGloas, builderIndex);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
// Handle validator exit
|
|
64
25
|
const validity = getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature);
|
|
65
26
|
if (validity !== VoluntaryExitValidity.valid) {
|
|
66
27
|
throw Error(`Invalid voluntary exit at forkSeq=${fork} reason=${validity}`);
|
|
67
28
|
}
|
|
29
|
+
if (fork >= ForkSeq.gloas && isBuilderIndex(voluntaryExit.validatorIndex)) {
|
|
30
|
+
initiateBuilderExit(state, convertValidatorIndexToBuilderIndex(voluntaryExit.validatorIndex));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
68
33
|
const validator = state.validators.get(signedVoluntaryExit.message.validatorIndex);
|
|
69
34
|
initiateValidatorExit(fork, state, validator);
|
|
70
35
|
}
|
|
71
36
|
export function getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature = true) {
|
|
37
|
+
const currentEpoch = state.epochCtx.epoch;
|
|
38
|
+
const voluntaryExit = signedVoluntaryExit.message;
|
|
39
|
+
// Exits must specify an epoch when they become valid; they are not valid before then
|
|
40
|
+
if (currentEpoch < voluntaryExit.epoch) {
|
|
41
|
+
return VoluntaryExitValidity.earlyEpoch;
|
|
42
|
+
}
|
|
43
|
+
// Check if this is a builder exit
|
|
44
|
+
if (fork >= ForkSeq.gloas && isBuilderIndex(voluntaryExit.validatorIndex)) {
|
|
45
|
+
return getBuilderVoluntaryExitValidity(state, signedVoluntaryExit, verifySignature);
|
|
46
|
+
}
|
|
47
|
+
return getValidatorVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature);
|
|
48
|
+
}
|
|
49
|
+
function getBuilderVoluntaryExitValidity(state, signedVoluntaryExit, verifySignature) {
|
|
50
|
+
const { config, epochCtx } = state;
|
|
51
|
+
const builderIndex = convertValidatorIndexToBuilderIndex(signedVoluntaryExit.message.validatorIndex);
|
|
52
|
+
if (builderIndex >= state.builders.length) {
|
|
53
|
+
return VoluntaryExitValidity.inactive;
|
|
54
|
+
}
|
|
55
|
+
const builder = state.builders.getReadonly(builderIndex);
|
|
56
|
+
// Verify the builder is active
|
|
57
|
+
if (!isActiveBuilder(builder, state.finalizedCheckpoint.epoch)) {
|
|
58
|
+
return builder.withdrawableEpoch !== FAR_FUTURE_EPOCH
|
|
59
|
+
? VoluntaryExitValidity.alreadyExited
|
|
60
|
+
: VoluntaryExitValidity.inactive;
|
|
61
|
+
}
|
|
62
|
+
// Only exit builder if it has no pending withdrawals in the queue
|
|
63
|
+
if (getPendingBalanceToWithdrawForBuilder(state, builderIndex) !== 0) {
|
|
64
|
+
return VoluntaryExitValidity.pendingWithdrawals;
|
|
65
|
+
}
|
|
66
|
+
// Verify signature
|
|
67
|
+
if (verifySignature &&
|
|
68
|
+
!verifyVoluntaryExitSignature(config, epochCtx.pubkeyCache, new BeaconStateView(state), signedVoluntaryExit)) {
|
|
69
|
+
return VoluntaryExitValidity.invalidSignature;
|
|
70
|
+
}
|
|
71
|
+
return VoluntaryExitValidity.valid;
|
|
72
|
+
}
|
|
73
|
+
function getValidatorVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature) {
|
|
72
74
|
const { config, epochCtx } = state;
|
|
73
75
|
const voluntaryExit = signedVoluntaryExit.message;
|
|
74
|
-
|
|
76
|
+
if (voluntaryExit.validatorIndex >= state.validators.length) {
|
|
77
|
+
return VoluntaryExitValidity.inactive;
|
|
78
|
+
}
|
|
79
|
+
const validator = state.validators.getReadonly(voluntaryExit.validatorIndex);
|
|
75
80
|
const currentEpoch = epochCtx.epoch;
|
|
76
81
|
// verify the validator is active
|
|
77
82
|
if (!isActiveValidator(validator, currentEpoch)) {
|
|
@@ -81,10 +86,6 @@ export function getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verif
|
|
|
81
86
|
if (validator.exitEpoch !== FAR_FUTURE_EPOCH) {
|
|
82
87
|
return VoluntaryExitValidity.alreadyExited;
|
|
83
88
|
}
|
|
84
|
-
// exits must specify an epoch when they become valid; they are not valid before then
|
|
85
|
-
if (currentEpoch < voluntaryExit.epoch) {
|
|
86
|
-
return VoluntaryExitValidity.earlyEpoch;
|
|
87
|
-
}
|
|
88
89
|
// verify the validator had been active long enough
|
|
89
90
|
if (currentEpoch < validator.activationEpoch + config.SHARD_COMMITTEE_PERIOD) {
|
|
90
91
|
return VoluntaryExitValidity.shortTimeActive;
|
|
@@ -94,8 +95,9 @@ export function getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verif
|
|
|
94
95
|
getPendingBalanceToWithdraw(state, voluntaryExit.validatorIndex) !== 0) {
|
|
95
96
|
return VoluntaryExitValidity.pendingWithdrawals;
|
|
96
97
|
}
|
|
98
|
+
// Verify signature
|
|
97
99
|
if (verifySignature &&
|
|
98
|
-
!verifyVoluntaryExitSignature(
|
|
100
|
+
!verifyVoluntaryExitSignature(config, epochCtx.pubkeyCache, new BeaconStateView(state), signedVoluntaryExit)) {
|
|
99
101
|
return VoluntaryExitValidity.invalidSignature;
|
|
100
102
|
}
|
|
101
103
|
return VoluntaryExitValidity.valid;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processVoluntaryExit.js","sourceRoot":"","sources":["../../src/block/processVoluntaryExit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"processVoluntaryExit.js","sourceRoot":"","sources":["../../src/block/processVoluntaryExit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAE,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAC,4BAA4B,EAAC,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAC,eAAe,EAAC,MAAM,iCAAiC,CAAC;AAEhE,OAAO,EACL,mCAAmC,EACnC,qCAAqC,EACrC,mBAAmB,EACnB,eAAe,EACf,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,2BAA2B,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAC,qBAAqB,EAAC,MAAM,YAAY,CAAC;SAErC,qBAAqB;AAAjC,IAAY,qBAQX;AARD,WAAY,qBAAqB;IAC/B,wCAAe,CAAA;IACf,8CAAqB,CAAA;IACrB,yDAAgC,CAAA;IAChC,mDAA0B,CAAA;IAC1B,8DAAqC,CAAA;IACrC,mEAA0C,CAAA;IAC1C,+DAAsC,CAAA;AAAC,CACzC,EARY,qBAAqB,KAArB,qBAAqB,QAQhC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAa,EACb,KAAgC,EAChC,mBAA+C,EAC/C,eAAe,GAAG,IAAI,EAChB;IACN,MAAM,aAAa,GAAG,mBAAmB,CAAC,OAAO,CAAC;IAElD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,EAAE,KAAK,EAAE,mBAAmB,EAAE,eAAe,CAAC,CAAC;IAC7F,IAAI,QAAQ,KAAK,qBAAqB,CAAC,KAAK,EAAE,CAAC;QAC7C,MAAM,KAAK,CAAC,qCAAqC,IAAI,WAAW,QAAQ,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;QAC1E,mBAAmB,CACjB,KAA+B,EAC/B,mCAAmC,CAAC,aAAa,CAAC,cAAc,CAAC,CAClE,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACnF,qBAAqB,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAAA,CAC/C;AAED,MAAM,UAAU,wBAAwB,CACtC,IAAa,EACb,KAAgC,EAChC,mBAA+C,EAC/C,eAAe,GAAG,IAAI,EACC;IACvB,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC1C,MAAM,aAAa,GAAG,mBAAmB,CAAC,OAAO,CAAC;IAElD,qFAAqF;IACrF,IAAI,YAAY,GAAG,aAAa,CAAC,KAAK,EAAE,CAAC;QACvC,OAAO,qBAAqB,CAAC,UAAU,CAAC;IAC1C,CAAC;IAED,kCAAkC;IAClC,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;QAC1E,OAAO,+BAA+B,CAAC,KAA+B,EAAE,mBAAmB,EAAE,eAAe,CAAC,CAAC;IAChH,CAAC;IAED,OAAO,iCAAiC,CAAC,IAAI,EAAE,KAAK,EAAE,mBAAmB,EAAE,eAAe,CAAC,CAAC;AAAA,CAC7F;AAED,SAAS,+BAA+B,CACtC,KAA6B,EAC7B,mBAA+C,EAC/C,eAAwB,EACD;IACvB,MAAM,EAAC,MAAM,EAAE,QAAQ,EAAC,GAAG,KAAK,CAAC;IACjC,MAAM,YAAY,GAAG,mCAAmC,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAErG,IAAI,YAAY,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC1C,OAAO,qBAAqB,CAAC,QAAQ,CAAC;IACxC,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IAEzD,+BAA+B;IAC/B,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/D,OAAO,OAAO,CAAC,iBAAiB,KAAK,gBAAgB;YACnD,CAAC,CAAC,qBAAqB,CAAC,aAAa;YACrC,CAAC,CAAC,qBAAqB,CAAC,QAAQ,CAAC;IACrC,CAAC;IAED,kEAAkE;IAClE,IAAI,qCAAqC,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACrE,OAAO,qBAAqB,CAAC,kBAAkB,CAAC;IAClD,CAAC;IAED,mBAAmB;IACnB,IACE,eAAe;QACf,CAAC,4BAA4B,CAAC,MAAM,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,mBAAmB,CAAC,EAC5G,CAAC;QACD,OAAO,qBAAqB,CAAC,gBAAgB,CAAC;IAChD,CAAC;IAED,OAAO,qBAAqB,CAAC,KAAK,CAAC;AAAA,CACpC;AAED,SAAS,iCAAiC,CACxC,IAAa,EACb,KAAgC,EAChC,mBAA+C,EAC/C,eAAwB,EACD;IACvB,MAAM,EAAC,MAAM,EAAE,QAAQ,EAAC,GAAG,KAAK,CAAC;IACjC,MAAM,aAAa,GAAG,mBAAmB,CAAC,OAAO,CAAC;IAElD,IAAI,aAAa,CAAC,cAAc,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QAC5D,OAAO,qBAAqB,CAAC,QAAQ,CAAC;IACxC,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IAC7E,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC;IAEpC,iCAAiC;IACjC,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,CAAC;QAChD,OAAO,qBAAqB,CAAC,QAAQ,CAAC;IACxC,CAAC;IAED,qCAAqC;IACrC,IAAI,SAAS,CAAC,SAAS,KAAK,gBAAgB,EAAE,CAAC;QAC7C,OAAO,qBAAqB,CAAC,aAAa,CAAC;IAC7C,CAAC;IAED,mDAAmD;IACnD,IAAI,YAAY,GAAG,SAAS,CAAC,eAAe,GAAG,MAAM,CAAC,sBAAsB,EAAE,CAAC;QAC7E,OAAO,qBAAqB,CAAC,eAAe,CAAC;IAC/C,CAAC;IAED,oEAAoE;IACpE,IACE,IAAI,IAAI,OAAO,CAAC,OAAO;QACvB,2BAA2B,CAAC,KAAiC,EAAE,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,EAClG,CAAC;QACD,OAAO,qBAAqB,CAAC,kBAAkB,CAAC;IAClD,CAAC;IAED,mBAAmB;IACnB,IACE,eAAe;QACf,CAAC,4BAA4B,CAAC,MAAM,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,mBAAmB,CAAC,EAC5G,CAAC;QACD,OAAO,qBAAqB,CAAC,gBAAgB,CAAC;IAChD,CAAC;IAED,OAAO,qBAAqB,CAAC,KAAK,CAAC;AAAA,CACpC;AAED,MAAM,UAAU,oBAAoB,CAClC,IAAa,EACb,KAAgC,EAChC,mBAA+C,EAC/C,eAAe,GAAG,IAAI,EACb;IACT,OAAO,wBAAwB,CAAC,IAAI,EAAE,KAAK,EAAE,mBAAmB,EAAE,eAAe,CAAC,KAAK,qBAAqB,CAAC,KAAK,CAAC;AAAA,CACpH"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BeaconConfig } from "@lodestar/config";
|
|
2
2
|
import { IndexedAttestation, SignedBeaconBlock } from "@lodestar/types";
|
|
3
3
|
import { SyncCommitteeCache } from "../cache/syncCommitteeCache.js";
|
|
4
|
+
import { CachedBeaconStateAllForks } from "../types.js";
|
|
4
5
|
import { ISignatureSet } from "../util/index.js";
|
|
5
6
|
export * from "./attesterSlashings.js";
|
|
6
7
|
export * from "./blsToExecutionChange.js";
|
|
@@ -16,7 +17,7 @@ export * from "./voluntaryExits.js";
|
|
|
16
17
|
* Includes all signatures on the block (except the deposit signatures) for verification.
|
|
17
18
|
* Deposits are not included because they can legally have invalid signatures.
|
|
18
19
|
*/
|
|
19
|
-
export declare function getBlockSignatureSets(config: BeaconConfig, currentSyncCommitteeIndexed: SyncCommitteeCache, signedBlock: SignedBeaconBlock, indexedAttestations: IndexedAttestation[], opts?: {
|
|
20
|
+
export declare function getBlockSignatureSets(config: BeaconConfig, currentSyncCommitteeIndexed: SyncCommitteeCache, state: CachedBeaconStateAllForks, signedBlock: SignedBeaconBlock, indexedAttestations: IndexedAttestation[], opts?: {
|
|
20
21
|
/** Useful since block proposer signature is verified beforehand on gossip validation */
|
|
21
22
|
skipProposerSignature?: boolean;
|
|
22
23
|
}): ISignatureSet[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/signatureSets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAC,kBAAkB,EAAE,iBAAiB,EAAkB,MAAM,iBAAiB,CAAC;AAEvF,OAAO,EAAC,kBAAkB,EAAC,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/signatureSets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAC,kBAAkB,EAAE,iBAAiB,EAAkB,MAAM,iBAAiB,CAAC;AAEvF,OAAO,EAAC,kBAAkB,EAAC,MAAM,gCAAgC,CAAC;AAElE,OAAO,EAAC,yBAAyB,EAAC,MAAM,aAAa,CAAC;AACtD,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAS/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AAEpC;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,2BAA2B,EAAE,kBAAkB,EAC/C,KAAK,EAAE,yBAAyB,EAChC,WAAW,EAAE,iBAAiB,EAC9B,mBAAmB,EAAE,kBAAkB,EAAE,EACzC,IAAI,CAAC,EAAE;IACL,wFAAwF;IACxF,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,GACA,aAAa,EAAE,CAyCjB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ForkSeq } from "@lodestar/params";
|
|
2
2
|
import { getSyncCommitteeSignatureSet } from "../block/processSyncCommittee.js";
|
|
3
|
+
import { BeaconStateView } from "../stateView/beaconStateView.js";
|
|
3
4
|
import { getAttesterSlashingsSignatureSets } from "./attesterSlashings.js";
|
|
4
5
|
import { getBlsToExecutionChangeSignatureSets } from "./blsToExecutionChange.js";
|
|
5
6
|
import { getAttestationsSignatureSets } from "./indexedAttestation.js";
|
|
@@ -21,7 +22,7 @@ export * from "./voluntaryExits.js";
|
|
|
21
22
|
* Includes all signatures on the block (except the deposit signatures) for verification.
|
|
22
23
|
* Deposits are not included because they can legally have invalid signatures.
|
|
23
24
|
*/
|
|
24
|
-
export function getBlockSignatureSets(config, currentSyncCommitteeIndexed, signedBlock, indexedAttestations, opts) {
|
|
25
|
+
export function getBlockSignatureSets(config, currentSyncCommitteeIndexed, state, signedBlock, indexedAttestations, opts) {
|
|
25
26
|
// fork based validations
|
|
26
27
|
const fork = config.getForkSeq(signedBlock.message.slot);
|
|
27
28
|
const signatureSets = [
|
|
@@ -29,7 +30,7 @@ export function getBlockSignatureSets(config, currentSyncCommitteeIndexed, signe
|
|
|
29
30
|
...getProposerSlashingsSignatureSets(config, signedBlock),
|
|
30
31
|
...getAttesterSlashingsSignatureSets(config, signedBlock),
|
|
31
32
|
...getAttestationsSignatureSets(config, signedBlock, indexedAttestations),
|
|
32
|
-
...getVoluntaryExitsSignatureSets(config, signedBlock),
|
|
33
|
+
...getVoluntaryExitsSignatureSets(config, new BeaconStateView(state), signedBlock),
|
|
33
34
|
];
|
|
34
35
|
if (!opts?.skipProposerSignature) {
|
|
35
36
|
signatureSets.push(getBlockProposerSignatureSet(config, signedBlock));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/signatureSets/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAEzC,OAAO,EAAC,4BAA4B,EAAC,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/signatureSets/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAEzC,OAAO,EAAC,4BAA4B,EAAC,MAAM,kCAAkC,CAAC;AAE9E,OAAO,EAAC,eAAe,EAAC,MAAM,iCAAiC,CAAC;AAGhE,OAAO,EAAC,iCAAiC,EAAC,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAC,oCAAoC,EAAC,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAC,4BAA4B,EAAC,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAC,4BAA4B,EAAC,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAC,iCAAiC,EAAC,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAC,2BAA2B,EAAC,MAAM,aAAa,CAAC;AACxD,OAAO,EAAC,8BAA8B,EAAC,MAAM,qBAAqB,CAAC;AAEnE,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AAEpC;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAoB,EACpB,2BAA+C,EAC/C,KAAgC,EAChC,WAA8B,EAC9B,mBAAyC,EACzC,IAGC,EACgB;IACjB,yBAAyB;IACzB,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD,MAAM,aAAa,GAAG;QACpB,2BAA2B,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC;QACxD,GAAG,iCAAiC,CAAC,MAAM,EAAE,WAAW,CAAC;QACzD,GAAG,iCAAiC,CAAC,MAAM,EAAE,WAAW,CAAC;QACzD,GAAG,4BAA4B,CAAC,MAAM,EAAE,WAAW,EAAE,mBAAmB,CAAC;QACzE,GAAG,8BAA8B,CAAC,MAAM,EAAE,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;KACnF,CAAC;IAEF,IAAI,CAAC,IAAI,EAAE,qBAAqB,EAAE,CAAC;QACjC,aAAa,CAAC,IAAI,CAAC,4BAA4B,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,2DAA2D;IAC3D,IAAI,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,yBAAyB,GAAG,4BAA4B,CAC5D,MAAM,EACN,2BAA2B,EAC1B,WAAwC,CAAC,OAAO,CAClD,CAAC;QACF,2FAA2F;QAC3F,IAAI,yBAAyB,EAAE,CAAC;YAC9B,aAAa,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,IAAI,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5B,MAAM,iCAAiC,GAAG,oCAAoC,CAC5E,MAAM,EACN,WAAwC,CACzC,CAAC;QACF,IAAI,iCAAiC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjD,aAAa,CAAC,IAAI,CAAC,GAAG,iCAAiC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AAAA,CACtB"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { BeaconConfig } from "@lodestar/config";
|
|
2
2
|
import { SignedBeaconBlock, Slot, phase0 } from "@lodestar/types";
|
|
3
3
|
import { PubkeyCache } from "../cache/pubkeyCache.js";
|
|
4
|
+
import { IBeaconStateView } from "../stateView/interface.js";
|
|
4
5
|
import { ISignatureSet } from "../util/index.js";
|
|
5
|
-
export declare function verifyVoluntaryExitSignature(config: BeaconConfig, pubkeyCache: PubkeyCache,
|
|
6
|
+
export declare function verifyVoluntaryExitSignature(config: BeaconConfig, pubkeyCache: PubkeyCache, state: IBeaconStateView, signedVoluntaryExit: phase0.SignedVoluntaryExit): boolean;
|
|
6
7
|
/**
|
|
7
8
|
* Extract signatures to allow validating all block signatures at once
|
|
8
9
|
*/
|
|
9
|
-
export declare function getVoluntaryExitSignatureSet(config: BeaconConfig,
|
|
10
|
-
export declare function getVoluntaryExitsSignatureSets(config: BeaconConfig, signedBlock: SignedBeaconBlock): ISignatureSet[];
|
|
10
|
+
export declare function getVoluntaryExitSignatureSet(config: BeaconConfig, state: IBeaconStateView, signedVoluntaryExit: phase0.SignedVoluntaryExit): ISignatureSet;
|
|
11
|
+
export declare function getVoluntaryExitsSignatureSets(config: BeaconConfig, state: IBeaconStateView, signedBlock: SignedBeaconBlock): ISignatureSet[];
|
|
12
|
+
export declare function getValidatorVoluntaryExitSignatureSet(config: BeaconConfig, stateSlot: Slot, signedVoluntaryExit: phase0.SignedVoluntaryExit): ISignatureSet;
|
|
13
|
+
export declare function getBuilderVoluntaryExitSignatureSet(config: BeaconConfig, state: IBeaconStateView, signedVoluntaryExit: phase0.SignedVoluntaryExit): ISignatureSet;
|
|
14
|
+
export declare function isBuilderVoluntaryExit(signedVoluntaryExit: phase0.SignedVoluntaryExit): boolean;
|
|
11
15
|
//# sourceMappingURL=voluntaryExits.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voluntaryExits.d.ts","sourceRoot":"","sources":["../../src/signatureSets/voluntaryExits.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"voluntaryExits.d.ts","sourceRoot":"","sources":["../../src/signatureSets/voluntaryExits.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAC,iBAAiB,EAAE,IAAI,EAAE,MAAM,EAAM,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAC,WAAW,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAC,gBAAgB,EAAC,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EACL,aAAa,EAOd,MAAM,kBAAkB,CAAC;AAE1B,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,gBAAgB,EACvB,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,GAC9C,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,gBAAgB,EACvB,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,GAC9C,aAAa,CAQf;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,gBAAgB,EACvB,WAAW,EAAE,iBAAiB,GAC7B,aAAa,EAAE,CAIjB;AAED,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,IAAI,EACf,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,GAC9C,aAAa,CAUf;AAED,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,gBAAgB,EACvB,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,GAC9C,aAAa,CAYf;AAED,wBAAgB,sBAAsB,CAAC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,GAAG,OAAO,CAE/F"}
|
|
@@ -1,12 +1,24 @@
|
|
|
1
|
+
import { PublicKey } from "@chainsafe/blst";
|
|
2
|
+
import { ForkSeq } from "@lodestar/params";
|
|
1
3
|
import { ssz } from "@lodestar/types";
|
|
2
|
-
import { SignatureSetType, computeSigningRoot, computeStartSlotAtEpoch, verifySignatureSet, } from "../util/index.js";
|
|
3
|
-
export function verifyVoluntaryExitSignature(config, pubkeyCache,
|
|
4
|
-
return verifySignatureSet(getVoluntaryExitSignatureSet(config,
|
|
4
|
+
import { SignatureSetType, computeSigningRoot, computeStartSlotAtEpoch, convertValidatorIndexToBuilderIndex, isBuilderIndex, verifySignatureSet, } from "../util/index.js";
|
|
5
|
+
export function verifyVoluntaryExitSignature(config, pubkeyCache, state, signedVoluntaryExit) {
|
|
6
|
+
return verifySignatureSet(getVoluntaryExitSignatureSet(config, state, signedVoluntaryExit), pubkeyCache);
|
|
5
7
|
}
|
|
6
8
|
/**
|
|
7
9
|
* Extract signatures to allow validating all block signatures at once
|
|
8
10
|
*/
|
|
9
|
-
export function getVoluntaryExitSignatureSet(config,
|
|
11
|
+
export function getVoluntaryExitSignatureSet(config, state, signedVoluntaryExit) {
|
|
12
|
+
const fork = config.getForkSeq(state.slot);
|
|
13
|
+
if (fork >= ForkSeq.gloas && isBuilderVoluntaryExit(signedVoluntaryExit)) {
|
|
14
|
+
return getBuilderVoluntaryExitSignatureSet(config, state, signedVoluntaryExit);
|
|
15
|
+
}
|
|
16
|
+
return getValidatorVoluntaryExitSignatureSet(config, state.slot, signedVoluntaryExit);
|
|
17
|
+
}
|
|
18
|
+
export function getVoluntaryExitsSignatureSets(config, state, signedBlock) {
|
|
19
|
+
return signedBlock.message.body.voluntaryExits.map((voluntaryExit) => getVoluntaryExitSignatureSet(config, state, voluntaryExit));
|
|
20
|
+
}
|
|
21
|
+
export function getValidatorVoluntaryExitSignatureSet(config, stateSlot, signedVoluntaryExit) {
|
|
10
22
|
const messageSlot = computeStartSlotAtEpoch(signedVoluntaryExit.message.epoch);
|
|
11
23
|
const domain = config.getDomainForVoluntaryExit(stateSlot, messageSlot);
|
|
12
24
|
return {
|
|
@@ -16,10 +28,19 @@ export function getVoluntaryExitSignatureSet(config, stateSlot, signedVoluntaryE
|
|
|
16
28
|
signature: signedVoluntaryExit.signature,
|
|
17
29
|
};
|
|
18
30
|
}
|
|
19
|
-
export function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
31
|
+
export function getBuilderVoluntaryExitSignatureSet(config, state, signedVoluntaryExit) {
|
|
32
|
+
const messageSlot = computeStartSlotAtEpoch(signedVoluntaryExit.message.epoch);
|
|
33
|
+
const domain = config.getDomainForVoluntaryExit(state.slot, messageSlot);
|
|
34
|
+
const builderIndex = convertValidatorIndexToBuilderIndex(signedVoluntaryExit.message.validatorIndex);
|
|
35
|
+
const builder = state.getBuilder(builderIndex);
|
|
36
|
+
return {
|
|
37
|
+
type: SignatureSetType.single,
|
|
38
|
+
pubkey: PublicKey.fromBytes(builder.pubkey),
|
|
39
|
+
signingRoot: computeSigningRoot(ssz.phase0.VoluntaryExit, signedVoluntaryExit.message, domain),
|
|
40
|
+
signature: signedVoluntaryExit.signature,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function isBuilderVoluntaryExit(signedVoluntaryExit) {
|
|
44
|
+
return isBuilderIndex(signedVoluntaryExit.message.validatorIndex);
|
|
24
45
|
}
|
|
25
46
|
//# sourceMappingURL=voluntaryExits.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voluntaryExits.js","sourceRoot":"","sources":["../../src/signatureSets/voluntaryExits.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"voluntaryExits.js","sourceRoot":"","sources":["../../src/signatureSets/voluntaryExits.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/ChainSafe/lodestar/issues"
|
|
13
13
|
},
|
|
14
|
-
"version": "1.41.0-dev.
|
|
14
|
+
"version": "1.41.0-dev.bb16850567",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -67,14 +67,14 @@
|
|
|
67
67
|
"@chainsafe/pubkey-index-map": "^3.0.0",
|
|
68
68
|
"@chainsafe/ssz": "^1.2.2",
|
|
69
69
|
"@chainsafe/swap-or-not-shuffle": "^1.2.1",
|
|
70
|
-
"@lodestar/config": "^1.41.0-dev.
|
|
71
|
-
"@lodestar/params": "^1.41.0-dev.
|
|
72
|
-
"@lodestar/types": "^1.41.0-dev.
|
|
73
|
-
"@lodestar/utils": "^1.41.0-dev.
|
|
74
|
-
"@vekexasia/bigint-buffer2": "^1.1.
|
|
70
|
+
"@lodestar/config": "^1.41.0-dev.bb16850567",
|
|
71
|
+
"@lodestar/params": "^1.41.0-dev.bb16850567",
|
|
72
|
+
"@lodestar/types": "^1.41.0-dev.bb16850567",
|
|
73
|
+
"@lodestar/utils": "^1.41.0-dev.bb16850567",
|
|
74
|
+
"@vekexasia/bigint-buffer2": "^1.1.1"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
-
"@lodestar/api": "^1.41.0-dev.
|
|
77
|
+
"@lodestar/api": "^1.41.0-dev.bb16850567"
|
|
78
78
|
},
|
|
79
79
|
"keywords": [
|
|
80
80
|
"ethereum",
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"beacon",
|
|
83
83
|
"blockchain"
|
|
84
84
|
],
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "659b2cdaf3eb6ba38abacec70d9f44d89bc291ff"
|
|
86
86
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {PublicKey, Signature, verify} from "@chainsafe/blst";
|
|
2
1
|
import {FAR_FUTURE_EPOCH, ForkSeq} from "@lodestar/params";
|
|
3
|
-
import {phase0
|
|
2
|
+
import {phase0} from "@lodestar/types";
|
|
4
3
|
import {verifyVoluntaryExitSignature} from "../signatureSets/index.js";
|
|
4
|
+
import {BeaconStateView} from "../stateView/beaconStateView.js";
|
|
5
5
|
import {CachedBeaconStateAllForks, CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
|
|
6
6
|
import {
|
|
7
7
|
convertValidatorIndexToBuilderIndex,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
isActiveBuilder,
|
|
11
11
|
isBuilderIndex,
|
|
12
12
|
} from "../util/gloas.js";
|
|
13
|
-
import {
|
|
13
|
+
import {getPendingBalanceToWithdraw, isActiveValidator} from "../util/index.js";
|
|
14
14
|
import {initiateValidatorExit} from "./index.js";
|
|
15
15
|
|
|
16
16
|
export enum VoluntaryExitValidity {
|
|
@@ -35,57 +35,20 @@ export function processVoluntaryExit(
|
|
|
35
35
|
verifySignature = true
|
|
36
36
|
): void {
|
|
37
37
|
const voluntaryExit = signedVoluntaryExit.message;
|
|
38
|
-
const currentEpoch = getCurrentEpoch(state);
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
throw Error(`
|
|
39
|
+
const validity = getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature);
|
|
40
|
+
if (validity !== VoluntaryExitValidity.valid) {
|
|
41
|
+
throw Error(`Invalid voluntary exit at forkSeq=${fork} reason=${validity}`);
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
// Check if this is a builder exit
|
|
46
44
|
if (fork >= ForkSeq.gloas && isBuilderIndex(voluntaryExit.validatorIndex)) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// Verify the builder is active
|
|
52
|
-
if (!isActiveBuilder(builder, state.finalizedCheckpoint.epoch)) {
|
|
53
|
-
throw Error(`Builder ${builderIndex} is not active`);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Only exit builder if it has no pending withdrawals in the queue
|
|
57
|
-
if (getPendingBalanceToWithdrawForBuilder(stateGloas, builderIndex) !== 0) {
|
|
58
|
-
throw Error(`Builder ${builderIndex} has pending withdrawals`);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Verify signature
|
|
62
|
-
if (verifySignature) {
|
|
63
|
-
const domain = state.config.getDomainForVoluntaryExit(state.slot);
|
|
64
|
-
const signingRoot = computeSigningRoot(ssz.phase0.VoluntaryExit, voluntaryExit, domain);
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const publicKey = PublicKey.fromBytes(builder.pubkey);
|
|
68
|
-
const signature = Signature.fromBytes(signedVoluntaryExit.signature, true);
|
|
69
|
-
|
|
70
|
-
if (!verify(signingRoot, publicKey, signature)) {
|
|
71
|
-
throw Error("BLS verify failed");
|
|
72
|
-
}
|
|
73
|
-
} catch (e) {
|
|
74
|
-
throw Error(`Builder ${builderIndex} invalid exit signature reason=${(e as Error).message}`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Initiate builder exit
|
|
79
|
-
initiateBuilderExit(stateGloas, builderIndex);
|
|
45
|
+
initiateBuilderExit(
|
|
46
|
+
state as CachedBeaconStateGloas,
|
|
47
|
+
convertValidatorIndexToBuilderIndex(voluntaryExit.validatorIndex)
|
|
48
|
+
);
|
|
80
49
|
return;
|
|
81
50
|
}
|
|
82
51
|
|
|
83
|
-
// Handle validator exit
|
|
84
|
-
const validity = getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature);
|
|
85
|
-
if (validity !== VoluntaryExitValidity.valid) {
|
|
86
|
-
throw Error(`Invalid voluntary exit at forkSeq=${fork} reason=${validity}`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
52
|
const validator = state.validators.get(signedVoluntaryExit.message.validatorIndex);
|
|
90
53
|
initiateValidatorExit(fork, state, validator);
|
|
91
54
|
}
|
|
@@ -95,10 +58,74 @@ export function getVoluntaryExitValidity(
|
|
|
95
58
|
state: CachedBeaconStateAllForks,
|
|
96
59
|
signedVoluntaryExit: phase0.SignedVoluntaryExit,
|
|
97
60
|
verifySignature = true
|
|
61
|
+
): VoluntaryExitValidity {
|
|
62
|
+
const currentEpoch = state.epochCtx.epoch;
|
|
63
|
+
const voluntaryExit = signedVoluntaryExit.message;
|
|
64
|
+
|
|
65
|
+
// Exits must specify an epoch when they become valid; they are not valid before then
|
|
66
|
+
if (currentEpoch < voluntaryExit.epoch) {
|
|
67
|
+
return VoluntaryExitValidity.earlyEpoch;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Check if this is a builder exit
|
|
71
|
+
if (fork >= ForkSeq.gloas && isBuilderIndex(voluntaryExit.validatorIndex)) {
|
|
72
|
+
return getBuilderVoluntaryExitValidity(state as CachedBeaconStateGloas, signedVoluntaryExit, verifySignature);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return getValidatorVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function getBuilderVoluntaryExitValidity(
|
|
79
|
+
state: CachedBeaconStateGloas,
|
|
80
|
+
signedVoluntaryExit: phase0.SignedVoluntaryExit,
|
|
81
|
+
verifySignature: boolean
|
|
82
|
+
): VoluntaryExitValidity {
|
|
83
|
+
const {config, epochCtx} = state;
|
|
84
|
+
const builderIndex = convertValidatorIndexToBuilderIndex(signedVoluntaryExit.message.validatorIndex);
|
|
85
|
+
|
|
86
|
+
if (builderIndex >= state.builders.length) {
|
|
87
|
+
return VoluntaryExitValidity.inactive;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const builder = state.builders.getReadonly(builderIndex);
|
|
91
|
+
|
|
92
|
+
// Verify the builder is active
|
|
93
|
+
if (!isActiveBuilder(builder, state.finalizedCheckpoint.epoch)) {
|
|
94
|
+
return builder.withdrawableEpoch !== FAR_FUTURE_EPOCH
|
|
95
|
+
? VoluntaryExitValidity.alreadyExited
|
|
96
|
+
: VoluntaryExitValidity.inactive;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Only exit builder if it has no pending withdrawals in the queue
|
|
100
|
+
if (getPendingBalanceToWithdrawForBuilder(state, builderIndex) !== 0) {
|
|
101
|
+
return VoluntaryExitValidity.pendingWithdrawals;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Verify signature
|
|
105
|
+
if (
|
|
106
|
+
verifySignature &&
|
|
107
|
+
!verifyVoluntaryExitSignature(config, epochCtx.pubkeyCache, new BeaconStateView(state), signedVoluntaryExit)
|
|
108
|
+
) {
|
|
109
|
+
return VoluntaryExitValidity.invalidSignature;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return VoluntaryExitValidity.valid;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function getValidatorVoluntaryExitValidity(
|
|
116
|
+
fork: ForkSeq,
|
|
117
|
+
state: CachedBeaconStateAllForks,
|
|
118
|
+
signedVoluntaryExit: phase0.SignedVoluntaryExit,
|
|
119
|
+
verifySignature: boolean
|
|
98
120
|
): VoluntaryExitValidity {
|
|
99
121
|
const {config, epochCtx} = state;
|
|
100
122
|
const voluntaryExit = signedVoluntaryExit.message;
|
|
101
|
-
|
|
123
|
+
|
|
124
|
+
if (voluntaryExit.validatorIndex >= state.validators.length) {
|
|
125
|
+
return VoluntaryExitValidity.inactive;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const validator = state.validators.getReadonly(voluntaryExit.validatorIndex);
|
|
102
129
|
const currentEpoch = epochCtx.epoch;
|
|
103
130
|
|
|
104
131
|
// verify the validator is active
|
|
@@ -111,11 +138,6 @@ export function getVoluntaryExitValidity(
|
|
|
111
138
|
return VoluntaryExitValidity.alreadyExited;
|
|
112
139
|
}
|
|
113
140
|
|
|
114
|
-
// exits must specify an epoch when they become valid; they are not valid before then
|
|
115
|
-
if (currentEpoch < voluntaryExit.epoch) {
|
|
116
|
-
return VoluntaryExitValidity.earlyEpoch;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
141
|
// verify the validator had been active long enough
|
|
120
142
|
if (currentEpoch < validator.activationEpoch + config.SHARD_COMMITTEE_PERIOD) {
|
|
121
143
|
return VoluntaryExitValidity.shortTimeActive;
|
|
@@ -129,9 +151,10 @@ export function getVoluntaryExitValidity(
|
|
|
129
151
|
return VoluntaryExitValidity.pendingWithdrawals;
|
|
130
152
|
}
|
|
131
153
|
|
|
154
|
+
// Verify signature
|
|
132
155
|
if (
|
|
133
156
|
verifySignature &&
|
|
134
|
-
!verifyVoluntaryExitSignature(
|
|
157
|
+
!verifyVoluntaryExitSignature(config, epochCtx.pubkeyCache, new BeaconStateView(state), signedVoluntaryExit)
|
|
135
158
|
) {
|
|
136
159
|
return VoluntaryExitValidity.invalidSignature;
|
|
137
160
|
}
|
|
@@ -3,6 +3,8 @@ import {ForkSeq} from "@lodestar/params";
|
|
|
3
3
|
import {IndexedAttestation, SignedBeaconBlock, altair, capella} from "@lodestar/types";
|
|
4
4
|
import {getSyncCommitteeSignatureSet} from "../block/processSyncCommittee.js";
|
|
5
5
|
import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
|
|
6
|
+
import {BeaconStateView} from "../stateView/beaconStateView.js";
|
|
7
|
+
import {CachedBeaconStateAllForks} from "../types.js";
|
|
6
8
|
import {ISignatureSet} from "../util/index.js";
|
|
7
9
|
import {getAttesterSlashingsSignatureSets} from "./attesterSlashings.js";
|
|
8
10
|
import {getBlsToExecutionChangeSignatureSets} from "./blsToExecutionChange.js";
|
|
@@ -30,6 +32,7 @@ export * from "./voluntaryExits.js";
|
|
|
30
32
|
export function getBlockSignatureSets(
|
|
31
33
|
config: BeaconConfig,
|
|
32
34
|
currentSyncCommitteeIndexed: SyncCommitteeCache,
|
|
35
|
+
state: CachedBeaconStateAllForks,
|
|
33
36
|
signedBlock: SignedBeaconBlock,
|
|
34
37
|
indexedAttestations: IndexedAttestation[],
|
|
35
38
|
opts?: {
|
|
@@ -45,7 +48,7 @@ export function getBlockSignatureSets(
|
|
|
45
48
|
...getProposerSlashingsSignatureSets(config, signedBlock),
|
|
46
49
|
...getAttesterSlashingsSignatureSets(config, signedBlock),
|
|
47
50
|
...getAttestationsSignatureSets(config, signedBlock, indexedAttestations),
|
|
48
|
-
...getVoluntaryExitsSignatureSets(config, signedBlock),
|
|
51
|
+
...getVoluntaryExitsSignatureSets(config, new BeaconStateView(state), signedBlock),
|
|
49
52
|
];
|
|
50
53
|
|
|
51
54
|
if (!opts?.skipProposerSignature) {
|
|
@@ -1,27 +1,56 @@
|
|
|
1
|
+
import {PublicKey} from "@chainsafe/blst";
|
|
1
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
|
+
import {ForkSeq} from "@lodestar/params";
|
|
2
4
|
import {SignedBeaconBlock, Slot, phase0, ssz} from "@lodestar/types";
|
|
3
5
|
import {PubkeyCache} from "../cache/pubkeyCache.js";
|
|
6
|
+
import {IBeaconStateView} from "../stateView/interface.js";
|
|
4
7
|
import {
|
|
5
8
|
ISignatureSet,
|
|
6
9
|
SignatureSetType,
|
|
7
10
|
computeSigningRoot,
|
|
8
11
|
computeStartSlotAtEpoch,
|
|
12
|
+
convertValidatorIndexToBuilderIndex,
|
|
13
|
+
isBuilderIndex,
|
|
9
14
|
verifySignatureSet,
|
|
10
15
|
} from "../util/index.js";
|
|
11
16
|
|
|
12
17
|
export function verifyVoluntaryExitSignature(
|
|
13
18
|
config: BeaconConfig,
|
|
14
19
|
pubkeyCache: PubkeyCache,
|
|
15
|
-
|
|
20
|
+
state: IBeaconStateView,
|
|
16
21
|
signedVoluntaryExit: phase0.SignedVoluntaryExit
|
|
17
22
|
): boolean {
|
|
18
|
-
return verifySignatureSet(getVoluntaryExitSignatureSet(config,
|
|
23
|
+
return verifySignatureSet(getVoluntaryExitSignatureSet(config, state, signedVoluntaryExit), pubkeyCache);
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
/**
|
|
22
27
|
* Extract signatures to allow validating all block signatures at once
|
|
23
28
|
*/
|
|
24
29
|
export function getVoluntaryExitSignatureSet(
|
|
30
|
+
config: BeaconConfig,
|
|
31
|
+
state: IBeaconStateView,
|
|
32
|
+
signedVoluntaryExit: phase0.SignedVoluntaryExit
|
|
33
|
+
): ISignatureSet {
|
|
34
|
+
const fork = config.getForkSeq(state.slot);
|
|
35
|
+
|
|
36
|
+
if (fork >= ForkSeq.gloas && isBuilderVoluntaryExit(signedVoluntaryExit)) {
|
|
37
|
+
return getBuilderVoluntaryExitSignatureSet(config, state, signedVoluntaryExit);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return getValidatorVoluntaryExitSignatureSet(config, state.slot, signedVoluntaryExit);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function getVoluntaryExitsSignatureSets(
|
|
44
|
+
config: BeaconConfig,
|
|
45
|
+
state: IBeaconStateView,
|
|
46
|
+
signedBlock: SignedBeaconBlock
|
|
47
|
+
): ISignatureSet[] {
|
|
48
|
+
return signedBlock.message.body.voluntaryExits.map((voluntaryExit) =>
|
|
49
|
+
getVoluntaryExitSignatureSet(config, state, voluntaryExit)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function getValidatorVoluntaryExitSignatureSet(
|
|
25
54
|
config: BeaconConfig,
|
|
26
55
|
stateSlot: Slot,
|
|
27
56
|
signedVoluntaryExit: phase0.SignedVoluntaryExit
|
|
@@ -37,11 +66,24 @@ export function getVoluntaryExitSignatureSet(
|
|
|
37
66
|
};
|
|
38
67
|
}
|
|
39
68
|
|
|
40
|
-
export function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
);
|
|
69
|
+
export function getBuilderVoluntaryExitSignatureSet(
|
|
70
|
+
config: BeaconConfig,
|
|
71
|
+
state: IBeaconStateView,
|
|
72
|
+
signedVoluntaryExit: phase0.SignedVoluntaryExit
|
|
73
|
+
): ISignatureSet {
|
|
74
|
+
const messageSlot = computeStartSlotAtEpoch(signedVoluntaryExit.message.epoch);
|
|
75
|
+
const domain = config.getDomainForVoluntaryExit(state.slot, messageSlot);
|
|
76
|
+
const builderIndex = convertValidatorIndexToBuilderIndex(signedVoluntaryExit.message.validatorIndex);
|
|
77
|
+
const builder = state.getBuilder(builderIndex);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
type: SignatureSetType.single,
|
|
81
|
+
pubkey: PublicKey.fromBytes(builder.pubkey),
|
|
82
|
+
signingRoot: computeSigningRoot(ssz.phase0.VoluntaryExit, signedVoluntaryExit.message, domain),
|
|
83
|
+
signature: signedVoluntaryExit.signature,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function isBuilderVoluntaryExit(signedVoluntaryExit: phase0.SignedVoluntaryExit): boolean {
|
|
88
|
+
return isBuilderIndex(signedVoluntaryExit.message.validatorIndex);
|
|
47
89
|
}
|