@lodestar/state-transition 1.40.0-dev.3be9500fa9 → 1.40.0-dev.45b04262dc
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/index.d.ts +1 -0
- package/lib/block/index.d.ts.map +1 -1
- package/lib/block/index.js +1 -0
- package/lib/block/index.js.map +1 -1
- package/lib/block/isValidIndexedAttestation.d.ts.map +1 -1
- package/lib/block/isValidIndexedAttestation.js +2 -2
- package/lib/block/isValidIndexedAttestation.js.map +1 -1
- package/lib/block/isValidIndexedPayloadAttestation.d.ts.map +1 -1
- package/lib/block/isValidIndexedPayloadAttestation.js +1 -1
- package/lib/block/isValidIndexedPayloadAttestation.js.map +1 -1
- package/lib/block/processAttestationsAltair.d.ts.map +1 -1
- package/lib/block/processAttestationsAltair.js +3 -4
- package/lib/block/processAttestationsAltair.js.map +1 -1
- package/lib/block/processBlockHeader.d.ts.map +1 -1
- package/lib/block/processBlockHeader.js +1 -2
- package/lib/block/processBlockHeader.js.map +1 -1
- package/lib/block/processBlsToExecutionChange.d.ts.map +1 -1
- package/lib/block/processBlsToExecutionChange.js +1 -2
- package/lib/block/processBlsToExecutionChange.js.map +1 -1
- package/lib/block/processConsolidationRequest.d.ts +1 -2
- package/lib/block/processConsolidationRequest.d.ts.map +1 -1
- package/lib/block/processConsolidationRequest.js +5 -4
- package/lib/block/processConsolidationRequest.js.map +1 -1
- package/lib/block/processDepositRequest.d.ts +8 -2
- package/lib/block/processDepositRequest.d.ts.map +1 -1
- package/lib/block/processDepositRequest.js +81 -8
- package/lib/block/processDepositRequest.js.map +1 -1
- package/lib/block/processExecutionPayload.d.ts.map +1 -1
- package/lib/block/processExecutionPayload.js +1 -2
- package/lib/block/processExecutionPayload.js.map +1 -1
- package/lib/block/processExecutionPayloadBid.d.ts.map +1 -1
- package/lib/block/processExecutionPayloadBid.js +17 -31
- package/lib/block/processExecutionPayloadBid.js.map +1 -1
- package/lib/block/processExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/block/processExecutionPayloadEnvelope.js +27 -27
- package/lib/block/processExecutionPayloadEnvelope.js.map +1 -1
- package/lib/block/processOperations.js +2 -2
- package/lib/block/processOperations.js.map +1 -1
- package/lib/block/processPayloadAttestation.d.ts.map +1 -1
- package/lib/block/processPayloadAttestation.js +1 -1
- package/lib/block/processPayloadAttestation.js.map +1 -1
- package/lib/block/processProposerSlashing.js +2 -2
- package/lib/block/processProposerSlashing.js.map +1 -1
- package/lib/block/processSyncCommittee.d.ts +1 -2
- package/lib/block/processSyncCommittee.d.ts.map +1 -1
- package/lib/block/processSyncCommittee.js +6 -6
- package/lib/block/processSyncCommittee.js.map +1 -1
- package/lib/block/processVoluntaryExit.d.ts +1 -1
- package/lib/block/processVoluntaryExit.d.ts.map +1 -1
- package/lib/block/processVoluntaryExit.js +45 -3
- package/lib/block/processVoluntaryExit.js.map +1 -1
- package/lib/block/processWithdrawalRequest.js +1 -1
- package/lib/block/processWithdrawalRequest.js.map +1 -1
- package/lib/block/processWithdrawals.d.ts +1 -0
- package/lib/block/processWithdrawals.d.ts.map +1 -1
- package/lib/block/processWithdrawals.js +122 -68
- package/lib/block/processWithdrawals.js.map +1 -1
- package/lib/epoch/processBuilderPendingPayments.d.ts.map +1 -1
- package/lib/epoch/processBuilderPendingPayments.js +1 -4
- package/lib/epoch/processBuilderPendingPayments.js.map +1 -1
- package/lib/epoch/processPendingAttestations.d.ts.map +1 -1
- package/lib/epoch/processPendingAttestations.js +1 -1
- package/lib/epoch/processPendingAttestations.js.map +1 -1
- package/lib/signatureSets/attesterSlashings.d.ts +3 -4
- package/lib/signatureSets/attesterSlashings.d.ts.map +1 -1
- package/lib/signatureSets/attesterSlashings.js +6 -6
- package/lib/signatureSets/attesterSlashings.js.map +1 -1
- package/lib/signatureSets/blsToExecutionChange.d.ts +3 -3
- package/lib/signatureSets/blsToExecutionChange.d.ts.map +1 -1
- package/lib/signatureSets/blsToExecutionChange.js.map +1 -1
- package/lib/signatureSets/executionPayloadBid.d.ts +4 -0
- package/lib/signatureSets/executionPayloadBid.d.ts.map +1 -0
- package/lib/signatureSets/executionPayloadBid.js +8 -0
- package/lib/signatureSets/executionPayloadBid.js.map +1 -0
- package/lib/signatureSets/executionPayloadEnvelope.d.ts +4 -0
- package/lib/signatureSets/executionPayloadEnvelope.d.ts.map +1 -0
- package/lib/signatureSets/executionPayloadEnvelope.js +8 -0
- package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -0
- package/lib/signatureSets/index.d.ts +3 -2
- package/lib/signatureSets/index.d.ts.map +1 -1
- package/lib/signatureSets/index.js +10 -8
- package/lib/signatureSets/index.js.map +1 -1
- package/lib/signatureSets/indexedAttestation.d.ts +3 -4
- package/lib/signatureSets/indexedAttestation.d.ts.map +1 -1
- package/lib/signatureSets/indexedAttestation.js +6 -6
- package/lib/signatureSets/indexedAttestation.js.map +1 -1
- package/lib/signatureSets/indexedPayloadAttestation.d.ts +5 -4
- package/lib/signatureSets/indexedPayloadAttestation.d.ts.map +1 -1
- package/lib/signatureSets/indexedPayloadAttestation.js +3 -3
- package/lib/signatureSets/indexedPayloadAttestation.js.map +1 -1
- package/lib/signatureSets/proposer.d.ts +3 -3
- package/lib/signatureSets/proposer.d.ts.map +1 -1
- package/lib/signatureSets/proposer.js +12 -12
- package/lib/signatureSets/proposer.js.map +1 -1
- package/lib/signatureSets/proposerSlashings.d.ts +2 -3
- package/lib/signatureSets/proposerSlashings.d.ts.map +1 -1
- package/lib/signatureSets/proposerSlashings.js +6 -6
- package/lib/signatureSets/proposerSlashings.js.map +1 -1
- package/lib/signatureSets/randao.d.ts +1 -1
- package/lib/signatureSets/randao.d.ts.map +1 -1
- package/lib/signatureSets/randao.js +4 -4
- package/lib/signatureSets/randao.js.map +1 -1
- package/lib/signatureSets/voluntaryExits.d.ts +2 -2
- package/lib/signatureSets/voluntaryExits.d.ts.map +1 -1
- package/lib/signatureSets/voluntaryExits.js +6 -6
- package/lib/signatureSets/voluntaryExits.js.map +1 -1
- package/lib/slot/index.d.ts.map +1 -1
- package/lib/slot/index.js +1 -1
- package/lib/slot/index.js.map +1 -1
- package/lib/util/electra.d.ts.map +1 -1
- package/lib/util/electra.js +1 -2
- package/lib/util/electra.js.map +1 -1
- package/lib/util/gloas.d.ts +46 -5
- package/lib/util/gloas.d.ts.map +1 -1
- package/lib/util/gloas.js +92 -6
- package/lib/util/gloas.js.map +1 -1
- package/lib/util/index.d.ts +1 -0
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +1 -0
- package/lib/util/index.js.map +1 -1
- package/lib/util/interop.js +1 -1
- package/lib/util/interop.js.map +1 -1
- package/lib/util/loadState/findModifiedInactivityScores.d.ts +1 -1
- package/lib/util/loadState/findModifiedInactivityScores.d.ts.map +1 -1
- package/lib/util/loadState/findModifiedInactivityScores.js +3 -2
- package/lib/util/loadState/findModifiedInactivityScores.js.map +1 -1
- package/lib/util/loadState/findModifiedValidators.d.ts +2 -2
- package/lib/util/loadState/findModifiedValidators.d.ts.map +1 -1
- package/lib/util/loadState/findModifiedValidators.js +4 -3
- package/lib/util/loadState/findModifiedValidators.js.map +1 -1
- package/lib/util/loadState/loadValidator.d.ts.map +1 -1
- package/lib/util/loadState/loadValidator.js +3 -2
- package/lib/util/loadState/loadValidator.js.map +1 -1
- package/lib/util/signatureSets.d.ts +38 -5
- package/lib/util/signatureSets.d.ts.map +1 -1
- package/lib/util/signatureSets.js +48 -6
- package/lib/util/signatureSets.js.map +1 -1
- package/lib/util/validator.d.ts +6 -1
- package/lib/util/validator.d.ts.map +1 -1
- package/lib/util/validator.js +26 -16
- package/lib/util/validator.js.map +1 -1
- package/package.json +8 -8
- package/src/block/index.ts +1 -0
- package/src/block/isValidIndexedAttestation.ts +3 -2
- package/src/block/isValidIndexedPayloadAttestation.ts +4 -1
- package/src/block/processAttestationsAltair.ts +3 -10
- package/src/block/processBlockHeader.ts +1 -2
- package/src/block/processBlsToExecutionChange.ts +1 -2
- package/src/block/processConsolidationRequest.ts +5 -5
- package/src/block/processDepositRequest.ts +101 -8
- package/src/block/processExecutionPayload.ts +1 -2
- package/src/block/processExecutionPayloadBid.ts +21 -44
- package/src/block/processExecutionPayloadEnvelope.ts +35 -32
- package/src/block/processOperations.ts +2 -2
- package/src/block/processPayloadAttestation.ts +1 -1
- package/src/block/processProposerSlashing.ts +2 -2
- package/src/block/processSyncCommittee.ts +4 -7
- package/src/block/processVoluntaryExit.ts +60 -5
- package/src/block/processWithdrawalRequest.ts +1 -1
- package/src/block/processWithdrawals.ts +169 -72
- package/src/epoch/processBuilderPendingPayments.ts +1 -5
- package/src/epoch/processPendingAttestations.ts +1 -1
- package/src/signatureSets/attesterSlashings.ts +3 -7
- package/src/signatureSets/blsToExecutionChange.ts +3 -3
- package/src/signatureSets/executionPayloadBid.ts +14 -0
- package/src/signatureSets/executionPayloadEnvelope.ts +13 -0
- package/src/signatureSets/index.ts +8 -9
- package/src/signatureSets/indexedAttestation.ts +2 -7
- package/src/signatureSets/indexedPayloadAttestation.ts +9 -7
- package/src/signatureSets/proposer.ts +8 -12
- package/src/signatureSets/proposerSlashings.ts +4 -7
- package/src/signatureSets/randao.ts +4 -8
- package/src/signatureSets/voluntaryExits.ts +5 -10
- package/src/slot/index.ts +1 -1
- package/src/util/electra.ts +1 -4
- package/src/util/gloas.ts +117 -11
- package/src/util/index.ts +1 -0
- package/src/util/interop.ts +1 -1
- package/src/util/loadState/findModifiedInactivityScores.ts +4 -2
- package/src/util/loadState/findModifiedValidators.ts +4 -3
- package/src/util/loadState/loadValidator.ts +3 -2
- package/src/util/signatureSets.ts +84 -8
- package/src/util/validator.ts +31 -16
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import {PublicKey, Signature, verify} from "@chainsafe/blst";
|
|
1
2
|
import {FAR_FUTURE_EPOCH, ForkSeq} from "@lodestar/params";
|
|
2
|
-
import {phase0} from "@lodestar/types";
|
|
3
|
+
import {phase0, ssz} from "@lodestar/types";
|
|
3
4
|
import {verifyVoluntaryExitSignature} from "../signatureSets/index.js";
|
|
4
|
-
import {CachedBeaconStateAllForks, CachedBeaconStateElectra} from "../types.js";
|
|
5
|
-
import {
|
|
5
|
+
import {CachedBeaconStateAllForks, CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
|
|
6
|
+
import {
|
|
7
|
+
convertValidatorIndexToBuilderIndex,
|
|
8
|
+
getPendingBalanceToWithdrawForBuilder,
|
|
9
|
+
initiateBuilderExit,
|
|
10
|
+
isActiveBuilder,
|
|
11
|
+
isBuilderIndex,
|
|
12
|
+
} from "../util/gloas.js";
|
|
13
|
+
import {computeSigningRoot, getCurrentEpoch, getPendingBalanceToWithdraw, isActiveValidator} from "../util/index.js";
|
|
6
14
|
import {initiateValidatorExit} from "./index.js";
|
|
7
15
|
|
|
8
16
|
export enum VoluntaryExitValidity {
|
|
@@ -16,7 +24,7 @@ export enum VoluntaryExitValidity {
|
|
|
16
24
|
}
|
|
17
25
|
|
|
18
26
|
/**
|
|
19
|
-
* Process a VoluntaryExit operation. Initiates the exit of a validator.
|
|
27
|
+
* Process a VoluntaryExit operation. Initiates the exit of a validator or builder.
|
|
20
28
|
*
|
|
21
29
|
* PERF: Work depends on number of VoluntaryExit per block. On regular networks the average is 0 / block.
|
|
22
30
|
*/
|
|
@@ -26,6 +34,53 @@ export function processVoluntaryExit(
|
|
|
26
34
|
signedVoluntaryExit: phase0.SignedVoluntaryExit,
|
|
27
35
|
verifySignature = true
|
|
28
36
|
): void {
|
|
37
|
+
const voluntaryExit = signedVoluntaryExit.message;
|
|
38
|
+
const currentEpoch = getCurrentEpoch(state);
|
|
39
|
+
|
|
40
|
+
// Exits must specify an epoch when they become valid; they are not valid before then
|
|
41
|
+
if (currentEpoch < voluntaryExit.epoch) {
|
|
42
|
+
throw Error(`Voluntary exit epoch ${voluntaryExit.epoch} is after current epoch ${currentEpoch}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Check if this is a builder exit
|
|
46
|
+
if (fork >= ForkSeq.gloas && isBuilderIndex(voluntaryExit.validatorIndex)) {
|
|
47
|
+
const stateGloas = state as CachedBeaconStateGloas;
|
|
48
|
+
const builderIndex = convertValidatorIndexToBuilderIndex(voluntaryExit.validatorIndex);
|
|
49
|
+
const builder = stateGloas.builders.getReadonly(builderIndex);
|
|
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);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Handle validator exit
|
|
29
84
|
const validity = getVoluntaryExitValidity(fork, state, signedVoluntaryExit, verifySignature);
|
|
30
85
|
if (validity !== VoluntaryExitValidity.valid) {
|
|
31
86
|
throw Error(`Invalid voluntary exit at forkSeq=${fork} reason=${validity}`);
|
|
@@ -69,7 +124,7 @@ export function getVoluntaryExitValidity(
|
|
|
69
124
|
// only exit validator if it has no pending withdrawals in the queue
|
|
70
125
|
if (
|
|
71
126
|
fork >= ForkSeq.electra &&
|
|
72
|
-
getPendingBalanceToWithdraw(
|
|
127
|
+
getPendingBalanceToWithdraw(state as CachedBeaconStateElectra, voluntaryExit.validatorIndex) !== 0
|
|
73
128
|
) {
|
|
74
129
|
return VoluntaryExitValidity.pendingWithdrawals;
|
|
75
130
|
}
|
|
@@ -42,7 +42,7 @@ export function processWithdrawalRequest(
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// TODO Electra: Consider caching pendingPartialWithdrawals
|
|
45
|
-
const pendingBalanceToWithdraw = getPendingBalanceToWithdraw(
|
|
45
|
+
const pendingBalanceToWithdraw = getPendingBalanceToWithdraw(state, validatorIndex);
|
|
46
46
|
const validatorBalance = state.balances.get(validatorIndex);
|
|
47
47
|
|
|
48
48
|
if (isFullExitRequest) {
|
|
@@ -1,23 +1,29 @@
|
|
|
1
|
-
import {byteArrayEquals} from "@chainsafe/ssz";
|
|
2
1
|
import {
|
|
3
2
|
FAR_FUTURE_EPOCH,
|
|
4
3
|
ForkSeq,
|
|
4
|
+
MAX_BUILDERS_PER_WITHDRAWALS_SWEEP,
|
|
5
5
|
MAX_EFFECTIVE_BALANCE,
|
|
6
6
|
MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP,
|
|
7
7
|
MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP,
|
|
8
8
|
MAX_WITHDRAWALS_PER_PAYLOAD,
|
|
9
9
|
MIN_ACTIVATION_BALANCE,
|
|
10
10
|
} from "@lodestar/params";
|
|
11
|
-
import {ValidatorIndex, capella, ssz} from "@lodestar/types";
|
|
12
|
-
import {toRootHex} from "@lodestar/utils";
|
|
11
|
+
import {BuilderIndex, ValidatorIndex, capella, ssz} from "@lodestar/types";
|
|
12
|
+
import {byteArrayEquals, toRootHex} from "@lodestar/utils";
|
|
13
13
|
import {CachedBeaconStateCapella, CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
convertBuilderIndexToValidatorIndex,
|
|
16
|
+
convertValidatorIndexToBuilderIndex,
|
|
17
|
+
isBuilderIndex,
|
|
18
|
+
isParentBlockFull,
|
|
19
|
+
} from "../util/gloas.ts";
|
|
15
20
|
import {
|
|
16
21
|
decreaseBalance,
|
|
17
22
|
getMaxEffectiveBalance,
|
|
18
23
|
hasEth1WithdrawalCredential,
|
|
19
24
|
hasExecutionWithdrawalCredential,
|
|
20
25
|
isCapellaPayloadHeader,
|
|
26
|
+
isPartiallyWithdrawableValidator,
|
|
21
27
|
} from "../util/index.js";
|
|
22
28
|
|
|
23
29
|
export function processWithdrawals(
|
|
@@ -32,9 +38,14 @@ export function processWithdrawals(
|
|
|
32
38
|
|
|
33
39
|
// processedBuilderWithdrawalsCount is withdrawals coming from builder payment since gloas (EIP-7732)
|
|
34
40
|
// processedPartialWithdrawalsCount is withdrawals coming from EL since electra (EIP-7002)
|
|
41
|
+
// processedBuildersSweepCount is withdrawals from builder sweep since gloas (EIP-7732)
|
|
35
42
|
// processedValidatorSweepCount is withdrawals coming from validator sweep
|
|
36
|
-
const {
|
|
37
|
-
|
|
43
|
+
const {
|
|
44
|
+
expectedWithdrawals,
|
|
45
|
+
processedBuilderWithdrawalsCount,
|
|
46
|
+
processedPartialWithdrawalsCount,
|
|
47
|
+
processedBuildersSweepCount,
|
|
48
|
+
} = getExpectedWithdrawals(fork, state);
|
|
38
49
|
const numWithdrawals = expectedWithdrawals.length;
|
|
39
50
|
|
|
40
51
|
// After gloas, withdrawals are verified later in processExecutionPayloadEnvelope
|
|
@@ -78,20 +89,20 @@ export function processWithdrawals(
|
|
|
78
89
|
|
|
79
90
|
if (fork >= ForkSeq.gloas) {
|
|
80
91
|
const stateGloas = state as CachedBeaconStateGloas;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
stateGloas.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
|
|
93
|
+
// Store expected withdrawals for verification
|
|
94
|
+
stateGloas.payloadExpectedWithdrawals = ssz.capella.Withdrawals.toViewDU(expectedWithdrawals);
|
|
95
|
+
|
|
96
|
+
// Update builder pending withdrawals queue
|
|
97
|
+
stateGloas.builderPendingWithdrawals = stateGloas.builderPendingWithdrawals.sliceFrom(
|
|
98
|
+
processedBuilderWithdrawalsCount
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// Update next builder index for sweep
|
|
102
|
+
if (stateGloas.builders.length > 0) {
|
|
103
|
+
const nextIndex = stateGloas.nextWithdrawalBuilderIndex + processedBuildersSweepCount;
|
|
104
|
+
stateGloas.nextWithdrawalBuilderIndex = nextIndex % stateGloas.builders.length;
|
|
105
|
+
}
|
|
95
106
|
}
|
|
96
107
|
// Update the nextWithdrawalIndex
|
|
97
108
|
// https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.0/specs/capella/beacon-chain.md#new-update_next_withdrawal_index
|
|
@@ -116,10 +127,14 @@ export function processWithdrawals(
|
|
|
116
127
|
function getBuilderWithdrawals(
|
|
117
128
|
state: CachedBeaconStateGloas,
|
|
118
129
|
withdrawalIndex: number,
|
|
119
|
-
|
|
130
|
+
priorWithdrawals: capella.Withdrawal[],
|
|
131
|
+
builderBalanceAfterWithdrawals: Map<number, number>
|
|
120
132
|
): {builderWithdrawals: capella.Withdrawal[]; withdrawalIndex: number; processedCount: number} {
|
|
133
|
+
const withdrawalsLimit = MAX_WITHDRAWALS_PER_PAYLOAD - 1;
|
|
134
|
+
if (priorWithdrawals.length > withdrawalsLimit) {
|
|
135
|
+
throw Error(`Prior withdrawals exceed limit: ${priorWithdrawals.length} > ${withdrawalsLimit}`);
|
|
136
|
+
}
|
|
121
137
|
const builderWithdrawals: capella.Withdrawal[] = [];
|
|
122
|
-
const epoch = state.epochCtx.epoch;
|
|
123
138
|
const allBuilderPendingWithdrawals =
|
|
124
139
|
state.builderPendingWithdrawals.length <= MAX_WITHDRAWALS_PER_PAYLOAD
|
|
125
140
|
? state.builderPendingWithdrawals.getAllReadonly()
|
|
@@ -127,55 +142,103 @@ function getBuilderWithdrawals(
|
|
|
127
142
|
|
|
128
143
|
let processedCount = 0;
|
|
129
144
|
for (let i = 0; i < state.builderPendingWithdrawals.length; i++) {
|
|
145
|
+
// Check combined length against limit
|
|
146
|
+
const allWithdrawals = priorWithdrawals.length + builderWithdrawals.length;
|
|
147
|
+
if (allWithdrawals >= withdrawalsLimit) {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
|
|
130
151
|
const withdrawal = allBuilderPendingWithdrawals
|
|
131
152
|
? allBuilderPendingWithdrawals[i]
|
|
132
153
|
: state.builderPendingWithdrawals.getReadonly(i);
|
|
133
154
|
|
|
134
|
-
|
|
135
|
-
|
|
155
|
+
const builderIndex = withdrawal.builderIndex;
|
|
156
|
+
|
|
157
|
+
// Get builder balance (from builder.balance, not state.balances)
|
|
158
|
+
let balance = builderBalanceAfterWithdrawals.get(builderIndex);
|
|
159
|
+
if (balance === undefined) {
|
|
160
|
+
balance = state.builders.getReadonly(builderIndex).balance;
|
|
161
|
+
builderBalanceAfterWithdrawals.set(builderIndex, balance);
|
|
136
162
|
}
|
|
137
163
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
164
|
+
// Use the withdrawal amount directly as specified in the spec
|
|
165
|
+
builderWithdrawals.push({
|
|
166
|
+
index: withdrawalIndex,
|
|
167
|
+
validatorIndex: convertBuilderIndexToValidatorIndex(builderIndex),
|
|
168
|
+
address: withdrawal.feeRecipient,
|
|
169
|
+
amount: BigInt(withdrawal.amount),
|
|
170
|
+
});
|
|
171
|
+
withdrawalIndex++;
|
|
172
|
+
builderBalanceAfterWithdrawals.set(builderIndex, balance - withdrawal.amount);
|
|
141
173
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
balance = state.balances.get(builderIndex);
|
|
145
|
-
balanceAfterWithdrawals.set(builderIndex, balance);
|
|
146
|
-
}
|
|
174
|
+
processedCount++;
|
|
175
|
+
}
|
|
147
176
|
|
|
148
|
-
|
|
177
|
+
return {builderWithdrawals, withdrawalIndex, processedCount};
|
|
178
|
+
}
|
|
149
179
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
180
|
+
function getBuildersSweepWithdrawals(
|
|
181
|
+
state: CachedBeaconStateGloas,
|
|
182
|
+
withdrawalIndex: number,
|
|
183
|
+
numPriorWithdrawal: number,
|
|
184
|
+
builderBalanceAfterWithdrawals: Map<number, number>
|
|
185
|
+
): {buildersSweepWithdrawals: capella.Withdrawal[]; withdrawalIndex: number; processedCount: number} {
|
|
186
|
+
const withdrawalsLimit = MAX_WITHDRAWALS_PER_PAYLOAD - 1;
|
|
187
|
+
if (numPriorWithdrawal > withdrawalsLimit) {
|
|
188
|
+
throw Error(`Prior withdrawals exceed limit: ${numPriorWithdrawal} > ${withdrawalsLimit}`);
|
|
189
|
+
}
|
|
190
|
+
const buildersSweepWithdrawals: capella.Withdrawal[] = [];
|
|
191
|
+
const epoch = state.epochCtx.epoch;
|
|
192
|
+
const builders = state.builders;
|
|
156
193
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
194
|
+
// Return early if no builders
|
|
195
|
+
if (builders.length === 0) {
|
|
196
|
+
return {buildersSweepWithdrawals, withdrawalIndex, processedCount: 0};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const buildersLimit = Math.min(builders.length, MAX_BUILDERS_PER_WITHDRAWALS_SWEEP);
|
|
200
|
+
let processedCount = 0;
|
|
201
|
+
|
|
202
|
+
for (let n = 0; n < buildersLimit; n++) {
|
|
203
|
+
if (buildersSweepWithdrawals.length + numPriorWithdrawal >= withdrawalsLimit) {
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Get next builder in turn
|
|
208
|
+
const builderIndex = (state.nextWithdrawalBuilderIndex + n) % builders.length;
|
|
209
|
+
const builder = builders.getReadonly(builderIndex);
|
|
210
|
+
|
|
211
|
+
// Get builder balance
|
|
212
|
+
let balance = builderBalanceAfterWithdrawals.get(builderIndex);
|
|
213
|
+
if (balance === undefined) {
|
|
214
|
+
balance = builder.balance;
|
|
215
|
+
builderBalanceAfterWithdrawals.set(builderIndex, balance);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Check if builder is withdrawable and has balance
|
|
219
|
+
if (builder.withdrawableEpoch <= epoch && balance > 0) {
|
|
220
|
+
// Withdraw full balance to builder's execution address
|
|
221
|
+
buildersSweepWithdrawals.push({
|
|
222
|
+
index: withdrawalIndex,
|
|
223
|
+
validatorIndex: convertBuilderIndexToValidatorIndex(builderIndex),
|
|
224
|
+
address: builder.executionAddress,
|
|
225
|
+
amount: BigInt(balance),
|
|
226
|
+
});
|
|
227
|
+
withdrawalIndex++;
|
|
228
|
+
builderBalanceAfterWithdrawals.set(builderIndex, 0);
|
|
167
229
|
}
|
|
230
|
+
|
|
168
231
|
processedCount++;
|
|
169
232
|
}
|
|
170
233
|
|
|
171
|
-
return {
|
|
234
|
+
return {buildersSweepWithdrawals, withdrawalIndex, processedCount};
|
|
172
235
|
}
|
|
173
236
|
|
|
174
237
|
function getPendingPartialWithdrawals(
|
|
175
238
|
state: CachedBeaconStateElectra,
|
|
176
239
|
withdrawalIndex: number,
|
|
177
240
|
numPriorWithdrawal: number,
|
|
178
|
-
|
|
241
|
+
validatorBalanceAfterWithdrawals: Map<ValidatorIndex, number>
|
|
179
242
|
): {pendingPartialWithdrawals: capella.Withdrawal[]; withdrawalIndex: number; processedCount: number} {
|
|
180
243
|
const epoch = state.epochCtx.epoch;
|
|
181
244
|
const pendingPartialWithdrawals: capella.Withdrawal[] = [];
|
|
@@ -203,17 +266,17 @@ function getPendingPartialWithdrawals(
|
|
|
203
266
|
: state.pendingPartialWithdrawals.getReadonly(i);
|
|
204
267
|
if (
|
|
205
268
|
withdrawal.withdrawableEpoch > epoch ||
|
|
206
|
-
pendingPartialWithdrawals.length + numPriorWithdrawal
|
|
269
|
+
pendingPartialWithdrawals.length + numPriorWithdrawal >= partialWithdrawalBound
|
|
207
270
|
) {
|
|
208
271
|
break;
|
|
209
272
|
}
|
|
210
273
|
|
|
211
274
|
const validatorIndex = withdrawal.validatorIndex;
|
|
212
275
|
const validator = validators.getReadonly(validatorIndex);
|
|
213
|
-
let balance =
|
|
276
|
+
let balance = validatorBalanceAfterWithdrawals.get(validatorIndex);
|
|
214
277
|
if (balance === undefined) {
|
|
215
278
|
balance = state.balances.get(validatorIndex);
|
|
216
|
-
|
|
279
|
+
validatorBalanceAfterWithdrawals.set(validatorIndex, balance);
|
|
217
280
|
}
|
|
218
281
|
|
|
219
282
|
if (
|
|
@@ -231,7 +294,7 @@ function getPendingPartialWithdrawals(
|
|
|
231
294
|
amount: withdrawableBalance,
|
|
232
295
|
});
|
|
233
296
|
withdrawalIndex++;
|
|
234
|
-
|
|
297
|
+
validatorBalanceAfterWithdrawals.set(validatorIndex, balance - Number(withdrawableBalance));
|
|
235
298
|
}
|
|
236
299
|
processedCount++;
|
|
237
300
|
}
|
|
@@ -244,7 +307,7 @@ function getValidatorsSweepWithdrawals(
|
|
|
244
307
|
state: CachedBeaconStateCapella | CachedBeaconStateElectra | CachedBeaconStateGloas,
|
|
245
308
|
withdrawalIndex: number,
|
|
246
309
|
numPriorWithdrawal: number,
|
|
247
|
-
|
|
310
|
+
validatorBalanceAfterWithdrawals: Map<ValidatorIndex, number>
|
|
248
311
|
): {sweepWithdrawals: capella.Withdrawal[]; processedCount: number} {
|
|
249
312
|
const sweepWithdrawals: capella.Withdrawal[] = [];
|
|
250
313
|
const epoch = state.epochCtx.epoch;
|
|
@@ -264,13 +327,13 @@ function getValidatorsSweepWithdrawals(
|
|
|
264
327
|
const validatorIndex = (nextWithdrawalValidatorIndex + n) % validators.length;
|
|
265
328
|
|
|
266
329
|
const validator = validators.getReadonly(validatorIndex);
|
|
267
|
-
let balance =
|
|
330
|
+
let balance = validatorBalanceAfterWithdrawals.get(validatorIndex);
|
|
268
331
|
if (balance === undefined) {
|
|
269
332
|
balance = balances.get(validatorIndex);
|
|
270
|
-
|
|
333
|
+
validatorBalanceAfterWithdrawals.set(validatorIndex, balance);
|
|
271
334
|
}
|
|
272
335
|
|
|
273
|
-
const {withdrawableEpoch, withdrawalCredentials
|
|
336
|
+
const {withdrawableEpoch, withdrawalCredentials} = validator;
|
|
274
337
|
const hasWithdrawableCredentials = isPostElectra
|
|
275
338
|
? hasExecutionWithdrawalCredential(withdrawalCredentials)
|
|
276
339
|
: hasEth1WithdrawalCredential(withdrawalCredentials);
|
|
@@ -290,13 +353,11 @@ function getValidatorsSweepWithdrawals(
|
|
|
290
353
|
amount: BigInt(balance),
|
|
291
354
|
});
|
|
292
355
|
withdrawalIndex++;
|
|
293
|
-
|
|
294
|
-
} else if (
|
|
295
|
-
effectiveBalance === (isPostElectra ? getMaxEffectiveBalance(withdrawalCredentials) : MAX_EFFECTIVE_BALANCE) &&
|
|
296
|
-
balance > effectiveBalance
|
|
297
|
-
) {
|
|
356
|
+
validatorBalanceAfterWithdrawals.set(validatorIndex, 0);
|
|
357
|
+
} else if (isPartiallyWithdrawableValidator(fork, validator, balance)) {
|
|
298
358
|
// capella partial withdrawal
|
|
299
|
-
const
|
|
359
|
+
const maxEffectiveBalance = isPostElectra ? getMaxEffectiveBalance(withdrawalCredentials) : MAX_EFFECTIVE_BALANCE;
|
|
360
|
+
const partialAmount = balance - maxEffectiveBalance;
|
|
300
361
|
sweepWithdrawals.push({
|
|
301
362
|
index: withdrawalIndex,
|
|
302
363
|
validatorIndex,
|
|
@@ -304,7 +365,7 @@ function getValidatorsSweepWithdrawals(
|
|
|
304
365
|
amount: BigInt(partialAmount),
|
|
305
366
|
});
|
|
306
367
|
withdrawalIndex++;
|
|
307
|
-
|
|
368
|
+
validatorBalanceAfterWithdrawals.set(validatorIndex, balance - partialAmount);
|
|
308
369
|
}
|
|
309
370
|
processedCount++;
|
|
310
371
|
}
|
|
@@ -317,7 +378,16 @@ function applyWithdrawals(
|
|
|
317
378
|
withdrawals: capella.Withdrawal[]
|
|
318
379
|
): void {
|
|
319
380
|
for (const withdrawal of withdrawals) {
|
|
320
|
-
|
|
381
|
+
if (isBuilderIndex(withdrawal.validatorIndex)) {
|
|
382
|
+
// Handle builder withdrawal
|
|
383
|
+
const builderIndex = convertValidatorIndexToBuilderIndex(withdrawal.validatorIndex);
|
|
384
|
+
const builder = (state as CachedBeaconStateGloas).builders.get(builderIndex);
|
|
385
|
+
const withdrawalAmount = Number(withdrawal.amount);
|
|
386
|
+
builder.balance -= Math.min(withdrawalAmount, builder.balance);
|
|
387
|
+
} else {
|
|
388
|
+
// Handle validator withdrawal
|
|
389
|
+
decreaseBalance(state, withdrawal.validatorIndex, Number(withdrawal.amount));
|
|
390
|
+
}
|
|
321
391
|
}
|
|
322
392
|
}
|
|
323
393
|
|
|
@@ -328,6 +398,7 @@ export function getExpectedWithdrawals(
|
|
|
328
398
|
expectedWithdrawals: capella.Withdrawal[];
|
|
329
399
|
processedBuilderWithdrawalsCount: number;
|
|
330
400
|
processedPartialWithdrawalsCount: number;
|
|
401
|
+
processedBuildersSweepCount: number;
|
|
331
402
|
processedValidatorSweepCount: number;
|
|
332
403
|
} {
|
|
333
404
|
if (fork < ForkSeq.capella) {
|
|
@@ -337,20 +408,28 @@ export function getExpectedWithdrawals(
|
|
|
337
408
|
let withdrawalIndex = state.nextWithdrawalIndex;
|
|
338
409
|
|
|
339
410
|
const expectedWithdrawals: capella.Withdrawal[] = [];
|
|
340
|
-
//
|
|
411
|
+
// Separate maps to track balances after applying withdrawals
|
|
341
412
|
// https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.0/specs/capella/beacon-chain.md#new-get_balance_after_withdrawals
|
|
342
|
-
const
|
|
413
|
+
const builderBalanceAfterWithdrawals = new Map<BuilderIndex, number>();
|
|
414
|
+
const validatorBalanceAfterWithdrawals = new Map<ValidatorIndex, number>();
|
|
343
415
|
// partialWithdrawalsCount is withdrawals coming from EL since electra (EIP-7002)
|
|
344
416
|
let processedPartialWithdrawalsCount = 0;
|
|
345
417
|
// builderWithdrawalsCount is withdrawals coming from builder payments since Gloas (EIP-7732)
|
|
346
418
|
let processedBuilderWithdrawalsCount = 0;
|
|
419
|
+
// buildersSweepCount is withdrawals from builder sweep since Gloas (EIP-7732)
|
|
420
|
+
let processedBuildersSweepCount = 0;
|
|
347
421
|
|
|
348
422
|
if (fork >= ForkSeq.gloas) {
|
|
349
423
|
const {
|
|
350
424
|
builderWithdrawals,
|
|
351
425
|
withdrawalIndex: newWithdrawalIndex,
|
|
352
426
|
processedCount,
|
|
353
|
-
} = getBuilderWithdrawals(
|
|
427
|
+
} = getBuilderWithdrawals(
|
|
428
|
+
state as CachedBeaconStateGloas,
|
|
429
|
+
withdrawalIndex,
|
|
430
|
+
expectedWithdrawals,
|
|
431
|
+
builderBalanceAfterWithdrawals
|
|
432
|
+
);
|
|
354
433
|
|
|
355
434
|
expectedWithdrawals.push(...builderWithdrawals);
|
|
356
435
|
withdrawalIndex = newWithdrawalIndex;
|
|
@@ -366,7 +445,7 @@ export function getExpectedWithdrawals(
|
|
|
366
445
|
state as CachedBeaconStateElectra,
|
|
367
446
|
withdrawalIndex,
|
|
368
447
|
expectedWithdrawals.length,
|
|
369
|
-
|
|
448
|
+
validatorBalanceAfterWithdrawals
|
|
370
449
|
);
|
|
371
450
|
|
|
372
451
|
expectedWithdrawals.push(...pendingPartialWithdrawals);
|
|
@@ -374,12 +453,29 @@ export function getExpectedWithdrawals(
|
|
|
374
453
|
processedPartialWithdrawalsCount = processedCount;
|
|
375
454
|
}
|
|
376
455
|
|
|
456
|
+
if (fork >= ForkSeq.gloas) {
|
|
457
|
+
const {
|
|
458
|
+
buildersSweepWithdrawals,
|
|
459
|
+
withdrawalIndex: newWithdrawalIndex,
|
|
460
|
+
processedCount,
|
|
461
|
+
} = getBuildersSweepWithdrawals(
|
|
462
|
+
state as CachedBeaconStateGloas,
|
|
463
|
+
withdrawalIndex,
|
|
464
|
+
expectedWithdrawals.length,
|
|
465
|
+
builderBalanceAfterWithdrawals
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
expectedWithdrawals.push(...buildersSweepWithdrawals);
|
|
469
|
+
withdrawalIndex = newWithdrawalIndex;
|
|
470
|
+
processedBuildersSweepCount = processedCount;
|
|
471
|
+
}
|
|
472
|
+
|
|
377
473
|
const {sweepWithdrawals, processedCount: processedValidatorSweepCount} = getValidatorsSweepWithdrawals(
|
|
378
474
|
fork,
|
|
379
475
|
state,
|
|
380
476
|
withdrawalIndex,
|
|
381
477
|
expectedWithdrawals.length,
|
|
382
|
-
|
|
478
|
+
validatorBalanceAfterWithdrawals
|
|
383
479
|
);
|
|
384
480
|
|
|
385
481
|
expectedWithdrawals.push(...sweepWithdrawals);
|
|
@@ -388,6 +484,7 @@ export function getExpectedWithdrawals(
|
|
|
388
484
|
expectedWithdrawals,
|
|
389
485
|
processedBuilderWithdrawalsCount,
|
|
390
486
|
processedPartialWithdrawalsCount,
|
|
487
|
+
processedBuildersSweepCount,
|
|
391
488
|
processedValidatorSweepCount,
|
|
392
489
|
};
|
|
393
490
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
2
2
|
import {ssz} from "@lodestar/types";
|
|
3
3
|
import {CachedBeaconStateGloas} from "../types.ts";
|
|
4
|
-
import {computeExitEpochAndUpdateChurn} from "../util/epoch.ts";
|
|
5
4
|
import {getBuilderPaymentQuorumThreshold} from "../util/gloas.ts";
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -12,10 +11,7 @@ export function processBuilderPendingPayments(state: CachedBeaconStateGloas): vo
|
|
|
12
11
|
|
|
13
12
|
for (let i = 0; i < SLOTS_PER_EPOCH; i++) {
|
|
14
13
|
const payment = state.builderPendingPayments.get(i);
|
|
15
|
-
if (payment.weight
|
|
16
|
-
const exitQueueEpoch = computeExitEpochAndUpdateChurn(state, BigInt(payment.withdrawal.amount));
|
|
17
|
-
payment.withdrawal.withdrawableEpoch = exitQueueEpoch + state.config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY;
|
|
18
|
-
|
|
14
|
+
if (payment.weight >= quorum) {
|
|
19
15
|
state.builderPendingWithdrawals.push(payment.withdrawal);
|
|
20
16
|
}
|
|
21
17
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {byteArrayEquals} from "@chainsafe/ssz";
|
|
2
1
|
import {Epoch, phase0} from "@lodestar/types";
|
|
2
|
+
import {byteArrayEquals} from "@lodestar/utils";
|
|
3
3
|
import {CachedBeaconStatePhase0} from "../types.js";
|
|
4
4
|
import {computeStartSlotAtEpoch, getBlockRootAtSlot} from "../util/index.js";
|
|
5
5
|
|
|
@@ -1,38 +1,34 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
2
|
import {DOMAIN_BEACON_ATTESTER} from "@lodestar/params";
|
|
3
3
|
import {AttesterSlashing, IndexedAttestationBigint, SignedBeaconBlock, Slot, ssz} from "@lodestar/types";
|
|
4
|
-
import {Index2PubkeyCache} from "../cache/pubkeyCache.js";
|
|
5
4
|
import {ISignatureSet, SignatureSetType, computeSigningRoot, computeStartSlotAtEpoch} from "../util/index.js";
|
|
6
5
|
|
|
7
6
|
/** Get signature sets from all AttesterSlashing objects in a block */
|
|
8
7
|
export function getAttesterSlashingsSignatureSets(
|
|
9
8
|
config: BeaconConfig,
|
|
10
|
-
index2pubkey: Index2PubkeyCache,
|
|
11
9
|
signedBlock: SignedBeaconBlock
|
|
12
10
|
): ISignatureSet[] {
|
|
13
11
|
// the getDomain() api requires the state slot as 1st param, however it's the same to block.slot in state-transition
|
|
14
12
|
// and the same epoch when we verify blocks in batch in beacon-node. So we can safely use block.slot here.
|
|
15
13
|
const blockSlot = signedBlock.message.slot;
|
|
16
14
|
return signedBlock.message.body.attesterSlashings.flatMap((attesterSlashing) =>
|
|
17
|
-
getAttesterSlashingSignatureSets(config,
|
|
15
|
+
getAttesterSlashingSignatureSets(config, blockSlot, attesterSlashing)
|
|
18
16
|
);
|
|
19
17
|
}
|
|
20
18
|
|
|
21
19
|
/** Get signature sets from a single AttesterSlashing object */
|
|
22
20
|
export function getAttesterSlashingSignatureSets(
|
|
23
21
|
config: BeaconConfig,
|
|
24
|
-
index2pubkey: Index2PubkeyCache,
|
|
25
22
|
stateSlot: Slot,
|
|
26
23
|
attesterSlashing: AttesterSlashing
|
|
27
24
|
): ISignatureSet[] {
|
|
28
25
|
return [attesterSlashing.attestation1, attesterSlashing.attestation2].map((attestation) =>
|
|
29
|
-
getIndexedAttestationBigintSignatureSet(config,
|
|
26
|
+
getIndexedAttestationBigintSignatureSet(config, stateSlot, attestation)
|
|
30
27
|
);
|
|
31
28
|
}
|
|
32
29
|
|
|
33
30
|
export function getIndexedAttestationBigintSignatureSet(
|
|
34
31
|
config: BeaconConfig,
|
|
35
|
-
index2pubkey: Index2PubkeyCache,
|
|
36
32
|
stateSlot: Slot,
|
|
37
33
|
indexedAttestation: IndexedAttestationBigint
|
|
38
34
|
): ISignatureSet {
|
|
@@ -41,7 +37,7 @@ export function getIndexedAttestationBigintSignatureSet(
|
|
|
41
37
|
|
|
42
38
|
return {
|
|
43
39
|
type: SignatureSetType.aggregate,
|
|
44
|
-
|
|
40
|
+
indices: indexedAttestation.attestingIndices.map((i) => Number(i)),
|
|
45
41
|
signingRoot: computeSigningRoot(ssz.phase0.AttestationDataBigint, indexedAttestation.data, domain),
|
|
46
42
|
signature: indexedAttestation.signature,
|
|
47
43
|
};
|
|
@@ -2,7 +2,7 @@ import {PublicKey} from "@chainsafe/blst";
|
|
|
2
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
3
|
import {DOMAIN_BLS_TO_EXECUTION_CHANGE, ForkName} from "@lodestar/params";
|
|
4
4
|
import {capella, ssz} from "@lodestar/types";
|
|
5
|
-
import {
|
|
5
|
+
import {SignatureSetType, SingleSignatureSet, computeSigningRoot, verifySignatureSet} from "../util/index.js";
|
|
6
6
|
|
|
7
7
|
export function verifyBlsToExecutionChangeSignature(
|
|
8
8
|
config: BeaconConfig,
|
|
@@ -17,7 +17,7 @@ export function verifyBlsToExecutionChangeSignature(
|
|
|
17
17
|
export function getBlsToExecutionChangeSignatureSet(
|
|
18
18
|
config: BeaconConfig,
|
|
19
19
|
signedBLSToExecutionChange: capella.SignedBLSToExecutionChange
|
|
20
|
-
):
|
|
20
|
+
): SingleSignatureSet {
|
|
21
21
|
// signatureFork for signing domain is fixed
|
|
22
22
|
const signatureFork = ForkName.phase0;
|
|
23
23
|
const domain = config.getDomainAtFork(signatureFork, DOMAIN_BLS_TO_EXECUTION_CHANGE);
|
|
@@ -35,7 +35,7 @@ export function getBlsToExecutionChangeSignatureSet(
|
|
|
35
35
|
export function getBlsToExecutionChangeSignatureSets(
|
|
36
36
|
config: BeaconConfig,
|
|
37
37
|
signedBlock: capella.SignedBeaconBlock
|
|
38
|
-
):
|
|
38
|
+
): SingleSignatureSet[] {
|
|
39
39
|
return signedBlock.message.body.blsToExecutionChanges.map((blsToExecutionChange) =>
|
|
40
40
|
getBlsToExecutionChangeSignatureSet(config, blsToExecutionChange)
|
|
41
41
|
);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
2
|
+
import {DOMAIN_BEACON_BUILDER} from "@lodestar/params";
|
|
3
|
+
import {Slot, gloas, ssz} from "@lodestar/types";
|
|
4
|
+
import {computeSigningRoot} from "../util/index.js";
|
|
5
|
+
|
|
6
|
+
export function getExecutionPayloadBidSigningRoot(
|
|
7
|
+
config: BeaconConfig,
|
|
8
|
+
stateSlot: Slot,
|
|
9
|
+
bid: gloas.ExecutionPayloadBid
|
|
10
|
+
): Uint8Array {
|
|
11
|
+
const domain = config.getDomain(stateSlot, DOMAIN_BEACON_BUILDER);
|
|
12
|
+
|
|
13
|
+
return computeSigningRoot(ssz.gloas.ExecutionPayloadBid, bid, domain);
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
2
|
+
import {DOMAIN_BEACON_BUILDER} from "@lodestar/params";
|
|
3
|
+
import {gloas, ssz} from "@lodestar/types";
|
|
4
|
+
import {computeSigningRoot} from "../util/index.js";
|
|
5
|
+
|
|
6
|
+
export function getExecutionPayloadEnvelopeSigningRoot(
|
|
7
|
+
config: BeaconConfig,
|
|
8
|
+
envelope: gloas.ExecutionPayloadEnvelope
|
|
9
|
+
): Uint8Array {
|
|
10
|
+
const domain = config.getDomain(envelope.slot, DOMAIN_BEACON_BUILDER);
|
|
11
|
+
|
|
12
|
+
return computeSigningRoot(ssz.gloas.ExecutionPayloadEnvelope, envelope, domain);
|
|
13
|
+
}
|