diff --git a/packages/beacon-node/src/api/impl/beacon/blocks/index.ts b/packages/beacon-node/src/api/impl/beacon/blocks/index.ts index 1b8a59cc8967..4d0f96d1ea08 100644 --- a/packages/beacon-node/src/api/impl/beacon/blocks/index.ts +++ b/packages/beacon-node/src/api/impl/beacon/blocks/index.ts @@ -7,7 +7,7 @@ import { signedBeaconBlockToBlinded, } from "@lodestar/state-transition"; import {ForkExecution, SLOTS_PER_HISTORICAL_ROOT, isForkExecution} from "@lodestar/params"; -import {sleep, fromHex, toHex} from "@lodestar/utils"; +import {sleep, fromHex, toRootHex} from "@lodestar/utils"; import { deneb, isSignedBlockContents, @@ -97,9 +97,9 @@ export function getBeaconBlockApi({ // state transition to produce the stateRoot const slot = signedBlock.message.slot; const fork = config.getForkName(slot); - const blockRoot = toHex(chain.config.getForkTypes(slot).BeaconBlock.hashTreeRoot(signedBlock.message)); + const blockRoot = toRootHex(chain.config.getForkTypes(slot).BeaconBlock.hashTreeRoot(signedBlock.message)); // bodyRoot should be the same to produced block - const bodyRoot = toHex(chain.config.getForkTypes(slot).BeaconBlockBody.hashTreeRoot(signedBlock.message.body)); + const bodyRoot = toRootHex(chain.config.getForkTypes(slot).BeaconBlockBody.hashTreeRoot(signedBlock.message.body)); const blockLocallyProduced = chain.producedBlockRoot.has(blockRoot) || chain.producedBlindedBlockRoot.has(blockRoot); const valLogMeta = {slot, blockRoot, bodyRoot, broadcastValidation, blockLocallyProduced}; @@ -147,7 +147,7 @@ export function getBeaconBlockApi({ ); throw new BlockError(signedBlock, { code: BlockErrorCode.PARENT_UNKNOWN, - parentRoot: toHex(signedBlock.message.parentRoot), + parentRoot: toRootHex(signedBlock.message.parentRoot), }); } @@ -243,7 +243,7 @@ export function getBeaconBlockApi({ opts: PublishBlockOpts = {} ) => { const slot = signedBlindedBlock.message.slot; - const blockRoot = toHex( + const blockRoot = toRootHex( chain.config .getExecutionForkTypes(signedBlindedBlock.message.slot) .BlindedBeaconBlock.hashTreeRoot(signedBlindedBlock.message) @@ -258,7 +258,7 @@ export function getBeaconBlockApi({ chain.logger.debug("Reconstructing signedBlockOrContents", {slot, blockRoot, source}); const contents = executionPayload - ? chain.producedContentsCache.get(toHex(executionPayload.blockHash)) ?? null + ? chain.producedContentsCache.get(toRootHex(executionPayload.blockHash)) ?? null : null; const signedBlockOrContents = reconstructFullBlockOrContents(signedBlindedBlock, {executionPayload, contents}); @@ -354,7 +354,7 @@ export function getBeaconBlockApi({ } finalized = false; - if (summary.blockRoot !== toHex(canonicalRoot)) { + if (summary.blockRoot !== toRootHex(canonicalRoot)) { const block = await db.block.get(fromHex(summary.blockRoot)); if (block) { result.push(toBeaconHeaderResponse(config, block)); @@ -473,7 +473,7 @@ export function getBeaconBlockApi({ } if (!blobSidecars) { - throw Error(`blobSidecars not found in db for slot=${block.message.slot} root=${toHex(blockRoot)}`); + throw Error(`blobSidecars not found in db for slot=${block.message.slot} root=${toRootHex(blockRoot)}`); } return { diff --git a/packages/beacon-node/src/api/impl/lodestar/index.ts b/packages/beacon-node/src/api/impl/lodestar/index.ts index d3083dda8e9c..0e8d2b1fa94b 100644 --- a/packages/beacon-node/src/api/impl/lodestar/index.ts +++ b/packages/beacon-node/src/api/impl/lodestar/index.ts @@ -3,7 +3,7 @@ import path from "node:path"; import {routes} from "@lodestar/api"; import {ApplicationMethods} from "@lodestar/api/server"; import {Repository} from "@lodestar/db"; -import {toHex} from "@lodestar/utils"; +import {toHex, toRootHex} from "@lodestar/utils"; import {getLatestWeakSubjectivityCheckpointEpoch} from "@lodestar/state-transition"; import {ChainForkConfig} from "@lodestar/config"; import {ssz} from "@lodestar/types"; @@ -202,7 +202,7 @@ function regenRequestToJson(config: ChainForkConfig, regenRequest: RegenRequest) case "getPreState": { const slot = regenRequest.args[0].slot; return { - root: toHex(config.getForkTypes(slot).BeaconBlock.hashTreeRoot(regenRequest.args[0])), + root: toRootHex(config.getForkTypes(slot).BeaconBlock.hashTreeRoot(regenRequest.args[0])), slot, }; } diff --git a/packages/beacon-node/src/api/impl/validator/index.ts b/packages/beacon-node/src/api/impl/validator/index.ts index b2a0b8575f5c..9d692a4cc405 100644 --- a/packages/beacon-node/src/api/impl/validator/index.ts +++ b/packages/beacon-node/src/api/impl/validator/index.ts @@ -41,7 +41,7 @@ import { BlindedBeaconBlock, } from "@lodestar/types"; import {ExecutionStatus, DataAvailabilityStatus} from "@lodestar/fork-choice"; -import {fromHex, toHex, resolveOrRacePromises, prettyWeiToEth} from "@lodestar/utils"; +import {fromHex, toHex, resolveOrRacePromises, prettyWeiToEth, toRootHex} from "@lodestar/utils"; import { AttestationError, AttestationErrorCode, @@ -324,7 +324,7 @@ export function getValidatorApi( function notOnOptimisticBlockRoot(beaconBlockRoot: Root): void { const protoBeaconBlock = chain.forkChoice.getBlock(beaconBlockRoot); if (!protoBeaconBlock) { - throw new ApiError(400, `Block not in forkChoice, beaconBlockRoot=${toHex(beaconBlockRoot)}`); + throw new ApiError(400, `Block not in forkChoice, beaconBlockRoot=${toRootHex(beaconBlockRoot)}`); } if (protoBeaconBlock.executionStatus === ExecutionStatus.Syncing) @@ -336,7 +336,7 @@ export function getValidatorApi( function notOnOutOfRangeData(beaconBlockRoot: Root): void { const protoBeaconBlock = chain.forkChoice.getBlock(beaconBlockRoot); if (!protoBeaconBlock) { - throw new ApiError(400, `Block not in forkChoice, beaconBlockRoot=${toHex(beaconBlockRoot)}`); + throw new ApiError(400, `Block not in forkChoice, beaconBlockRoot=${toRootHex(beaconBlockRoot)}`); } if (protoBeaconBlock.dataAvailabilityStatus === DataAvailabilityStatus.OutOfRange) @@ -416,7 +416,7 @@ export function getValidatorApi( slot, executionPayloadValue, consensusBlockValue, - root: toHex(config.getExecutionForkTypes(slot).BlindedBeaconBlock.hashTreeRoot(block)), + root: toRootHex(config.getExecutionForkTypes(slot).BlindedBeaconBlock.hashTreeRoot(block)), }); if (chain.opts.persistProducedBlocks) { @@ -494,13 +494,13 @@ export function getValidatorApi( slot, executionPayloadValue, consensusBlockValue, - root: toHex(config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block)), + root: toRootHex(config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block)), }); if (chain.opts.persistProducedBlocks) { void chain.persistBlock(block, "produced_engine_block"); } if (isForkBlobs(version)) { - const blockHash = toHex((block as bellatrix.BeaconBlock).body.executionPayload.blockHash); + const blockHash = toRootHex((block as bellatrix.BeaconBlock).body.executionPayload.blockHash); const contents = chain.producedContentsCache.get(blockHash); if (contents === undefined) { throw Error("contents missing in cache"); @@ -869,7 +869,7 @@ export function getValidatorApi( // and it hasn't been in our forkchoice since we haven't seen / processing that block // see https://github.com/ChainSafe/lodestar/issues/5063 if (!chain.forkChoice.hasBlock(beaconBlockRoot)) { - const rootHex = toHex(beaconBlockRoot); + const rootHex = toRootHex(beaconBlockRoot); network.searchUnknownSlotRoot({slot, root: rootHex}); // if result of this call is false, i.e. block hasn't seen after 1 slot then the below notOnOptimisticBlockRoot call will throw error await chain.waitForBlock(slot, rootHex); @@ -954,7 +954,7 @@ export function getValidatorApi( return { data: duties, meta: { - dependentRoot: toHex(dependentRoot), + dependentRoot: toRootHex(dependentRoot), executionOptimistic: isOptimisticBlock(head), }, }; @@ -1006,7 +1006,7 @@ export function getValidatorApi( return { data: duties, meta: { - dependentRoot: toHex(dependentRoot), + dependentRoot: toRootHex(dependentRoot), executionOptimistic: isOptimisticBlock(head), }, }; @@ -1071,7 +1071,7 @@ export function getValidatorApi( await waitForSlot(slot); // Must never request for a future slot > currentSlot - const dataRootHex = toHex(attestationDataRoot); + const dataRootHex = toRootHex(attestationDataRoot); const aggregate = chain.attestationPool.getAggregate(slot, dataRootHex); if (!aggregate) { diff --git a/packages/beacon-node/src/chain/archiver/archiveBlocks.ts b/packages/beacon-node/src/chain/archiver/archiveBlocks.ts index 76bfe651ad77..ed6dd5bfc091 100644 --- a/packages/beacon-node/src/chain/archiver/archiveBlocks.ts +++ b/packages/beacon-node/src/chain/archiver/archiveBlocks.ts @@ -1,7 +1,7 @@ import {fromHexString} from "@chainsafe/ssz"; import {Epoch, Slot, RootHex} from "@lodestar/types"; import {IForkChoice} from "@lodestar/fork-choice"; -import {Logger, toHex} from "@lodestar/utils"; +import {Logger, toRootHex} from "@lodestar/utils"; import {ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params"; import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition"; import {KeyValue} from "@lodestar/db"; @@ -137,7 +137,7 @@ async function migrateBlocksFromHotToColdDb(db: IBeaconDb, blocks: BlockRootSlot canonicalBlocks.map(async (block) => { const blockBuffer = await db.block.getBinary(block.root); if (!blockBuffer) { - throw Error(`No block found for slot ${block.slot} root ${toHex(block.root)}`); + throw Error(`No block found for slot ${block.slot} root ${toRootHex(block.root)}`); } return { key: block.slot, @@ -177,7 +177,7 @@ async function migrateBlobSidecarsFromHotToColdDb( .map(async (block) => { const bytes = await db.blobSidecars.getBinary(block.root); if (!bytes) { - throw Error(`No blobSidecars found for slot ${block.slot} root ${toHex(block.root)}`); + throw Error(`No blobSidecars found for slot ${block.slot} root ${toRootHex(block.root)}`); } return {key: block.slot, value: bytes}; }) diff --git a/packages/beacon-node/src/chain/blocks/index.ts b/packages/beacon-node/src/chain/blocks/index.ts index eb8c2663c9b6..a7a2ced2ad7a 100644 --- a/packages/beacon-node/src/chain/blocks/index.ts +++ b/packages/beacon-node/src/chain/blocks/index.ts @@ -1,4 +1,4 @@ -import {toHex, isErrorAborted} from "@lodestar/utils"; +import {isErrorAborted, toRootHex} from "@lodestar/utils"; import {SignedBeaconBlock} from "@lodestar/types"; import {JobItemQueue, isQueueErrorAborted} from "../../util/queue/index.js"; import {Metrics} from "../../metrics/metrics.js"; @@ -127,7 +127,7 @@ export async function processBlocks( const blockSlot = signedBlock.message.slot; const {preState, postState} = err.type; const forkTypes = this.config.getForkTypes(blockSlot); - const invalidRoot = toHex(postState.hashTreeRoot()); + const invalidRoot = toRootHex(postState.hashTreeRoot()); const suffix = `slot_${blockSlot}_invalid_state_root_${invalidRoot}`; this.persistInvalidSszValue(forkTypes.SignedBeaconBlock, signedBlock, suffix); diff --git a/packages/beacon-node/src/chain/blocks/verifyBlock.ts b/packages/beacon-node/src/chain/blocks/verifyBlock.ts index bf4cc7e60dcd..4d21342bd8cc 100644 --- a/packages/beacon-node/src/chain/blocks/verifyBlock.ts +++ b/packages/beacon-node/src/chain/blocks/verifyBlock.ts @@ -1,4 +1,3 @@ -import {toHexString} from "@chainsafe/ssz"; import { CachedBeaconStateAllForks, computeEpochAtSlot, @@ -9,7 +8,7 @@ import {bellatrix, deneb} from "@lodestar/types"; import {ForkName} from "@lodestar/params"; import {ProtoBlock, ExecutionStatus, DataAvailabilityStatus} from "@lodestar/fork-choice"; import {ChainForkConfig} from "@lodestar/config"; -import {Logger} from "@lodestar/utils"; +import {Logger, toRootHex} from "@lodestar/utils"; import {BlockError, BlockErrorCode} from "../errors/index.js"; import {BlockProcessOpts} from "../options.js"; import {RegenCaller} from "../regen/index.js"; @@ -198,9 +197,9 @@ export async function verifyBlocksInEpoch( } function logOnPowBlock(logger: Logger, config: ChainForkConfig, mergeBlock: bellatrix.BeaconBlock): void { - const mergeBlockHash = toHexString(config.getForkTypes(mergeBlock.slot).BeaconBlock.hashTreeRoot(mergeBlock)); - const mergeExecutionHash = toHexString(mergeBlock.body.executionPayload.blockHash); - const mergePowHash = toHexString(mergeBlock.body.executionPayload.parentHash); + const mergeBlockHash = toRootHex(config.getForkTypes(mergeBlock.slot).BeaconBlock.hashTreeRoot(mergeBlock)); + const mergeExecutionHash = toRootHex(mergeBlock.body.executionPayload.blockHash); + const mergePowHash = toRootHex(mergeBlock.body.executionPayload.parentHash); logger.info(POS_PANDA_MERGE_TRANSITION_BANNER); logger.info("Execution transitioning from PoW to PoS!!!"); logger.info("Importing block referencing terminal PoW block", { diff --git a/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts b/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts index d08a747259b1..284d4c0976ee 100644 --- a/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts +++ b/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts @@ -1,4 +1,3 @@ -import {toHexString} from "@chainsafe/ssz"; import { CachedBeaconStateAllForks, isExecutionStateType, @@ -17,7 +16,7 @@ import { LVHInvalidResponse, } from "@lodestar/fork-choice"; import {ChainForkConfig} from "@lodestar/config"; -import {ErrorAborted, Logger} from "@lodestar/utils"; +import {ErrorAborted, Logger, toRootHex} from "@lodestar/utils"; import {ForkSeq, SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY} from "@lodestar/params"; import {IExecutionEngine} from "../../execution/engine/interface.js"; @@ -205,10 +204,8 @@ export async function verifyBlocksExecutionPayload( // in import block if (isMergeTransitionBlock) { const mergeBlock = block.message as bellatrix.BeaconBlock; - const mergeBlockHash = toHexString( - chain.config.getForkTypes(mergeBlock.slot).BeaconBlock.hashTreeRoot(mergeBlock) - ); - const powBlockRootHex = toHexString(mergeBlock.body.executionPayload.parentHash); + const mergeBlockHash = toRootHex(chain.config.getForkTypes(mergeBlock.slot).BeaconBlock.hashTreeRoot(mergeBlock)); + const powBlockRootHex = toRootHex(mergeBlock.body.executionPayload.parentHash); const powBlock = await chain.eth1.getPowBlock(powBlockRootHex).catch((error) => { // Lets just warn the user here, errors if any will be reported on // `assertValidTerminalPowBlock` checks @@ -330,7 +327,7 @@ export async function verifyBlockExecutionPayload( const lvhResponse = { executionStatus, latestValidExecHash: execResult.latestValidHash, - invalidateFromParentBlockRoot: toHexString(block.message.parentRoot), + invalidateFromParentBlockRoot: toRootHex(block.message.parentRoot), }; const execError = new BlockError(block, { code: BlockErrorCode.EXECUTION_ENGINE_ERROR, @@ -407,7 +404,7 @@ function getSegmentErrorResponse( for (let mayBeLVHIndex = blockIndex - 1; mayBeLVHIndex >= 0; mayBeLVHIndex--) { const block = blocks[mayBeLVHIndex]; if ( - toHexString((block.message.body as bellatrix.BeaconBlockBody).executionPayload.blockHash) === + toRootHex((block.message.body as bellatrix.BeaconBlockBody).executionPayload.blockHash) === lvhResponse.latestValidExecHash ) { lvhFound = true; diff --git a/packages/beacon-node/src/chain/blocks/verifyBlocksSanityChecks.ts b/packages/beacon-node/src/chain/blocks/verifyBlocksSanityChecks.ts index fcbcfea05d6e..573dfa52ce8b 100644 --- a/packages/beacon-node/src/chain/blocks/verifyBlocksSanityChecks.ts +++ b/packages/beacon-node/src/chain/blocks/verifyBlocksSanityChecks.ts @@ -2,7 +2,7 @@ import {computeStartSlotAtEpoch} from "@lodestar/state-transition"; import {ChainForkConfig} from "@lodestar/config"; import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice"; import {Slot} from "@lodestar/types"; -import {toHexString, toRootHex} from "@lodestar/utils"; +import {toRootHex} from "@lodestar/utils"; import {IClock} from "../../util/clock.js"; import {BlockError, BlockErrorCode} from "../errors/index.js"; import {BlockInput, ImportBlockOpts} from "./types.js"; @@ -85,9 +85,7 @@ export function verifyBlocksSanityChecks( // Not already known // IGNORE if `partiallyVerifiedBlock.ignoreIfKnown` - const blockHash = toHexString( - chain.config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message) - ); + const blockHash = toRootHex(chain.config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message)); if (chain.forkChoice.hasBlockHex(blockHash)) { if (opts.ignoreIfKnown) { continue; diff --git a/packages/beacon-node/src/chain/blocks/writeBlockInputToDb.ts b/packages/beacon-node/src/chain/blocks/writeBlockInputToDb.ts index b0f5ab159591..89cf7ddc7556 100644 --- a/packages/beacon-node/src/chain/blocks/writeBlockInputToDb.ts +++ b/packages/beacon-node/src/chain/blocks/writeBlockInputToDb.ts @@ -1,4 +1,4 @@ -import {toHex} from "@lodestar/utils"; +import {toRootHex} from "@lodestar/utils"; import {BeaconChain} from "../chain.js"; import {BlockInput, BlockInputType} from "./types.js"; @@ -15,7 +15,7 @@ export async function writeBlockInputToDb(this: BeaconChain, blocksInput: BlockI for (const blockInput of blocksInput) { const {block, blockBytes} = blockInput; const blockRoot = this.config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message); - const blockRootHex = toHex(blockRoot); + const blockRootHex = toRootHex(blockRoot); if (blockBytes) { // skip serializing data if we already have it this.metrics?.importBlock.persistBlockWithSerializedDataCount.inc(); @@ -59,7 +59,7 @@ export async function removeEagerlyPersistedBlockInputs(this: BeaconChain, block for (const blockInput of blockInputs) { const {block, type} = blockInput; const blockRoot = this.config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message); - const blockRootHex = toHex(blockRoot); + const blockRootHex = toRootHex(blockRoot); if (!this.forkChoice.hasBlockHex(blockRootHex)) { blockToRemove.push(block); diff --git a/packages/beacon-node/src/chain/chain.ts b/packages/beacon-node/src/chain/chain.ts index 43f72d81e882..75608ab33b2e 100644 --- a/packages/beacon-node/src/chain/chain.ts +++ b/packages/beacon-node/src/chain/chain.ts @@ -35,7 +35,7 @@ import { } from "@lodestar/types"; import {CheckpointWithHex, ExecutionStatus, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice"; import {ProcessShutdownCallback} from "@lodestar/validator"; -import {Logger, gweiToWei, isErrorAborted, pruneSetToMax, sleep, toHex, toRootHex} from "@lodestar/utils"; +import {Logger, gweiToWei, isErrorAborted, pruneSetToMax, sleep, toRootHex} from "@lodestar/utils"; import {ForkSeq, GENESIS_SLOT, SLOTS_PER_EPOCH} from "@lodestar/params"; import {GENESIS_EPOCH, ZERO_HASH} from "../constants/index.js"; @@ -691,7 +691,7 @@ export class BeaconChain implements IBeaconChain { blockType === BlockType.Full ? this.config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block) : this.config.getExecutionForkTypes(slot).BlindedBeaconBlock.hashTreeRoot(block as BlindedBeaconBlock); - const blockRootHex = toHex(blockRoot); + const blockRootHex = toRootHex(blockRoot); // track the produced block for consensus broadcast validations if (blockType === BlockType.Full) { @@ -729,7 +729,7 @@ export class BeaconChain implements IBeaconChain { * ) */ getContents(beaconBlock: deneb.BeaconBlock): deneb.Contents { - const blockHash = toHex(beaconBlock.body.executionPayload.blockHash); + const blockHash = toRootHex(beaconBlock.body.executionPayload.blockHash); const contents = this.producedContentsCache.get(blockHash); if (!contents) { throw Error(`No contents for executionPayload.blockHash ${blockHash}`); @@ -926,7 +926,7 @@ export class BeaconChain implements IBeaconChain { checkpointRoot: checkpoint.rootHex, stateId, stateSlot: state.slot, - stateRoot: toHex(state.hashTreeRoot()), + stateRoot: toRootHex(state.hashTreeRoot()), }); } @@ -997,7 +997,7 @@ export class BeaconChain implements IBeaconChain { // by default store to lodestar_archive of current dir const dirpath = path.join(this.opts.persistInvalidSszObjectsDir ?? "invalid_ssz_objects", dateStr); - const filepath = path.join(dirpath, `${typeName}_${toHex(root)}.ssz`); + const filepath = path.join(dirpath, `${typeName}_${toRootHex(root)}.ssz`); await ensureDir(dirpath); diff --git a/packages/beacon-node/src/chain/forkChoice/index.ts b/packages/beacon-node/src/chain/forkChoice/index.ts index 385b79dcf713..d57b7f86cb98 100644 --- a/packages/beacon-node/src/chain/forkChoice/index.ts +++ b/packages/beacon-node/src/chain/forkChoice/index.ts @@ -1,4 +1,3 @@ -import {toHexString} from "@chainsafe/ssz"; import {Slot} from "@lodestar/types"; import {ChainForkConfig} from "@lodestar/config"; import { @@ -91,7 +90,7 @@ export function initializeForkChoice( ...(isExecutionStateType(state) && isMergeTransitionComplete(state) ? { - executionPayloadBlockHash: toHexString(state.latestExecutionPayloadHeader.blockHash), + executionPayloadBlockHash: toRootHex(state.latestExecutionPayloadHeader.blockHash), executionPayloadNumber: state.latestExecutionPayloadHeader.blockNumber, executionStatus: blockHeader.slot === GENESIS_SLOT ? ExecutionStatus.Valid : ExecutionStatus.Syncing, } diff --git a/packages/beacon-node/src/chain/opPools/aggregatedAttestationPool.ts b/packages/beacon-node/src/chain/opPools/aggregatedAttestationPool.ts index d896c9d3cc35..8277732ea1d5 100644 --- a/packages/beacon-node/src/chain/opPools/aggregatedAttestationPool.ts +++ b/packages/beacon-node/src/chain/opPools/aggregatedAttestationPool.ts @@ -10,7 +10,7 @@ import { getBlockRootAtSlot, } from "@lodestar/state-transition"; import {IForkChoice, EpochDifference} from "@lodestar/fork-choice"; -import {toHex, MapDef, toRootHex} from "@lodestar/utils"; +import {MapDef, toRootHex} from "@lodestar/utils"; import {intersectUint8Arrays, IntersectResult} from "../../util/bitArray.js"; import {pruneBySlot, signatureFromBytesNoCheck} from "./utils.js"; import {InsertOutcome} from "./types.js"; @@ -514,7 +514,7 @@ export function getValidateAttestationDataFn( } // the isValidAttestationData does not depend on slot and index - const beaconBlockRootHex = toHex(attData.beaconBlockRoot); + const beaconBlockRootHex = toRootHex(attData.beaconBlockRoot); const cacheKey = beaconBlockRootHex + targetEpoch; let isValid = cachedValidatedAttestationData.get(cacheKey); if (isValid === undefined) { @@ -559,7 +559,7 @@ export function isValidAttestationData( if (stateEpoch < 2 || targetEpoch < 2) { return true; } - const beaconBlockRootHex = toHex(data.beaconBlockRoot); + const beaconBlockRootHex = toRootHex(data.beaconBlockRoot); return isValidShuffling(forkChoice, state, beaconBlockRootHex, targetEpoch); } diff --git a/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts b/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts index 214fbdc890ec..d1b410610a43 100644 --- a/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts +++ b/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts @@ -32,7 +32,7 @@ import { } from "@lodestar/state-transition"; import {ChainForkConfig} from "@lodestar/config"; import {ForkSeq, ForkExecution, isForkExecution} from "@lodestar/params"; -import {toHex, sleep, Logger} from "@lodestar/utils"; +import {toHex, sleep, Logger, toRootHex} from "@lodestar/utils"; import type {BeaconChain} from "../chain.js"; import {PayloadId, IExecutionEngine, IExecutionBuilder, PayloadAttributes} from "../../execution/index.js"; import {ZERO_HASH, ZERO_HASH_HEX} from "../../constants/index.js"; @@ -273,7 +273,7 @@ export async function produceBlockBody( prepType, payloadId, fetchedTime, - executionHeadBlockHash: toHex(engineRes.executionPayload.blockHash), + executionHeadBlockHash: toRootHex(engineRes.executionPayload.blockHash), }); if (executionPayload.transactions.length === 0) { this.metrics?.blockPayload.emptyPayloads.inc({prepType}); @@ -290,7 +290,7 @@ export async function produceBlockBody( } (blockBody as deneb.BeaconBlockBody).blobKzgCommitments = blobsBundle.commitments; - const blockHash = toHex(executionPayload.blockHash); + const blockHash = toRootHex(executionPayload.blockHash); const contents = {kzgProofs: blobsBundle.proofs, blobs: blobsBundle.blobs}; blobsResult = {type: BlobsResultType.produced, contents, blockHash}; @@ -380,7 +380,7 @@ export async function prepareExecutionPayload( const prevRandao = getRandaoMix(state, state.epochCtx.epoch); const payloadIdCached = chain.executionEngine.payloadIdCache.get({ - headBlockHash: toHex(parentHash), + headBlockHash: toRootHex(parentHash), finalizedBlockHash, timestamp: numToQuantity(timestamp), prevRandao: toHex(prevRandao), @@ -414,7 +414,7 @@ export async function prepareExecutionPayload( payloadId = await chain.executionEngine.notifyForkchoiceUpdate( fork, - toHex(parentHash), + toRootHex(parentHash), safeBlockHash, finalizedBlockHash, attributes diff --git a/packages/beacon-node/src/chain/validation/blobSidecar.ts b/packages/beacon-node/src/chain/validation/blobSidecar.ts index f1ea7bfa95c8..4c82d7be153d 100644 --- a/packages/beacon-node/src/chain/validation/blobSidecar.ts +++ b/packages/beacon-node/src/chain/validation/blobSidecar.ts @@ -1,5 +1,5 @@ import {deneb, Root, Slot, ssz} from "@lodestar/types"; -import {toHex, verifyMerkleBranch} from "@lodestar/utils"; +import {toRootHex, verifyMerkleBranch} from "@lodestar/utils"; import {computeStartSlotAtEpoch, getBlockHeaderProposerSignatureSet} from "@lodestar/state-transition"; import {KZG_COMMITMENT_INCLUSION_PROOF_DEPTH, KZG_COMMITMENT_SUBTREE_INDEX0} from "@lodestar/params"; @@ -57,7 +57,7 @@ export async function validateGossipBlobSidecar( // check, we will load the parent and state from disk only to find out later that we // already know this block. const blockRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(blobSidecar.signedBlockHeader.message); - const blockHex = toHex(blockRoot); + const blockHex = toRootHex(blockRoot); if (chain.forkChoice.getBlockHex(blockHex) !== null) { throw new BlobSidecarGossipError(GossipAction.IGNORE, {code: BlobSidecarErrorCode.ALREADY_KNOWN, root: blockHex}); } @@ -68,7 +68,7 @@ export async function validateGossipBlobSidecar( // _[IGNORE]_ The blob's block's parent (defined by `sidecar.block_parent_root`) has been seen (via both // gossip and non-gossip sources) (a client MAY queue blocks for processing once the parent block is // retrieved). - const parentRoot = toHex(blobSidecar.signedBlockHeader.message.parentRoot); + const parentRoot = toRootHex(blobSidecar.signedBlockHeader.message.parentRoot); const parentBlock = chain.forkChoice.getBlockHex(parentRoot); if (parentBlock === null) { // If fork choice does *not* consider the parent to be a descendant of the finalized block, @@ -183,9 +183,9 @@ export function validateBlobSidecars( !byteArrayEquals(expectedKzgCommitments[index], blobSidecar.kzgCommitment) ) { throw new Error( - `Invalid blob with slot=${blobBlockHeader.slot} blobBlockRoot=${toHex(blobBlockRoot)} index=${ + `Invalid blob with slot=${blobBlockHeader.slot} blobBlockRoot=${toRootHex(blobBlockRoot)} index=${ blobSidecar.index - } for the block blockRoot=${toHex(blockRoot)} slot=${blockSlot} index=${index}` + } for the block blockRoot=${toRootHex(blockRoot)} slot=${blockSlot} index=${index}` ); } blobs.push(blobSidecar.blob); diff --git a/packages/beacon-node/src/eth1/eth1MergeBlockTracker.ts b/packages/beacon-node/src/eth1/eth1MergeBlockTracker.ts index 8602b3058180..9ba4a09a5549 100644 --- a/packages/beacon-node/src/eth1/eth1MergeBlockTracker.ts +++ b/packages/beacon-node/src/eth1/eth1MergeBlockTracker.ts @@ -1,7 +1,6 @@ -import {toHexString} from "@chainsafe/ssz"; import {ChainConfig} from "@lodestar/config"; import {RootHex} from "@lodestar/types"; -import {Logger, pruneSetToMax} from "@lodestar/utils"; +import {Logger, pruneSetToMax, toRootHex} from "@lodestar/utils"; import {Metrics} from "../metrics/index.js"; import {ZERO_HASH_HEX} from "../constants/index.js"; import {enumToIndexMap} from "../util/enum.js"; @@ -239,7 +238,7 @@ export class Eth1MergeBlockTracker { private async internalGetTerminalPowBlockFromEth1(): Promise { // Search merge block by hash // Terminal block hash override takes precedence over terminal total difficulty - const terminalBlockHash = toHexString(this.config.TERMINAL_BLOCK_HASH); + const terminalBlockHash = toRootHex(this.config.TERMINAL_BLOCK_HASH); if (terminalBlockHash !== ZERO_HASH_HEX) { const block = await this.getPowBlock(terminalBlockHash); if (block) { diff --git a/packages/beacon-node/src/eth1/utils/eth1Vote.ts b/packages/beacon-node/src/eth1/utils/eth1Vote.ts index 3940ccb27bae..cdc8fa04163e 100644 --- a/packages/beacon-node/src/eth1/utils/eth1Vote.ts +++ b/packages/beacon-node/src/eth1/utils/eth1Vote.ts @@ -2,7 +2,7 @@ import {EPOCHS_PER_ETH1_VOTING_PERIOD, SLOTS_PER_EPOCH} from "@lodestar/params"; import {ChainForkConfig} from "@lodestar/config"; import {phase0, RootHex} from "@lodestar/types"; import {BeaconStateAllForks, computeTimeAtSlot} from "@lodestar/state-transition"; -import {toHex} from "@lodestar/utils"; +import {toRootHex} from "@lodestar/utils"; export type Eth1DataGetter = ({ timestampRange, @@ -128,7 +128,7 @@ function getEth1DataKey(eth1Data: phase0.Eth1Data): string { * Serialize eth1Data types to a unique string ID. It is only used for comparison. */ export function fastSerializeEth1Data(eth1Data: phase0.Eth1Data): string { - return toHex(eth1Data.blockHash) + eth1Data.depositCount.toString(16) + toHex(eth1Data.depositRoot); + return toRootHex(eth1Data.blockHash) + eth1Data.depositCount.toString(16) + toRootHex(eth1Data.depositRoot); } export function votingPeriodStartTime(config: ChainForkConfig, state: BeaconStateAllForks): number { diff --git a/packages/beacon-node/src/metrics/validatorMonitor.ts b/packages/beacon-node/src/metrics/validatorMonitor.ts index e5c8eef83679..5492f57edc02 100644 --- a/packages/beacon-node/src/metrics/validatorMonitor.ts +++ b/packages/beacon-node/src/metrics/validatorMonitor.ts @@ -8,7 +8,7 @@ import { getBlockRootAtSlot, ParticipationFlags, } from "@lodestar/state-transition"; -import {LogData, LogHandler, LogLevel, Logger, MapDef, MapDefMax, toHex} from "@lodestar/utils"; +import {LogData, LogHandler, LogLevel, Logger, MapDef, MapDefMax, toRootHex} from "@lodestar/utils"; import {BeaconBlock, RootHex, altair, deneb} from "@lodestar/types"; import {ChainConfig, ChainForkConfig} from "@lodestar/config"; import {ForkSeq, INTERVALS_PER_SLOT, MIN_ATTESTATION_INCLUSION_DELAY, SLOTS_PER_EPOCH} from "@lodestar/params"; @@ -392,7 +392,7 @@ export function createValidatorMonitor( const summary = getEpochSummary(validator, computeEpochAtSlot(block.slot)); summary.blockProposals.push({ - blockRoot: toHex(config.getForkTypes(block.slot).BeaconBlock.hashTreeRoot(block)), + blockRoot: toRootHex(config.getForkTypes(block.slot).BeaconBlock.hashTreeRoot(block)), blockSlot: block.slot, poolSubmitDelaySec: delaySec, successfullyImported: false, @@ -416,7 +416,7 @@ export function createValidatorMonitor( proposal.successfullyImported = true; } else { summary.blockProposals.push({ - blockRoot: toHex(config.getForkTypes(block.slot).BeaconBlock.hashTreeRoot(block)), + blockRoot: toRootHex(config.getForkTypes(block.slot).BeaconBlock.hashTreeRoot(block)), blockSlot: block.slot, poolSubmitDelaySec: null, successfullyImported: true, @@ -445,7 +445,7 @@ export function createValidatorMonitor( const attestationSummary = validator.attestations .getOrDefault(indexedAttestation.data.target.epoch) - .getOrDefault(toHex(indexedAttestation.data.target.root)); + .getOrDefault(toRootHex(indexedAttestation.data.target.root)); if ( attestationSummary.poolSubmitDelayMinSec === null || attestationSummary.poolSubmitDelayMinSec > delaySec @@ -494,7 +494,7 @@ export function createValidatorMonitor( validator.attestations .getOrDefault(indexedAttestation.data.target.epoch) - .getOrDefault(toHex(indexedAttestation.data.target.root)) + .getOrDefault(toRootHex(indexedAttestation.data.target.root)) .aggregateInclusionDelaysSec.push(delaySec); } } @@ -533,7 +533,7 @@ export function createValidatorMonitor( validator.attestations .getOrDefault(indexedAttestation.data.target.epoch) - .getOrDefault(toHex(indexedAttestation.data.target.root)) + .getOrDefault(toRootHex(indexedAttestation.data.target.root)) .aggregateInclusionDelaysSec.push(delaySec); } } @@ -577,7 +577,7 @@ export function createValidatorMonitor( validator.attestations .getOrDefault(indexedAttestation.data.target.epoch) - .getOrDefault(toHex(indexedAttestation.data.target.root)) + .getOrDefault(toRootHex(indexedAttestation.data.target.root)) .blockInclusions.push({ blockRoot: inclusionBlockRoot, blockSlot: inclusionBlockSlot, @@ -650,7 +650,7 @@ export function createValidatorMonitor( if (config.getForkSeq(headState.slot) >= ForkSeq.altair) { const {previousEpochParticipation} = headState as CachedBeaconStateAltair; const prevEpochStartSlot = computeStartSlotAtEpoch(prevEpoch); - const prevEpochTargetRoot = toHex(getBlockRootAtSlot(headState, prevEpochStartSlot)); + const prevEpochTargetRoot = toRootHex(getBlockRootAtSlot(headState, prevEpochStartSlot)); // Check attestation performance for (const [index, validator] of validators.entries()) { @@ -1041,7 +1041,7 @@ export class RootHexCache { getBlockRootAtSlot(slot: Slot): RootHex { let root = this.blockRootSlotCache.get(slot); if (!root) { - root = toHex(getBlockRootAtSlot(this.state, slot)); + root = toRootHex(getBlockRootAtSlot(this.state, slot)); this.blockRootSlotCache.set(slot, root); } return root; diff --git a/packages/beacon-node/src/network/peers/utils/assertPeerRelevance.ts b/packages/beacon-node/src/network/peers/utils/assertPeerRelevance.ts index 95743331ab2a..96e35e9d317d 100644 --- a/packages/beacon-node/src/network/peers/utils/assertPeerRelevance.ts +++ b/packages/beacon-node/src/network/peers/utils/assertPeerRelevance.ts @@ -1,5 +1,6 @@ import {toHexString} from "@chainsafe/ssz"; import {ForkDigest, Root, Slot, phase0, ssz} from "@lodestar/types"; +import {toRootHex} from "@lodestar/utils"; // TODO: Why this value? (From Lighthouse) const FUTURE_SLOT_TOLERANCE = 1; @@ -82,6 +83,6 @@ export function renderIrrelevantPeerType(type: IrrelevantPeerType): string { case IrrelevantPeerCode.DIFFERENT_CLOCKS: return `DIFFERENT_CLOCKS slotDiff: ${type.slotDiff}`; case IrrelevantPeerCode.DIFFERENT_FINALIZED: - return `DIFFERENT_FINALIZED root: ${toHexString(type.remoteRoot)} expected: ${toHexString(type.expectedRoot)}`; + return `DIFFERENT_FINALIZED root: ${toRootHex(type.remoteRoot)} expected: ${toRootHex(type.expectedRoot)}`; } } diff --git a/packages/beacon-node/src/network/reqresp/handlers/blobSidecarsByRoot.ts b/packages/beacon-node/src/network/reqresp/handlers/blobSidecarsByRoot.ts index 6aa16a0c2629..144d470d7199 100644 --- a/packages/beacon-node/src/network/reqresp/handlers/blobSidecarsByRoot.ts +++ b/packages/beacon-node/src/network/reqresp/handlers/blobSidecarsByRoot.ts @@ -1,7 +1,7 @@ import {ResponseError, ResponseOutgoing, RespStatus} from "@lodestar/reqresp"; import {BLOBSIDECAR_FIXED_SIZE} from "@lodestar/params"; import {deneb, RootHex} from "@lodestar/types"; -import {toHex, fromHex} from "@lodestar/utils"; +import {fromHex, toRootHex} from "@lodestar/utils"; import {IBeaconChain} from "../../../chain/index.js"; import {IBeaconDb} from "../../../db/index.js"; import {BLOB_SIDECARS_IN_WRAPPER_INDEX} from "../../../db/repositories/blobSidecars.js"; @@ -20,7 +20,7 @@ export async function* onBlobSidecarsByRoot( for (const blobIdentifier of requestBody) { const {blockRoot, index} = blobIdentifier; - const blockRootHex = toHex(blockRoot); + const blockRootHex = toRootHex(blockRoot); const block = chain.forkChoice.getBlockHex(blockRootHex); // NOTE: Only support non-finalized blocks. diff --git a/packages/beacon-node/src/sync/backfill/backfill.ts b/packages/beacon-node/src/sync/backfill/backfill.ts index 15ba34f4e583..38258fde07fd 100644 --- a/packages/beacon-node/src/sync/backfill/backfill.ts +++ b/packages/beacon-node/src/sync/backfill/backfill.ts @@ -3,7 +3,7 @@ import {StrictEventEmitter} from "strict-event-emitter-types"; import {BeaconStateAllForks, blockToHeader} from "@lodestar/state-transition"; import {BeaconConfig, ChainForkConfig} from "@lodestar/config"; import {phase0, Root, SignedBeaconBlock, Slot, ssz} from "@lodestar/types"; -import {ErrorAborted, Logger, sleep, toHex, toRootHex} from "@lodestar/utils"; +import {ErrorAborted, Logger, sleep, toRootHex} from "@lodestar/utils"; import {SLOTS_PER_EPOCH} from "@lodestar/params"; import {IBeaconChain} from "../../chain/index.js"; @@ -527,7 +527,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter} ) // TODO: explode and stop the entire node throw new Error( - `InvalidWsCheckpoint root=${toHex(this.wsCheckpointHeader.root)}, epoch=${ + `InvalidWsCheckpoint root=${toRootHex(this.wsCheckpointHeader.root)}, epoch=${ this.wsCheckpointHeader.slot / SLOTS_PER_EPOCH }, ${ wsDbCheckpointBlock @@ -589,7 +589,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter} } else { validSequence = false; this.logger.warn( - `Invalid backfill sequence: previous finalized or checkpoint block root=${toHex( + `Invalid backfill sequence: previous finalized or checkpoint block root=${toRootHex( this.prevFinalizedCheckpointBlock.root )}, slot=${this.prevFinalizedCheckpointBlock.slot} ${ prevBackfillCpBlock ? "found at slot=" + prevBackfillCpBlock.message.slot : "not found" @@ -643,7 +643,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter} if (cleanupSeqs.length > 0) { await this.db.backfilledRanges.batchDelete(cleanupSeqs.map((entry) => entry.key)); this.logger.debug( - `Cleaned up the old sequences between ${this.backfillStartFromSlot},${toHex( + `Cleaned up the old sequences between ${this.backfillStartFromSlot},${toRootHex( this.syncAnchor.lastBackSyncedBlock.root )}`, {cleanupSeqs: JSON.stringify(cleanupSeqs)} @@ -669,7 +669,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter} if (expectedSlot !== null && anchorBlock.message.slot !== expectedSlot) throw Error( - `Invalid slot of anchorBlock read from DB with root=${toHex( + `Invalid slot of anchorBlock read from DB with root=${toRootHex( anchorBlockRoot )}, expected=${expectedSlot}, actual=${anchorBlock.message.slot}` ); @@ -686,7 +686,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter} // Before moving anchorBlock back, we need check for prevFinalizedCheckpointBlock if (anchorBlock.message.slot < this.prevFinalizedCheckpointBlock.slot) { throw Error( - `Skipped a prevFinalizedCheckpointBlock with slot=${toHex( + `Skipped a prevFinalizedCheckpointBlock with slot=${toRootHex( this.prevFinalizedCheckpointBlock.root )}, root=${toRootHex(this.prevFinalizedCheckpointBlock.root)}` ); @@ -699,7 +699,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter} throw Error( `Invalid root for prevFinalizedCheckpointBlock at slot=${ this.prevFinalizedCheckpointBlock.slot - }, expected=${toRootHex(this.prevFinalizedCheckpointBlock.root)}, found=${toHex(anchorBlockRoot)}` + }, expected=${toRootHex(this.prevFinalizedCheckpointBlock.root)}, found=${toRootHex(anchorBlockRoot)}` ); } diff --git a/packages/beacon-node/src/sync/range/range.ts b/packages/beacon-node/src/sync/range/range.ts index d20e0c3690cd..887a86a3aaf2 100644 --- a/packages/beacon-node/src/sync/range/range.ts +++ b/packages/beacon-node/src/sync/range/range.ts @@ -3,7 +3,7 @@ import {StrictEventEmitter} from "strict-event-emitter-types"; import {computeStartSlotAtEpoch} from "@lodestar/state-transition"; import {BeaconConfig} from "@lodestar/config"; import {Epoch, phase0} from "@lodestar/types"; -import {Logger, toHex} from "@lodestar/utils"; +import {Logger, toRootHex} from "@lodestar/utils"; import {IBeaconChain} from "../../chain/index.js"; import {INetwork} from "../../network/index.js"; import {Metrics} from "../../metrics/index.js"; @@ -119,7 +119,7 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) { syncType, startEpoch, targetSlot: target.slot, - targetRoot: toHex(target.root), + targetRoot: toRootHex(target.root), }); // If the peer existed in any other chain, remove it. @@ -242,7 +242,7 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) { syncType, firstEpoch: syncChain.firstBatchEpoch, targetSlot: syncChain.target.slot, - targetRoot: toHex(syncChain.target.root), + targetRoot: toRootHex(syncChain.target.root), }); } @@ -274,7 +274,7 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) { lastValidatedSlot: syncChain.lastValidatedSlot, firstEpoch: syncChain.firstBatchEpoch, targetSlot: syncChain.target.slot, - targetRoot: toHex(syncChain.target.root), + targetRoot: toRootHex(syncChain.target.root), validatedEpochs: syncChain.validatedEpochs, }); diff --git a/packages/beacon-node/src/sync/range/utils/chainTarget.ts b/packages/beacon-node/src/sync/range/utils/chainTarget.ts index 221b6e1be68f..15076a028818 100644 --- a/packages/beacon-node/src/sync/range/utils/chainTarget.ts +++ b/packages/beacon-node/src/sync/range/utils/chainTarget.ts @@ -1,5 +1,5 @@ -import {toHexString} from "@chainsafe/ssz"; import {Root, Slot} from "@lodestar/types"; +import {toRootHex} from "@lodestar/utils"; /** * Sync this up to this target. Uses slot instead of epoch to re-use logic for finalized sync @@ -21,7 +21,7 @@ export function computeMostCommonTarget(targets: ChainTarget[]): ChainTarget { let mostCommonCount = 0; for (const target of targets) { - const targetId = `${target.slot}-${toHexString(target.root)}`; + const targetId = `${target.slot}-${toRootHex(target.root)}`; const count = 1 + (countById.get(targetId) ?? 0); countById.set(targetId, count); if (count > mostCommonCount) { diff --git a/packages/beacon-node/src/sync/range/utils/hashBlocks.ts b/packages/beacon-node/src/sync/range/utils/hashBlocks.ts index 522242924a3c..986d023d9ca1 100644 --- a/packages/beacon-node/src/sync/range/utils/hashBlocks.ts +++ b/packages/beacon-node/src/sync/range/utils/hashBlocks.ts @@ -1,6 +1,6 @@ import {RootHex} from "@lodestar/types"; import {ChainForkConfig} from "@lodestar/config"; -import {toHex} from "@lodestar/utils"; +import {toRootHex} from "@lodestar/utils"; import {BlockInput} from "../../../chain/blocks/types.js"; /** @@ -12,14 +12,14 @@ export function hashBlocks(blocks: BlockInput[], config: ChainForkConfig): RootH return "0x"; case 1: { const block0 = blocks[0].block; - return toHex(config.getForkTypes(block0.message.slot).SignedBeaconBlock.hashTreeRoot(block0)); + return toRootHex(config.getForkTypes(block0.message.slot).SignedBeaconBlock.hashTreeRoot(block0)); } default: { const block0 = blocks[0].block; const blockN = blocks[blocks.length - 1].block; return ( - toHex(config.getForkTypes(block0.message.slot).SignedBeaconBlock.hashTreeRoot(block0)) + - toHex(config.getForkTypes(blockN.message.slot).SignedBeaconBlock.hashTreeRoot(blockN)) + toRootHex(config.getForkTypes(block0.message.slot).SignedBeaconBlock.hashTreeRoot(block0)) + + toRootHex(config.getForkTypes(blockN.message.slot).SignedBeaconBlock.hashTreeRoot(blockN)) ); } } diff --git a/packages/beacon-node/test/unit/eth1/eth1MergeBlockTracker.test.ts b/packages/beacon-node/test/unit/eth1/eth1MergeBlockTracker.test.ts index 938c272b316a..151f3931cfde 100644 --- a/packages/beacon-node/test/unit/eth1/eth1MergeBlockTracker.test.ts +++ b/packages/beacon-node/test/unit/eth1/eth1MergeBlockTracker.test.ts @@ -32,7 +32,7 @@ describe("eth1 / Eth1MergeBlockTracker", () => { }); it("Should find terminal pow block through TERMINAL_BLOCK_HASH", async () => { - config.TERMINAL_BLOCK_HASH = Buffer.alloc(1, 32); + config.TERMINAL_BLOCK_HASH = Buffer.alloc(32, 1); const block: EthJsonRpcBlockRaw = { number: toHex(10), hash: toRootHex(11), diff --git a/packages/state-transition/src/block/processAttestationPhase0.ts b/packages/state-transition/src/block/processAttestationPhase0.ts index 248ba83b4ed2..95fc575003ee 100644 --- a/packages/state-transition/src/block/processAttestationPhase0.ts +++ b/packages/state-transition/src/block/processAttestationPhase0.ts @@ -1,7 +1,7 @@ -import {toHexString} from "@chainsafe/ssz"; import {Slot, phase0, ssz} from "@lodestar/types"; import {MIN_ATTESTATION_INCLUSION_DELAY, SLOTS_PER_EPOCH, ForkSeq} from "@lodestar/params"; +import {toRootHex} from "@lodestar/utils"; import {computeEpochAtSlot} from "../util/index.js"; import {CachedBeaconStatePhase0, CachedBeaconStateAllForks} from "../types.js"; import {isValidIndexedAttestation} from "./index.js"; @@ -113,5 +113,5 @@ export function isTimelyTarget(fork: ForkSeq, inclusionDistance: Slot): boolean } export function checkpointToStr(checkpoint: phase0.Checkpoint): string { - return `${toHexString(checkpoint.root)}:${checkpoint.epoch}`; + return `${toRootHex(checkpoint.root)}:${checkpoint.epoch}`; } diff --git a/packages/state-transition/src/block/processBlockHeader.ts b/packages/state-transition/src/block/processBlockHeader.ts index 755850969b4f..da3e389fb507 100644 --- a/packages/state-transition/src/block/processBlockHeader.ts +++ b/packages/state-transition/src/block/processBlockHeader.ts @@ -1,5 +1,6 @@ -import {toHexString, byteArrayEquals} from "@chainsafe/ssz"; +import {byteArrayEquals} from "@chainsafe/ssz"; import {BeaconBlock, BlindedBeaconBlock, ssz} from "@lodestar/types"; +import {toRootHex} from "@lodestar/utils"; import {CachedBeaconStateAllForks} from "../types.js"; import {ZERO_HASH} from "../constants/index.js"; import {blindedOrFullBlockToHeader} from "../util/index.js"; @@ -32,7 +33,7 @@ export function processBlockHeader(state: CachedBeaconStateAllForks, block: Beac // verify that the parent matches if (!byteArrayEquals(block.parentRoot, ssz.phase0.BeaconBlockHeader.hashTreeRoot(state.latestBlockHeader))) { throw new Error( - `Block parent root ${toHexString(block.parentRoot)} does not match state latest block, block slot=${slot}` + `Block parent root ${toRootHex(block.parentRoot)} does not match state latest block, block slot=${slot}` ); } diff --git a/packages/state-transition/src/block/processWithdrawals.ts b/packages/state-transition/src/block/processWithdrawals.ts index ddea73c27a26..9ae4c570e013 100644 --- a/packages/state-transition/src/block/processWithdrawals.ts +++ b/packages/state-transition/src/block/processWithdrawals.ts @@ -1,4 +1,4 @@ -import {byteArrayEquals, toHexString} from "@chainsafe/ssz"; +import {byteArrayEquals} from "@chainsafe/ssz"; import {ssz, capella} from "@lodestar/types"; import { MAX_EFFECTIVE_BALANCE, @@ -6,6 +6,7 @@ import { MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP, } from "@lodestar/params"; +import {toRootHex} from "@lodestar/utils"; import {CachedBeaconStateCapella} from "../types.js"; import {decreaseBalance, hasEth1WithdrawalCredential, isCapellaPayloadHeader} from "../util/index.js"; @@ -21,9 +22,9 @@ export function processWithdrawals( const actualWithdrawalsRoot = payload.withdrawalsRoot; if (!byteArrayEquals(expectedWithdrawalsRoot, actualWithdrawalsRoot)) { throw Error( - `Invalid withdrawalsRoot of executionPayloadHeader, expected=${toHexString( + `Invalid withdrawalsRoot of executionPayloadHeader, expected=${toRootHex( expectedWithdrawalsRoot - )}, actual=${toHexString(actualWithdrawalsRoot)}` + )}, actual=${toRootHex(actualWithdrawalsRoot)}` ); } } else { diff --git a/packages/state-transition/src/stateTransition.ts b/packages/state-transition/src/stateTransition.ts index 78bcaa140c62..a454bf4b34d0 100644 --- a/packages/state-transition/src/stateTransition.ts +++ b/packages/state-transition/src/stateTransition.ts @@ -1,6 +1,6 @@ -import {toHexString} from "@chainsafe/ssz"; import {SignedBeaconBlock, SignedBlindedBeaconBlock, Slot, ssz} from "@lodestar/types"; import {SLOTS_PER_EPOCH} from "@lodestar/params"; +import {toRootHex} from "@lodestar/utils"; import {BeaconStateTransitionMetrics, onPostStateMetrics, onStateCloneMetrics} from "./metrics.js"; import {beforeProcessEpoch, EpochTransitionCache, EpochTransitionCacheOpts} from "./cache/epochTransitionCache.js"; import { @@ -123,7 +123,7 @@ export function stateTransition( if (!ssz.Root.equals(block.stateRoot, stateRoot)) { throw new Error( - `Invalid state root at slot ${block.slot}, expected=${toHexString(block.stateRoot)}, actual=${toHexString( + `Invalid state root at slot ${block.slot}, expected=${toRootHex(block.stateRoot)}, actual=${toRootHex( stateRoot )}` ); diff --git a/packages/state-transition/src/util/epochShuffling.ts b/packages/state-transition/src/util/epochShuffling.ts index e101da38f297..856721d8d083 100644 --- a/packages/state-transition/src/util/epochShuffling.ts +++ b/packages/state-transition/src/util/epochShuffling.ts @@ -1,6 +1,5 @@ -import {toHexString} from "@chainsafe/ssz"; import {Epoch, RootHex, ValidatorIndex} from "@lodestar/types"; -import {intDiv} from "@lodestar/utils"; +import {intDiv, toRootHex} from "@lodestar/utils"; import { DOMAIN_BEACON_ATTESTER, MAX_COMMITTEES_PER_SLOT, @@ -108,5 +107,5 @@ export function computeEpochShuffling( export function getShufflingDecisionBlock(state: BeaconStateAllForks, epoch: Epoch): RootHex { const pivotSlot = computeStartSlotAtEpoch(epoch - 1) - 1; - return toHexString(getBlockRootAtSlot(state, pivotSlot)); + return toRootHex(getBlockRootAtSlot(state, pivotSlot)); } diff --git a/packages/state-transition/src/util/weakSubjectivity.ts b/packages/state-transition/src/util/weakSubjectivity.ts index 6bd6636c3e70..0e606e66340f 100644 --- a/packages/state-transition/src/util/weakSubjectivity.ts +++ b/packages/state-transition/src/util/weakSubjectivity.ts @@ -1,9 +1,9 @@ -import {toHexString} from "@chainsafe/ssz"; import {BeaconConfig, ChainForkConfig} from "@lodestar/config"; import {EFFECTIVE_BALANCE_INCREMENT, MAX_DEPOSITS, MAX_EFFECTIVE_BALANCE, SLOTS_PER_EPOCH} from "@lodestar/params"; import {Epoch, Root} from "@lodestar/types"; import {ssz} from "@lodestar/types"; import {Checkpoint} from "@lodestar/types/phase0"; +import {toRootHex} from "@lodestar/utils"; import {ZERO_HASH} from "../constants/constants.js"; import {BeaconStateAllForks, CachedBeaconStateAllForks} from "../types.js"; import {computeEpochAtSlot, getCurrentEpoch, computeCheckpointEpochAtStateSlot} from "./epoch.js"; @@ -127,9 +127,7 @@ export function ensureWithinWeakSubjectivityPeriod( const wsStateEpoch = computeCheckpointEpochAtStateSlot(wsState.slot); const blockRoot = getLatestBlockRoot(wsState); if (!ssz.Root.equals(blockRoot, wsCheckpoint.root)) { - throw new Error( - `Roots do not match. expected=${toHexString(wsCheckpoint.root)}, actual=${toHexString(blockRoot)}` - ); + throw new Error(`Roots do not match. expected=${toRootHex(wsCheckpoint.root)}, actual=${toRootHex(blockRoot)}`); } if (!ssz.Epoch.equals(wsStateEpoch, wsCheckpoint.epoch)) { throw new Error(`Epochs do not match. expected=${wsCheckpoint.epoch}, actual=${wsStateEpoch}`); diff --git a/packages/utils/src/bytes.ts b/packages/utils/src/bytes.ts index f4a622da021e..820cf7d63300 100644 --- a/packages/utils/src/bytes.ts +++ b/packages/utils/src/bytes.ts @@ -63,6 +63,10 @@ const rootBuf = Buffer.alloc(32); * Convert a Uint8Array, length 32, to 0x-prefixed hex string */ export function toRootHex(root: Uint8Array): string { + if (root.length !== 32) { + throw Error(`Expect root to be 32 bytes, got ${root.length}`); + } + rootBuf.set(root); return `0x${rootBuf.toString("hex")}`; }