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

Integrate execution engine #3262

Merged
merged 7 commits into from
Sep 28, 2021
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
30 changes: 30 additions & 0 deletions packages/cli/src/options/beaconNodeOptions/execution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {defaultOptions, IBeaconNodeOptions} from "@chainsafe/lodestar";
import {ICliCommandOptions} from "../../util";

export type ExecutionEngineArgs = {
"execution.urls": string[];
"execution.timeout": number;
};

export function parseArgs(args: ExecutionEngineArgs): IBeaconNodeOptions["executionEngine"] {
return {
urls: args["execution.urls"],
timeout: args["execution.timeout"],
};
}

export const options: ICliCommandOptions<ExecutionEngineArgs> = {
"execution.urls": {
description: "Urls to execution client engine API",
type: "array",
defaultDescription: defaultOptions.executionEngine.urls.join(" "),
group: "execution",
},

"execution.timeout": {
description: "Timeout in miliseconds for execution engine API HTTP client",
type: "number",
defaultDescription: String(defaultOptions.executionEngine.timeout),
group: "execution",
},
};
4 changes: 4 additions & 0 deletions packages/cli/src/options/beaconNodeOptions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {removeUndefinedRecursive} from "../../util";
import * as api from "./api";
import * as chain from "./chain";
import * as eth1 from "./eth1";
import * as execution from "./execution";
import * as logger from "./logger";
import * as metrics from "./metrics";
import * as network from "./network";
Expand All @@ -12,6 +13,7 @@ import * as sync from "./sync";
export type IBeaconNodeArgs = api.IApiArgs &
chain.IChainArgs &
eth1.IEth1Args &
execution.ExecutionEngineArgs &
logger.ILoggerArgs &
metrics.IMetricsArgs &
network.INetworkArgs &
Expand All @@ -24,6 +26,7 @@ export function parseBeaconNodeArgs(args: IBeaconNodeArgs): RecursivePartial<IBe
chain: chain.parseArgs(args),
// db: {},
eth1: eth1.parseArgs(args),
executionEngine: execution.parseArgs(args),
logger: logger.parseArgs(args),
metrics: metrics.parseArgs(args),
network: network.parseArgs(args),
Expand All @@ -35,6 +38,7 @@ export const beaconNodeOptions = {
...api.options,
...chain.options,
...eth1.options,
...execution.options,
...logger.options,
...metrics.options,
...network.options,
Expand Down
7 changes: 7 additions & 0 deletions packages/cli/test/unit/options/beaconNodeOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ describe("options / beaconNodeOptions", () => {
"eth1.providerUrls": ["http://my.node:8545"],
"eth1.depositContractDeployBlock": 1625314,

"execution.urls": ["http://localhost:8550"],
"execution.timeout": 12000,

"logger.eth1.level": "debug",
"logger.unknown.level": "debug",

Expand Down Expand Up @@ -66,6 +69,10 @@ describe("options / beaconNodeOptions", () => {
providerUrls: ["http://my.node:8545"],
depositContractDeployBlock: 1625314,
},
executionEngine: {
urls: ["http://localhost:8550"],
timeout: 12000,
},
logger: {
eth1: {
level: LogLevel.debug,
Expand Down
3 changes: 3 additions & 0 deletions packages/fork-choice/src/forkChoice/forkChoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ export class ForkChoice implements IForkChoice {
parentRoot: parentRootHex,
targetRoot: toHexString(targetRoot),
stateRoot: toHexString(block.stateRoot),
executionPayloadBlockHash: merge.isMergeBlockBodyType(block.body)
? toHexString(block.body.executionPayload.blockHash)
: null,
justifiedEpoch: stateJustifiedEpoch,
justifiedRoot: toHexString(state.currentJustifiedCheckpoint.root),
finalizedEpoch: finalizedCheckpoint.epoch,
Expand Down
7 changes: 2 additions & 5 deletions packages/fork-choice/src/forkChoice/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,9 @@ export interface IForkChoice {
}

export type PowBlock = {
blockhash: Root;
parentHash: Root;
isProcessed: boolean;
isValid: boolean;
blockhash: RootHex;
parentHash: RootHex;
totalDifficulty: bigint;
difficulty: bigint;
};

export type OnBlockPrecachedData = {
Expand Down
6 changes: 6 additions & 0 deletions packages/fork-choice/src/protoArray/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ export interface IProtoBlock {
* it also just exists for upstream components (namely attestation verification)
*/
targetRoot: RootHex;
/**
* `executionPayloadBlockHash` is not necessary for ProtoArray either.
* Here to do ExecutionEngine.notify_forkchoice_updated() easier.
* TODO: Check with other teams if this is the optimal strategy
*/
executionPayloadBlockHash: RootHex | null;
justifiedEpoch: Epoch;
justifiedRoot: RootHex;
finalizedEpoch: Epoch;
Expand Down
46 changes: 10 additions & 36 deletions packages/fork-choice/src/protoArray/protoArray.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Epoch, Slot, RootHex} from "@chainsafe/lodestar-types";
import {Epoch, RootHex} from "@chainsafe/lodestar-types";

import {IProtoBlock, IProtoNode, HEX_ZERO_HASH} from "./interface";
import {ProtoArrayError, ProtoArrayErrorCode} from "./errors";
Expand Down Expand Up @@ -38,45 +38,19 @@ export class ProtoArray {
this.indices = new Map<string, number>();
}

static initialize({
slot,
parentRoot,
stateRoot,
blockRoot,
justifiedEpoch,
justifiedRoot,
finalizedEpoch,
finalizedRoot,
}: {
slot: Slot;
parentRoot: RootHex;
stateRoot: RootHex;
blockRoot: RootHex;
justifiedEpoch: Epoch;
justifiedRoot: RootHex;
finalizedEpoch: Epoch;
finalizedRoot: RootHex;
}): ProtoArray {
static initialize(block: Omit<IProtoBlock, "targetRoot">): ProtoArray {
const protoArray = new ProtoArray({
pruneThreshold: DEFAULT_PRUNE_THRESHOLD,
justifiedEpoch,
justifiedRoot,
finalizedEpoch,
finalizedRoot,
justifiedEpoch: block.justifiedEpoch,
justifiedRoot: block.justifiedRoot,
finalizedEpoch: block.finalizedEpoch,
finalizedRoot: block.finalizedRoot,
});
const block: IProtoBlock = {
slot,
blockRoot,
parentRoot,
stateRoot,
protoArray.onBlock({
...block,
// We are using the blockROot as the targetRoot, since it always lies on an epoch boundary
targetRoot: blockRoot,
justifiedEpoch,
justifiedRoot,
finalizedEpoch,
finalizedRoot,
};
protoArray.onBlock(block);
targetRoot: block.blockRoot,
});
return protoArray;
}

Expand Down
6 changes: 4 additions & 2 deletions packages/fork-choice/test/unit/forkChoice/forkChoice.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ForkChoice, IForkChoiceStore, ProtoArray} from "../../../src";
import {ForkChoice, IForkChoiceStore, IProtoBlock, ProtoArray} from "../../../src";
import {config} from "@chainsafe/lodestar-config/default";
import {expect} from "chai";
import {fromHexString} from "@chainsafe/ssz";
Expand All @@ -18,19 +18,21 @@ describe("Forkchoice", function () {
stateRoot,
parentRoot,
blockRoot: finalizedRoot,
executionPayloadBlockHash: null,
justifiedEpoch: genesisEpoch,
justifiedRoot: genesisRoot,
finalizedEpoch: genesisEpoch,
finalizedRoot: genesisRoot,
});

// Add block that is a finalized descendant.
const block = {
const block: IProtoBlock = {
slot: genesisSlot + 1,
blockRoot: finalizedDesc,
parentRoot: finalizedRoot,
stateRoot,
targetRoot: finalizedRoot,
executionPayloadBlockHash: null,
justifiedEpoch: genesisEpoch,
justifiedRoot: genesisRoot,
finalizedEpoch: genesisEpoch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe("getCommonAncestor", () => {
stateRoot: "-",
parentRoot: "-",
blockRoot: "0",
executionPayloadBlockHash: null,
justifiedEpoch: 0,
justifiedRoot: "-",
finalizedEpoch: 0,
Expand All @@ -42,6 +43,7 @@ describe("getCommonAncestor", () => {
parentRoot: block.parent,
stateRoot: "-",
targetRoot: "-",
executionPayloadBlockHash: null,
justifiedEpoch: 0,
justifiedRoot: "-",
finalizedEpoch: 0,
Expand Down
3 changes: 3 additions & 0 deletions packages/fork-choice/test/unit/protoArray/protoArray.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ describe("ProtoArray", () => {
stateRoot,
parentRoot,
blockRoot: finalizedRoot,
executionPayloadBlockHash: null,
justifiedEpoch: genesisEpoch,
justifiedRoot: stateRoot,
finalizedEpoch: genesisEpoch,
Expand All @@ -32,6 +33,7 @@ describe("ProtoArray", () => {
parentRoot: finalizedRoot,
stateRoot,
targetRoot: finalizedRoot,
executionPayloadBlockHash: null,
justifiedEpoch: genesisEpoch,
justifiedRoot: stateRoot,
finalizedEpoch: genesisEpoch,
Expand All @@ -45,6 +47,7 @@ describe("ProtoArray", () => {
parentRoot: unknown,
stateRoot,
targetRoot: finalizedRoot,
executionPayloadBlockHash: null,
justifiedEpoch: genesisEpoch,
justifiedRoot: stateRoot,
finalizedEpoch: genesisEpoch,
Expand Down
21 changes: 18 additions & 3 deletions packages/lodestar/src/chain/blocks/importBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import {
CachedBeaconState,
computeStartSlotAtEpoch,
getEffectiveBalances,
merge,
} from "@chainsafe/lodestar-beacon-state-transition";
import {IForkChoice, OnBlockPrecachedData} from "@chainsafe/lodestar-fork-choice";
import {ILogger} from "@chainsafe/lodestar-utils";
import {IChainForkConfig} from "@chainsafe/lodestar-config";
import {IMetrics} from "../../metrics";
import {IEth1ForBlockProduction} from "../../eth1";
import {IBeaconDb} from "../../db";
import {CheckpointStateCache, StateContextCache, toCheckpointHex} from "../stateCache";
import {ChainEvent} from "../emitter";
Expand All @@ -20,6 +22,7 @@ import {FullyVerifiedBlock} from "./types";

export type ImportBlockModules = {
db: IBeaconDb;
eth1: IEth1ForBlockProduction;
forkChoice: IForkChoice;
stateCache: StateContextCache;
checkpointStateCache: CheckpointStateCache;
Expand Down Expand Up @@ -76,9 +79,21 @@ export async function importBlock(chain: ImportBlockModules, fullyVerifiedBlock:
onBlockPrecachedData.justifiedBalances = getEffectiveBalances(state);
}

// TODO: Figure out how to fetch for merge
// powBlock: undefined,
// powBlockParent: undefined,
if (
merge.isMergeStateType(postState) &&
merge.isMergeBlockBodyType(block.message.body) &&
merge.isMergeBlock(postState, block.message.body)
) {
// pow_block = get_pow_block(block.body.execution_payload.parent_hash)
const powBlockRootHex = toHexString(block.message.body.executionPayload.parentHash);
const powBlock = await chain.eth1.getPowBlock(powBlockRootHex);
if (!powBlock) throw Error(`merge block parent POW block not found ${powBlockRootHex}`);
// pow_parent = get_pow_block(pow_block.parent_hash)
const powBlockParent = await chain.eth1.getPowBlock(powBlock.parentHash);
if (!powBlockParent) throw Error(`merge block parent's parent POW block not found ${powBlock.parentHash}`);
onBlockPrecachedData.powBlock = powBlock;
onBlockPrecachedData.powBlockParent = powBlockParent;
}

chain.forkChoice.onBlock(block.message, postState, onBlockPrecachedData);

Expand Down
Loading