Skip to content

Commit 929d0ea

Browse files
authored
feat: add fulu definition (#7479)
**Motivation** Both `peerDAS` and `FOCIL` both rely on these changes and its little harm to merge them into unstable so that both branches can build on this without diverging.
1 parent b785bbd commit 929d0ea

File tree

28 files changed

+187
-3
lines changed

28 files changed

+187
-3
lines changed

packages/beacon-node/test/spec/presets/fork.test.ts

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
CachedBeaconStateBellatrix,
88
CachedBeaconStateCapella,
99
CachedBeaconStateDeneb,
10+
CachedBeaconStateElectra,
1011
CachedBeaconStatePhase0,
1112
} from "@lodestar/state-transition";
1213
import * as slotFns from "@lodestar/state-transition/slot";
@@ -38,6 +39,8 @@ const fork: TestRunnerFn<ForkStateCase, BeaconStateAllForks> = (forkNext) => {
3839
return slotFns.upgradeStateToDeneb(preState as CachedBeaconStateCapella);
3940
case ForkName.electra:
4041
return slotFns.upgradeStateToElectra(preState as CachedBeaconStateDeneb);
42+
case ForkName.fulu:
43+
return slotFns.upgradeStateToFulu(preState as CachedBeaconStateElectra);
4144
}
4245
},
4346
options: {

packages/beacon-node/test/spec/presets/transition.test.ts

+9
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ function getTransitionConfig(fork: ForkName, forkEpoch: number): Partial<ChainCo
108108
DENEB_FORK_EPOCH: 0,
109109
ELECTRA_FORK_EPOCH: forkEpoch,
110110
};
111+
case ForkName.fulu:
112+
return {
113+
ALTAIR_FORK_EPOCH: 0,
114+
BELLATRIX_FORK_EPOCH: 0,
115+
CAPELLA_FORK_EPOCH: 0,
116+
DENEB_FORK_EPOCH: 0,
117+
ELECTRA_FORK_EPOCH: 0,
118+
FULU_FORK_EPOCH: forkEpoch,
119+
};
111120
}
112121
}
113122

packages/beacon-node/test/unit/chain/lightclient/upgradeLightClientHeader.test.ts

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ describe("UpgradeLightClientHeader", () => {
1515
CAPELLA_FORK_EPOCH: 3,
1616
DENEB_FORK_EPOCH: 4,
1717
ELECTRA_FORK_EPOCH: 5,
18+
FULU_FORK_EPOCH: 6,
1819
});
1920

2021
const genesisValidatorsRoot = Buffer.alloc(32, 0xaa);
@@ -28,6 +29,7 @@ describe("UpgradeLightClientHeader", () => {
2829
bellatrix: ssz.altair.LightClientHeader.defaultValue(),
2930
deneb: ssz.deneb.LightClientHeader.defaultValue(),
3031
electra: ssz.deneb.LightClientHeader.defaultValue(),
32+
fulu: ssz.deneb.LightClientHeader.defaultValue(),
3133
};
3234

3335
testSlots = {
@@ -37,6 +39,7 @@ describe("UpgradeLightClientHeader", () => {
3739
capella: 25,
3840
deneb: 33,
3941
electra: 41,
42+
fulu: 54,
4043
};
4144
});
4245

packages/beacon-node/test/unit/network/fork.test.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ function getForkConfig({
1010
capella,
1111
deneb,
1212
electra,
13+
fulu,
1314
}: {
1415
phase0: number;
1516
altair: number;
1617
bellatrix: number;
1718
capella: number;
1819
deneb: number;
1920
electra: number;
21+
fulu: number;
2022
}): BeaconConfig {
2123
const forks: Record<ForkName, ForkInfo> = {
2224
phase0: {
@@ -67,6 +69,14 @@ function getForkConfig({
6769
prevVersion: Buffer.from([0, 0, 0, 4]),
6870
prevForkName: ForkName.deneb,
6971
},
72+
fulu: {
73+
name: ForkName.fulu,
74+
seq: ForkSeq.fulu,
75+
epoch: fulu,
76+
version: Buffer.from([0, 0, 0, 6]),
77+
prevVersion: Buffer.from([0, 0, 0, 5]),
78+
prevForkName: ForkName.electra,
79+
},
7080
};
7181
const forksAscendingEpochOrder = Object.values(forks);
7282
const forksDescendingEpochOrder = Object.values(forks).reverse();
@@ -144,9 +154,10 @@ for (const testScenario of testScenarios) {
144154
const {phase0, altair, bellatrix, capella, testCases} = testScenario;
145155
const deneb = Infinity;
146156
const electra = Infinity;
157+
const fulu = Infinity;
147158

148159
describe(`network / fork: phase0: ${phase0}, altair: ${altair}, bellatrix: ${bellatrix} capella: ${capella}`, () => {
149-
const forkConfig = getForkConfig({phase0, altair, bellatrix, capella, deneb, electra});
160+
const forkConfig = getForkConfig({phase0, altair, bellatrix, capella, deneb, electra, fulu});
150161
const forks = forkConfig.forks;
151162
for (const testCase of testCases) {
152163
const {epoch, currentFork, nextFork, activeForks} = testCase;

packages/beacon-node/test/utils/config.ts

+9
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,14 @@ export function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig {
3838
DENEB_FORK_EPOCH: 0,
3939
ELECTRA_FORK_EPOCH: forkEpoch,
4040
});
41+
case ForkName.fulu:
42+
return createChainForkConfig({
43+
ALTAIR_FORK_EPOCH: 0,
44+
BELLATRIX_FORK_EPOCH: 0,
45+
CAPELLA_FORK_EPOCH: 0,
46+
DENEB_FORK_EPOCH: 0,
47+
ELECTRA_FORK_EPOCH: 0,
48+
FULU_FORK_EPOCH: forkEpoch,
49+
});
4150
}
4251
}

packages/config/src/chainConfig/configs/mainnet.ts

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ export const chainConfig: ChainConfig = {
5252
ELECTRA_FORK_VERSION: b("0x05000000"),
5353
ELECTRA_FORK_EPOCH: Infinity,
5454

55+
// FULU
56+
FULU_FORK_VERSION: b("0x06000000"),
57+
FULU_FORK_EPOCH: Infinity,
58+
5559
// Time parameters
5660
// ---------------------------------------------------------------
5761
// 12 seconds

packages/config/src/chainConfig/configs/minimal.ts

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ export const chainConfig: ChainConfig = {
4747
// ELECTRA
4848
ELECTRA_FORK_VERSION: b("0x05000001"),
4949
ELECTRA_FORK_EPOCH: Infinity,
50+
// FULU
51+
FULU_FORK_VERSION: b("0x06000001"),
52+
FULU_FORK_EPOCH: Infinity,
5053

5154
// Time parameters
5255
// ---------------------------------------------------------------

packages/config/src/chainConfig/networks/chiado.ts

+3
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,7 @@ export const chiadoChainConfig: ChainConfig = {
4040
// Electra
4141
ELECTRA_FORK_VERSION: b("0x0500006f"),
4242
ELECTRA_FORK_EPOCH: Infinity,
43+
// Fulu
44+
FULU_FORK_VERSION: b("0x0600006f"),
45+
FULU_FORK_EPOCH: Infinity,
4346
};

packages/config/src/chainConfig/networks/ephemery.ts

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ const baseChainConfig: ChainConfig = {
4040
// Electra
4141
ELECTRA_FORK_VERSION: b("0x6000101b"),
4242
ELECTRA_FORK_EPOCH: 10,
43+
// Fulu
44+
FULU_FORK_VERSION: b("0x7000101b"),
45+
FULU_FORK_EPOCH: Infinity,
4346

4447
// Deposit contract
4548
// ---------------------------------------------------------------

packages/config/src/chainConfig/networks/gnosis.ts

+3
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,7 @@ export const gnosisChainConfig: ChainConfig = {
5454
// Electra
5555
ELECTRA_FORK_VERSION: b("0x05000064"),
5656
ELECTRA_FORK_EPOCH: Infinity,
57+
// Fulu
58+
FULU_FORK_VERSION: b("0x06000064"),
59+
FULU_FORK_EPOCH: Infinity,
5760
};

packages/config/src/chainConfig/networks/holesky.ts

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ export const holeskyChainConfig: ChainConfig = {
3636
// Electra
3737
ELECTRA_FORK_VERSION: b("0x06017000"),
3838
ELECTRA_FORK_EPOCH: 115968,
39+
// Fulu
40+
FULU_FORK_VERSION: b("0x07017000"),
41+
FULU_FORK_EPOCH: Infinity,
3942

4043
// # 28,000,000,000 Gwei to ensure quicker ejection
4144
EJECTION_BALANCE: 28000000000,

packages/config/src/chainConfig/networks/sepolia.ts

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ export const sepoliaChainConfig: ChainConfig = {
3636
// Electra
3737
ELECTRA_FORK_VERSION: b("0x90000074"),
3838
ELECTRA_FORK_EPOCH: 222464,
39+
// Fulu
40+
FULU_FORK_VERSION: b("0x90000075"),
41+
FULU_FORK_EPOCH: 222464,
3942

4043
// Deposit contract
4144
// ---------------------------------------------------------------

packages/config/src/chainConfig/types.ts

+6
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ export type ChainConfig = {
4141
// ELECTRA
4242
ELECTRA_FORK_VERSION: Uint8Array;
4343
ELECTRA_FORK_EPOCH: number;
44+
// FULU
45+
FULU_FORK_VERSION: Uint8Array;
46+
FULU_FORK_EPOCH: number;
4447

4548
// Time parameters
4649
SECONDS_PER_SLOT: number;
@@ -112,6 +115,9 @@ export const chainConfigTypes: SpecTypes<ChainConfig> = {
112115
// ELECTRA
113116
ELECTRA_FORK_VERSION: "bytes",
114117
ELECTRA_FORK_EPOCH: "number",
118+
// FULU
119+
FULU_FORK_VERSION: "bytes",
120+
FULU_FORK_EPOCH: "number",
115121

116122
// Time parameters
117123
SECONDS_PER_SLOT: "number",

packages/config/src/forkConfig/index.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,18 @@ export function createForkConfig(config: ChainConfig): ForkConfig {
6868
prevVersion: config.DENEB_FORK_VERSION,
6969
prevForkName: ForkName.deneb,
7070
};
71+
const fulu: ForkInfo = {
72+
name: ForkName.fulu,
73+
seq: ForkSeq.fulu,
74+
epoch: config.FULU_FORK_EPOCH,
75+
version: config.FULU_FORK_VERSION,
76+
prevVersion: config.ELECTRA_FORK_VERSION,
77+
prevForkName: ForkName.electra,
78+
};
7179

7280
/** Forks in order order of occurence, `phase0` first */
7381
// Note: Downstream code relies on proper ordering.
74-
const forks = {phase0, altair, bellatrix, capella, deneb, electra};
82+
const forks = {phase0, altair, bellatrix, capella, deneb, electra, fulu};
7583

7684
// Prevents allocating an array on every getForkInfo() call
7785
const forksAscendingEpochOrder = Object.values(forks);

packages/light-client/src/spec/utils.ts

+7
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,18 @@ export function upgradeLightClientHeader(
134134
// Break if no further upgradation is required else fall through
135135
if (ForkSeq[targetFork] <= ForkSeq.deneb) break;
136136

137+
// biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here
137138
case ForkName.electra:
138139
// No changes to LightClientHeader in Electra
139140

140141
// Break if no further upgrades is required else fall through
141142
if (ForkSeq[targetFork] <= ForkSeq.electra) break;
143+
144+
case ForkName.fulu:
145+
// No changes to LightClientHeader in Electra
146+
147+
// Break if no further upgrades is required else fall through
148+
if (ForkSeq[targetFork] <= ForkSeq.fulu) break;
142149
}
143150
return upgradedHeader;
144151
}

packages/params/src/forkName.ts

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export enum ForkName {
88
capella = "capella",
99
deneb = "deneb",
1010
electra = "electra",
11+
fulu = "fulu",
1112
}
1213

1314
/**
@@ -20,6 +21,7 @@ export enum ForkSeq {
2021
capella = 3,
2122
deneb = 4,
2223
electra = 5,
24+
fulu = 6,
2325
}
2426

2527
function exclude<T extends ForkName, U extends T>(coll: T[], val: U[]): Exclude<T, U>[] {

packages/params/test/unit/__snapshots__/forkName.test.ts.snap

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ exports[`forkName > should have valid allForks 1`] = `
88
"capella",
99
"deneb",
1010
"electra",
11+
"fulu",
1112
]
1213
`;
1314

@@ -18,6 +19,7 @@ exports[`forkName > should have valid post-altair forks 1`] = `
1819
"capella",
1920
"deneb",
2021
"electra",
22+
"fulu",
2123
]
2224
`;
2325

@@ -27,6 +29,7 @@ exports[`forkName > should have valid post-bellatrix forks 1`] = `
2729
"capella",
2830
"deneb",
2931
"electra",
32+
"fulu",
3033
]
3134
`;
3235

@@ -35,12 +38,14 @@ exports[`forkName > should have valid post-capella forks 1`] = `
3538
"capella",
3639
"deneb",
3740
"electra",
41+
"fulu",
3842
]
3943
`;
4044

4145
exports[`forkName > should have valid post-deneb forks 1`] = `
4246
[
4347
"deneb",
4448
"electra",
49+
"fulu",
4550
]
4651
`;

packages/state-transition/src/cache/stateCache.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
BeaconStateDeneb,
1212
BeaconStateElectra,
1313
BeaconStateExecutions,
14+
BeaconStateFulu,
1415
BeaconStatePhase0,
1516
} from "./types.js";
1617

@@ -132,6 +133,7 @@ export type CachedBeaconStateBellatrix = CachedBeaconState<BeaconStateBellatrix>
132133
export type CachedBeaconStateCapella = CachedBeaconState<BeaconStateCapella>;
133134
export type CachedBeaconStateDeneb = CachedBeaconState<BeaconStateDeneb>;
134135
export type CachedBeaconStateElectra = CachedBeaconState<BeaconStateElectra>;
136+
export type CachedBeaconStateFulu = CachedBeaconState<BeaconStateFulu>;
135137

136138
export type CachedBeaconStateAllForks = CachedBeaconState<BeaconStateAllForks>;
137139
export type CachedBeaconStateExecutions = CachedBeaconState<BeaconStateExecutions>;

packages/state-transition/src/cache/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export type BeaconStateBellatrix = CompositeViewDU<SSZTypesFor<ForkName.bellatri
99
export type BeaconStateCapella = CompositeViewDU<SSZTypesFor<ForkName.capella, "BeaconState">>;
1010
export type BeaconStateDeneb = CompositeViewDU<SSZTypesFor<ForkName.deneb, "BeaconState">>;
1111
export type BeaconStateElectra = CompositeViewDU<SSZTypesFor<ForkName.electra, "BeaconState">>;
12+
export type BeaconStateFulu = CompositeViewDU<SSZTypesFor<ForkName.fulu, "BeaconState">>;
1213

1314
export type BeaconStateAllForks = CompositeViewDU<SSZTypesFor<ForkAll, "BeaconState">>;
1415
export type BeaconStateExecutions = CompositeViewDU<SSZTypesFor<ForkPostBellatrix, "BeaconState">>;

packages/state-transition/src/slot/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export {upgradeStateToBellatrix} from "./upgradeStateToBellatrix.js";
88
export {upgradeStateToCapella} from "./upgradeStateToCapella.js";
99
export {upgradeStateToDeneb} from "./upgradeStateToDeneb.js";
1010
export {upgradeStateToElectra} from "./upgradeStateToElectra.js";
11+
export {upgradeStateToFulu} from "./upgradeStateToFulu.js";
1112

1213
/**
1314
* Dial state to next slot. Common for all forks
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {ssz} from "@lodestar/types";
2+
import {getCachedBeaconState} from "../cache/stateCache.js";
3+
import {CachedBeaconStateElectra, CachedBeaconStateFulu} from "../types.js";
4+
5+
/**
6+
* Upgrade a state from Electra to Fulu.
7+
*/
8+
export function upgradeStateToFulu(stateElectra: CachedBeaconStateElectra): CachedBeaconStateFulu {
9+
const {config} = stateElectra;
10+
11+
const stateElectraNode = ssz.electra.BeaconState.commitViewDU(stateElectra);
12+
const stateFuluView = ssz.fulu.BeaconState.getViewDU(stateElectraNode);
13+
14+
const stateFulu = getCachedBeaconState(stateFuluView, stateElectra);
15+
16+
stateFulu.fork = ssz.phase0.Fork.toViewDU({
17+
previousVersion: stateElectra.fork.currentVersion,
18+
currentVersion: config.FULU_FORK_VERSION,
19+
epoch: stateElectra.epochCtx.epoch,
20+
});
21+
22+
stateFulu.commit();
23+
// Clear cache to ensure the cache of capella fields is not used by new deneb fields
24+
25+
return stateFulu;
26+
}

packages/state-transition/src/stateTransition.ts

+5
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ import {
1616
upgradeStateToDeneb,
1717
upgradeStateToElectra,
1818
} from "./slot/index.js";
19+
import {upgradeStateToFulu} from "./slot/upgradeStateToFulu.js";
1920
import {
2021
CachedBeaconStateAllForks,
2122
CachedBeaconStateAltair,
2223
CachedBeaconStateBellatrix,
2324
CachedBeaconStateCapella,
2425
CachedBeaconStateDeneb,
26+
CachedBeaconStateElectra,
2527
CachedBeaconStatePhase0,
2628
} from "./types.js";
2729
import {computeEpochAtSlot} from "./util/index.js";
@@ -264,6 +266,9 @@ function processSlotsWithTransientCache(
264266
if (stateEpoch === config.ELECTRA_FORK_EPOCH) {
265267
postState = upgradeStateToElectra(postState as CachedBeaconStateDeneb) as CachedBeaconStateAllForks;
266268
}
269+
if (stateEpoch === config.FULU_FORK_EPOCH) {
270+
postState = upgradeStateToFulu(postState as CachedBeaconStateElectra) as CachedBeaconStateAllForks;
271+
}
267272
} else {
268273
postState.slot++;
269274
}

packages/state-transition/src/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type {
1010
CachedBeaconStateCapella,
1111
CachedBeaconStateDeneb,
1212
CachedBeaconStateElectra,
13+
CachedBeaconStateFulu,
1314
} from "./cache/stateCache.js";
1415

1516
export type {
@@ -21,4 +22,5 @@ export type {
2122
BeaconStateCapella,
2223
BeaconStateDeneb,
2324
BeaconStateElectra,
25+
BeaconStateFulu,
2426
} from "./cache/types.js";

0 commit comments

Comments
 (0)