Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-4844: Implement beaconBlocksMaybeBlobsByRoot #4869

Merged
merged 2 commits into from
Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 61 additions & 3 deletions packages/beacon-node/src/network/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,67 @@ export class Network implements INetwork {
}

async beaconBlocksMaybeBlobsByRoot(peerId: PeerId, request: phase0.BeaconBlocksByRootRequest): Promise<BlockInput[]> {
// TODO EIP-4844: Will throw an error for blocks post EIP-4844
const blocks = await this.reqResp.beaconBlocksByRoot(peerId, request);
return blocks.map((block) => getBlockInput.preEIP4844(this.config, block));
// Assume all requests are post EIP-4844
g11tech marked this conversation as resolved.
Show resolved Hide resolved
if (this.config.getForkSeq(this.chain.forkChoice.getFinalizedBlock().slot) >= ForkSeq.eip4844) {
const blocksAndBlobs = await this.reqResp.beaconBlockAndBlobsSidecarByRoot(peerId, request);
return blocksAndBlobs.map(({beaconBlock, blobsSidecar}) =>
getBlockInput.postEIP4844(this.config, beaconBlock, blobsSidecar)
);
}

// Assume all request are pre EIP-4844
else if (this.config.getForkSeq(this.clock.currentSlot) < ForkSeq.eip4844) {
const blocks = await this.reqResp.beaconBlocksByRoot(peerId, request);
return blocks.map((block) => getBlockInput.preEIP4844(this.config, block));
}

// NOTE: Consider blocks may be post or pre EIP-4844
// TODO EIP-4844: Request either blocks, or blocks+blobs
else {
const results = await Promise.all(
request.map(
async (beaconBlockRoot): Promise<BlockInput | null> => {
const [resultBlockBlobs, resultBlocks] = await Promise.allSettled([
this.reqResp.beaconBlockAndBlobsSidecarByRoot(peerId, [beaconBlockRoot]),
this.reqResp.beaconBlocksByRoot(peerId, [beaconBlockRoot]),
]);

if (resultBlockBlobs.status === "fulfilled" && resultBlockBlobs.value.length === 1) {
const {beaconBlock, blobsSidecar} = resultBlockBlobs.value[0];
return getBlockInput.postEIP4844(this.config, beaconBlock, blobsSidecar);
}

if (resultBlocks.status === "rejected") {
return Promise.reject(resultBlocks.reason);
}

// Promise fullfilled + no result = block not found
if (resultBlocks.value.length < 1) {
return null;
}

const block = resultBlocks.value[0];

if (this.config.getForkSeq(block.message.slot) >= ForkSeq.eip4844) {
// beaconBlockAndBlobsSidecarByRoot should have succeeded
if (resultBlockBlobs.status === "rejected") {
// Recycle existing error for beaconBlockAndBlobsSidecarByRoot if any
return Promise.reject(resultBlockBlobs.reason);
} else {
throw Error(
`Received post EIP-4844 ${beaconBlockRoot} over beaconBlocksByRoot not beaconBlockAndBlobsSidecarByRoot`
);
}
}

// Block is pre EIP-4844
return getBlockInput.preEIP4844(this.config, block);
}
)
);

return results.filter((blockOrNull): blockOrNull is BlockInput => blockOrNull !== null);
}
}

/**
Expand Down
15 changes: 15 additions & 0 deletions packages/beacon-node/src/network/reqresp/ReqRespBeaconNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,21 @@ export class ReqRespBeaconNode extends ReqResp implements IReqRespBeaconNode {
);
}

async beaconBlockAndBlobsSidecarByRoot(
peerId: PeerId,
request: eip4844.BeaconBlockAndBlobsSidecarByRootRequest
): Promise<eip4844.SignedBeaconBlockAndBlobsSidecar[]> {
return collectMaxResponse(
this.sendRequest<eip4844.BeaconBlockAndBlobsSidecarByRootRequest, eip4844.SignedBeaconBlockAndBlobsSidecar>(
peerId,
ReqRespMethod.BeaconBlockAndBlobsSidecarByRoot,
[Version.V1],
request
),
request.length
);
}

/**
* Returns the list of protocols that must be subscribed during a specific fork.
* Any protocol not in this list must be un-subscribed.
Expand Down
4 changes: 4 additions & 0 deletions packages/beacon-node/src/network/reqresp/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export interface IReqRespBeaconNode {
): Promise<allForks.SignedBeaconBlock[]>;
beaconBlocksByRoot(peerId: PeerId, request: phase0.BeaconBlocksByRootRequest): Promise<allForks.SignedBeaconBlock[]>;
blobsSidecarsByRange(peerId: PeerId, request: eip4844.BlobsSidecarsByRangeRequest): Promise<eip4844.BlobsSidecar[]>;
beaconBlockAndBlobsSidecarByRoot(
peerId: PeerId,
request: eip4844.BeaconBlockAndBlobsSidecarByRootRequest
): Promise<eip4844.SignedBeaconBlockAndBlobsSidecar[]>;
pruneOnPeerDisconnect(peerId: PeerId): void;
lightClientBootstrap(peerId: PeerId, request: Uint8Array): Promise<altair.LightClientBootstrap>;
lightClientOptimisticUpdate(peerId: PeerId): Promise<altair.LightClientOptimisticUpdate>;
Expand Down
2 changes: 2 additions & 0 deletions packages/beacon-node/src/network/reqresp/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export enum ReqRespMethod {
BeaconBlocksByRange = "beacon_blocks_by_range",
BeaconBlocksByRoot = "beacon_blocks_by_root",
BlobsSidecarsByRange = "blobs_sidecars_by_range",
BeaconBlockAndBlobsSidecarByRoot = "beacon_block_and_blobs_sidecar_by_root",
LightClientBootstrap = "light_client_bootstrap",
LightClientUpdatesByRange = "light_client_updates_by_range",
LightClientFinalityUpdate = "light_client_finality_update",
Expand All @@ -26,6 +27,7 @@ type RequestBodyByMethod = {
[ReqRespMethod.BeaconBlocksByRange]: unknown;
[ReqRespMethod.BeaconBlocksByRoot]: unknown;
[ReqRespMethod.BlobsSidecarsByRange]: unknown;
[ReqRespMethod.BeaconBlockAndBlobsSidecarByRoot]: unknown;
[ReqRespMethod.LightClientBootstrap]: unknown;
[ReqRespMethod.LightClientUpdatesByRange]: unknown;
[ReqRespMethod.LightClientFinalityUpdate]: unknown;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ describe("network / peers / PeerManager", function () {
beaconBlocksByRange = sinon.stub();
beaconBlocksByRoot = sinon.stub();
blobsSidecarsByRange = sinon.stub();
beaconBlockAndBlobsSidecarByRoot = sinon.stub();
pruneOnPeerDisconnect = sinon.stub();
lightClientBootstrap = sinon.stub();
lightClientOptimisticUpdate = sinon.stub();
Expand Down