@lodestar/state-transition 1.39.0-dev.95389042f8 → 1.39.0-dev.ad129ced66
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/isValidIndexedAttestation.d.ts +4 -5
- package/lib/block/isValidIndexedAttestation.d.ts.map +1 -1
- package/lib/block/isValidIndexedAttestation.js +9 -10
- package/lib/block/isValidIndexedAttestation.js.map +1 -1
- package/lib/block/processAttestationPhase0.d.ts.map +1 -1
- package/lib/block/processAttestationPhase0.js +1 -1
- package/lib/block/processAttestationPhase0.js.map +1 -1
- package/lib/block/processAttesterSlashing.d.ts +3 -2
- package/lib/block/processAttesterSlashing.d.ts.map +1 -1
- package/lib/block/processAttesterSlashing.js +3 -3
- package/lib/block/processAttesterSlashing.js.map +1 -1
- package/lib/block/processBlsToExecutionChange.d.ts +3 -1
- package/lib/block/processBlsToExecutionChange.d.ts.map +1 -1
- package/lib/block/processBlsToExecutionChange.js +7 -11
- package/lib/block/processBlsToExecutionChange.js.map +1 -1
- package/lib/block/processProposerSlashing.d.ts +5 -2
- package/lib/block/processProposerSlashing.d.ts.map +1 -1
- package/lib/block/processProposerSlashing.js +7 -5
- package/lib/block/processProposerSlashing.js.map +1 -1
- package/lib/cache/epochCache.d.ts +6 -12
- package/lib/cache/epochCache.d.ts.map +1 -1
- package/lib/cache/epochCache.js +33 -105
- package/lib/cache/epochCache.js.map +1 -1
- package/lib/cache/epochTransitionCache.d.ts +5 -12
- package/lib/cache/epochTransitionCache.d.ts.map +1 -1
- package/lib/cache/epochTransitionCache.js +4 -14
- package/lib/cache/epochTransitionCache.js.map +1 -1
- package/lib/cache/stateCache.d.ts.map +1 -1
- package/lib/cache/stateCache.js +1 -2
- package/lib/cache/stateCache.js.map +1 -1
- package/lib/epoch/processProposerLookahead.d.ts.map +1 -1
- package/lib/epoch/processProposerLookahead.js +3 -6
- package/lib/epoch/processProposerLookahead.js.map +1 -1
- package/lib/rewards/blockRewards.d.ts +2 -1
- package/lib/rewards/blockRewards.d.ts.map +1 -1
- package/lib/rewards/blockRewards.js +3 -2
- package/lib/rewards/blockRewards.js.map +1 -1
- package/lib/rewards/syncCommitteeRewards.d.ts.map +1 -1
- package/lib/rewards/syncCommitteeRewards.js +10 -11
- package/lib/rewards/syncCommitteeRewards.js.map +1 -1
- package/lib/signatureSets/blsToExecutionChange.d.ts +1 -2
- package/lib/signatureSets/blsToExecutionChange.d.ts.map +1 -1
- package/lib/signatureSets/blsToExecutionChange.js +2 -2
- package/lib/signatureSets/blsToExecutionChange.js.map +1 -1
- package/lib/types.d.ts +1 -1
- package/lib/types.d.ts.map +1 -1
- package/lib/util/epochShuffling.d.ts +1 -34
- package/lib/util/epochShuffling.d.ts.map +1 -1
- package/lib/util/epochShuffling.js +1 -1
- package/lib/util/epochShuffling.js.map +1 -1
- package/package.json +7 -7
- package/src/block/isValidIndexedAttestation.ts +17 -12
- package/src/block/processAttestationPhase0.ts +2 -1
- package/src/block/processAttesterSlashing.ts +16 -4
- package/src/block/processBlsToExecutionChange.ts +13 -14
- package/src/block/processProposerSlashing.ts +21 -11
- package/src/cache/epochCache.ts +40 -118
- package/src/cache/epochTransitionCache.ts +9 -34
- package/src/cache/stateCache.ts +1 -2
- package/src/epoch/processProposerLookahead.ts +3 -7
- package/src/rewards/blockRewards.ts +6 -3
- package/src/rewards/syncCommitteeRewards.ts +10 -13
- package/src/signatureSets/blsToExecutionChange.ts +2 -3
- package/src/types.ts +1 -0
- package/src/util/epochShuffling.ts +2 -43
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncCommitteeRewards.d.ts","sourceRoot":"","sources":["../../src/rewards/syncCommitteeRewards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAC,WAAW,EAAE,cAAc,EAAU,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAC,yBAAyB,EAA0B,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"syncCommitteeRewards.d.ts","sourceRoot":"","sources":["../../src/rewards/syncCommitteeRewards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAC,WAAW,EAAE,cAAc,EAAU,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAC,yBAAyB,EAA0B,MAAM,wBAAwB,CAAC;AAE1F,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,iBAAiB,EAC/B,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,yBAAyB,EACnC,YAAY,GAAE,CAAC,cAAc,GAAG,MAAM,CAAC,EAAO,GAC7C,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CA2CvC"}
|
|
@@ -5,28 +5,27 @@ export async function computeSyncCommitteeRewards(config, index2pubkey, block, p
|
|
|
5
5
|
throw Error("Cannot get sync rewards as phase0 block does not have sync committee");
|
|
6
6
|
}
|
|
7
7
|
const altairBlock = block;
|
|
8
|
-
const preStateAltair = preState;
|
|
8
|
+
const preStateAltair = preState.clone();
|
|
9
9
|
// Bound syncCommitteeValidatorIndices in case it goes beyond SYNC_COMMITTEE_SIZE just to be safe
|
|
10
10
|
const syncCommitteeValidatorIndices = preStateAltair.epochCtx.currentSyncCommitteeIndexed.validatorIndices.slice(0, SYNC_COMMITTEE_SIZE);
|
|
11
11
|
const { syncParticipantReward } = preStateAltair.epochCtx;
|
|
12
12
|
const { syncCommitteeBits } = altairBlock.body.syncAggregate;
|
|
13
|
-
//
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const balanceRecord = balances.get(i);
|
|
13
|
+
// Track reward deltas per validator (can appear multiple times in sync committee)
|
|
14
|
+
const rewardDeltas = new Map();
|
|
15
|
+
// Iterate by position index to correctly access syncCommitteeBits
|
|
16
|
+
for (let i = 0; i < syncCommitteeValidatorIndices.length; i++) {
|
|
17
|
+
const validatorIndex = syncCommitteeValidatorIndices[i];
|
|
18
|
+
const currentDelta = rewardDeltas.get(validatorIndex) ?? 0;
|
|
20
19
|
if (syncCommitteeBits.get(i)) {
|
|
21
20
|
// Positive rewards for participants
|
|
22
|
-
|
|
21
|
+
rewardDeltas.set(validatorIndex, currentDelta + syncParticipantReward);
|
|
23
22
|
}
|
|
24
23
|
else {
|
|
25
24
|
// Negative rewards for non participants
|
|
26
|
-
|
|
25
|
+
rewardDeltas.set(validatorIndex, currentDelta - syncParticipantReward);
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
|
-
const rewards = Array.from(
|
|
28
|
+
const rewards = Array.from(rewardDeltas, ([validatorIndex, reward]) => ({ validatorIndex, reward }));
|
|
30
29
|
if (validatorIds.length) {
|
|
31
30
|
const filtersSet = new Set(validatorIds);
|
|
32
31
|
return rewards.filter((reward) => filtersSet.has(reward.validatorIndex) || filtersSet.has(index2pubkey[reward.validatorIndex].toHex()));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncCommitteeRewards.js","sourceRoot":"","sources":["../../src/rewards/syncCommitteeRewards.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAE,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"syncCommitteeRewards.js","sourceRoot":"","sources":["../../src/rewards/syncCommitteeRewards.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAE,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AAK/D,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,MAAoB,EACpB,YAA+B,EAC/B,KAAkB,EAClB,QAAmC,EACnC,eAA4C,EAAE;IAE9C,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,KAAK,CAAC,sEAAsE,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,WAAW,GAAG,KAA2B,CAAC;IAChD,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,EAA6B,CAAC;IAEnE,iGAAiG;IACjG,MAAM,6BAA6B,GAAG,cAAc,CAAC,QAAQ,CAAC,2BAA2B,CAAC,gBAAgB,CAAC,KAAK,CAC9G,CAAC,EACD,mBAAmB,CACpB,CAAC;IACF,MAAM,EAAC,qBAAqB,EAAC,GAAG,cAAc,CAAC,QAAQ,CAAC;IACxD,MAAM,EAAC,iBAAiB,EAAC,GAAG,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC;IAE3D,kFAAkF;IAClF,MAAM,YAAY,GAAgC,IAAI,GAAG,EAAE,CAAC;IAE5D,kEAAkE;IAClE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,6BAA6B,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9D,MAAM,cAAc,GAAG,6BAA6B,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,oCAAoC;YACpC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,GAAG,qBAAqB,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,wCAAwC;YACxC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,GAAG,qBAAqB,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,cAAc,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,EAAC,cAAc,EAAE,MAAM,EAAC,CAAC,CAAC,CAAC;IAEnG,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;QACzC,OAAO,OAAO,CAAC,MAAM,CACnB,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,KAAK,EAAE,CAAC,CACjH,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { BeaconConfig } from "@lodestar/config";
|
|
2
2
|
import { capella } from "@lodestar/types";
|
|
3
|
-
import { CachedBeaconStateAllForks } from "../types.js";
|
|
4
3
|
import { ISignatureSet } from "../util/index.js";
|
|
5
|
-
export declare function verifyBlsToExecutionChangeSignature(
|
|
4
|
+
export declare function verifyBlsToExecutionChangeSignature(config: BeaconConfig, signedBLSToExecutionChange: capella.SignedBLSToExecutionChange): boolean;
|
|
6
5
|
/**
|
|
7
6
|
* Extract signatures to allow validating all block signatures at once
|
|
8
7
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blsToExecutionChange.d.ts","sourceRoot":"","sources":["../../src/signatureSets/blsToExecutionChange.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAC,OAAO,EAAM,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"blsToExecutionChange.d.ts","sourceRoot":"","sources":["../../src/signatureSets/blsToExecutionChange.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAC,OAAO,EAAM,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAC,aAAa,EAA2D,MAAM,kBAAkB,CAAC;AAEzG,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,YAAY,EACpB,0BAA0B,EAAE,OAAO,CAAC,0BAA0B,GAC7D,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,YAAY,EACpB,0BAA0B,EAAE,OAAO,CAAC,0BAA0B,GAC7D,aAAa,CAaf;AAED,wBAAgB,oCAAoC,CAClD,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,OAAO,CAAC,iBAAiB,GACrC,aAAa,EAAE,CAIjB"}
|
|
@@ -2,8 +2,8 @@ import { PublicKey } from "@chainsafe/blst";
|
|
|
2
2
|
import { DOMAIN_BLS_TO_EXECUTION_CHANGE, ForkName } from "@lodestar/params";
|
|
3
3
|
import { ssz } from "@lodestar/types";
|
|
4
4
|
import { SignatureSetType, computeSigningRoot, verifySignatureSet } from "../util/index.js";
|
|
5
|
-
export function verifyBlsToExecutionChangeSignature(
|
|
6
|
-
return verifySignatureSet(getBlsToExecutionChangeSignatureSet(
|
|
5
|
+
export function verifyBlsToExecutionChangeSignature(config, signedBLSToExecutionChange) {
|
|
6
|
+
return verifySignatureSet(getBlsToExecutionChangeSignatureSet(config, signedBLSToExecutionChange));
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Extract signatures to allow validating all block signatures at once
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blsToExecutionChange.js","sourceRoot":"","sources":["../../src/signatureSets/blsToExecutionChange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EAAC,8BAA8B,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAU,GAAG,EAAC,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"blsToExecutionChange.js","sourceRoot":"","sources":["../../src/signatureSets/blsToExecutionChange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EAAC,8BAA8B,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAU,GAAG,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAgB,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AAEzG,MAAM,UAAU,mCAAmC,CACjD,MAAoB,EACpB,0BAA8D;IAE9D,OAAO,kBAAkB,CAAC,mCAAmC,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC,CAAC;AACrG,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mCAAmC,CACjD,MAAoB,EACpB,0BAA8D;IAE9D,4CAA4C;IAC5C,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,aAAa,EAAE,8BAA8B,CAAC,CAAC;IAErF,OAAO;QACL,IAAI,EAAE,gBAAgB,CAAC,MAAM;QAC7B,+FAA+F;QAC/F,yDAAyD;QACzD,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,0BAA0B,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC;QACnF,WAAW,EAAE,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,0BAA0B,CAAC,OAAO,EAAE,MAAM,CAAC;QAC7G,SAAS,EAAE,0BAA0B,CAAC,SAAS;KAChD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oCAAoC,CAClD,MAAoB,EACpB,WAAsC;IAEtC,OAAO,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,oBAAoB,EAAE,EAAE,CACjF,mCAAmC,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAClE,CAAC;AACJ,CAAC"}
|
package/lib/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { EpochCache } from "./cache/epochCache.js";
|
|
2
2
|
export type { EpochTransitionCache } from "./cache/epochTransitionCache.js";
|
|
3
3
|
export type { CachedBeaconStateAllForks, CachedBeaconStateAltair, CachedBeaconStateBellatrix, CachedBeaconStateCapella, CachedBeaconStateDeneb, CachedBeaconStateElectra, CachedBeaconStateExecutions, CachedBeaconStateFulu, CachedBeaconStateGloas, CachedBeaconStatePhase0, } from "./cache/stateCache.js";
|
|
4
|
-
export type { BeaconStateAllForks, BeaconStateAltair, BeaconStateBellatrix, BeaconStateCapella, BeaconStateDeneb, BeaconStateElectra, BeaconStateExecutions, BeaconStateFulu, BeaconStateGloas, BeaconStatePhase0, } from "./cache/types.js";
|
|
4
|
+
export type { BeaconStateAllForks, BeaconStateAltair, BeaconStateBellatrix, BeaconStateCapella, BeaconStateDeneb, BeaconStateElectra, BeaconStateExecutions, BeaconStateFulu, BeaconStateGloas, BeaconStatePhase0, ShufflingGetter, } from "./cache/types.js";
|
|
5
5
|
//# sourceMappingURL=types.d.ts.map
|
package/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AACjD,YAAY,EAAC,oBAAoB,EAAC,MAAM,iCAAiC,CAAC;AAC1E,YAAY,EACV,yBAAyB,EACzB,uBAAuB,EACvB,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,2BAA2B,EAC3B,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AACjD,YAAY,EAAC,oBAAoB,EAAC,MAAM,iCAAiC,CAAC;AAC1E,YAAY,EACV,yBAAyB,EACzB,uBAAuB,EACvB,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,2BAA2B,EAC3B,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,GAChB,MAAM,kBAAkB,CAAC"}
|
|
@@ -1,40 +1,6 @@
|
|
|
1
1
|
import { BeaconConfig } from "@lodestar/config";
|
|
2
2
|
import { Epoch, RootHex, ValidatorIndex } from "@lodestar/types";
|
|
3
|
-
import { GaugeExtra, Logger, NoLabels } from "@lodestar/utils";
|
|
4
3
|
import { BeaconStateAllForks } from "../types.js";
|
|
5
|
-
export interface ShufflingBuildProps {
|
|
6
|
-
state: BeaconStateAllForks;
|
|
7
|
-
activeIndices: Uint32Array;
|
|
8
|
-
}
|
|
9
|
-
export interface PublicShufflingCacheMetrics {
|
|
10
|
-
shufflingCache: {
|
|
11
|
-
nextShufflingNotOnEpochCache: GaugeExtra<NoLabels>;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
export interface IShufflingCache {
|
|
15
|
-
metrics: PublicShufflingCacheMetrics | null;
|
|
16
|
-
logger: Logger | null;
|
|
17
|
-
/**
|
|
18
|
-
* Gets a cached shuffling via the epoch and decision root. If the state and
|
|
19
|
-
* activeIndices are passed and a shuffling is not available it will be built
|
|
20
|
-
* synchronously. If the state is not passed and the shuffling is not available
|
|
21
|
-
* nothing will be returned.
|
|
22
|
-
*
|
|
23
|
-
* NOTE: If a shuffling is already queued and not calculated it will build and resolve
|
|
24
|
-
* the promise but the already queued build will happen at some later time
|
|
25
|
-
*/
|
|
26
|
-
getSync<T extends ShufflingBuildProps | undefined>(epoch: Epoch, decisionRoot: RootHex, buildProps?: T): T extends ShufflingBuildProps ? EpochShuffling : EpochShuffling | null;
|
|
27
|
-
/**
|
|
28
|
-
* Gets a cached shuffling via the epoch and decision root. Returns a promise
|
|
29
|
-
* for the shuffling if it hs not calculated yet. Returns null if a build has
|
|
30
|
-
* not been queued nor a shuffling was calculated.
|
|
31
|
-
*/
|
|
32
|
-
get(epoch: Epoch, decisionRoot: RootHex): Promise<EpochShuffling | null>;
|
|
33
|
-
/**
|
|
34
|
-
* Queue asynchronous build for an EpochShuffling
|
|
35
|
-
*/
|
|
36
|
-
build(epoch: Epoch, decisionRoot: RootHex, state: BeaconStateAllForks, activeIndices: Uint32Array): void;
|
|
37
|
-
}
|
|
38
4
|
/**
|
|
39
5
|
* Readonly interface for EpochShuffling.
|
|
40
6
|
*/
|
|
@@ -72,6 +38,7 @@ export type EpochShuffling = {
|
|
|
72
38
|
export declare function computeCommitteeCount(activeValidatorCount: number): number;
|
|
73
39
|
export declare function computeEpochShuffling(state: BeaconStateAllForks, activeIndices: Uint32Array, epoch: Epoch): EpochShuffling;
|
|
74
40
|
export declare function computeEpochShufflingAsync(state: BeaconStateAllForks, activeIndices: Uint32Array, epoch: Epoch): Promise<EpochShuffling>;
|
|
41
|
+
export declare function calculateDecisionRoot(state: BeaconStateAllForks, epoch: Epoch): RootHex;
|
|
75
42
|
/**
|
|
76
43
|
* Get the shuffling decision block root for the given epoch of given state
|
|
77
44
|
* - Special case close to genesis block, return the genesis block root
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epochShuffling.d.ts","sourceRoot":"","sources":["../../src/util/epochShuffling.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAS9C,OAAO,EAAC,KAAK,EAAE,OAAO,EAAE,cAAc,EAAM,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"epochShuffling.d.ts","sourceRoot":"","sources":["../../src/util/epochShuffling.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAS9C,OAAO,EAAC,KAAK,EAAE,OAAO,EAAE,cAAc,EAAM,MAAM,iBAAiB,CAAC;AAEpE,OAAO,EAAC,mBAAmB,EAAC,MAAM,aAAa,CAAC;AAMhD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC;IAEb;;OAEG;IACH,aAAa,EAAE,WAAW,CAAC;IAE3B;;OAEG;IACH,SAAS,EAAE,WAAW,CAAC;IAEvB;;;;;;;OAOG;IACH,UAAU,EAAE,WAAW,EAAE,EAAE,CAAC;IAE5B;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAI1E;AA2BD,wBAAgB,qBAAqB,CAEnC,KAAK,EAAE,mBAAmB,EAC1B,aAAa,EAAE,WAAW,EAC1B,KAAK,EAAE,KAAK,GACX,cAAc,CAWhB;AAED,wBAAsB,0BAA0B,CAE9C,KAAK,EAAE,mBAAmB,EAC1B,aAAa,EAAE,WAAW,EAC1B,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,cAAc,CAAC,CAWzB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAGvF;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,KAAK,GACX,OAAO,CAIT"}
|
|
@@ -59,7 +59,7 @@ state, activeIndices, epoch) {
|
|
|
59
59
|
committeesPerSlot: committees[0].length,
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
|
-
function calculateDecisionRoot(state, epoch) {
|
|
62
|
+
export function calculateDecisionRoot(state, epoch) {
|
|
63
63
|
const pivotSlot = computeStartSlotAtEpoch(epoch - 1) - 1;
|
|
64
64
|
return toRootHex(getBlockRootAtSlot(state, pivotSlot));
|
|
65
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epochShuffling.js","sourceRoot":"","sources":["../../src/util/epochShuffling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAE,aAAa,EAAC,MAAM,gCAAgC,CAAC;AAEjF,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EACf,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAiC,GAAG,EAAC,MAAM,iBAAiB,CAAC;AACpE,OAAO,
|
|
1
|
+
{"version":3,"file":"epochShuffling.js","sourceRoot":"","sources":["../../src/util/epochShuffling.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.39.0-dev.
|
|
14
|
+
"version": "1.39.0-dev.ad129ced66",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -62,14 +62,14 @@
|
|
|
62
62
|
"@chainsafe/pubkey-index-map": "^3.0.0",
|
|
63
63
|
"@chainsafe/ssz": "^1.2.2",
|
|
64
64
|
"@chainsafe/swap-or-not-shuffle": "^1.2.1",
|
|
65
|
-
"@lodestar/config": "^1.39.0-dev.
|
|
66
|
-
"@lodestar/params": "^1.39.0-dev.
|
|
67
|
-
"@lodestar/types": "^1.39.0-dev.
|
|
68
|
-
"@lodestar/utils": "^1.39.0-dev.
|
|
65
|
+
"@lodestar/config": "^1.39.0-dev.ad129ced66",
|
|
66
|
+
"@lodestar/params": "^1.39.0-dev.ad129ced66",
|
|
67
|
+
"@lodestar/types": "^1.39.0-dev.ad129ced66",
|
|
68
|
+
"@lodestar/utils": "^1.39.0-dev.ad129ced66",
|
|
69
69
|
"bigint-buffer": "^1.1.5"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@lodestar/api": "^1.39.0-dev.
|
|
72
|
+
"@lodestar/api": "^1.39.0-dev.ad129ced66"
|
|
73
73
|
},
|
|
74
74
|
"keywords": [
|
|
75
75
|
"ethereum",
|
|
@@ -77,5 +77,5 @@
|
|
|
77
77
|
"beacon",
|
|
78
78
|
"blockchain"
|
|
79
79
|
],
|
|
80
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "530782824aadb2d9875d1fa8cbae5428a131e117"
|
|
81
81
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
2
|
import {ForkSeq, MAX_COMMITTEES_PER_SLOT, MAX_VALIDATORS_PER_COMMITTEE} from "@lodestar/params";
|
|
3
|
-
import {IndexedAttestation, IndexedAttestationBigint} from "@lodestar/types";
|
|
3
|
+
import {IndexedAttestation, IndexedAttestationBigint, Slot} from "@lodestar/types";
|
|
4
4
|
import {Index2PubkeyCache} from "../cache/pubkeyCache.js";
|
|
5
5
|
import {getIndexedAttestationBigintSignatureSet, getIndexedAttestationSignatureSet} from "../signatureSets/index.js";
|
|
6
|
-
import {CachedBeaconStateAllForks} from "../types.js";
|
|
7
6
|
import {verifySignatureSet} from "../util/index.js";
|
|
8
7
|
|
|
9
8
|
/**
|
|
@@ -12,16 +11,17 @@ import {verifySignatureSet} from "../util/index.js";
|
|
|
12
11
|
export function isValidIndexedAttestation(
|
|
13
12
|
config: BeaconConfig,
|
|
14
13
|
index2pubkey: Index2PubkeyCache,
|
|
15
|
-
|
|
14
|
+
stateSlot: Slot,
|
|
15
|
+
validatorsLen: number,
|
|
16
16
|
indexedAttestation: IndexedAttestation,
|
|
17
17
|
verifySignature: boolean
|
|
18
18
|
): boolean {
|
|
19
|
-
if (!isValidIndexedAttestationIndices(
|
|
19
|
+
if (!isValidIndexedAttestationIndices(config, stateSlot, validatorsLen, indexedAttestation.attestingIndices)) {
|
|
20
20
|
return false;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
if (verifySignature) {
|
|
24
|
-
return verifySignatureSet(getIndexedAttestationSignatureSet(config, index2pubkey,
|
|
24
|
+
return verifySignatureSet(getIndexedAttestationSignatureSet(config, index2pubkey, stateSlot, indexedAttestation));
|
|
25
25
|
}
|
|
26
26
|
return true;
|
|
27
27
|
}
|
|
@@ -29,17 +29,18 @@ export function isValidIndexedAttestation(
|
|
|
29
29
|
export function isValidIndexedAttestationBigint(
|
|
30
30
|
config: BeaconConfig,
|
|
31
31
|
index2pubkey: Index2PubkeyCache,
|
|
32
|
-
|
|
32
|
+
stateSlot: Slot,
|
|
33
|
+
validatorsLen: number,
|
|
33
34
|
indexedAttestation: IndexedAttestationBigint,
|
|
34
35
|
verifySignature: boolean
|
|
35
36
|
): boolean {
|
|
36
|
-
if (!isValidIndexedAttestationIndices(
|
|
37
|
+
if (!isValidIndexedAttestationIndices(config, stateSlot, validatorsLen, indexedAttestation.attestingIndices)) {
|
|
37
38
|
return false;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
if (verifySignature) {
|
|
41
42
|
return verifySignatureSet(
|
|
42
|
-
getIndexedAttestationBigintSignatureSet(config, index2pubkey,
|
|
43
|
+
getIndexedAttestationBigintSignatureSet(config, index2pubkey, stateSlot, indexedAttestation)
|
|
43
44
|
);
|
|
44
45
|
}
|
|
45
46
|
return true;
|
|
@@ -48,10 +49,15 @@ export function isValidIndexedAttestationBigint(
|
|
|
48
49
|
/**
|
|
49
50
|
* Check if `indexedAttestation` has sorted and unique indices and a valid aggregate signature.
|
|
50
51
|
*/
|
|
51
|
-
export function isValidIndexedAttestationIndices(
|
|
52
|
+
export function isValidIndexedAttestationIndices(
|
|
53
|
+
config: BeaconConfig,
|
|
54
|
+
stateSlot: Slot,
|
|
55
|
+
validatorsLen: number,
|
|
56
|
+
indices: number[]
|
|
57
|
+
): boolean {
|
|
52
58
|
// verify max number of indices
|
|
53
59
|
const maxIndices =
|
|
54
|
-
|
|
60
|
+
config.getForkSeq(stateSlot) >= ForkSeq.electra
|
|
55
61
|
? MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT
|
|
56
62
|
: MAX_VALIDATORS_PER_COMMITTEE;
|
|
57
63
|
if (!(indices.length > 0 && indices.length <= maxIndices)) {
|
|
@@ -68,9 +74,8 @@ export function isValidIndexedAttestationIndices(state: CachedBeaconStateAllFork
|
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
// check if indices are out of bounds, by checking the highest index (since it is sorted)
|
|
71
|
-
// TODO - SLOW CODE - Does this .length check the tree and is expensive?
|
|
72
77
|
const lastIndex = indices.at(-1);
|
|
73
|
-
if (lastIndex && lastIndex >=
|
|
78
|
+
if (lastIndex && lastIndex >= validatorsLen) {
|
|
74
79
|
return false;
|
|
75
80
|
}
|
|
76
81
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
1
2
|
import {ForkSeq} from "@lodestar/params";
|
|
2
|
-
import {AttesterSlashing} from "@lodestar/types";
|
|
3
|
+
import {AttesterSlashing, Slot} from "@lodestar/types";
|
|
3
4
|
import {Index2PubkeyCache} from "../cache/pubkeyCache.js";
|
|
4
5
|
import {CachedBeaconStateAllForks} from "../types.js";
|
|
5
6
|
import {getAttesterSlashableIndices, isSlashableAttestationData, isSlashableValidator} from "../util/index.js";
|
|
@@ -19,7 +20,14 @@ export function processAttesterSlashing(
|
|
|
19
20
|
verifySignatures = true
|
|
20
21
|
): void {
|
|
21
22
|
const {epochCtx} = state;
|
|
22
|
-
assertValidAttesterSlashing(
|
|
23
|
+
assertValidAttesterSlashing(
|
|
24
|
+
state.config,
|
|
25
|
+
epochCtx.index2pubkey,
|
|
26
|
+
state.slot,
|
|
27
|
+
state.validators.length,
|
|
28
|
+
attesterSlashing,
|
|
29
|
+
verifySignatures
|
|
30
|
+
);
|
|
23
31
|
|
|
24
32
|
const intersectingIndices = getAttesterSlashableIndices(attesterSlashing);
|
|
25
33
|
|
|
@@ -39,8 +47,10 @@ export function processAttesterSlashing(
|
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
export function assertValidAttesterSlashing(
|
|
50
|
+
config: BeaconConfig,
|
|
42
51
|
index2pubkey: Index2PubkeyCache,
|
|
43
|
-
|
|
52
|
+
stateSlot: Slot,
|
|
53
|
+
validatorsLen: number,
|
|
44
54
|
attesterSlashing: AttesterSlashing,
|
|
45
55
|
verifySignatures = true
|
|
46
56
|
): void {
|
|
@@ -55,7 +65,9 @@ export function assertValidAttesterSlashing(
|
|
|
55
65
|
// be higher than the clock and the slashing would still be valid. Same applies to attestation data index, which
|
|
56
66
|
// can be any arbitrary value. Must use bigint variants to hash correctly to all possible values
|
|
57
67
|
for (const [i, attestation] of [attestation1, attestation2].entries()) {
|
|
58
|
-
if (
|
|
68
|
+
if (
|
|
69
|
+
!isValidIndexedAttestationBigint(config, index2pubkey, stateSlot, validatorsLen, attestation, verifySignatures)
|
|
70
|
+
) {
|
|
59
71
|
throw new Error(`AttesterSlashing attestation${i} is invalid`);
|
|
60
72
|
}
|
|
61
73
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {digest} from "@chainsafe/as-sha256";
|
|
2
2
|
import {byteArrayEquals} from "@chainsafe/ssz";
|
|
3
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
3
4
|
import {BLS_WITHDRAWAL_PREFIX, ETH1_ADDRESS_WITHDRAWAL_PREFIX} from "@lodestar/params";
|
|
4
5
|
import {capella} from "@lodestar/types";
|
|
6
|
+
import {Validator} from "@lodestar/types/phase0";
|
|
5
7
|
import {toHex} from "@lodestar/utils";
|
|
6
8
|
import {verifyBlsToExecutionChangeSignature} from "../signatureSets/index.js";
|
|
7
9
|
import {CachedBeaconStateCapella} from "../types.js";
|
|
@@ -12,12 +14,18 @@ export function processBlsToExecutionChange(
|
|
|
12
14
|
): void {
|
|
13
15
|
const addressChange = signedBlsToExecutionChange.message;
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
if (addressChange.validatorIndex >= state.validators.length) {
|
|
18
|
+
throw Error(
|
|
19
|
+
`withdrawalValidatorIndex ${addressChange.validatorIndex} >= state.validators len ${state.validators.length}`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const validator = state.validators.get(addressChange.validatorIndex);
|
|
24
|
+
const validation = isValidBlsToExecutionChange(state.config, validator, signedBlsToExecutionChange, true);
|
|
16
25
|
if (!validation.valid) {
|
|
17
26
|
throw validation.error;
|
|
18
27
|
}
|
|
19
28
|
|
|
20
|
-
const validator = state.validators.get(addressChange.validatorIndex);
|
|
21
29
|
const newWithdrawalCredentials = new Uint8Array(32);
|
|
22
30
|
newWithdrawalCredentials[0] = ETH1_ADDRESS_WITHDRAWAL_PREFIX;
|
|
23
31
|
newWithdrawalCredentials.set(addressChange.toExecutionAddress, 12);
|
|
@@ -27,22 +35,13 @@ export function processBlsToExecutionChange(
|
|
|
27
35
|
}
|
|
28
36
|
|
|
29
37
|
export function isValidBlsToExecutionChange(
|
|
30
|
-
|
|
38
|
+
config: BeaconConfig,
|
|
39
|
+
validator: Validator,
|
|
31
40
|
signedBLSToExecutionChange: capella.SignedBLSToExecutionChange,
|
|
32
41
|
verifySignature = true
|
|
33
42
|
): {valid: true} | {valid: false; error: Error} {
|
|
34
43
|
const addressChange = signedBLSToExecutionChange.message;
|
|
35
44
|
|
|
36
|
-
if (addressChange.validatorIndex >= state.validators.length) {
|
|
37
|
-
return {
|
|
38
|
-
valid: false,
|
|
39
|
-
error: Error(
|
|
40
|
-
`withdrawalValidatorIndex ${addressChange.validatorIndex} > state.validators len ${state.validators.length}`
|
|
41
|
-
),
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const validator = state.validators.getReadonly(addressChange.validatorIndex);
|
|
46
45
|
const {withdrawalCredentials} = validator;
|
|
47
46
|
if (withdrawalCredentials[0] !== BLS_WITHDRAWAL_PREFIX) {
|
|
48
47
|
return {
|
|
@@ -65,7 +64,7 @@ export function isValidBlsToExecutionChange(
|
|
|
65
64
|
};
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
if (verifySignature && !verifyBlsToExecutionChangeSignature(
|
|
67
|
+
if (verifySignature && !verifyBlsToExecutionChangeSignature(config, signedBLSToExecutionChange)) {
|
|
69
68
|
return {
|
|
70
69
|
valid: false,
|
|
71
70
|
error: Error(
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
1
2
|
import {ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
2
|
-
import {phase0, ssz} from "@lodestar/types";
|
|
3
|
+
import {Slot, phase0, ssz} from "@lodestar/types";
|
|
4
|
+
import {Validator} from "@lodestar/types/phase0";
|
|
5
|
+
import {Index2PubkeyCache} from "../cache/pubkeyCache.js";
|
|
3
6
|
import {getProposerSlashingSignatureSets} from "../signatureSets/index.js";
|
|
4
7
|
import {CachedBeaconStateAllForks, CachedBeaconStateGloas} from "../types.js";
|
|
5
8
|
import {computeEpochAtSlot, isSlashableValidator} from "../util/index.js";
|
|
@@ -18,7 +21,15 @@ export function processProposerSlashing(
|
|
|
18
21
|
proposerSlashing: phase0.ProposerSlashing,
|
|
19
22
|
verifySignatures = true
|
|
20
23
|
): void {
|
|
21
|
-
|
|
24
|
+
const proposer = state.validators.getReadonly(proposerSlashing.signedHeader1.message.proposerIndex);
|
|
25
|
+
assertValidProposerSlashing(
|
|
26
|
+
state.config,
|
|
27
|
+
state.epochCtx.index2pubkey,
|
|
28
|
+
state.slot,
|
|
29
|
+
proposerSlashing,
|
|
30
|
+
proposer,
|
|
31
|
+
verifySignatures
|
|
32
|
+
);
|
|
22
33
|
|
|
23
34
|
if (fork >= ForkSeq.gloas) {
|
|
24
35
|
const slot = Number(proposerSlashing.signedHeader1.message.slot);
|
|
@@ -45,8 +56,11 @@ export function processProposerSlashing(
|
|
|
45
56
|
}
|
|
46
57
|
|
|
47
58
|
export function assertValidProposerSlashing(
|
|
48
|
-
|
|
59
|
+
config: BeaconConfig,
|
|
60
|
+
index2pubkey: Index2PubkeyCache,
|
|
61
|
+
stateSlot: Slot,
|
|
49
62
|
proposerSlashing: phase0.ProposerSlashing,
|
|
63
|
+
proposer: Validator,
|
|
50
64
|
verifySignatures = true
|
|
51
65
|
): void {
|
|
52
66
|
const header1 = proposerSlashing.signedHeader1.message;
|
|
@@ -70,19 +84,15 @@ export function assertValidProposerSlashing(
|
|
|
70
84
|
}
|
|
71
85
|
|
|
72
86
|
// verify the proposer is slashable
|
|
73
|
-
|
|
74
|
-
|
|
87
|
+
// ideally we would get the proposer from state.validators using proposerIndex but that requires access to state
|
|
88
|
+
// instead of that we pass in the proposer directly from the consumer side
|
|
89
|
+
if (!isSlashableValidator(proposer, computeEpochAtSlot(stateSlot))) {
|
|
75
90
|
throw new Error("ProposerSlashing proposer is not slashable");
|
|
76
91
|
}
|
|
77
92
|
|
|
78
93
|
// verify signatures
|
|
79
94
|
if (verifySignatures) {
|
|
80
|
-
const signatureSets = getProposerSlashingSignatureSets(
|
|
81
|
-
state.config,
|
|
82
|
-
state.epochCtx.index2pubkey,
|
|
83
|
-
state.slot,
|
|
84
|
-
proposerSlashing
|
|
85
|
-
);
|
|
95
|
+
const signatureSets = getProposerSlashingSignatureSets(config, index2pubkey, stateSlot, proposerSlashing);
|
|
86
96
|
for (let i = 0; i < signatureSets.length; i++) {
|
|
87
97
|
if (!verifySignatureSet(signatureSets[i])) {
|
|
88
98
|
throw new Error(`ProposerSlashing header${i + 1} signature invalid`);
|