Skip to content

Commit

Permalink
Add normalizeMerkleBranch
Browse files Browse the repository at this point in the history
  • Loading branch information
ensi321 committed Aug 19, 2024
1 parent a3bf280 commit b836ce5
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 13 deletions.
7 changes: 6 additions & 1 deletion packages/beacon-node/src/chain/lightClient/proofs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import {Tree} from "@chainsafe/persistent-merkle-tree";
import {BeaconStateAllForks, CachedBeaconStateAllForks} from "@lodestar/state-transition";
import {FINALIZED_ROOT_GINDEX, BLOCK_BODY_EXECUTION_PAYLOAD_GINDEX, ForkExecution, FINALIZED_ROOT_GINDEX_ELECTRA} from "@lodestar/params";
import {
FINALIZED_ROOT_GINDEX,
BLOCK_BODY_EXECUTION_PAYLOAD_GINDEX,
ForkExecution,
FINALIZED_ROOT_GINDEX_ELECTRA,
} from "@lodestar/params";
import {BeaconBlockBody, SSZTypesFor, ssz} from "@lodestar/types";

import {SyncCommitteeWitness} from "./types.js";
Expand Down
23 changes: 18 additions & 5 deletions packages/beacon-node/src/network/reqresp/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import {Type} from "@chainsafe/ssz";
import {ForkLightClient, ForkName, isForkLightClient} from "@lodestar/params";
import {Protocol, ProtocolHandler, ReqRespRequest} from "@lodestar/reqresp";
import {Metadata, Root, SignedBeaconBlock, altair, deneb, phase0, ssz, sszTypesFor} from "@lodestar/types";
import {
LightClientBootstrap,
LightClientFinalityUpdate,
LightClientOptimisticUpdate,
LightClientUpdate,
Metadata,
Root,
SignedBeaconBlock,
altair,
deneb,
phase0,
ssz,
sszTypesFor,
} from "@lodestar/types";

export type ProtocolNoHandler = Omit<Protocol, "handler">;

Expand Down Expand Up @@ -48,10 +61,10 @@ type ResponseBodyByMethod = {
[ReqRespMethod.BeaconBlocksByRoot]: SignedBeaconBlock;
[ReqRespMethod.BlobSidecarsByRange]: deneb.BlobSidecar;
[ReqRespMethod.BlobSidecarsByRoot]: deneb.BlobSidecar;
[ReqRespMethod.LightClientBootstrap]: altair.LightClientBootstrap;
[ReqRespMethod.LightClientUpdatesByRange]: altair.LightClientUpdate;
[ReqRespMethod.LightClientFinalityUpdate]: altair.LightClientFinalityUpdate;
[ReqRespMethod.LightClientOptimisticUpdate]: altair.LightClientOptimisticUpdate;
[ReqRespMethod.LightClientBootstrap]: LightClientBootstrap;
[ReqRespMethod.LightClientUpdatesByRange]: LightClientUpdate;
[ReqRespMethod.LightClientFinalityUpdate]: LightClientFinalityUpdate;
[ReqRespMethod.LightClientOptimisticUpdate]: LightClientOptimisticUpdate;
};

/** Request SSZ type for each method and ForkName */
Expand Down
23 changes: 20 additions & 3 deletions packages/light-client/src/spec/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
BLOCK_BODY_EXECUTION_PAYLOAD_INDEX as EXECUTION_PAYLOAD_INDEX,
NEXT_SYNC_COMMITTEE_DEPTH_ELECTRA,
isForkPostElectra,
FINALIZED_ROOT_DEPTH_ELECTRA,
} from "@lodestar/params";
import {
ssz,
Expand All @@ -24,6 +25,7 @@ import {
import {ChainForkConfig} from "@lodestar/config";

import {isValidMerkleBranch, computeEpochAtSlot, computeSyncPeriodAtSlot} from "../utils/index.js";
import {normalizeMerkleBranch} from "../utils/normalizeMerkleBranch.js";
import {LightClientStore} from "./store.js";

export const GENESIS_SLOT = 0;
Expand All @@ -44,15 +46,18 @@ export function getSafetyThreshold(maxActiveParticipants: number): number {
}

export function getZeroSyncCommitteeBranch(fork: ForkName): Uint8Array[] {
const nextSyncCommitteeDepth = isForkPostElectra(fork) ? NEXT_SYNC_COMMITTEE_DEPTH_ELECTRA : NEXT_SYNC_COMMITTEE_DEPTH;
const nextSyncCommitteeDepth = isForkPostElectra(fork)
? NEXT_SYNC_COMMITTEE_DEPTH_ELECTRA
: NEXT_SYNC_COMMITTEE_DEPTH;

return Array.from({length: nextSyncCommitteeDepth}, () => ZERO_HASH);
}

export function isSyncCommitteeUpdate(update: LightClientUpdate): boolean {
return (
// Fast return for when constructing full LightClientUpdate from partial updates
update.nextSyncCommitteeBranch !== getZeroSyncCommitteeBranch(isElectraLightClientUpdate(update) ? ForkName.electra : ForkName.altair) &&
update.nextSyncCommitteeBranch !==
getZeroSyncCommitteeBranch(isElectraLightClientUpdate(update) ? ForkName.electra : ForkName.altair) &&
update.nextSyncCommitteeBranch.some((branch) => !byteArrayEquals(branch, ZERO_HASH))
);
}
Expand Down Expand Up @@ -169,7 +174,7 @@ export function isValidLightClientHeader(config: ChainForkConfig, header: LightC
if (
(header as LightClientHeader<ForkName.electra>).execution.depositRequestsRoot !== undefined ||
(header as LightClientHeader<ForkName.electra>).execution.withdrawalRequestsRoot !== undefined ||
(header as LightClientHeader<ForkName.electra>).execution.consolidationRequestsRoot !== undefined
(header as LightClientHeader<ForkName.electra>).execution.consolidationRequestsRoot !== undefined
) {
return false;
}
Expand All @@ -193,6 +198,14 @@ export function upgradeLightClientUpdate(
): LightClientUpdate {
update.attestedHeader = upgradeLightClientHeader(config, targetFork, update.attestedHeader);
update.finalizedHeader = upgradeLightClientHeader(config, targetFork, update.finalizedHeader);
update.nextSyncCommitteeBranch = normalizeMerkleBranch(
update.nextSyncCommitteeBranch,
isForkPostElectra(targetFork) ? NEXT_SYNC_COMMITTEE_DEPTH_ELECTRA : NEXT_SYNC_COMMITTEE_DEPTH
);
update.finalityBranch = normalizeMerkleBranch(
update.finalityBranch,
isForkPostElectra(targetFork) ? FINALIZED_ROOT_DEPTH_ELECTRA : FINALIZED_ROOT_DEPTH
);

return update;
}
Expand All @@ -204,6 +217,10 @@ export function upgradeLightClientFinalityUpdate(
): LightClientFinalityUpdate {
finalityUpdate.attestedHeader = upgradeLightClientHeader(config, targetFork, finalityUpdate.attestedHeader);
finalityUpdate.finalizedHeader = upgradeLightClientHeader(config, targetFork, finalityUpdate.finalizedHeader);
finalityUpdate.finalityBranch = normalizeMerkleBranch(
finalityUpdate.finalityBranch,
isForkPostElectra(targetFork) ? FINALIZED_ROOT_DEPTH_ELECTRA : FINALIZED_ROOT_DEPTH
);

return finalityUpdate;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import {byteArrayEquals} from "@chainsafe/ssz";
import {LightClientBootstrap, Root, ssz} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {toHex} from "@lodestar/utils";
import {isForkPostElectra} from "@lodestar/params";
import {isValidMerkleBranch} from "../utils/verifyMerkleBranch.js";
import {isValidLightClientHeader} from "./utils.js";
import { isForkPostElectra } from "@lodestar/params";

const CURRENT_SYNC_COMMITTEE_INDEX = 22;
const CURRENT_SYNC_COMMITTEE_DEPTH = 5;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {ChainForkConfig} from "@lodestar/config";
import {
FINALIZED_ROOT_INDEX,
FINALIZED_ROOT_DEPTH,
NEXT_SYNC_COMMITTEE_INDEX,
NEXT_SYNC_COMMITTEE_DEPTH,
MIN_SYNC_COMMITTEE_PARTICIPANTS,
DOMAIN_SYNC_COMMITTEE,
Expand Down
16 changes: 16 additions & 0 deletions packages/light-client/src/utils/normalizeMerkleBranch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {ZERO_HASH} from "../spec/utils.js";

export const SYNC_COMMITTEES_DEPTH = 4;
export const SYNC_COMMITTEES_INDEX = 11;

/**
* Given merkle branch ``branch``, extend its depth according to ``depth``
* If given ``depth`` is less than the depth of ``branch``, it will return
* unmodified ``branch``
*/
export function normalizeMerkleBranch(branch: Uint8Array[], depth: number): Uint8Array[] {
const numBytes = Math.floor(branch.length / 8);
const numExtraBytesRequired = depth - numBytes;

return [...Array.from({length: numExtraBytesRequired}, () => ZERO_HASH), ...branch];
}
16 changes: 14 additions & 2 deletions packages/light-client/src/validation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import bls from "@chainsafe/bls";
import type {PublicKey, Signature} from "@chainsafe/bls/types";
import {altair, isElectraLightClientUpdate, LightClientFinalityUpdate, LightClientUpdate, Root, Slot, ssz} from "@lodestar/types";
import {
altair,
isElectraLightClientUpdate,
LightClientFinalityUpdate,
LightClientUpdate,
Root,
Slot,
ssz,
} from "@lodestar/types";
import {
FINALIZED_ROOT_INDEX,
FINALIZED_ROOT_DEPTH,
Expand Down Expand Up @@ -42,7 +50,11 @@ export function assertValidLightClientUpdate(
if (isFinalized) {
assertValidFinalityProof(update);
} else {
assertZeroHashes(update.finalityBranch, isElectraLightClientUpdate(update) ? FINALIZED_ROOT_DEPTH_ELECTRA : FINALIZED_ROOT_DEPTH, "finalityBranches");
assertZeroHashes(
update.finalityBranch,
isElectraLightClientUpdate(update) ? FINALIZED_ROOT_DEPTH_ELECTRA : FINALIZED_ROOT_DEPTH,
"finalityBranches"
);
}

// DIFF FROM SPEC:
Expand Down

0 comments on commit b836ce5

Please sign in to comment.