Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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 @@ -11,7 +11,6 @@ type AttDataBase64 = string;
export type AttestationDataCacheEntry = {
// part of shuffling data, so this does not take memory
committeeValidatorIndices: Uint32Array;
// TODO: remove this? this is available in SingleAttestation
committeeIndex: CommitteeIndex;
// IndexedAttestationData signing root, 32 bytes
signingRoot: Uint8Array;
Expand All @@ -21,8 +20,6 @@ export type AttestationDataCacheEntry = {
// for example in a mainnet node subscribing to all subnets, attestations are processed up to 20k per slot
attestationData: phase0.AttestationData;
subnet: number;
// aggregationBits only populates post-electra. Pre-electra can use get it directly from attestationOrBytes
aggregationBits: BitArray | null;
};

export enum RejectReason {
Expand Down
29 changes: 10 additions & 19 deletions packages/beacon-node/src/chain/validation/attestation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export type AttestationValidationResult = {
subnet: number;
attDataRootHex: RootHex;
committeeIndex: CommitteeIndex;
aggregationBits: BitArray | null; // Field populated post-electra only
aggregationBits: BitArray;
};

export type AttestationOrBytes = ApiAttestation | GossipAttestation;
Expand Down Expand Up @@ -344,11 +344,6 @@ async function validateAttestationNoSignatureCheck(
code: AttestationErrorCode.NOT_EXACTLY_ONE_AGGREGATION_BIT_SET,
});
}
} else {
// Populate aggregationBits if cached post-electra, else we populate later
if (attestationOrCache.cache && attestationOrCache.cache.aggregationBits !== null) {
aggregationBits = attestationOrCache.cache.aggregationBits;
}
}

let committeeValidatorIndices: Uint32Array;
Expand Down Expand Up @@ -423,18 +418,15 @@ async function validateAttestationNoSignatureCheck(
validatorIndex = (attestationOrCache.attestation as SingleAttestation<ForkPostElectra>).attesterIndex;
// [REJECT] The attester is a member of the committee -- i.e.
// `attestation.attester_index in get_beacon_committee(state, attestation.data.slot, index)`.
// If `aggregationBitsElectra` exists, that means we have already cached it. No need to check again
if (aggregationBits === null) {
// Position of the validator in its committee
const committeeValidatorIndex = committeeValidatorIndices.indexOf(validatorIndex);
if (committeeValidatorIndex === -1) {
throw new AttestationError(GossipAction.REJECT, {
code: AttestationErrorCode.ATTESTER_NOT_IN_COMMITTEE,
});
}

aggregationBits = BitArray.fromSingleBit(committeeValidatorIndices.length, committeeValidatorIndex);
// Position of the validator in its committee
const committeeValidatorIndex = committeeValidatorIndices.indexOf(validatorIndex);
if (committeeValidatorIndex === -1) {
throw new AttestationError(GossipAction.REJECT, {
code: AttestationErrorCode.ATTESTER_NOT_IN_COMMITTEE,
});
}

aggregationBits = BitArray.fromSingleBit(committeeValidatorIndices.length, committeeValidatorIndex);
}

// LH > verify_middle_checks
Expand Down Expand Up @@ -504,7 +496,6 @@ async function validateAttestationNoSignatureCheck(
// root of AttestationData was already cached during getIndexedAttestationSignatureSet
attDataRootHex,
attestationData: attData,
aggregationBits: isForkPostElectra(fork) ? aggregationBits : null,
});
}
}
Expand Down Expand Up @@ -540,7 +531,7 @@ async function validateAttestationNoSignatureCheck(
signatureSet,
validatorIndex,
committeeIndex,
aggregationBits: isForkPostElectra(fork) ? aggregationBits : null,
aggregationBits,
};
}

Expand Down