@lodestar/state-transition 1.36.0-dev.793f92c091 → 1.36.0-dev.a0d00ac6dc

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.
@@ -1,11 +1,21 @@
1
1
  import { ForkSeq } from "@lodestar/params";
2
2
  import { phase0 } from "@lodestar/types";
3
3
  import { CachedBeaconStateAllForks } from "../types.js";
4
+ export declare enum VoluntaryExitValidity {
5
+ valid = "valid",
6
+ inactive = "inactive",
7
+ alreadyExited = "already_exited",
8
+ earlyEpoch = "early_epoch",
9
+ shortTimeActive = "short_time_active",
10
+ pendingWithdrawals = "pending_withdrawals",
11
+ invalidSignature = "invalid_signature"
12
+ }
4
13
  /**
5
14
  * Process a VoluntaryExit operation. Initiates the exit of a validator.
6
15
  *
7
16
  * PERF: Work depends on number of VoluntaryExit per block. On regular networks the average is 0 / block.
8
17
  */
9
18
  export declare function processVoluntaryExit(fork: ForkSeq, state: CachedBeaconStateAllForks, signedVoluntaryExit: phase0.SignedVoluntaryExit, verifySignature?: boolean): void;
19
+ export declare function getVoluntaryExitValidity(fork: ForkSeq, state: CachedBeaconStateAllForks, signedVoluntaryExit: phase0.SignedVoluntaryExit, verifySignature?: boolean): VoluntaryExitValidity;
10
20
  export declare function isValidVoluntaryExit(fork: ForkSeq, state: CachedBeaconStateAllForks, signedVoluntaryExit: phase0.SignedVoluntaryExit, verifySignature?: boolean): boolean;
11
21
  //# sourceMappingURL=processVoluntaryExit.d.ts.map
@@ -1 +1 @@
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;AAEvC,OAAO,EAAC,yBAAyB,EAA2B,MAAM,aAAa,CAAC;AAIhF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,yBAAyB,EAChC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,EAC/C,eAAe,UAAO,GACrB,IAAI,CAON;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,yBAAyB,EAChC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,EAC/C,eAAe,UAAO,GACrB,OAAO,CAuBT"}
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;AAEvC,OAAO,EAAC,yBAAyB,EAA2B,MAAM,aAAa,CAAC;AAIhF,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,CAQN;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,yBAAyB,EAChC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,EAC/C,eAAe,UAAO,GACrB,qBAAqB,CAuCvB;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,yBAAyB,EAChC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,EAC/C,eAAe,UAAO,GACrB,OAAO,CAET"}
@@ -2,38 +2,61 @@ import { FAR_FUTURE_EPOCH, ForkSeq } from "@lodestar/params";
2
2
  import { verifyVoluntaryExitSignature } from "../signatureSets/index.js";
3
3
  import { getPendingBalanceToWithdraw, isActiveValidator } from "../util/index.js";
4
4
  import { initiateValidatorExit } from "./index.js";
5
+ export var VoluntaryExitValidity;
6
+ (function (VoluntaryExitValidity) {
7
+ VoluntaryExitValidity["valid"] = "valid";
8
+ VoluntaryExitValidity["inactive"] = "inactive";
9
+ VoluntaryExitValidity["alreadyExited"] = "already_exited";
10
+ VoluntaryExitValidity["earlyEpoch"] = "early_epoch";
11
+ VoluntaryExitValidity["shortTimeActive"] = "short_time_active";
12
+ VoluntaryExitValidity["pendingWithdrawals"] = "pending_withdrawals";
13
+ VoluntaryExitValidity["invalidSignature"] = "invalid_signature";
14
+ })(VoluntaryExitValidity || (VoluntaryExitValidity = {}));
5
15
  /**
6
16
  * Process a VoluntaryExit operation. Initiates the exit of a validator.
7
17
  *
8
18
  * PERF: Work depends on number of VoluntaryExit per block. On regular networks the average is 0 / block.
9
19
  */
10
20
  export function processVoluntaryExit(fork, state, signedVoluntaryExit, verifySignature = true) {
11
- if (!isValidVoluntaryExit(fork, state, signedVoluntaryExit, verifySignature)) {
12
- throw Error(`Invalid voluntary exit at forkSeq=${fork}`);
21
+ const validity = getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature);
22
+ if (validity !== VoluntaryExitValidity.valid) {
23
+ throw Error(`Invalid voluntary exit at forkSeq=${fork} reason=${validity}`);
13
24
  }
14
25
  const validator = state.validators.get(signedVoluntaryExit.message.validatorIndex);
15
26
  initiateValidatorExit(fork, state, validator);
16
27
  }
17
- export function isValidVoluntaryExit(fork, state, signedVoluntaryExit, verifySignature = true) {
28
+ export function getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature = true) {
18
29
  const { config, epochCtx } = state;
19
30
  const voluntaryExit = signedVoluntaryExit.message;
20
31
  const validator = state.validators.get(voluntaryExit.validatorIndex);
21
32
  const currentEpoch = epochCtx.epoch;
22
- return (
23
33
  // verify the validator is active
24
- isActiveValidator(validator, currentEpoch) &&
25
- // verify exit has not been initiated
26
- validator.exitEpoch === FAR_FUTURE_EPOCH &&
27
- // exits must specify an epoch when they become valid; they are not valid before then
28
- currentEpoch >= voluntaryExit.epoch &&
29
- // verify the validator had been active long enough
30
- currentEpoch >= validator.activationEpoch + config.SHARD_COMMITTEE_PERIOD &&
31
- (fork >= ForkSeq.electra
32
- ? // only exit validator if it has no pending withdrawals in the queue
33
- getPendingBalanceToWithdraw(state, voluntaryExit.validatorIndex) === 0
34
- : // there are no pending withdrawals in previous forks
35
- true) &&
36
- // verify signature
37
- (!verifySignature || verifyVoluntaryExitSignature(state, signedVoluntaryExit)));
34
+ if (!isActiveValidator(validator, currentEpoch)) {
35
+ return VoluntaryExitValidity.inactive;
36
+ }
37
+ // verify exit has not been initiated
38
+ if (validator.exitEpoch !== FAR_FUTURE_EPOCH) {
39
+ return VoluntaryExitValidity.alreadyExited;
40
+ }
41
+ // exits must specify an epoch when they become valid; they are not valid before then
42
+ if (currentEpoch < voluntaryExit.epoch) {
43
+ return VoluntaryExitValidity.earlyEpoch;
44
+ }
45
+ // verify the validator had been active long enough
46
+ if (currentEpoch < validator.activationEpoch + config.SHARD_COMMITTEE_PERIOD) {
47
+ return VoluntaryExitValidity.shortTimeActive;
48
+ }
49
+ // only exit validator if it has no pending withdrawals in the queue
50
+ if (fork >= ForkSeq.electra &&
51
+ getPendingBalanceToWithdraw(state, voluntaryExit.validatorIndex) !== 0) {
52
+ return VoluntaryExitValidity.pendingWithdrawals;
53
+ }
54
+ if (verifySignature && !verifyVoluntaryExitSignature(state, signedVoluntaryExit)) {
55
+ return VoluntaryExitValidity.invalidSignature;
56
+ }
57
+ return VoluntaryExitValidity.valid;
58
+ }
59
+ export function isValidVoluntaryExit(fork, state, signedVoluntaryExit, verifySignature = true) {
60
+ return getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature) === VoluntaryExitValidity.valid;
38
61
  }
39
62
  //# sourceMappingURL=processVoluntaryExit.js.map
@@ -1 +1 @@
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;AAEvE,OAAO,EAAC,2BAA2B,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAC,qBAAqB,EAAC,MAAM,YAAY,CAAC;AAEjD;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAa,EACb,KAAgC,EAChC,mBAA+C,EAC/C,eAAe,GAAG,IAAI;IAEtB,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,mBAAmB,EAAE,eAAe,CAAC,EAAE,CAAC;QAC7E,MAAM,KAAK,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;IAC3D,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;AAChD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,IAAa,EACb,KAAgC,EAChC,mBAA+C,EAC/C,eAAe,GAAG,IAAI;IAEtB,MAAM,EAAC,MAAM,EAAE,QAAQ,EAAC,GAAG,KAAK,CAAC;IACjC,MAAM,aAAa,GAAG,mBAAmB,CAAC,OAAO,CAAC;IAClD,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IACrE,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC;IAEpC,OAAO;IACL,iCAAiC;IACjC,iBAAiB,CAAC,SAAS,EAAE,YAAY,CAAC;QAC1C,qCAAqC;QACrC,SAAS,CAAC,SAAS,KAAK,gBAAgB;QACxC,qFAAqF;QACrF,YAAY,IAAI,aAAa,CAAC,KAAK;QACnC,mDAAmD;QACnD,YAAY,IAAI,SAAS,CAAC,eAAe,GAAG,MAAM,CAAC,sBAAsB;QACzE,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO;YACtB,CAAC,CAAC,oEAAoE;gBACpE,2BAA2B,CAAC,KAAiC,EAAE,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC;YACpG,CAAC,CAAC,qDAAqD;gBACrD,IAAI,CAAC;QACT,mBAAmB;QACnB,CAAC,CAAC,eAAe,IAAI,4BAA4B,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAC/E,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"processVoluntaryExit.js","sourceRoot":"","sources":["../../src/block/processVoluntaryExit.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export { assertValidAttesterSlashing } from "./block/processAttesterSlashing.js"
4
4
  export { isValidBlsToExecutionChange } from "./block/processBlsToExecutionChange.js";
5
5
  export { becomesNewEth1Data } from "./block/processEth1Data.js";
6
6
  export { assertValidProposerSlashing } from "./block/processProposerSlashing.js";
7
- export { isValidVoluntaryExit } from "./block/processVoluntaryExit.js";
7
+ export { VoluntaryExitValidity, getVoluntaryExitValidity, isValidVoluntaryExit } from "./block/processVoluntaryExit.js";
8
8
  export { getExpectedWithdrawals } from "./block/processWithdrawals.js";
9
9
  export { ProposerRewardType } from "./block/types.js";
10
10
  export { type EffectiveBalanceIncrements, getEffectiveBalanceIncrementsWithLen, getEffectiveBalanceIncrementsZeroed, } from "./cache/effectiveBalanceIncrements.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,iCAAiC,EAAE,yBAAyB,EAAC,MAAM,sCAAsC,CAAC;AAClH,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAC,2BAA2B,EAAC,MAAM,wCAAwC,CAAC;AAEnF,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAE/E,OAAO,EAAC,oBAAoB,EAAC,MAAM,iCAAiC,CAAC;AAErE,OAAO,EAAC,sBAAsB,EAAC,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,KAAK,0BAA0B,EAC/B,oCAAoC,EACpC,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,KAAK,uBAAuB,EAC5B,kCAAkC,GACnC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAC,KAAK,oBAAoB,EAAE,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AAE9F,OAAO,EAAC,KAAK,iBAAiB,EAAC,MAAM,wBAAwB,CAAC;AAE9D,OAAO,EACL,KAAK,gBAAgB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,6BAA6B,EAC7B,+BAA+B,EAC/B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,YAAY,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAC,KAAK,4BAA4B,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC;AAC3E,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EAEf,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,2BAA2B,EAC3B,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,YAAY,CAAC;AACpB,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,iCAAiC,EAAE,yBAAyB,EAAC,MAAM,sCAAsC,CAAC;AAClH,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAC,2BAA2B,EAAC,MAAM,wCAAwC,CAAC;AAEnF,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAE/E,OAAO,EAAC,qBAAqB,EAAE,wBAAwB,EAAE,oBAAoB,EAAC,MAAM,iCAAiC,CAAC;AAEtH,OAAO,EAAC,sBAAsB,EAAC,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,KAAK,0BAA0B,EAC/B,oCAAoC,EACpC,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,KAAK,uBAAuB,EAC5B,kCAAkC,GACnC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAC,KAAK,oBAAoB,EAAE,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AAE9F,OAAO,EAAC,KAAK,iBAAiB,EAAC,MAAM,wBAAwB,CAAC;AAE9D,OAAO,EACL,KAAK,gBAAgB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,6BAA6B,EAC7B,+BAA+B,EAC/B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,YAAY,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAC,KAAK,4BAA4B,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC;AAC3E,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EAEf,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,2BAA2B,EAC3B,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,YAAY,CAAC;AACpB,cAAc,iBAAiB,CAAC"}
package/lib/index.js CHANGED
@@ -6,7 +6,7 @@ export { isValidBlsToExecutionChange } from "./block/processBlsToExecutionChange
6
6
  export { becomesNewEth1Data } from "./block/processEth1Data.js";
7
7
  export { assertValidProposerSlashing } from "./block/processProposerSlashing.js";
8
8
  // BeaconChain validation
9
- export { isValidVoluntaryExit } from "./block/processVoluntaryExit.js";
9
+ export { VoluntaryExitValidity, getVoluntaryExitValidity, isValidVoluntaryExit } from "./block/processVoluntaryExit.js";
10
10
  // Withdrawals for new blocks
11
11
  export { getExpectedWithdrawals } from "./block/processWithdrawals.js";
12
12
  export { ProposerRewardType } from "./block/types.js";
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,iCAAiC,EAAE,yBAAyB,EAAC,MAAM,sCAAsC,CAAC;AAClH,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAC,2BAA2B,EAAC,MAAM,wCAAwC,CAAC;AACnF,qCAAqC;AACrC,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAC/E,yBAAyB;AACzB,OAAO,EAAC,oBAAoB,EAAC,MAAM,iCAAiC,CAAC;AACrE,6BAA6B;AAC7B,OAAO,EAAC,sBAAsB,EAAC,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAEL,oCAAoC,EACpC,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,eAAe,EACf,mBAAmB,EAEnB,kCAAkC,GACnC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAA4B,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AAG9F,oBAAoB;AACpB,OAAO,EAEL,uBAAuB,EACvB,mBAAmB,EACnB,6BAA6B,EAC7B,+BAA+B,EAC/B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AAErC,OAAO,EAAoC,UAAU,EAAC,MAAM,cAAc,CAAC;AAC3E,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AAsBrC,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,iCAAiC,EAAE,yBAAyB,EAAC,MAAM,sCAAsC,CAAC;AAClH,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAC,2BAA2B,EAAC,MAAM,wCAAwC,CAAC;AACnF,qCAAqC;AACrC,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAC/E,yBAAyB;AACzB,OAAO,EAAC,qBAAqB,EAAE,wBAAwB,EAAE,oBAAoB,EAAC,MAAM,iCAAiC,CAAC;AACtH,6BAA6B;AAC7B,OAAO,EAAC,sBAAsB,EAAC,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAEL,oCAAoC,EACpC,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,eAAe,EACf,mBAAmB,EAEnB,kCAAkC,GACnC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAA4B,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AAG9F,oBAAoB;AACpB,OAAO,EAEL,uBAAuB,EACvB,mBAAmB,EACnB,6BAA6B,EAC7B,+BAA+B,EAC/B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AAErC,OAAO,EAAoC,UAAU,EAAC,MAAM,cAAc,CAAC;AAC3E,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AAsBrC,cAAc,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -11,35 +11,30 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/ChainSafe/lodestar/issues"
13
13
  },
14
- "version": "1.36.0-dev.793f92c091",
14
+ "version": "1.36.0-dev.a0d00ac6dc",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
18
18
  "bun": "./src/index.ts",
19
+ "types": "./lib/index.d.ts",
19
20
  "import": "./lib/index.js"
20
21
  },
21
22
  "./block": {
22
23
  "bun": "./src/block/index.ts",
24
+ "types": "./lib/block/index.d.ts",
23
25
  "import": "./lib/block/index.js"
24
26
  },
25
27
  "./epoch": {
26
28
  "bun": "./src/epoch/index.ts",
29
+ "types": "./lib/epoch/index.d.ts",
27
30
  "import": "./lib/epoch/index.js"
28
31
  },
29
32
  "./slot": {
30
33
  "bun": "./src/slot/index.ts",
34
+ "types": "./lib/slot/index.d.ts",
31
35
  "import": "./lib/slot/index.js"
32
36
  }
33
37
  },
34
- "typesVersions": {
35
- "*": {
36
- "*": [
37
- "*",
38
- "lib/*",
39
- "lib/*/index"
40
- ]
41
- }
42
- },
43
38
  "files": [
44
39
  "src",
45
40
  "lib",
@@ -67,10 +62,10 @@
67
62
  "@chainsafe/pubkey-index-map": "^3.0.0",
68
63
  "@chainsafe/ssz": "^1.2.2",
69
64
  "@chainsafe/swap-or-not-shuffle": "^1.2.1",
70
- "@lodestar/config": "1.36.0-dev.793f92c091",
71
- "@lodestar/params": "1.36.0-dev.793f92c091",
72
- "@lodestar/types": "1.36.0-dev.793f92c091",
73
- "@lodestar/utils": "1.36.0-dev.793f92c091",
65
+ "@lodestar/config": "1.36.0-dev.a0d00ac6dc",
66
+ "@lodestar/params": "1.36.0-dev.a0d00ac6dc",
67
+ "@lodestar/types": "1.36.0-dev.a0d00ac6dc",
68
+ "@lodestar/utils": "1.36.0-dev.a0d00ac6dc",
74
69
  "bigint-buffer": "^1.1.5"
75
70
  },
76
71
  "keywords": [
@@ -79,5 +74,5 @@
79
74
  "beacon",
80
75
  "blockchain"
81
76
  ],
82
- "gitHead": "77b9473f42e62290ea090af8b4e3cbd9eb7084b3"
77
+ "gitHead": "73afcce1f8e8e9b2b602e7a40f2aa6869d91ef0c"
83
78
  }
@@ -5,6 +5,16 @@ import {CachedBeaconStateAllForks, CachedBeaconStateElectra} from "../types.js";
5
5
  import {getPendingBalanceToWithdraw, isActiveValidator} from "../util/index.js";
6
6
  import {initiateValidatorExit} from "./index.js";
7
7
 
8
+ export enum VoluntaryExitValidity {
9
+ valid = "valid",
10
+ inactive = "inactive",
11
+ alreadyExited = "already_exited",
12
+ earlyEpoch = "early_epoch",
13
+ shortTimeActive = "short_time_active",
14
+ pendingWithdrawals = "pending_withdrawals",
15
+ invalidSignature = "invalid_signature",
16
+ }
17
+
8
18
  /**
9
19
  * Process a VoluntaryExit operation. Initiates the exit of a validator.
10
20
  *
@@ -16,40 +26,66 @@ export function processVoluntaryExit(
16
26
  signedVoluntaryExit: phase0.SignedVoluntaryExit,
17
27
  verifySignature = true
18
28
  ): void {
19
- if (!isValidVoluntaryExit(fork, state, signedVoluntaryExit, verifySignature)) {
20
- throw Error(`Invalid voluntary exit at forkSeq=${fork}`);
29
+ const validity = getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature);
30
+ if (validity !== VoluntaryExitValidity.valid) {
31
+ throw Error(`Invalid voluntary exit at forkSeq=${fork} reason=${validity}`);
21
32
  }
22
33
 
23
34
  const validator = state.validators.get(signedVoluntaryExit.message.validatorIndex);
24
35
  initiateValidatorExit(fork, state, validator);
25
36
  }
26
37
 
27
- export function isValidVoluntaryExit(
38
+ export function getVoluntaryExitValidity(
28
39
  fork: ForkSeq,
29
40
  state: CachedBeaconStateAllForks,
30
41
  signedVoluntaryExit: phase0.SignedVoluntaryExit,
31
42
  verifySignature = true
32
- ): boolean {
43
+ ): VoluntaryExitValidity {
33
44
  const {config, epochCtx} = state;
34
45
  const voluntaryExit = signedVoluntaryExit.message;
35
46
  const validator = state.validators.get(voluntaryExit.validatorIndex);
36
47
  const currentEpoch = epochCtx.epoch;
37
48
 
38
- return (
39
- // verify the validator is active
40
- isActiveValidator(validator, currentEpoch) &&
41
- // verify exit has not been initiated
42
- validator.exitEpoch === FAR_FUTURE_EPOCH &&
43
- // exits must specify an epoch when they become valid; they are not valid before then
44
- currentEpoch >= voluntaryExit.epoch &&
45
- // verify the validator had been active long enough
46
- currentEpoch >= validator.activationEpoch + config.SHARD_COMMITTEE_PERIOD &&
47
- (fork >= ForkSeq.electra
48
- ? // only exit validator if it has no pending withdrawals in the queue
49
- getPendingBalanceToWithdraw(state as CachedBeaconStateElectra, voluntaryExit.validatorIndex) === 0
50
- : // there are no pending withdrawals in previous forks
51
- true) &&
52
- // verify signature
53
- (!verifySignature || verifyVoluntaryExitSignature(state, signedVoluntaryExit))
54
- );
49
+ // verify the validator is active
50
+ if (!isActiveValidator(validator, currentEpoch)) {
51
+ return VoluntaryExitValidity.inactive;
52
+ }
53
+
54
+ // verify exit has not been initiated
55
+ if (validator.exitEpoch !== FAR_FUTURE_EPOCH) {
56
+ return VoluntaryExitValidity.alreadyExited;
57
+ }
58
+
59
+ // exits must specify an epoch when they become valid; they are not valid before then
60
+ if (currentEpoch < voluntaryExit.epoch) {
61
+ return VoluntaryExitValidity.earlyEpoch;
62
+ }
63
+
64
+ // verify the validator had been active long enough
65
+ if (currentEpoch < validator.activationEpoch + config.SHARD_COMMITTEE_PERIOD) {
66
+ return VoluntaryExitValidity.shortTimeActive;
67
+ }
68
+
69
+ // only exit validator if it has no pending withdrawals in the queue
70
+ if (
71
+ fork >= ForkSeq.electra &&
72
+ getPendingBalanceToWithdraw(state as CachedBeaconStateElectra, voluntaryExit.validatorIndex) !== 0
73
+ ) {
74
+ return VoluntaryExitValidity.pendingWithdrawals;
75
+ }
76
+
77
+ if (verifySignature && !verifyVoluntaryExitSignature(state, signedVoluntaryExit)) {
78
+ return VoluntaryExitValidity.invalidSignature;
79
+ }
80
+
81
+ return VoluntaryExitValidity.valid;
82
+ }
83
+
84
+ export function isValidVoluntaryExit(
85
+ fork: ForkSeq,
86
+ state: CachedBeaconStateAllForks,
87
+ signedVoluntaryExit: phase0.SignedVoluntaryExit,
88
+ verifySignature = true
89
+ ): boolean {
90
+ return getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature) === VoluntaryExitValidity.valid;
55
91
  }
package/src/index.ts CHANGED
@@ -10,7 +10,7 @@ export {isValidBlsToExecutionChange} from "./block/processBlsToExecutionChange.j
10
10
  export {becomesNewEth1Data} from "./block/processEth1Data.js";
11
11
  export {assertValidProposerSlashing} from "./block/processProposerSlashing.js";
12
12
  // BeaconChain validation
13
- export {isValidVoluntaryExit} from "./block/processVoluntaryExit.js";
13
+ export {VoluntaryExitValidity, getVoluntaryExitValidity, isValidVoluntaryExit} from "./block/processVoluntaryExit.js";
14
14
  // Withdrawals for new blocks
15
15
  export {getExpectedWithdrawals} from "./block/processWithdrawals.js";
16
16
  export {ProposerRewardType} from "./block/types.js";