-
-
Notifications
You must be signed in to change notification settings - Fork 289
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Compute emptyKzgAggregatedProof once lazily * Fetch blocks and blobs in concurrently * Remove BlockInput case postEIP4844OldBlobs * Review beaconBlocksMaybeBlobsByRoot * Rename beaconBlocksMaybeBlobsByRange * Ensure beaconBlocksMaybeBlobsByRange is same epoch * rebase fixes * type fix * blobs by range edge condition handling * fix test * fix breaking spec --------- Co-authored-by: harkamal <[email protected]>
- Loading branch information
Showing
10 changed files
with
169 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRoot.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import {PeerId} from "@libp2p/interface-peer-id"; | ||
import {IBeaconConfig} from "@lodestar/config"; | ||
import {RequestError, RequestErrorCode} from "@lodestar/reqresp"; | ||
import {Epoch, phase0, Root, Slot} from "@lodestar/types"; | ||
import {toHex} from "@lodestar/utils"; | ||
import {ForkSeq} from "@lodestar/params"; | ||
import {BlockInput, getBlockInput} from "../../chain/blocks/types.js"; | ||
import {wrapError} from "../../util/wrapError.js"; | ||
import {IReqRespBeaconNode} from "./interface.js"; | ||
|
||
export async function beaconBlocksMaybeBlobsByRoot( | ||
config: IBeaconConfig, | ||
reqResp: IReqRespBeaconNode, | ||
peerId: PeerId, | ||
request: phase0.BeaconBlocksByRootRequest, | ||
currentSlot: Epoch, | ||
finalizedSlot: Slot | ||
): Promise<BlockInput[]> { | ||
// Assume all requests are post Deneb | ||
if (config.getForkSeq(finalizedSlot) >= ForkSeq.deneb) { | ||
const blocksAndBlobs = await reqResp.beaconBlockAndBlobsSidecarByRoot(peerId, request); | ||
return blocksAndBlobs.map(({beaconBlock, blobsSidecar}) => | ||
getBlockInput.postDeneb(config, beaconBlock, blobsSidecar) | ||
); | ||
} | ||
|
||
// Assume all request are pre EIP-4844 | ||
else if (config.getForkSeq(currentSlot) < ForkSeq.deneb) { | ||
const blocks = await reqResp.beaconBlocksByRoot(peerId, request); | ||
return blocks.map((block) => getBlockInput.preDeneb(config, block)); | ||
} | ||
|
||
// We don't know if a requested root is after the deneb fork or not. | ||
// Thus some sort of retry is necessary while deneb is not finalized | ||
else { | ||
return Promise.all( | ||
request.map(async (beaconBlockRoot) => | ||
beaconBlockAndBlobsSidecarByRootFallback(config, reqResp, peerId, beaconBlockRoot) | ||
) | ||
); | ||
} | ||
} | ||
|
||
async function beaconBlockAndBlobsSidecarByRootFallback( | ||
config: IBeaconConfig, | ||
reqResp: IReqRespBeaconNode, | ||
peerId: PeerId, | ||
beaconBlockRoot: Root | ||
): Promise<BlockInput> { | ||
const resBlockBlobs = await wrapError(reqResp.beaconBlockAndBlobsSidecarByRoot(peerId, [beaconBlockRoot])); | ||
|
||
if (resBlockBlobs.err) { | ||
// From the spec, if the block is from before the fork, errors with 3: ResourceUnavailable | ||
// > Clients MUST support requesting blocks and sidecars since minimum_request_epoch, where | ||
// minimum_request_epoch = max(finalized_epoch, current_epoch - MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS, EIP4844_FORK_EPOCH). | ||
// If any root in the request content references a block earlier than minimum_request_epoch, | ||
// peers SHOULD respond with error code 3: ResourceUnavailable. | ||
// Ref: https://github.com/ethereum/consensus-specs/blob/aede132f4999ed54b98d35e27aca9451042a1ee9/specs/eip4844/p2p-interface.md#beaconblockandblobssidecarbyroot-v1 | ||
if ( | ||
resBlockBlobs.err instanceof RequestError && | ||
resBlockBlobs.err.type.code === RequestErrorCode.RESOURCE_UNAVAILABLE | ||
) { | ||
// retry with blocks | ||
} else { | ||
// Unexpected error, throw | ||
throw resBlockBlobs.err; | ||
} | ||
} else { | ||
if (resBlockBlobs.result.length < 1) { | ||
throw Error(`beaconBlockAndBlobsSidecarByRoot return empty for block root ${toHex(beaconBlockRoot)}`); | ||
} | ||
|
||
const {beaconBlock, blobsSidecar} = resBlockBlobs.result[0]; | ||
return getBlockInput.postDeneb(config, beaconBlock, blobsSidecar); | ||
} | ||
|
||
const resBlocks = await reqResp.beaconBlocksByRoot(peerId, [beaconBlockRoot]); | ||
if (resBlocks.length < 1) { | ||
throw Error(`beaconBlocksByRoot return empty for block root ${toHex(beaconBlockRoot)}`); | ||
} | ||
|
||
return getBlockInput.preDeneb(config, resBlocks[0]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
export * from "./ReqRespBeaconNode.js"; | ||
export * from "./interface.js"; | ||
export * from "./doBeaconBlocksMaybeBlobsByRange.js"; | ||
export * from "./beaconBlocksMaybeBlobsByRange.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import {IChainForkConfig} from "@lodestar/config"; | ||
import {deneb} from "@lodestar/types"; | ||
import {ckzg} from "./kzg.js"; | ||
|
||
// Cache empty KZG proof, compute once lazily if needed | ||
let emptyKzgAggregatedProof: Uint8Array | null = null; | ||
function getEmptyKzgAggregatedProof(): Uint8Array { | ||
if (!emptyKzgAggregatedProof) { | ||
emptyKzgAggregatedProof = ckzg.computeAggregateKzgProof([]); | ||
} | ||
return emptyKzgAggregatedProof; | ||
} | ||
|
||
/** | ||
* Construct a valid BlobsSidecar for a SignedBeaconBlock that references 0 commitments | ||
*/ | ||
export function getEmptyBlobsSidecar(config: IChainForkConfig, block: deneb.SignedBeaconBlock): deneb.BlobsSidecar { | ||
return { | ||
beaconBlockRoot: config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message), | ||
beaconBlockSlot: block.message.slot, | ||
blobs: [], | ||
kzgAggregatedProof: getEmptyKzgAggregatedProof(), | ||
}; | ||
} |
Oops, something went wrong.