@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
package/src/block/index.ts
CHANGED
|
@@ -38,6 +38,7 @@ export {
|
|
|
38
38
|
export * from "./externalData.js";
|
|
39
39
|
export * from "./initiateValidatorExit.js";
|
|
40
40
|
export * from "./isValidIndexedAttestation.js";
|
|
41
|
+
export * from "./processDepositRequest.js";
|
|
41
42
|
export * from "./processOperations.js";
|
|
42
43
|
|
|
43
44
|
export function processBlock(
|
|
@@ -21,7 +21,7 @@ export function isValidIndexedAttestation(
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
if (verifySignature) {
|
|
24
|
-
return verifySignatureSet(getIndexedAttestationSignatureSet(config,
|
|
24
|
+
return verifySignatureSet(getIndexedAttestationSignatureSet(config, stateSlot, indexedAttestation), index2pubkey);
|
|
25
25
|
}
|
|
26
26
|
return true;
|
|
27
27
|
}
|
|
@@ -40,7 +40,8 @@ export function isValidIndexedAttestationBigint(
|
|
|
40
40
|
|
|
41
41
|
if (verifySignature) {
|
|
42
42
|
return verifySignatureSet(
|
|
43
|
-
getIndexedAttestationBigintSignatureSet(config,
|
|
43
|
+
getIndexedAttestationBigintSignatureSet(config, stateSlot, indexedAttestation),
|
|
44
|
+
index2pubkey
|
|
44
45
|
);
|
|
45
46
|
}
|
|
46
47
|
return true;
|
|
@@ -16,7 +16,10 @@ export function isValidIndexedPayloadAttestation(
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
if (verifySignature) {
|
|
19
|
-
return verifySignatureSet(
|
|
19
|
+
return verifySignatureSet(
|
|
20
|
+
getIndexedPayloadAttestationSignatureSet(state, indexedPayloadAttestation),
|
|
21
|
+
state.epochCtx.index2pubkey
|
|
22
|
+
);
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
return true;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {byteArrayEquals} from "@chainsafe/ssz";
|
|
2
1
|
import {
|
|
3
2
|
EFFECTIVE_BALANCE_INCREMENT,
|
|
4
3
|
ForkSeq,
|
|
@@ -15,7 +14,7 @@ import {
|
|
|
15
14
|
WEIGHT_DENOMINATOR,
|
|
16
15
|
} from "@lodestar/params";
|
|
17
16
|
import {Attestation, Epoch, phase0} from "@lodestar/types";
|
|
18
|
-
import {intSqrt} from "@lodestar/utils";
|
|
17
|
+
import {byteArrayEquals, intSqrt} from "@lodestar/utils";
|
|
19
18
|
import {BeaconStateTransitionMetrics} from "../metrics.js";
|
|
20
19
|
import {getAttestationWithIndicesSignatureSet} from "../signatureSets/indexedAttestation.js";
|
|
21
20
|
import {CachedBeaconStateAltair, CachedBeaconStateGloas} from "../types.js";
|
|
@@ -64,14 +63,8 @@ export function processAttestationsAltair(
|
|
|
64
63
|
// TODO: Why should we verify an indexed attestation that we just created? If it's just for the signature
|
|
65
64
|
// we can verify only that and nothing else.
|
|
66
65
|
if (verifySignature) {
|
|
67
|
-
const sigSet = getAttestationWithIndicesSignatureSet(
|
|
68
|
-
|
|
69
|
-
epochCtx.index2pubkey,
|
|
70
|
-
state.slot,
|
|
71
|
-
attestation,
|
|
72
|
-
attestingIndices
|
|
73
|
-
);
|
|
74
|
-
if (!verifySignatureSet(sigSet)) {
|
|
66
|
+
const sigSet = getAttestationWithIndicesSignatureSet(state.config, state.slot, attestation, attestingIndices);
|
|
67
|
+
if (!verifySignatureSet(sigSet, state.epochCtx.index2pubkey)) {
|
|
75
68
|
throw new Error("Attestation signature is not valid");
|
|
76
69
|
}
|
|
77
70
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {byteArrayEquals} from "@chainsafe/ssz";
|
|
2
1
|
import {BeaconBlock, BlindedBeaconBlock, ssz} from "@lodestar/types";
|
|
3
|
-
import {toRootHex} from "@lodestar/utils";
|
|
2
|
+
import {byteArrayEquals, toRootHex} from "@lodestar/utils";
|
|
4
3
|
import {ZERO_HASH} from "../constants/index.js";
|
|
5
4
|
import {CachedBeaconStateAllForks} from "../types.js";
|
|
6
5
|
import {blindedOrFullBlockToHeader} from "../util/index.js";
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import {digest} from "@chainsafe/as-sha256";
|
|
2
|
-
import {byteArrayEquals} from "@chainsafe/ssz";
|
|
3
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
4
3
|
import {BLS_WITHDRAWAL_PREFIX, ETH1_ADDRESS_WITHDRAWAL_PREFIX} from "@lodestar/params";
|
|
5
4
|
import {capella} from "@lodestar/types";
|
|
6
5
|
import {Validator} from "@lodestar/types/phase0";
|
|
7
|
-
import {toHex} from "@lodestar/utils";
|
|
6
|
+
import {byteArrayEquals, toHex} from "@lodestar/utils";
|
|
8
7
|
import {verifyBlsToExecutionChangeSignature} from "../signatureSets/index.js";
|
|
9
8
|
import {CachedBeaconStateCapella} from "../types.js";
|
|
10
9
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {FAR_FUTURE_EPOCH,
|
|
1
|
+
import {FAR_FUTURE_EPOCH, MIN_ACTIVATION_BALANCE, PENDING_CONSOLIDATIONS_LIMIT} from "@lodestar/params";
|
|
2
2
|
import {electra, ssz} from "@lodestar/types";
|
|
3
|
+
import {byteArrayEquals} from "@lodestar/utils";
|
|
3
4
|
import {CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
|
|
4
5
|
import {hasEth1WithdrawalCredential} from "../util/capella.js";
|
|
5
6
|
import {
|
|
@@ -13,7 +14,6 @@ import {getConsolidationChurnLimit, getPendingBalanceToWithdraw, isActiveValidat
|
|
|
13
14
|
|
|
14
15
|
// TODO Electra: Clean up necessary as there is a lot of overlap with isValidSwitchToCompoundRequest
|
|
15
16
|
export function processConsolidationRequest(
|
|
16
|
-
fork: ForkSeq,
|
|
17
17
|
state: CachedBeaconStateElectra | CachedBeaconStateGloas,
|
|
18
18
|
consolidationRequest: electra.ConsolidationRequest
|
|
19
19
|
): void {
|
|
@@ -57,7 +57,7 @@ export function processConsolidationRequest(
|
|
|
57
57
|
|
|
58
58
|
// Verify source withdrawal credentials
|
|
59
59
|
const hasCorrectCredential = hasExecutionWithdrawalCredential(sourceValidator.withdrawalCredentials);
|
|
60
|
-
const isCorrectSourceAddress =
|
|
60
|
+
const isCorrectSourceAddress = byteArrayEquals(sourceWithdrawalAddress, sourceAddress);
|
|
61
61
|
if (!(hasCorrectCredential && isCorrectSourceAddress)) {
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
@@ -83,7 +83,7 @@ export function processConsolidationRequest(
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// Verify the source has no pending withdrawals in the queue
|
|
86
|
-
if (getPendingBalanceToWithdraw(
|
|
86
|
+
if (getPendingBalanceToWithdraw(state, sourceIndex) > 0) {
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -125,7 +125,7 @@ function isValidSwitchToCompoundRequest(
|
|
|
125
125
|
const sourceValidator = state.validators.getReadonly(sourceIndex);
|
|
126
126
|
const sourceWithdrawalAddress = sourceValidator.withdrawalCredentials.subarray(12);
|
|
127
127
|
// Verify request has been authorized
|
|
128
|
-
if (
|
|
128
|
+
if (!byteArrayEquals(sourceWithdrawalAddress, sourceAddress)) {
|
|
129
129
|
return false;
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -1,21 +1,114 @@
|
|
|
1
|
-
import {UNSET_DEPOSIT_REQUESTS_START_INDEX} from "@lodestar/params";
|
|
2
|
-
import {electra, ssz} from "@lodestar/types";
|
|
1
|
+
import {FAR_FUTURE_EPOCH, ForkSeq, UNSET_DEPOSIT_REQUESTS_START_INDEX} from "@lodestar/params";
|
|
2
|
+
import {BLSPubkey, Bytes32, UintNum64, electra, ssz} from "@lodestar/types";
|
|
3
3
|
import {CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
|
|
4
|
+
import {findBuilderIndexByPubkey, isBuilderWithdrawalCredential} from "../util/gloas.js";
|
|
5
|
+
import {computeEpochAtSlot, isValidatorKnown} from "../util/index.js";
|
|
6
|
+
import {isValidDepositSignature} from "./processDeposit.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Apply a deposit for a builder. Either increases balance for existing builder or adds new builder to registry.
|
|
10
|
+
* Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-apply_deposit_for_builder
|
|
11
|
+
*/
|
|
12
|
+
export function applyDepositForBuilder(
|
|
13
|
+
state: CachedBeaconStateGloas,
|
|
14
|
+
pubkey: BLSPubkey,
|
|
15
|
+
withdrawalCredentials: Bytes32,
|
|
16
|
+
amount: UintNum64,
|
|
17
|
+
signature: Bytes32
|
|
18
|
+
): void {
|
|
19
|
+
const builderIndex = findBuilderIndexByPubkey(state, pubkey);
|
|
20
|
+
|
|
21
|
+
if (builderIndex !== null) {
|
|
22
|
+
// Existing builder - increase balance
|
|
23
|
+
const builder = state.builders.get(builderIndex);
|
|
24
|
+
builder.balance += amount;
|
|
25
|
+
} else {
|
|
26
|
+
// New builder - verify signature and add to registry
|
|
27
|
+
if (isValidDepositSignature(state.config, pubkey, withdrawalCredentials, amount, signature)) {
|
|
28
|
+
addBuilderToRegistry(state, pubkey, withdrawalCredentials, amount);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Add a new builder to the builders registry.
|
|
35
|
+
* Reuses slots from exited and fully withdrawn builders if available.
|
|
36
|
+
*/
|
|
37
|
+
function addBuilderToRegistry(
|
|
38
|
+
state: CachedBeaconStateGloas,
|
|
39
|
+
pubkey: BLSPubkey,
|
|
40
|
+
withdrawalCredentials: Bytes32,
|
|
41
|
+
amount: UintNum64
|
|
42
|
+
): void {
|
|
43
|
+
const currentEpoch = computeEpochAtSlot(state.slot);
|
|
44
|
+
|
|
45
|
+
// Try to find a reusable slot from an exited builder with zero balance
|
|
46
|
+
let builderIndex = state.builders.length;
|
|
47
|
+
for (let i = 0; i < state.builders.length; i++) {
|
|
48
|
+
const builder = state.builders.getReadonly(i);
|
|
49
|
+
if (builder.withdrawableEpoch <= currentEpoch && builder.balance === 0) {
|
|
50
|
+
builderIndex = i;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Create new builder
|
|
56
|
+
const newBuilder = ssz.gloas.Builder.toViewDU({
|
|
57
|
+
pubkey,
|
|
58
|
+
version: withdrawalCredentials[0],
|
|
59
|
+
executionAddress: withdrawalCredentials.subarray(12),
|
|
60
|
+
balance: amount,
|
|
61
|
+
depositEpoch: currentEpoch,
|
|
62
|
+
withdrawableEpoch: FAR_FUTURE_EPOCH,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (builderIndex < state.builders.length) {
|
|
66
|
+
// Reuse existing slot
|
|
67
|
+
state.builders.set(builderIndex, newBuilder);
|
|
68
|
+
} else {
|
|
69
|
+
// Append to end
|
|
70
|
+
state.builders.push(newBuilder);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
4
73
|
|
|
5
74
|
export function processDepositRequest(
|
|
75
|
+
fork: ForkSeq,
|
|
6
76
|
state: CachedBeaconStateElectra | CachedBeaconStateGloas,
|
|
7
77
|
depositRequest: electra.DepositRequest
|
|
8
78
|
): void {
|
|
9
|
-
|
|
79
|
+
const {pubkey, withdrawalCredentials, amount, signature} = depositRequest;
|
|
80
|
+
|
|
81
|
+
// Check if this is a builder or validator deposit
|
|
82
|
+
if (fork >= ForkSeq.gloas) {
|
|
83
|
+
const stateGloas = state as CachedBeaconStateGloas;
|
|
84
|
+
const builderIndex = findBuilderIndexByPubkey(stateGloas, pubkey);
|
|
85
|
+
const validatorIndex = state.epochCtx.getValidatorIndex(pubkey);
|
|
86
|
+
|
|
87
|
+
// Regardless of the withdrawal credentials prefix, if a builder/validator
|
|
88
|
+
// already exists with this pubkey, apply the deposit to their balance
|
|
89
|
+
const isBuilder = builderIndex !== null;
|
|
90
|
+
const isValidator = isValidatorKnown(state, validatorIndex);
|
|
91
|
+
const isBuilderPrefix = isBuilderWithdrawalCredential(withdrawalCredentials);
|
|
92
|
+
|
|
93
|
+
// Route to builder if it's an existing builder OR has builder prefix and is not a validator
|
|
94
|
+
if (isBuilder || (isBuilderPrefix && !isValidator)) {
|
|
95
|
+
// Apply builder deposits immediately
|
|
96
|
+
applyDepositForBuilder(stateGloas, pubkey, withdrawalCredentials, amount, signature);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Only set deposit_requests_start_index in Electra fork, not Gloas
|
|
102
|
+
if (fork < ForkSeq.gloas && state.depositRequestsStartIndex === UNSET_DEPOSIT_REQUESTS_START_INDEX) {
|
|
10
103
|
state.depositRequestsStartIndex = depositRequest.index;
|
|
11
104
|
}
|
|
12
105
|
|
|
13
|
-
//
|
|
106
|
+
// Add validator deposits to the queue
|
|
14
107
|
const pendingDeposit = ssz.electra.PendingDeposit.toViewDU({
|
|
15
|
-
pubkey
|
|
16
|
-
withdrawalCredentials
|
|
17
|
-
amount
|
|
18
|
-
signature
|
|
108
|
+
pubkey,
|
|
109
|
+
withdrawalCredentials,
|
|
110
|
+
amount,
|
|
111
|
+
signature,
|
|
19
112
|
slot: state.slot,
|
|
20
113
|
});
|
|
21
114
|
state.pendingDeposits.push(pendingDeposit);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {byteArrayEquals} from "@chainsafe/ssz";
|
|
2
1
|
import {ForkName, ForkSeq, isForkPostDeneb} from "@lodestar/params";
|
|
3
2
|
import {BeaconBlockBody, BlindedBeaconBlockBody, deneb, isExecutionPayload} from "@lodestar/types";
|
|
4
|
-
import {toHex, toRootHex} from "@lodestar/utils";
|
|
3
|
+
import {byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
|
|
5
4
|
import {CachedBeaconStateBellatrix, CachedBeaconStateCapella} from "../types.js";
|
|
6
5
|
import {
|
|
7
6
|
executionPayloadToPayloadHeader,
|
|
@@ -1,68 +1,47 @@
|
|
|
1
1
|
import {PublicKey, Signature, verify} from "@chainsafe/blst";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
DOMAIN_BEACON_BUILDER,
|
|
5
|
-
FAR_FUTURE_EPOCH,
|
|
6
|
-
ForkPostGloas,
|
|
7
|
-
MIN_ACTIVATION_BALANCE,
|
|
8
|
-
SLOTS_PER_EPOCH,
|
|
9
|
-
} from "@lodestar/params";
|
|
2
|
+
import {BUILDER_INDEX_SELF_BUILD, ForkPostGloas, SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
10
3
|
import {BeaconBlock, gloas, ssz} from "@lodestar/types";
|
|
11
|
-
import {toHex, toRootHex} from "@lodestar/utils";
|
|
4
|
+
import {byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
|
|
12
5
|
import {G2_POINT_AT_INFINITY} from "../constants/constants.ts";
|
|
6
|
+
import {getExecutionPayloadBidSigningRoot} from "../signatureSets/executionPayloadBid.js";
|
|
13
7
|
import {CachedBeaconStateGloas} from "../types.ts";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
8
|
+
import {canBuilderCoverBid, isActiveBuilder} from "../util/gloas.ts";
|
|
9
|
+
import {getCurrentEpoch, getRandaoMix} from "../util/index.ts";
|
|
16
10
|
|
|
17
11
|
export function processExecutionPayloadBid(state: CachedBeaconStateGloas, block: BeaconBlock<ForkPostGloas>): void {
|
|
18
12
|
const signedBid = block.body.signedExecutionPayloadBid;
|
|
19
13
|
const bid = signedBid.message;
|
|
20
14
|
const {builderIndex, value: amount} = bid;
|
|
21
|
-
const builder = state.validators.getReadonly(builderIndex);
|
|
22
15
|
|
|
23
16
|
// For self-builds, amount must be zero regardless of withdrawal credential prefix
|
|
24
|
-
if (builderIndex ===
|
|
17
|
+
if (builderIndex === BUILDER_INDEX_SELF_BUILD) {
|
|
25
18
|
if (amount !== 0) {
|
|
26
19
|
throw Error(`Invalid execution payload bid: self-build with non-zero amount ${amount}`);
|
|
27
20
|
}
|
|
28
21
|
if (!byteArrayEquals(signedBid.signature, G2_POINT_AT_INFINITY)) {
|
|
29
22
|
throw Error("Invalid execution payload bid: self-build with non-zero signature");
|
|
30
23
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
}
|
|
25
|
+
// Non-self builds require active builder with valid signature
|
|
26
|
+
else {
|
|
27
|
+
const builder = state.builders.getReadonly(builderIndex);
|
|
28
|
+
|
|
29
|
+
// Verify that the builder is active
|
|
30
|
+
if (!isActiveBuilder(builder, state.finalizedCheckpoint.epoch)) {
|
|
31
|
+
throw Error(`Invalid execution payload bid: builder ${builderIndex} is not active`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Verify that the builder has funds to cover the bid
|
|
35
|
+
if (!canBuilderCoverBid(state, builderIndex, amount)) {
|
|
36
|
+
throw Error(`Invalid execution payload bid: builder ${builderIndex} has insufficient balance`);
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
// Verify that the bid signature is valid
|
|
37
40
|
if (!verifyExecutionPayloadBidSignature(state, builder.pubkey, signedBid)) {
|
|
38
41
|
throw Error(`Invalid execution payload bid: invalid signature for builder ${builderIndex}`);
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
if (!isActiveValidator(builder, getCurrentEpoch(state))) {
|
|
43
|
-
throw Error(`Invalid execution payload bid: builder ${builderIndex} is not active`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (builder.slashed) {
|
|
47
|
-
throw Error(`Invalid execution payload bid: builder ${builderIndex} is slashed`);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const pendingPayments = state.builderPendingPayments
|
|
51
|
-
.getAllReadonly()
|
|
52
|
-
.filter((payment) => payment.withdrawal.builderIndex === builderIndex)
|
|
53
|
-
.reduce((acc, payment) => acc + payment.withdrawal.amount, 0);
|
|
54
|
-
const pendingWithdrawals = state.builderPendingWithdrawals
|
|
55
|
-
.getAllReadonly()
|
|
56
|
-
.filter((withdrawal) => withdrawal.builderIndex === builderIndex)
|
|
57
|
-
.reduce((acc, withdrawal) => acc + withdrawal.amount, 0);
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
amount !== 0 &&
|
|
61
|
-
state.balances.get(builderIndex) < amount + pendingPayments + pendingWithdrawals + MIN_ACTIVATION_BALANCE
|
|
62
|
-
) {
|
|
63
|
-
throw Error("Insufficient builder balance");
|
|
64
|
-
}
|
|
65
|
-
|
|
66
45
|
if (bid.slot !== block.slot) {
|
|
67
46
|
throw Error(`Bid slot ${bid.slot} does not match block slot ${block.slot}`);
|
|
68
47
|
}
|
|
@@ -91,7 +70,6 @@ export function processExecutionPayloadBid(state: CachedBeaconStateGloas, block:
|
|
|
91
70
|
feeRecipient: bid.feeRecipient,
|
|
92
71
|
amount,
|
|
93
72
|
builderIndex,
|
|
94
|
-
withdrawableEpoch: FAR_FUTURE_EPOCH,
|
|
95
73
|
}),
|
|
96
74
|
});
|
|
97
75
|
|
|
@@ -106,8 +84,7 @@ function verifyExecutionPayloadBidSignature(
|
|
|
106
84
|
pubkey: Uint8Array,
|
|
107
85
|
signedBid: gloas.SignedExecutionPayloadBid
|
|
108
86
|
): boolean {
|
|
109
|
-
const
|
|
110
|
-
const signingRoot = computeSigningRoot(ssz.gloas.ExecutionPayloadBid, signedBid.message, domain);
|
|
87
|
+
const signingRoot = getExecutionPayloadBidSigningRoot(state.config, state.slot, signedBid.message);
|
|
111
88
|
|
|
112
89
|
try {
|
|
113
90
|
const publicKey = PublicKey.fromBytes(pubkey);
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import {PublicKey, Signature, verify} from "@chainsafe/blst";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
BUILDER_INDEX_SELF_BUILD,
|
|
4
|
+
DOMAIN_BEACON_BUILDER,
|
|
5
|
+
SLOTS_PER_EPOCH,
|
|
6
|
+
SLOTS_PER_HISTORICAL_ROOT,
|
|
7
|
+
} from "@lodestar/params";
|
|
4
8
|
import {gloas, ssz} from "@lodestar/types";
|
|
5
|
-
import {toHex, toRootHex} from "@lodestar/utils";
|
|
9
|
+
import {byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
|
|
6
10
|
import {CachedBeaconStateGloas} from "../types.ts";
|
|
7
|
-
import {
|
|
11
|
+
import {computeSigningRoot, computeTimeAtSlot} from "../util/index.ts";
|
|
8
12
|
import {processConsolidationRequest} from "./processConsolidationRequest.ts";
|
|
9
13
|
import {processDepositRequest} from "./processDepositRequest.ts";
|
|
10
14
|
import {processWithdrawalRequest} from "./processWithdrawalRequest.ts";
|
|
@@ -19,13 +23,8 @@ export function processExecutionPayloadEnvelope(
|
|
|
19
23
|
const payload = envelope.payload;
|
|
20
24
|
const fork = state.config.getForkSeq(envelope.slot);
|
|
21
25
|
|
|
22
|
-
if (verify) {
|
|
23
|
-
|
|
24
|
-
const pubkey = state.validators.getReadonly(builderIndex).pubkey;
|
|
25
|
-
|
|
26
|
-
if (!verifyExecutionPayloadEnvelopeSignature(state, pubkey, signedEnvelope)) {
|
|
27
|
-
throw new Error("Payload Envelope has invalid signature");
|
|
28
|
-
}
|
|
26
|
+
if (verify && !verifyExecutionPayloadEnvelopeSignature(state, signedEnvelope)) {
|
|
27
|
+
throw Error(`Execution payload envelope has invalid signature builderIndex=${envelope.builderIndex}`);
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
validateExecutionPayloadEnvelope(state, envelope);
|
|
@@ -33,7 +32,7 @@ export function processExecutionPayloadEnvelope(
|
|
|
33
32
|
const requests = envelope.executionRequests;
|
|
34
33
|
|
|
35
34
|
for (const deposit of requests.deposits) {
|
|
36
|
-
processDepositRequest(state, deposit);
|
|
35
|
+
processDepositRequest(fork, state, deposit);
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
for (const withdrawal of requests.withdrawals) {
|
|
@@ -41,7 +40,7 @@ export function processExecutionPayloadEnvelope(
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
for (const consolidation of requests.consolidations) {
|
|
44
|
-
processConsolidationRequest(
|
|
43
|
+
processConsolidationRequest(state, consolidation);
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
// Queue the builder payment
|
|
@@ -50,9 +49,6 @@ export function processExecutionPayloadEnvelope(
|
|
|
50
49
|
const amount = payment.withdrawal.amount;
|
|
51
50
|
|
|
52
51
|
if (amount > 0) {
|
|
53
|
-
const exitQueueEpoch = computeExitEpochAndUpdateChurn(state, BigInt(amount));
|
|
54
|
-
|
|
55
|
-
payment.withdrawal.withdrawableEpoch = exitQueueEpoch + state.config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY;
|
|
56
52
|
state.builderPendingWithdrawals.push(payment.withdrawal);
|
|
57
53
|
}
|
|
58
54
|
|
|
@@ -75,6 +71,7 @@ function validateExecutionPayloadEnvelope(
|
|
|
75
71
|
): void {
|
|
76
72
|
const payload = envelope.payload;
|
|
77
73
|
|
|
74
|
+
// Cache latest block header state root
|
|
78
75
|
if (byteArrayEquals(state.latestBlockHeader.stateRoot, ssz.Root.defaultValue())) {
|
|
79
76
|
const previousStateRoot = state.hashTreeRoot();
|
|
80
77
|
state.latestBlockHeader.stateRoot = previousStateRoot;
|
|
@@ -87,20 +84,18 @@ function validateExecutionPayloadEnvelope(
|
|
|
87
84
|
);
|
|
88
85
|
}
|
|
89
86
|
|
|
90
|
-
// Verify consistency with the beacon block
|
|
91
87
|
if (envelope.slot !== state.slot) {
|
|
92
88
|
throw new Error(`Slot mismatch between envelope and state envelope=${envelope.slot} state=${state.slot}`);
|
|
93
89
|
}
|
|
94
90
|
|
|
95
|
-
const committedBid = state.latestExecutionPayloadBid;
|
|
96
91
|
// Verify consistency with the committed bid
|
|
92
|
+
const committedBid = state.latestExecutionPayloadBid;
|
|
97
93
|
if (envelope.builderIndex !== committedBid.builderIndex) {
|
|
98
94
|
throw new Error(
|
|
99
95
|
`Builder index mismatch between envelope and committed bid envelope=${envelope.builderIndex} committedBid=${committedBid.builderIndex}`
|
|
100
96
|
);
|
|
101
97
|
}
|
|
102
98
|
|
|
103
|
-
// Verify consistency with the committed bid
|
|
104
99
|
const envelopeKzgRoot = ssz.deneb.BlobKzgCommitments.hashTreeRoot(envelope.blobKzgCommitments);
|
|
105
100
|
if (!byteArrayEquals(committedBid.blobKzgCommitmentsRoot, envelopeKzgRoot)) {
|
|
106
101
|
throw new Error(
|
|
@@ -108,11 +103,18 @@ function validateExecutionPayloadEnvelope(
|
|
|
108
103
|
);
|
|
109
104
|
}
|
|
110
105
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
106
|
+
if (!byteArrayEquals(committedBid.prevRandao, payload.prevRandao)) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Prev randao mismatch between committed bid and payload committedBid=${toHex(committedBid.prevRandao)} payload=${toHex(payload.prevRandao)}`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Verify consistency with expected withdrawals
|
|
113
|
+
const payloadWithdrawalsRoot = ssz.capella.Withdrawals.hashTreeRoot(payload.withdrawals);
|
|
114
|
+
const expectedWithdrawalsRoot = state.payloadExpectedWithdrawals.hashTreeRoot();
|
|
115
|
+
if (!byteArrayEquals(payloadWithdrawalsRoot, expectedWithdrawalsRoot)) {
|
|
114
116
|
throw new Error(
|
|
115
|
-
`Withdrawals
|
|
117
|
+
`Withdrawals mismatch between payload and expected withdrawals payload=${toRootHex(payloadWithdrawalsRoot)} expected=${toRootHex(expectedWithdrawalsRoot)}`
|
|
116
118
|
);
|
|
117
119
|
}
|
|
118
120
|
|
|
@@ -137,13 +139,6 @@ function validateExecutionPayloadEnvelope(
|
|
|
137
139
|
);
|
|
138
140
|
}
|
|
139
141
|
|
|
140
|
-
// Verify prev_randao matches committed bid
|
|
141
|
-
if (!byteArrayEquals(committedBid.prevRandao, payload.prevRandao)) {
|
|
142
|
-
throw new Error(
|
|
143
|
-
`Prev randao mismatch between committed bid and payload committedBid=${toHex(committedBid.prevRandao)} payload=${toHex(payload.prevRandao)}`
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
142
|
// Verify timestamp
|
|
148
143
|
if (payload.timestamp !== computeTimeAtSlot(state.config, state.slot, state.genesisTime)) {
|
|
149
144
|
throw new Error(
|
|
@@ -164,14 +159,22 @@ function validateExecutionPayloadEnvelope(
|
|
|
164
159
|
|
|
165
160
|
function verifyExecutionPayloadEnvelopeSignature(
|
|
166
161
|
state: CachedBeaconStateGloas,
|
|
167
|
-
pubkey: Uint8Array,
|
|
168
162
|
signedEnvelope: gloas.SignedExecutionPayloadEnvelope
|
|
169
163
|
): boolean {
|
|
164
|
+
const builderIndex = signedEnvelope.message.builderIndex;
|
|
165
|
+
|
|
170
166
|
const domain = state.config.getDomain(state.slot, DOMAIN_BEACON_BUILDER);
|
|
171
167
|
const signingRoot = computeSigningRoot(ssz.gloas.ExecutionPayloadEnvelope, signedEnvelope.message, domain);
|
|
172
168
|
|
|
173
169
|
try {
|
|
174
|
-
|
|
170
|
+
let publicKey: PublicKey;
|
|
171
|
+
|
|
172
|
+
if (builderIndex === BUILDER_INDEX_SELF_BUILD) {
|
|
173
|
+
const validatorIndex = state.latestBlockHeader.proposerIndex;
|
|
174
|
+
publicKey = state.epochCtx.index2pubkey[validatorIndex];
|
|
175
|
+
} else {
|
|
176
|
+
publicKey = PublicKey.fromBytes(state.builders.getReadonly(builderIndex).pubkey);
|
|
177
|
+
}
|
|
175
178
|
const signature = Signature.fromBytes(signedEnvelope.signature, true);
|
|
176
179
|
|
|
177
180
|
return verify(signingRoot, publicKey, signature);
|
|
@@ -75,7 +75,7 @@ export function processOperations(
|
|
|
75
75
|
const bodyElectra = body as electra.BeaconBlockBody;
|
|
76
76
|
|
|
77
77
|
for (const depositRequest of bodyElectra.executionRequests.deposits) {
|
|
78
|
-
processDepositRequest(stateElectra, depositRequest);
|
|
78
|
+
processDepositRequest(fork, stateElectra, depositRequest);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
for (const elWithdrawalRequest of bodyElectra.executionRequests.withdrawals) {
|
|
@@ -83,7 +83,7 @@ export function processOperations(
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
for (const elConsolidationRequest of bodyElectra.executionRequests.consolidations) {
|
|
86
|
-
processConsolidationRequest(
|
|
86
|
+
processConsolidationRequest(stateElectra, elConsolidationRequest);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {byteArrayEquals} from "@chainsafe/ssz";
|
|
2
1
|
import {gloas} from "@lodestar/types";
|
|
2
|
+
import {byteArrayEquals} from "@lodestar/utils";
|
|
3
3
|
import {CachedBeaconStateGloas} from "../types.ts";
|
|
4
4
|
import {isValidIndexedPayloadAttestation} from "./isValidIndexedPayloadAttestation.ts";
|
|
5
5
|
|
|
@@ -92,9 +92,9 @@ export function assertValidProposerSlashing(
|
|
|
92
92
|
|
|
93
93
|
// verify signatures
|
|
94
94
|
if (verifySignatures) {
|
|
95
|
-
const signatureSets = getProposerSlashingSignatureSets(config,
|
|
95
|
+
const signatureSets = getProposerSlashingSignatureSets(config, stateSlot, proposerSlashing);
|
|
96
96
|
for (let i = 0; i < signatureSets.length; i++) {
|
|
97
|
-
if (!verifySignatureSet(signatureSets[i])) {
|
|
97
|
+
if (!verifySignatureSet(signatureSets[i], index2pubkey)) {
|
|
98
98
|
throw new Error(`ProposerSlashing header${i + 1} signature invalid`);
|
|
99
99
|
}
|
|
100
100
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {byteArrayEquals} from "@chainsafe/ssz";
|
|
2
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
2
|
import {DOMAIN_SYNC_COMMITTEE, SYNC_COMMITTEE_SIZE} from "@lodestar/params";
|
|
4
3
|
import {altair, ssz} from "@lodestar/types";
|
|
5
|
-
import {
|
|
4
|
+
import {byteArrayEquals} from "@lodestar/utils";
|
|
6
5
|
import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
|
|
7
6
|
import {G2_POINT_AT_INFINITY} from "../constants/index.js";
|
|
8
7
|
import {CachedBeaconStateAllForks} from "../types.js";
|
|
@@ -28,13 +27,12 @@ export function processSyncAggregate(
|
|
|
28
27
|
const participantIndices = block.body.syncAggregate.syncCommitteeBits.intersectValues(committeeIndices);
|
|
29
28
|
const signatureSet = getSyncCommitteeSignatureSet(
|
|
30
29
|
state.config,
|
|
31
|
-
state.epochCtx.index2pubkey,
|
|
32
30
|
state.epochCtx.currentSyncCommitteeIndexed,
|
|
33
31
|
block,
|
|
34
32
|
participantIndices
|
|
35
33
|
);
|
|
36
|
-
// When there's no participation we consider the signature valid and just ignore
|
|
37
|
-
if (signatureSet !== null && !verifySignatureSet(signatureSet)) {
|
|
34
|
+
// When there's no participation we consider the signature valid and just ignore it
|
|
35
|
+
if (signatureSet !== null && !verifySignatureSet(signatureSet, state.epochCtx.index2pubkey)) {
|
|
38
36
|
throw Error("Sync committee signature invalid");
|
|
39
37
|
}
|
|
40
38
|
}
|
|
@@ -73,7 +71,6 @@ export function processSyncAggregate(
|
|
|
73
71
|
|
|
74
72
|
export function getSyncCommitteeSignatureSet(
|
|
75
73
|
config: BeaconConfig,
|
|
76
|
-
index2pubkey: Index2PubkeyCache,
|
|
77
74
|
currentSyncCommitteeIndexed: SyncCommitteeCache,
|
|
78
75
|
block: altair.BeaconBlock,
|
|
79
76
|
/** Optional parameter to prevent computing it twice */
|
|
@@ -122,7 +119,7 @@ export function getSyncCommitteeSignatureSet(
|
|
|
122
119
|
|
|
123
120
|
return {
|
|
124
121
|
type: SignatureSetType.aggregate,
|
|
125
|
-
|
|
122
|
+
indices: participantIndices,
|
|
126
123
|
signingRoot: computeSigningRoot(ssz.Root, rootSigned, domain),
|
|
127
124
|
signature,
|
|
128
125
|
};
|