diff --git a/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts b/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts index d26703050070..e4c86b78907c 100644 --- a/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts +++ b/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts @@ -1,11 +1,10 @@ import {ChainForkConfig} from "@lodestar/config"; -import {ForkExecution, ForkSeq, isForkExecution} from "@lodestar/params"; +import {ForkExecution, ForkSeq, isForkExecution, isForkLightClient} from "@lodestar/params"; import { CachedBeaconStateAllForks, CachedBeaconStateBellatrix, CachedBeaconStateCapella, CachedBeaconStateExecutions, - computeEpochAtSlot, computeTimeAtSlot, getCurrentEpoch, getExpectedWithdrawals, @@ -143,8 +142,15 @@ export async function produceBlockBody<T extends BlockType>( ? Object.assign({}, commonBlockBody) : await produceCommonBlockBody.call(this, blockType, currentState, blockAttr); - const {attestations, deposits, voluntaryExits, attesterSlashings, proposerSlashings, blsToExecutionChanges} = - blockBody; + const { + attestations, + deposits, + voluntaryExits, + attesterSlashings, + proposerSlashings, + syncAggregate, + blsToExecutionChanges, + } = blockBody; Object.assign(logMeta, { attestations: attestations.length, @@ -154,6 +160,12 @@ export async function produceBlockBody<T extends BlockType>( proposerSlashings: proposerSlashings.length, }); + if (isForkLightClient(fork)) { + Object.assign(logMeta, { + syncAggregateParticipants: syncAggregate.syncCommitteeBits.getTrueBitIndexes().length, + }); + } + const endExecutionPayload = stepsMetrics?.startTimer(); if (isForkExecution(fork)) { const safeBlockHash = this.forkChoice.getJustifiedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX; @@ -608,7 +620,6 @@ export async function produceCommonBlockBody<T extends BlockType>( ? this.metrics?.executionBlockProductionTimeSteps : this.metrics?.builderBlockProductionTimeSteps; - const blockEpoch = computeEpochAtSlot(slot); const fork = currentState.config.getForkName(slot); // TODO: @@ -653,7 +664,7 @@ export async function produceCommonBlockBody<T extends BlockType>( } const endSyncAggregate = stepsMetrics?.startTimer(); - if (blockEpoch >= this.config.ALTAIR_FORK_EPOCH) { + if (ForkSeq[fork] >= ForkSeq.altair) { const syncAggregate = this.syncContributionAndProofPool.getAggregate(parentSlot, parentBlockRoot); this.metrics?.production.producedSyncAggregateParticipants.observe( syncAggregate.syncCommitteeBits.getTrueBitIndexes().length diff --git a/packages/beacon-node/test/mocks/mockedBeaconChain.ts b/packages/beacon-node/test/mocks/mockedBeaconChain.ts index b274284e3ab1..36d6fb27c53a 100644 --- a/packages/beacon-node/test/mocks/mockedBeaconChain.ts +++ b/packages/beacon-node/test/mocks/mockedBeaconChain.ts @@ -8,7 +8,7 @@ import {BeaconProposerCache} from "../../src/chain/beaconProposerCache.js"; import {BeaconChain} from "../../src/chain/chain.js"; import {ChainEventEmitter} from "../../src/chain/emitter.js"; import {LightClientServer} from "../../src/chain/lightClient/index.js"; -import {AggregatedAttestationPool, OpPool} from "../../src/chain/opPools/index.js"; +import {AggregatedAttestationPool, OpPool, SyncContributionAndProofPool} from "../../src/chain/opPools/index.js"; import {QueuedStateRegenerator} from "../../src/chain/regen/index.js"; import {ShufflingCache} from "../../src/chain/shufflingCache.js"; import {Eth1ForBlockProduction} from "../../src/eth1/index.js"; @@ -27,6 +27,7 @@ export type MockedBeaconChain = Mocked<BeaconChain> & { eth1: Mocked<Eth1ForBlockProduction>; opPool: Mocked<OpPool>; aggregatedAttestationPool: Mocked<AggregatedAttestationPool>; + syncContributionAndProofPool: Mocked<SyncContributionAndProofPool>; beaconProposerCache: Mocked<BeaconProposerCache>; shufflingCache: Mocked<ShufflingCache>; regen: Mocked<QueuedStateRegenerator>; @@ -94,10 +95,17 @@ vi.mock("../../src/chain/opPools/index.js", async (importActual) => { }; }); + const SyncContributionAndProofPool = vi.fn().mockImplementation(() => { + return { + getAggregate: vi.fn(), + }; + }); + return { ...mod, OpPool, AggregatedAttestationPool, + SyncContributionAndProofPool, }; }); @@ -124,6 +132,7 @@ vi.mock("../../src/chain/chain.js", async (importActual) => { eth1: new Eth1ForBlockProduction(), opPool: new OpPool(), aggregatedAttestationPool: new AggregatedAttestationPool(config), + syncContributionAndProofPool: new SyncContributionAndProofPool(), // @ts-expect-error beaconProposerCache: new BeaconProposerCache(), shufflingCache: new ShufflingCache(), diff --git a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts index 52f600b7174c..418dd2e56d8d 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts @@ -1,7 +1,7 @@ import {fromHexString, toHexString} from "@chainsafe/ssz"; import {ProtoBlock} from "@lodestar/fork-choice"; import {ForkName} from "@lodestar/params"; -import {CachedBeaconStateBellatrix, computeTimeAtSlot} from "@lodestar/state-transition"; +import {CachedBeaconStateBellatrix, G2_POINT_AT_INFINITY, computeTimeAtSlot} from "@lodestar/state-transition"; import {ssz} from "@lodestar/types"; import {afterEach, beforeEach, describe, expect, it, vi} from "vitest"; import {getValidatorApi} from "../../../../../src/api/impl/validator/index.js"; @@ -99,6 +99,10 @@ describe("api/validator - produceBlockV2", () => { eth1Data: ssz.phase0.Eth1Data.defaultValue(), deposits: [], }); + modules.chain["syncContributionAndProofPool"].getAggregate.mockReturnValue({ + syncCommitteeBits: ssz.altair.SyncCommitteeBits.defaultValue(), + syncCommitteeSignature: G2_POINT_AT_INFINITY, + }); modules.forkChoice.getJustifiedBlock.mockReturnValue({} as ProtoBlock); modules.forkChoice.getFinalizedBlock.mockReturnValue({} as ProtoBlock);