Skip to content

Commit e353f67

Browse files
authored
fix: check pubkey or validator index known to a state (#7284)
* fix: check pubkey or validator index known to a state * chore: add more comments
1 parent cd1211f commit e353f67

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

packages/state-transition/src/block/processConsolidationRequest.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {electra, ssz} from "@lodestar/types";
33

44
import {CachedBeaconStateElectra} from "../types.js";
55
import {hasEth1WithdrawalCredential} from "../util/capella.js";
6-
import {hasExecutionWithdrawalCredential, switchToCompoundingValidator} from "../util/electra.js";
6+
import {hasExecutionWithdrawalCredential, isPubkeyKnown, switchToCompoundingValidator} from "../util/electra.js";
77
import {computeConsolidationEpochAndUpdateChurn} from "../util/epoch.js";
88
import {getConsolidationChurnLimit, isActiveValidator} from "../util/validator.js";
99

@@ -13,6 +13,10 @@ export function processConsolidationRequest(
1313
consolidationRequest: electra.ConsolidationRequest
1414
): void {
1515
const {sourcePubkey, targetPubkey, sourceAddress} = consolidationRequest;
16+
if (!isPubkeyKnown(state, sourcePubkey) || !isPubkeyKnown(state, targetPubkey)) {
17+
return;
18+
}
19+
1620
const sourceIndex = state.epochCtx.getValidatorIndex(sourcePubkey);
1721
const targetIndex = state.epochCtx.getValidatorIndex(targetPubkey);
1822

@@ -97,6 +101,7 @@ function isValidSwitchToCompoundRequest(
97101

98102
// Verify pubkey exists
99103
if (sourceIndex === null) {
104+
// this check is mainly to make the compiler happy, pubkey is checked by the consumer already
100105
return false;
101106
}
102107

packages/state-transition/src/epoch/processPendingDeposits.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {PendingDeposit} from "@lodestar/types/lib/electra/types.js";
33
import {addValidatorToRegistry, isValidDepositSignature} from "../block/processDeposit.js";
44
import {CachedBeaconStateElectra, EpochTransitionCache} from "../types.js";
55
import {increaseBalance} from "../util/balance.js";
6-
import {hasCompoundingWithdrawalCredential} from "../util/electra.js";
6+
import {hasCompoundingWithdrawalCredential, isValidatorKnown} from "../util/electra.js";
77
import {computeStartSlotAtEpoch} from "../util/epoch.js";
88
import {getActivationExitChurnLimit} from "../util/validator.js";
99

@@ -51,7 +51,7 @@ export function processPendingDeposits(state: CachedBeaconStateElectra, cache: E
5151
let isValidatorWithdrawn = false;
5252

5353
const validatorIndex = state.epochCtx.getValidatorIndex(deposit.pubkey);
54-
if (validatorIndex !== null) {
54+
if (isValidatorKnown(state, validatorIndex)) {
5555
const validator = state.validators.getReadonly(validatorIndex);
5656
isValidatorExited = validator.exitEpoch < FAR_FUTURE_EPOCH;
5757
isValidatorWithdrawn = validator.withdrawableEpoch < nextEpoch;
@@ -103,7 +103,7 @@ function applyPendingDeposit(
103103
const {pubkey, withdrawalCredentials, amount, signature} = deposit;
104104
const cachedBalances = cache.balances;
105105

106-
if (validatorIndex === null) {
106+
if (!isValidatorKnown(state, validatorIndex)) {
107107
// Verify the deposit signature (proof of possession) which is not checked by the deposit contract
108108
if (isValidDepositSignature(state.config, pubkey, withdrawalCredentials, amount, signature)) {
109109
addValidatorToRegistry(ForkSeq.electra, state, pubkey, withdrawalCredentials, amount);

packages/state-transition/src/util/electra.ts

+17
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,20 @@ export function queueExcessActiveBalance(state: CachedBeaconStateElectra, index:
4545
state.pendingDeposits.push(pendingDeposit);
4646
}
4747
}
48+
49+
/**
50+
* Since we share pubkey2index, pubkey maybe added by other epoch transition but we don't have that validator in this state
51+
*/
52+
export function isPubkeyKnown(state: CachedBeaconStateElectra, pubkey: Uint8Array): boolean {
53+
return isValidatorKnown(state, state.epochCtx.getValidatorIndex(pubkey));
54+
}
55+
56+
/**
57+
* Since we share pubkey2index, validatorIndex maybe not null but we don't have that validator in this state
58+
*/
59+
export function isValidatorKnown(
60+
state: CachedBeaconStateElectra,
61+
index: ValidatorIndex | null
62+
): index is ValidatorIndex {
63+
return index !== null && index < state.validators.length;
64+
}

0 commit comments

Comments
 (0)