Skip to content

Commit 99941e8

Browse files
committed
test: correct lightclient committee root test for electra
The test incorrectly assumed sync committees would have alternating pubkeys [pk0, pk1, pk0, pk1, ...], but sync committees are computed using a weighted random shuffle based on validator effective balances and a seed. Post-electra, the shuffle algorithm uses 16-bit random values (vs 8-bit pre-electra) and MAX_EFFECTIVE_BALANCE_ELECTRA, producing different committee distributions. Fix: Get the actual sync committee root from the head state instead of constructing an incorrect expected committee. Closes #8723
1 parent 9defa5c commit 99941e8

File tree

1 file changed

+9
-20
lines changed

1 file changed

+9
-20
lines changed

packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import {afterEach, beforeEach, describe, expect, it} from "vitest";
2-
import {aggregateSerializedPublicKeys} from "@chainsafe/blst";
32
import {HttpHeader, getClient, routes} from "@lodestar/api";
43
import {ChainConfig, createBeaconConfig} from "@lodestar/config";
5-
import {ForkName, SYNC_COMMITTEE_SIZE} from "@lodestar/params";
4+
import {ForkName} from "@lodestar/params";
65
import {phase0, ssz} from "@lodestar/types";
76
import {sleep} from "@lodestar/utils";
87
import {Validator} from "@lodestar/validator";
@@ -119,29 +118,19 @@ describe("lightclient api", () => {
119118
expect(finalityUpdate).toBeDefined();
120119
});
121120

122-
it.skip("getLightClientCommitteeRoot() for the 1st period", async () => {
123-
// need to investigate why this test fails after upgrading to electra
124-
// TODO: https://github.com/ChainSafe/lodestar/issues/8723
121+
it("getLightClientCommitteeRoot() for the 1st period", async () => {
125122
await waitForBestUpdate();
126123

127124
const lightclient = getClient({baseUrl: `http://127.0.0.1:${restPort}`}, {config}).lightclient;
128125
const committeeRes = await lightclient.getLightClientCommitteeRoot({startPeriod: 0, count: 1});
129126
committeeRes.assertOk();
130-
const client = getClient({baseUrl: `http://127.0.0.1:${restPort}`}, {config}).beacon;
131-
const validators = (await client.postStateValidators({stateId: "head"})).value();
132-
const pubkeys = validators.map((v) => v.validator.pubkey);
133-
expect(pubkeys.length).toBe(validatorCount);
134-
// only 2 validators spreading to 512 committee slots
135-
const committeePubkeys = Array.from({length: SYNC_COMMITTEE_SIZE}, (_, i) =>
136-
i % 2 === 0 ? pubkeys[0] : pubkeys[1]
137-
);
138-
const aggregatePubkey = aggregateSerializedPublicKeys(committeePubkeys).toBytes();
127+
128+
// Get the actual sync committee root from the head state
129+
// The sync committee is computed using a weighted random shuffle, not simple alternation
130+
const headState = bn.chain.getHeadState();
131+
const expectedRoot = headState.currentSyncCommittee.hashTreeRoot();
132+
139133
// single committee hash since we requested for the first period
140-
expect(committeeRes.value()).toEqual([
141-
ssz.altair.SyncCommittee.hashTreeRoot({
142-
pubkeys: committeePubkeys,
143-
aggregatePubkey,
144-
}),
145-
]);
134+
expect(committeeRes.value()).toEqual([expectedRoot]);
146135
});
147136
});

0 commit comments

Comments
 (0)