Skip to content

Commit

Permalink
Merge branch 'nc/devnet-4' into nc/compounding-switch
Browse files Browse the repository at this point in the history
  • Loading branch information
ensi321 authored Oct 11, 2024
2 parents 522e8c9 + 1331994 commit 46b0d9a
Show file tree
Hide file tree
Showing 21 changed files with 273 additions and 221 deletions.
114 changes: 41 additions & 73 deletions packages/beacon-node/src/execution/engine/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {capella, deneb, electra, Wei, bellatrix, Root, ExecutionPayload, ExecutionRequests} from "@lodestar/types";
import {capella, deneb, electra, Wei, bellatrix, Root, ExecutionPayload, ExecutionRequests, ssz} from "@lodestar/types";
import {
BYTES_PER_LOGS_BLOOM,
FIELD_ELEMENTS_PER_BLOB,
Expand Down Expand Up @@ -161,29 +161,17 @@ export type WithdrawalRpc = {
amount: QUANTITY;
};

export type ExecutionRequestsRpc = {
deposits: DepositRequestRpc[];
withdrawals: WithdrawalRequestRpc[];
consolidations: ConsolidationRequestRpc[];
};
/**
* ExecutionRequestsRpc only holds 3 elements in the following order:
* - ssz'ed DepositRequests
* - ssz'ed WithdrawalRequests
* - ssz'ed ConsolidationRequests
*/
export type ExecutionRequestsRpc = [DepositRequestsRpc, WithdrawalRequestsRpc, ConsolidationRequestsRpc];

export type DepositRequestRpc = {
pubkey: DATA;
withdrawalCredentials: DATA;
amount: QUANTITY;
signature: DATA;
index: QUANTITY;
};
export type WithdrawalRequestRpc = {
sourceAddress: DATA;
validatorPubkey: DATA;
amount: QUANTITY;
};
export type ConsolidationRequestRpc = {
sourceAddress: DATA;
sourcePubkey: DATA;
targetPubkey: DATA;
};
export type DepositRequestsRpc = DATA;
export type WithdrawalRequestsRpc = DATA;
export type ConsolidationRequestsRpc = DATA;

export type VersionedHashesRpc = DATA[];

Expand Down Expand Up @@ -406,73 +394,53 @@ export function deserializeWithdrawal(serialized: WithdrawalRpc): capella.Withdr
} as capella.Withdrawal;
}

function serializeDepositRequest(depositRequest: electra.DepositRequest): DepositRequestRpc {
return {
pubkey: bytesToData(depositRequest.pubkey),
withdrawalCredentials: bytesToData(depositRequest.withdrawalCredentials),
amount: numToQuantity(depositRequest.amount),
signature: bytesToData(depositRequest.signature),
index: numToQuantity(depositRequest.index),
};
function serializeDepositRequests(depositRequests: electra.DepositRequests): DepositRequestsRpc {
return bytesToData(ssz.electra.DepositRequests.serialize(depositRequests));
}

function deserializeDepositRequest(serialized: DepositRequestRpc): electra.DepositRequest {
return {
pubkey: dataToBytes(serialized.pubkey, 48),
withdrawalCredentials: dataToBytes(serialized.withdrawalCredentials, 32),
amount: quantityToNum(serialized.amount),
signature: dataToBytes(serialized.signature, 96),
index: quantityToNum(serialized.index),
} as electra.DepositRequest;
function deserializeDepositRequests(serialized: DepositRequestsRpc): electra.DepositRequests {
return ssz.electra.DepositRequests.deserialize(dataToBytes(serialized, null));
}

function serializeWithdrawalRequest(withdrawalRequest: electra.WithdrawalRequest): WithdrawalRequestRpc {
return {
sourceAddress: bytesToData(withdrawalRequest.sourceAddress),
validatorPubkey: bytesToData(withdrawalRequest.validatorPubkey),
amount: numToQuantity(withdrawalRequest.amount),
};
function serializeWithdrawalRequests(withdrawalRequests: electra.WithdrawalRequests): WithdrawalRequestsRpc {
return bytesToData(ssz.electra.WithdrawalRequests.serialize(withdrawalRequests));
}

function deserializeWithdrawalRequest(withdrawalRequest: WithdrawalRequestRpc): electra.WithdrawalRequest {
return {
sourceAddress: dataToBytes(withdrawalRequest.sourceAddress, 20),
validatorPubkey: dataToBytes(withdrawalRequest.validatorPubkey, 48),
amount: quantityToBigint(withdrawalRequest.amount),
};
function deserializeWithdrawalRequest(serialized: WithdrawalRequestsRpc): electra.WithdrawalRequests {
return ssz.electra.WithdrawalRequests.deserialize(dataToBytes(serialized, null));
}

function serializeConsolidationRequest(consolidationRequest: electra.ConsolidationRequest): ConsolidationRequestRpc {
return {
sourceAddress: bytesToData(consolidationRequest.sourceAddress),
sourcePubkey: bytesToData(consolidationRequest.sourcePubkey),
targetPubkey: bytesToData(consolidationRequest.targetPubkey),
};
function serializeConsolidationRequests(
consolidationRequests: electra.ConsolidationRequests
): ConsolidationRequestsRpc {
return bytesToData(ssz.electra.ConsolidationRequests.serialize(consolidationRequests));
}

function deserializeConsolidationRequest(consolidationRequest: ConsolidationRequestRpc): electra.ConsolidationRequest {
return {
sourceAddress: dataToBytes(consolidationRequest.sourceAddress, 20),
sourcePubkey: dataToBytes(consolidationRequest.sourcePubkey, 48),
targetPubkey: dataToBytes(consolidationRequest.targetPubkey, 48),
};
function deserializeConsolidationRequests(serialized: ConsolidationRequestsRpc): electra.ConsolidationRequests {
return ssz.electra.ConsolidationRequests.deserialize(dataToBytes(serialized, null));
}

/**
* This is identical to get_execution_requests_list in
* https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.8/specs/electra/beacon-chain.md#new-get_execution_requests_list
*/
export function serializeExecutionRequests(executionRequests: ExecutionRequests): ExecutionRequestsRpc {
const {deposits, withdrawals, consolidations} = executionRequests;
return {
deposits: deposits.map(serializeDepositRequest),
withdrawals: withdrawals.map(serializeWithdrawalRequest),
consolidations: consolidations.map(serializeConsolidationRequest),
};

return [
serializeDepositRequests(deposits),
serializeWithdrawalRequests(withdrawals),
serializeConsolidationRequests(consolidations),
];
}

export function deserializeExecutionRequests(executionRequests: ExecutionRequestsRpc): ExecutionRequests {
const {deposits, withdrawals, consolidations} = executionRequests;
export function deserializeExecutionRequests(serialized: ExecutionRequestsRpc): ExecutionRequests {
const [deposits, withdrawals, consolidations] = serialized;

return {
deposits: deposits.map(deserializeDepositRequest),
withdrawals: withdrawals.map(deserializeWithdrawalRequest),
consolidations: consolidations.map(deserializeConsolidationRequest),
deposits: deserializeDepositRequests(deposits),
withdrawals: deserializeWithdrawalRequest(withdrawals),
consolidations: deserializeConsolidationRequests(consolidations),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const epochTransitionFns: Record<string, EpochTransitionFn> = {
epochFns.processSyncCommitteeUpdates(fork, state as CachedBeaconStateAltair);
},
historical_summaries_update: epochFns.processHistoricalSummariesUpdate as EpochTransitionFn,
pending_balance_deposits: epochFns.processPendingBalanceDeposits as EpochTransitionFn,
pending_deposits: epochFns.processPendingDeposits as EpochTransitionFn,
pending_consolidations: epochFns.processPendingConsolidations as EpochTransitionFn,
};

Expand Down
3 changes: 2 additions & 1 deletion packages/params/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export const {

MAX_EFFECTIVE_BALANCE_ELECTRA,
MIN_ACTIVATION_BALANCE,
PENDING_BALANCE_DEPOSITS_LIMIT,
PENDING_DEPOSITS_LIMIT,
PENDING_PARTIAL_WITHDRAWALS_LIMIT,
PENDING_CONSOLIDATIONS_LIMIT,
MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA,
Expand All @@ -107,6 +107,7 @@ export const {
MAX_ATTESTER_SLASHINGS_ELECTRA,
MAX_ATTESTATIONS_ELECTRA,
MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP,
MAX_PENDING_DEPOSITS_PER_EPOCH,
WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA,
} = activePreset;

Expand Down
3 changes: 2 additions & 1 deletion packages/params/src/presets/mainnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,12 @@ export const mainnetPreset: BeaconPreset = {
MAX_ATTESTER_SLASHINGS_ELECTRA: 1,
MAX_ATTESTATIONS_ELECTRA: 8,
MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 8,
MAX_PENDING_DEPOSITS_PER_EPOCH: 16,
// 2**11 * 10**9 (= 2,048,000,000,000) Gwei
MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000,
MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA: 4096,
MIN_ACTIVATION_BALANCE: 32000000000,
PENDING_BALANCE_DEPOSITS_LIMIT: 134217728,
PENDING_DEPOSITS_LIMIT: 134217728,
PENDING_PARTIAL_WITHDRAWALS_LIMIT: 134217728,
PENDING_CONSOLIDATIONS_LIMIT: 262144,
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: 1,
Expand Down
5 changes: 3 additions & 2 deletions packages/params/src/presets/minimal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,13 @@ export const minimalPreset: BeaconPreset = {
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 2,
MAX_ATTESTER_SLASHINGS_ELECTRA: 1,
MAX_ATTESTATIONS_ELECTRA: 8,
MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 1,
MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 2,
MAX_PENDING_DEPOSITS_PER_EPOCH: 16,
// 2**11 * 10**9 (= 2,048,000,000,000) Gwei
MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000,
MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA: 4096,
MIN_ACTIVATION_BALANCE: 32000000000,
PENDING_BALANCE_DEPOSITS_LIMIT: 134217728,
PENDING_DEPOSITS_LIMIT: 134217728,
PENDING_PARTIAL_WITHDRAWALS_LIMIT: 64,
PENDING_CONSOLIDATIONS_LIMIT: 64,
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: 1,
Expand Down
6 changes: 4 additions & 2 deletions packages/params/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,11 @@ export type BeaconPreset = {
MAX_ATTESTER_SLASHINGS_ELECTRA: number;
MAX_ATTESTATIONS_ELECTRA: number;
MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: number;
MAX_PENDING_DEPOSITS_PER_EPOCH: number;
MAX_EFFECTIVE_BALANCE_ELECTRA: number;
MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA: number;
MIN_ACTIVATION_BALANCE: number;
PENDING_BALANCE_DEPOSITS_LIMIT: number;
PENDING_DEPOSITS_LIMIT: number;
PENDING_PARTIAL_WITHDRAWALS_LIMIT: number;
PENDING_CONSOLIDATIONS_LIMIT: number;
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: number;
Expand Down Expand Up @@ -189,10 +190,11 @@ export const beaconPresetTypes: BeaconPresetTypes = {
MAX_ATTESTER_SLASHINGS_ELECTRA: "number",
MAX_ATTESTATIONS_ELECTRA: "number",
MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: "number",
MAX_PENDING_DEPOSITS_PER_EPOCH: "number",
MAX_EFFECTIVE_BALANCE_ELECTRA: "number",
MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA: "number",
MIN_ACTIVATION_BALANCE: "number",
PENDING_BALANCE_DEPOSITS_LIMIT: "number",
PENDING_DEPOSITS_LIMIT: "number",
PENDING_PARTIAL_WITHDRAWALS_LIMIT: "number",
PENDING_CONSOLIDATIONS_LIMIT: "number",
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: "number",
Expand Down
69 changes: 37 additions & 32 deletions packages/state-transition/src/block/processDeposit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import {
EFFECTIVE_BALANCE_INCREMENT,
FAR_FUTURE_EPOCH,
ForkSeq,
GENESIS_SLOT,
MAX_EFFECTIVE_BALANCE,
} from "@lodestar/params";

import {DepositData} from "@lodestar/types/lib/phase0/types.js";
import {DepositRequest} from "@lodestar/types/lib/electra/types.js";
import {BeaconConfig} from "@lodestar/config";
import {ZERO_HASH} from "../constants/index.js";
import {computeDomain, computeSigningRoot, increaseBalance} from "../util/index.js";
import {computeDomain, computeSigningRoot, getMaxEffectiveBalance, increaseBalance} from "../util/index.js";
import {CachedBeaconStateAllForks, CachedBeaconStateAltair, CachedBeaconStateElectra} from "../types.js";

/**
Expand Down Expand Up @@ -54,30 +55,42 @@ export function applyDeposit(
state: CachedBeaconStateAllForks,
deposit: DepositData | DepositRequest
): void {
const {config, validators, epochCtx} = state;
const {pubkey, withdrawalCredentials, amount} = deposit;
const {config, epochCtx} = state;
const {pubkey, withdrawalCredentials, amount, signature} = deposit;

const cachedIndex = epochCtx.getValidatorIndex(pubkey);
if (cachedIndex === null || !Number.isSafeInteger(cachedIndex) || cachedIndex >= validators.length) {
if (isValidDepositSignature(config, pubkey, withdrawalCredentials, amount, deposit.signature)) {
addValidatorToRegistry(fork, state, pubkey, withdrawalCredentials, amount);
}
} else {
if (fork < ForkSeq.electra) {
const isNewValidator = cachedIndex === null || !Number.isSafeInteger(cachedIndex);

if (fork < ForkSeq.electra) {
if (isNewValidator) {
if (isValidDepositSignature(config, pubkey, withdrawalCredentials, amount, signature)) {
addValidatorToRegistry(fork, state, pubkey, withdrawalCredentials, amount);
}
} else {
// increase balance by deposit amount right away pre-electra
increaseBalance(state, cachedIndex, amount);
} else if (fork >= ForkSeq.electra) {
const stateElectra = state as CachedBeaconStateElectra;
const pendingBalanceDeposit = ssz.electra.PendingBalanceDeposit.toViewDU({
index: cachedIndex,
amount: BigInt(amount),
});
stateElectra.pendingBalanceDeposits.push(pendingBalanceDeposit);
increaseBalance(state, cachedIndex, amount); }
} else {
const stateElectra = state as CachedBeaconStateElectra;
const pendingDeposit = ssz.electra.PendingDeposit.toViewDU({
pubkey,
withdrawalCredentials,
amount,
signature,
slot: GENESIS_SLOT, // Use GENESIS_SLOT to distinguish from a pending deposit request
});

if (isNewValidator) {
if (isValidDepositSignature(config, pubkey, withdrawalCredentials, amount, deposit.signature)) {
addValidatorToRegistry(fork, state, pubkey, withdrawalCredentials, 0);
stateElectra.pendingDeposits.push(pendingDeposit);
}
} else {
stateElectra.pendingDeposits.push(pendingDeposit);
}
}
}

function addValidatorToRegistry(
export function addValidatorToRegistry(
fork: ForkSeq,
state: CachedBeaconStateAllForks,
pubkey: BLSPubkey,
Expand All @@ -86,8 +99,10 @@ function addValidatorToRegistry(
): void {
const {validators, epochCtx} = state;
// add validator and balance entries
const effectiveBalance =
fork < ForkSeq.electra ? Math.min(amount - (amount % EFFECTIVE_BALANCE_INCREMENT), MAX_EFFECTIVE_BALANCE) : 0;
const effectiveBalance = Math.min(
amount - (amount % EFFECTIVE_BALANCE_INCREMENT),
fork < ForkSeq.electra ? MAX_EFFECTIVE_BALANCE : getMaxEffectiveBalance(withdrawalCredentials)
);
validators.push(
ssz.phase0.Validator.toViewDU({
pubkey,
Expand Down Expand Up @@ -123,20 +138,10 @@ function addValidatorToRegistry(
stateAltair.currentEpochParticipation.push(0);
}

if (fork < ForkSeq.electra) {
state.balances.push(amount);
} else if (fork >= ForkSeq.electra) {
state.balances.push(0);
const stateElectra = state as CachedBeaconStateElectra;
const pendingBalanceDeposit = ssz.electra.PendingBalanceDeposit.toViewDU({
index: validatorIndex,
amount: BigInt(amount),
});
stateElectra.pendingBalanceDeposits.push(pendingBalanceDeposit);
}
state.balances.push(amount);
}

function isValidDepositSignature(
export function isValidDepositSignature(
config: BeaconConfig,
pubkey: Uint8Array,
withdrawalCredentials: Uint8Array,
Expand Down
13 changes: 10 additions & 3 deletions packages/state-transition/src/block/processDepositRequest.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import {electra} from "@lodestar/types";
import {electra, ssz} from "@lodestar/types";
import {ForkSeq, UNSET_DEPOSIT_REQUESTS_START_INDEX} from "@lodestar/params";

import {CachedBeaconStateElectra} from "../types.js";
import {applyDeposit} from "./processDeposit.js";

export function processDepositRequest(
fork: ForkSeq,
Expand All @@ -13,5 +12,13 @@ export function processDepositRequest(
state.depositRequestsStartIndex = BigInt(depositRequest.index);
}

applyDeposit(fork, state, depositRequest);
// Create pending deposit
const pendingDeposit = ssz.electra.PendingDeposit.toViewDU({
pubkey: depositRequest.pubkey,
withdrawalCredentials: depositRequest.withdrawalCredentials,
amount: depositRequest.amount,
signature: depositRequest.signature,
slot: state.slot,
});
state.pendingDeposits.push(pendingDeposit);
}
5 changes: 3 additions & 2 deletions packages/state-transition/src/block/processWithdrawals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ export function getExpectedWithdrawals(

const withdrawals: capella.Withdrawal[] = [];
const isPostElectra = fork >= ForkSeq.electra;
// partialWithdrawalsCount is withdrawals coming from EL since electra (EIP-7002)
let partialWithdrawalsCount = 0;

if (isPostElectra) {
const stateElectra = state as CachedBeaconStateElectra;
Expand Down Expand Up @@ -138,11 +140,10 @@ export function getExpectedWithdrawals(
});
withdrawalIndex++;
}
partialWithdrawalsCount++;
}
}

// partialWithdrawalsCount is withdrawals coming from EL since electra (EIP-7002)
const partialWithdrawalsCount = withdrawals.length;
const bound = Math.min(validators.length, MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP);
let n = 0;
// Just run a bounded loop max iterating over all withdrawals
Expand Down
Loading

0 comments on commit 46b0d9a

Please sign in to comment.