Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export class AggregatedAttestationPool {
forkChoice: IForkChoice,
shufflingCache: ShufflingCache,
state: IBeaconStateView
): Attestation[] {
): electra.Attestation[] {
const forkSeq = ForkSeq[fork];
if (forkSeq < ForkSeq.electra) {
throw new Error("Does not support producing blocks for pre-electra forks anymore");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import {
isStatePostBellatrix,
isStatePostCapella,
isStatePostGloas,
upgradeAttestationToGloas,
upgradeAttesterSlashingToGloas,
} from "@lodestar/state-transition";
import {
BLSPubkey,
Expand Down Expand Up @@ -1006,11 +1008,11 @@ export async function produceCommonBlockBody<T extends BlockType>(
// logger.error("Attestation did not transfer to op pool", {}, e);
// }
// }
const [attesterSlashings, proposerSlashings, voluntaryExits, blsToExecutionChanges] =
const [opPoolAttesterSlashings, proposerSlashings, voluntaryExits, blsToExecutionChanges] =
this.opPool.getSlashingsAndExits(currentState, blockType, this.metrics);

const endAttestations = stepsMetrics?.startTimer();
const attestations = this.aggregatedAttestationPool.getAttestationsForBlock(
const opPoolAttestations = this.aggregatedAttestationPool.getAttestationsForBlock(
fork,
this.forkChoice,
this.shufflingCache,
Expand All @@ -1020,6 +1022,11 @@ export async function produceCommonBlockBody<T extends BlockType>(
step: BlockProductionStep.attestations,
});

const attestations = isForkPostGloas(fork) ? opPoolAttestations.map(upgradeAttestationToGloas) : opPoolAttestations;
const attesterSlashings = isForkPostGloas(fork)
? opPoolAttesterSlashings.map(upgradeAttesterSlashingToGloas)
: opPoolAttesterSlashings;
Comment on lines +1025 to +1028

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@twoeths pointed out this shouldn't be needed in discord, I haven't really checked if that is true or not, but easy to verify on kurtosis

but if it's needed, the code here is not ideal, so for attestation we only need to do this for 1 epoch since we can only include prev. and current epoch attestations

for attester slashings is seems tricky, there is no expiry on the message

ideally we don't need this at all

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I don't see these apis are needed
eip-7688 does not change typical object shape like AttesterSlashing. We can prove by having unit tests, make sure the final SignedBeaconBlock has the same root + serialized bytes
if it's not needed we should not introduce it to avoid the confusion later
unless kurtosis/unit test proves I'm wrong


const blockBody: Omit<CommonBlockBody, "blsToExecutionChanges" | "syncAggregate"> = {
randaoReveal,
graffiti,
Expand Down
5 changes: 5 additions & 0 deletions packages/state-transition/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ export type {EpochTransitionStep} from "./epoch/index.js";
export {type BeaconStateTransitionMetrics, getMetrics} from "./metrics.js";
export * from "./rewards/index.js";
export * from "./signatureSets/index.js";
export {
upgradeAttestationToGloas,
upgradeAttesterSlashingToGloas,
upgradeIndexedAttestationToGloas,
} from "./slot/upgradeStateToGloas.js";
export * from "./stateTransition.js";
export {BeaconStateView} from "./stateView/beaconStateView.js";
export {
Expand Down
7 changes: 6 additions & 1 deletion packages/state-transition/src/slot/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ export {upgradeStateToCapella} from "./upgradeStateToCapella.js";
export {upgradeStateToDeneb} from "./upgradeStateToDeneb.js";
export {upgradeStateToElectra} from "./upgradeStateToElectra.js";
export {upgradeStateToFulu} from "./upgradeStateToFulu.js";
export {upgradeStateToGloas} from "./upgradeStateToGloas.js";
export {
upgradeAttestationToGloas,
upgradeAttesterSlashingToGloas,
upgradeIndexedAttestationToGloas,
upgradeStateToGloas,
} from "./upgradeStateToGloas.js";

/**
* Dial state to next slot. Common for all forks
Expand Down
49 changes: 48 additions & 1 deletion packages/state-transition/src/slot/upgradeStateToGloas.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {getNodesAtDepth} from "@chainsafe/persistent-merkle-tree";
import {
BasicType,
BitArray,
CompositeType,
CompositeView,
CompositeViewDU,
Expand All @@ -11,7 +12,7 @@ import {
ValueOf,
} from "@chainsafe/ssz";
import {PAYLOAD_BUILDER_VERSION, SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
import {ssz} from "@lodestar/types";
import {electra, gloas, ssz} from "@lodestar/types";
import {toPubkeyHex} from "@lodestar/utils";
import {isValidDepositSignature} from "../block/processDeposit.js";
import {getCachedBeaconState} from "../cache/stateCache.js";
Expand Down Expand Up @@ -116,6 +117,52 @@ export function upgradeStateToGloas(stateFulu: CachedBeaconStateFulu): CachedBea
return stateGloas;
}

export function upgradeAttestationToGloas(pre: electra.Attestation): gloas.Attestation {
return {
aggregationBits: cloneBitArray(pre.aggregationBits),
data: pre.data,
signature: pre.signature,
committeeBits: cloneBitArray(pre.committeeBits),
};
Comment on lines +120 to +126

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is a no-op 😅

}

export function upgradeIndexedAttestationToGloas(pre: electra.IndexedAttestation): gloas.IndexedAttestation;
export function upgradeIndexedAttestationToGloas(pre: electra.IndexedAttestationBigint): gloas.IndexedAttestationBigint;
export function upgradeIndexedAttestationToGloas(
pre: electra.IndexedAttestation | electra.IndexedAttestationBigint
): gloas.IndexedAttestation | gloas.IndexedAttestationBigint {
if (isIndexedAttestationBigint(pre)) {
return {
attestingIndices: [...pre.attestingIndices],
data: pre.data,
signature: pre.signature,
};
}

return {
attestingIndices: [...pre.attestingIndices],
data: pre.data,
signature: pre.signature,
};
}

export function upgradeAttesterSlashingToGloas(pre: electra.AttesterSlashing): gloas.AttesterSlashing {
return {
attestation1: upgradeIndexedAttestationToGloas(pre.attestation1),
attestation2: upgradeIndexedAttestationToGloas(pre.attestation2),
};
}

function cloneBitArray(bitArray: BitArray): BitArray {
return bitArray.clone();
}

function isIndexedAttestationBigint(
attestation: electra.IndexedAttestation | electra.IndexedAttestationBigint
): attestation is electra.IndexedAttestationBigint {
return typeof attestation.data.slot === "bigint";
}

/**
* Migrate a composite list from fulu to its gloas progressive-list equivalent by reusing the fulu
* list's element nodes.
Expand Down
53 changes: 52 additions & 1 deletion packages/state-transition/test/unit/upgradeState.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {describe, expect, it} from "vitest";
import {BitArray} from "@chainsafe/ssz";
import {ChainForkConfig, createBeaconConfig, createChainForkConfig} from "@lodestar/config";
import {config as chainConfig} from "@lodestar/config/default";
import {FAR_FUTURE_EPOCH, ForkName} from "@lodestar/params";
Expand All @@ -7,7 +8,12 @@ import {createPubkeyCache} from "../../src/cache/pubkeyCache.js";
import {CachedBeaconStateFulu, createCachedBeaconState} from "../../src/cache/stateCache.js";
import {upgradeStateToDeneb} from "../../src/slot/upgradeStateToDeneb.js";
import {upgradeStateToElectra} from "../../src/slot/upgradeStateToElectra.js";
import {upgradeStateToGloas} from "../../src/slot/upgradeStateToGloas.js";
import {
upgradeAttestationToGloas,
upgradeAttesterSlashingToGloas,
upgradeIndexedAttestationToGloas,
upgradeStateToGloas,
} from "../../src/slot/upgradeStateToGloas.js";

describe("upgradeState", () => {
it("upgradeStateToDeneb", () => {
Expand Down Expand Up @@ -131,6 +137,51 @@ describe("upgradeState", () => {
expect(() => gloasState.hashTreeRoot()).not.toThrow();
expect(() => gloasState.toValue()).not.toThrow();
});

it("upgradeAttestationToGloas copies Fulu attestation bitlists into Gloas values", () => {
const attestation = ssz.electra.Attestation.defaultValue();
attestation.aggregationBits = BitArray.fromBitLen(4);
attestation.aggregationBits.set(0, true);
attestation.committeeBits.set(0, true);

const upgraded = upgradeAttestationToGloas(attestation);

expect(upgraded).toEqual(attestation);
expect(upgraded.aggregationBits).not.toBe(attestation.aggregationBits);
expect(upgraded.committeeBits).not.toBe(attestation.committeeBits);
expect(ssz.gloas.Attestation.deserialize(ssz.gloas.Attestation.serialize(upgraded))).toEqual(upgraded);

attestation.aggregationBits.set(0, false);
attestation.committeeBits.set(0, false);
expect(upgraded.aggregationBits.get(0)).toBe(true);
expect(upgraded.committeeBits.get(0)).toBe(true);
});

it("upgradeIndexedAttestationToGloas copies Fulu attesting indices into Gloas values", () => {
const indexedAttestation = ssz.electra.IndexedAttestation.defaultValue();
indexedAttestation.attestingIndices = [1, 3, 5];

const upgraded = upgradeIndexedAttestationToGloas(indexedAttestation);

expect(upgraded).toEqual(indexedAttestation);
expect(upgraded.attestingIndices).not.toBe(indexedAttestation.attestingIndices);
expect(ssz.gloas.IndexedAttestation.deserialize(ssz.gloas.IndexedAttestation.serialize(upgraded))).toEqual(
upgraded
);
});

it("upgradeAttesterSlashingToGloas upgrades both indexed attestations", () => {
const attesterSlashing = ssz.electra.AttesterSlashing.defaultValue();
attesterSlashing.attestation1.attestingIndices = [2, 4];
attesterSlashing.attestation2.attestingIndices = [6, 8];

const upgraded = upgradeAttesterSlashingToGloas(attesterSlashing);

expect(upgraded).toEqual(attesterSlashing);
expect(upgraded.attestation1.attestingIndices).not.toBe(attesterSlashing.attestation1.attestingIndices);
expect(upgraded.attestation2.attestingIndices).not.toBe(attesterSlashing.attestation2.attestingIndices);
expect(ssz.gloas.AttesterSlashing.deserialize(ssz.gloas.AttesterSlashing.serialize(upgraded))).toEqual(upgraded);
});
});

const ZERO_HASH = Buffer.alloc(32, 0);
Expand Down
5 changes: 0 additions & 5 deletions specrefs/.ethspecify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -415,11 +415,6 @@ exceptions:
- finalized_root_gindex_at_slot#gloas
- next_sync_committee_gindex_at_slot#gloas

# gloas (attestation upgrade helpers; lodestar ssz types are structurally cross-fork compatible)
- upgrade_attestation_to_gloas#gloas
- upgrade_attester_slashing_to_gloas#gloas
- upgrade_indexed_attestation_to_gloas#gloas

# computed helpers replacing config vars (added in alpha.3)
# the following are hardcoded in config files rather than computed at runtime
- compute_max_request_blob_sidecars#deneb
Expand Down
12 changes: 9 additions & 3 deletions specrefs/functions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12424,7 +12424,9 @@
</spec>

- name: upgrade_attestation_to_gloas#gloas
sources: []
sources:
- file: packages/state-transition/src/slot/upgradeStateToGloas.ts
search: export function upgradeAttestationToGloas(
spec: |
<spec fn="upgrade_attestation_to_gloas" fork="gloas" hash="efd969bf">
def upgrade_attestation_to_gloas(pre: fulu.Attestation) -> Attestation:
Expand All @@ -12437,7 +12439,9 @@
</spec>

- name: upgrade_attester_slashing_to_gloas#gloas
sources: []
sources:
- file: packages/state-transition/src/slot/upgradeStateToGloas.ts
search: export function upgradeAttesterSlashingToGloas(
spec: |
<spec fn="upgrade_attester_slashing_to_gloas" fork="gloas" hash="35f9184f">
def upgrade_attester_slashing_to_gloas(pre: fulu.AttesterSlashing) -> AttesterSlashing:
Expand All @@ -12448,7 +12452,9 @@
</spec>

- name: upgrade_indexed_attestation_to_gloas#gloas
sources: []
sources:
- file: packages/state-transition/src/slot/upgradeStateToGloas.ts
search: 'export function upgradeIndexedAttestationToGloas(pre: electra.IndexedAttestation):'
spec: |
<spec fn="upgrade_indexed_attestation_to_gloas" fork="gloas" hash="b13fb8df">
def upgrade_indexed_attestation_to_gloas(pre: fulu.IndexedAttestation) -> IndexedAttestation:
Expand Down
Loading