Skip to content

Commit

Permalink
Add eip-4844 types and config (#4778)
Browse files Browse the repository at this point in the history
* Add eip-4844 types

* Add eip-4844 config

* Declare eip-4844 params in validator

* Add state transition types

* Auto declare msgIdFn for future forks

* Fix tests

* Revert config preset changes

* Remove unnecessary diff

* Fix api / impl / config test
  • Loading branch information
dapplion committed Nov 26, 2022
1 parent 9e21c66 commit 798ec16
Show file tree
Hide file tree
Showing 33 changed files with 496 additions and 44 deletions.
6 changes: 6 additions & 0 deletions packages/beacon-node/src/api/impl/config/constants.ts
Expand Up @@ -34,6 +34,8 @@ import {
ATTESTATION_SUBNET_COUNT,
TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE,
SYNC_COMMITTEE_SUBNET_COUNT,
BLOB_TX_TYPE,
VERSIONED_HASH_VERSION_KZG,
} from "@lodestar/params";

/* eslint-disable @typescript-eslint/naming-convention */
Expand Down Expand Up @@ -94,4 +96,8 @@ export const specConstants = {

// ## Capella domain types
DOMAIN_BLS_TO_EXECUTION_CHANGE,

// EIP4844 types
BLOB_TX_TYPE,
VERSIONED_HASH_VERSION_KZG,
};
19 changes: 5 additions & 14 deletions packages/beacon-node/src/network/gossip/encoding.ts
Expand Up @@ -39,16 +39,14 @@ export function msgIdFn(gossipTopicCache: GossipTopicCache, msg: Message): Uint8

let vec: Uint8Array[];

switch (topic.fork) {
if (topic.fork === ForkName.phase0) {
// message id for phase0.
// ```
// SHA256(MESSAGE_DOMAIN_VALID_SNAPPY + snappy_decompress(message.data))[:20]
// ```
case ForkName.phase0:
vec = [MESSAGE_DOMAIN_VALID_SNAPPY, msg.data];
break;

// message id for altair.
vec = [MESSAGE_DOMAIN_VALID_SNAPPY, msg.data];
} else {
// message id for altair and subsequent future forks.
// ```
// SHA256(
// MESSAGE_DOMAIN_VALID_SNAPPY +
Expand All @@ -58,14 +56,7 @@ export function msgIdFn(gossipTopicCache: GossipTopicCache, msg: Message): Uint8
// )[:20]
// ```
// https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.7/specs/altair/p2p-interface.md#topics-and-messages
//
// TODO: check if the capella handling is same as the other forks
case ForkName.altair:
case ForkName.bellatrix:
case ForkName.capella: {
vec = [MESSAGE_DOMAIN_VALID_SNAPPY, intToBytes(msg.topic.length, 8), Buffer.from(msg.topic), msg.data];
break;
}
vec = [MESSAGE_DOMAIN_VALID_SNAPPY, intToBytes(msg.topic.length, 8), Buffer.from(msg.topic), msg.data];
}

return Buffer.from(digest(Buffer.concat(vec))).subarray(0, 20);
Expand Down
3 changes: 3 additions & 0 deletions packages/beacon-node/test/e2e/api/impl/config.test.ts
Expand Up @@ -9,6 +9,9 @@ const CONSTANT_NAMES_SKIP_LIST = new Set([
// This constant can also be derived from existing constants so it's not critical.
// PARTICIPATION_FLAG_WEIGHTS = [TIMELY_SOURCE_WEIGHT, TIMELY_TARGET_WEIGHT, TIMELY_HEAD_WEIGHT]
"PARTICIPATION_FLAG_WEIGHTS",
// TODO EIP-4844: This constant was added then removed on a spec re-write.
// When developing eip-4844 branch the tracked version still doesn't have released the removal
"DOMAIN_BLOBS_SIDECAR",
]);

describe("api / impl / config", function () {
Expand Down
2 changes: 2 additions & 0 deletions packages/beacon-node/test/spec/presets/fork.ts
Expand Up @@ -29,6 +29,8 @@ export const fork: TestRunnerFn<ForkStateCase, BeaconStateAllForks> = (forkNext)
return slotFns.upgradeStateToBellatrix(preState as CachedBeaconStateAltair);
case ForkName.capella:
return slotFns.upgradeStateToCapella(preState as CachedBeaconStateBellatrix);
case ForkName.eip4844:
throw Error("eip4844 not implemented");
}
},
options: {
Expand Down
2 changes: 2 additions & 0 deletions packages/beacon-node/test/spec/presets/transition.ts
Expand Up @@ -84,6 +84,8 @@ function getTransitionConfig(fork: ForkName, forkEpoch: number): Partial<IChainC
return {ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: forkEpoch};
case ForkName.capella:
return {ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: forkEpoch};
case ForkName.eip4844:
return {ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: 0, EIP4844_FORK_EPOCH: forkEpoch};
}
}

Expand Down
7 changes: 7 additions & 0 deletions packages/beacon-node/test/spec/utils/getConfig.ts
Expand Up @@ -21,5 +21,12 @@ export function getConfig(fork: ForkName, forkEpoch = 0): IChainForkConfig {
BELLATRIX_FORK_EPOCH: 0,
CAPELLA_FORK_EPOCH: forkEpoch,
});
case ForkName.eip4844:
return createIChainForkConfig({
ALTAIR_FORK_EPOCH: 0,
BELLATRIX_FORK_EPOCH: 0,
CAPELLA_FORK_EPOCH: 0,
EIP4844_FORK_EPOCH: forkEpoch,
});
}
}
14 changes: 13 additions & 1 deletion packages/beacon-node/test/unit/network/fork.test.ts
Expand Up @@ -8,11 +8,13 @@ function getForkConfig({
altair,
bellatrix,
capella,
eip4844,
}: {
phase0: number;
altair: number;
bellatrix: number;
capella: number;
eip4844: number;
}): IBeaconConfig {
const forks: Record<ForkName, IForkInfo> = {
phase0: {
Expand Down Expand Up @@ -47,6 +49,14 @@ function getForkConfig({
prevVersion: Buffer.from([0, 0, 0, 2]),
prevForkName: ForkName.bellatrix,
},
eip4844: {
name: ForkName.eip4844,
seq: ForkSeq.eip4844,
epoch: eip4844,
version: Buffer.from([0, 0, 0, 4]),
prevVersion: Buffer.from([0, 0, 0, 3]),
prevForkName: ForkName.capella,
},
};
const forksAscendingEpochOrder = Object.values(forks);
const forksDescendingEpochOrder = Object.values(forks).reverse();
Expand Down Expand Up @@ -122,9 +132,11 @@ const testScenarios = [

for (const testScenario of testScenarios) {
const {phase0, altair, bellatrix, capella, testCases} = testScenario;
// TODO EIP-4844: Is it necessary to test?
const eip4844 = Infinity;

describe(`network / fork: phase0: ${phase0}, altair: ${altair}, bellatrix: ${bellatrix} capella: ${capella}`, () => {
const forkConfig = getForkConfig({phase0, altair, bellatrix, capella});
const forkConfig = getForkConfig({phase0, altair, bellatrix, capella, eip4844});
const forks = forkConfig.forks;
for (const testCase of testCases) {
const {epoch, currentFork, nextFork, activeForks} = testCase;
Expand Down
10 changes: 10 additions & 0 deletions packages/config/src/chainConfig/presets/mainnet.ts
Expand Up @@ -41,6 +41,10 @@ export const chainConfig: IChainConfig = {
CAPELLA_FORK_VERSION: b("0x03000000"),
CAPELLA_FORK_EPOCH: Infinity,

// EIP-4844
EIP4844_FORK_VERSION: b("0x04000000"),
EIP4844_FORK_EPOCH: Infinity,

// Time parameters
// ---------------------------------------------------------------
// 12 seconds
Expand Down Expand Up @@ -74,4 +78,10 @@ export const chainConfig: IChainConfig = {
DEPOSIT_CHAIN_ID: 1,
DEPOSIT_NETWORK_ID: 1,
DEPOSIT_CONTRACT_ADDRESS: b("0x00000000219ab540356cBB839Cbe05303d7705Fa"),

// Blobs
// ---------------------------------------------------------------
// https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/p2p-interface.md#configuration
MAX_REQUEST_BLOBS_SIDECARS: 128,
MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS: 4096,
};
9 changes: 9 additions & 0 deletions packages/config/src/chainConfig/presets/minimal.ts
Expand Up @@ -39,6 +39,9 @@ export const chainConfig: IChainConfig = {
// Capella
CAPELLA_FORK_VERSION: b("0x03000001"),
CAPELLA_FORK_EPOCH: Infinity,
// EIP-4844
EIP4844_FORK_VERSION: b("0x04000001"),
EIP4844_FORK_EPOCH: Infinity,

// Time parameters
// ---------------------------------------------------------------
Expand Down Expand Up @@ -74,4 +77,10 @@ export const chainConfig: IChainConfig = {
DEPOSIT_NETWORK_ID: 5,
// Configured on a per testnet basis
DEPOSIT_CONTRACT_ADDRESS: b("0x1234567890123456789012345678901234567890"),

// Blobs
// ---------------------------------------------------------------
// https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/p2p-interface.md#configuration
MAX_REQUEST_BLOBS_SIDECARS: 128,
MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS: 4096,
};
16 changes: 16 additions & 0 deletions packages/config/src/chainConfig/types.ts
Expand Up @@ -37,6 +37,9 @@ export type IChainConfig = {
// Capella
CAPELLA_FORK_VERSION: Uint8Array;
CAPELLA_FORK_EPOCH: number;
// EIP-4844
EIP4844_FORK_VERSION: Uint8Array;
EIP4844_FORK_EPOCH: number;

// Time parameters
SECONDS_PER_SLOT: number;
Expand All @@ -59,6 +62,12 @@ export type IChainConfig = {
DEPOSIT_CHAIN_ID: number;
DEPOSIT_NETWORK_ID: number;
DEPOSIT_CONTRACT_ADDRESS: Uint8Array;

// EIP-4844
// https://github.com/ethereum/consensus-specs/blob/11a037fd9227e29ee809c9397b09f8cc3383a8c0/specs/eip4844/p2p-interface.md#configuration
MAX_REQUEST_BLOBS_SIDECARS: number;
/** The minimum epoch range over which a node must serve blobs sidecars */
MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS: number;
};

export const chainConfigTypes: SpecTypes<IChainConfig> = {
Expand Down Expand Up @@ -86,6 +95,9 @@ export const chainConfigTypes: SpecTypes<IChainConfig> = {
// Capella
CAPELLA_FORK_VERSION: "bytes",
CAPELLA_FORK_EPOCH: "number",
// EIP-4844
EIP4844_FORK_VERSION: "bytes",
EIP4844_FORK_EPOCH: "number",

// Time parameters
SECONDS_PER_SLOT: "number",
Expand All @@ -108,6 +120,10 @@ export const chainConfigTypes: SpecTypes<IChainConfig> = {
DEPOSIT_CHAIN_ID: "number",
DEPOSIT_NETWORK_ID: "number",
DEPOSIT_CONTRACT_ADDRESS: "bytes",

// Blobs
MAX_REQUEST_BLOBS_SIDECARS: "number",
MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS: "number",
};

/** Allows values in a Spec file */
Expand Down
10 changes: 9 additions & 1 deletion packages/config/src/forkConfig/index.ts
Expand Up @@ -39,10 +39,18 @@ export function createIForkConfig(config: IChainConfig): IForkConfig {
prevVersion: config.BELLATRIX_FORK_VERSION,
prevForkName: ForkName.bellatrix,
};
const eip4844: IForkInfo = {
name: ForkName.eip4844,
seq: ForkSeq.eip4844,
epoch: config.EIP4844_FORK_EPOCH,
version: config.EIP4844_FORK_VERSION,
prevVersion: config.CAPELLA_FORK_VERSION,
prevForkName: ForkName.capella,
};

/** Forks in order order of occurence, `phase0` first */
// Note: Downstream code relies on proper ordering.
const forks = {phase0, altair, bellatrix, capella};
const forks = {phase0, altair, bellatrix, capella, eip4844};

// Prevents allocating an array on every getForkInfo() call
const forksAscendingEpochOrder = Object.values(forks);
Expand Down
2 changes: 2 additions & 0 deletions packages/params/src/forkName.ts
Expand Up @@ -6,6 +6,7 @@ export enum ForkName {
altair = "altair",
bellatrix = "bellatrix",
capella = "capella",
eip4844 = "eip4844",
}

/**
Expand All @@ -16,4 +17,5 @@ export enum ForkSeq {
altair = 1,
bellatrix = 2,
capella = 3,
eip4844 = 4,
}
8 changes: 8 additions & 0 deletions packages/params/src/index.ts
Expand Up @@ -88,6 +88,9 @@ export const {
WITHDRAWAL_QUEUE_LIMIT,
MAX_BLS_TO_EXECUTION_CHANGES,
MAX_WITHDRAWALS_PER_PAYLOAD,

FIELD_ELEMENTS_PER_BLOB,
MAX_BLOBS_PER_BLOCK,
} = {...presets[ACTIVE_PRESET], ...userOverrides};

////////////
Expand Down Expand Up @@ -205,3 +208,8 @@ export const MAX_REQUEST_LIGHT_CLIENT_COMMITTEE_HASHES = 128;
*/
export const SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY = 128;
export const INTERVALS_PER_SLOT = 3;

// EIP-4844: Crypto const
export const BYTES_PER_FIELD_ELEMENT = 32;
export const BLOB_TX_TYPE = 0x05;
export const VERSIONED_HASH_VERSION_KZG = 0x01;
5 changes: 5 additions & 0 deletions packages/params/src/interface/eip4844.ts
@@ -0,0 +1,5 @@
/* eslint-disable @typescript-eslint/naming-convention */
export type EIP4844Preset = {
FIELD_ELEMENTS_PER_BLOB: number;
MAX_BLOBS_PER_BLOCK: number;
};
3 changes: 2 additions & 1 deletion packages/params/src/interface/index.ts
Expand Up @@ -2,5 +2,6 @@ import {Phase0Preset} from "./phase0.js";
import {AltairPreset} from "./altair.js";
import {BellatrixPreset} from "./bellatrix.js";
import {CapellaPreset} from "./capella.js";
import {EIP4844Preset} from "./eip4844.js";

export type BeaconPreset = Phase0Preset & AltairPreset & BellatrixPreset & CapellaPreset;
export type BeaconPreset = Phase0Preset & AltairPreset & BellatrixPreset & CapellaPreset & EIP4844Preset;
8 changes: 8 additions & 0 deletions packages/params/src/presets/mainnet/eip4844.ts
@@ -0,0 +1,8 @@
import {EIP4844Preset} from "../../interface/eip4844.js";

/* eslint-disable @typescript-eslint/naming-convention */
export const eip4844: EIP4844Preset = {
// https://github.com/ethereum/consensus-specs/blob/dev/presets/mainnet/eip4844.yaml
FIELD_ELEMENTS_PER_BLOB: 4096,
MAX_BLOBS_PER_BLOCK: 16,
};
2 changes: 2 additions & 0 deletions packages/params/src/presets/mainnet/index.ts
Expand Up @@ -3,6 +3,7 @@ import {phase0} from "./phase0.js";
import {altair} from "./altair.js";
import {bellatrix} from "./bellatrix.js";
import {capella} from "./capella.js";
import {eip4844} from "./eip4844.js";

export const commit = "v1.2.0";

Expand All @@ -11,4 +12,5 @@ export const preset: BeaconPreset = {
...altair,
...bellatrix,
...capella,
...eip4844,
};
8 changes: 8 additions & 0 deletions packages/params/src/presets/minimal/eip4844.ts
@@ -0,0 +1,8 @@
import {EIP4844Preset} from "../../interface/eip4844.js";

/* eslint-disable @typescript-eslint/naming-convention */
export const eip4844: EIP4844Preset = {
// https://github.com/ethereum/consensus-specs/blob/dev/presets/minimal/eip4844.yaml
FIELD_ELEMENTS_PER_BLOB: 4,
MAX_BLOBS_PER_BLOCK: 16,
};
2 changes: 2 additions & 0 deletions packages/params/src/presets/minimal/index.ts
Expand Up @@ -3,6 +3,7 @@ import {phase0} from "./phase0.js";
import {altair} from "./altair.js";
import {bellatrix} from "./bellatrix.js";
import {capella} from "./capella.js";
import {eip4844} from "./eip4844.js";

export const commit = "v1.2.0";

Expand All @@ -11,4 +12,5 @@ export const preset: BeaconPreset = {
...altair,
...bellatrix,
...capella,
...eip4844,
};
8 changes: 6 additions & 2 deletions packages/state-transition/src/cache/stateCache.ts
@@ -1,11 +1,13 @@
import {IBeaconConfig} from "@lodestar/config";
import {EpochContext, EpochContextImmutableData, EpochContextOpts} from "./epochContext.js";
import {
BeaconStateAllForks,
BeaconStateExecutions,
BeaconStatePhase0,
BeaconStateAltair,
BeaconStateBellatrix,
BeaconStateCapella,
BeaconStateAllForks,
BeaconStateEip4844,
} from "./types.js";

export type BeaconStateCache = {
Expand Down Expand Up @@ -115,8 +117,10 @@ export type CachedBeaconStatePhase0 = CachedBeaconState<BeaconStatePhase0>;
export type CachedBeaconStateAltair = CachedBeaconState<BeaconStateAltair>;
export type CachedBeaconStateBellatrix = CachedBeaconState<BeaconStateBellatrix>;
export type CachedBeaconStateCapella = CachedBeaconState<BeaconStateCapella>;
export type CachedBeaconStateEip4844 = CachedBeaconState<BeaconStateEip4844>;

export type CachedBeaconStateAllForks = CachedBeaconState<BeaconStateAllForks>;
export type CachedBeaconStateExecutions = CachedBeaconStateBellatrix | CachedBeaconStateCapella;
export type CachedBeaconStateExecutions = CachedBeaconState<BeaconStateExecutions>;
/**
* Create CachedBeaconState computing a new EpochContext instance
*/
Expand Down
10 changes: 8 additions & 2 deletions packages/state-transition/src/cache/types.ts
Expand Up @@ -5,11 +5,17 @@ export type BeaconStatePhase0 = CompositeViewDU<typeof ssz.phase0.BeaconState>;
export type BeaconStateAltair = CompositeViewDU<typeof ssz.altair.BeaconState>;
export type BeaconStateBellatrix = CompositeViewDU<typeof ssz.bellatrix.BeaconState>;
export type BeaconStateCapella = CompositeViewDU<typeof ssz.capella.BeaconState>;
export type BeaconStateEip4844 = CompositeViewDU<typeof ssz.eip4844.BeaconState>;

// Union at the TreeViewDU level
// - Works well as function argument and as generic type for allForks functions
//
// Quasy equivalent to
// CompositeViewDU<typeof ssz.phase0.BeaconState | typeof ssz.altair.BeaconState | typeof ssz.bellatrix.BeaconState>
export type BeaconStateAllForks = BeaconStatePhase0 | BeaconStateAltair | BeaconStateBellatrix | BeaconStateCapella;
export type BeaconStateExecutions = BeaconStateBellatrix | BeaconStateCapella;
export type BeaconStateAllForks =
| BeaconStatePhase0
| BeaconStateAltair
| BeaconStateBellatrix
| BeaconStateCapella
| BeaconStateEip4844;
export type BeaconStateExecutions = BeaconStateBellatrix | BeaconStateCapella | BeaconStateEip4844;

0 comments on commit 798ec16

Please sign in to comment.