@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
66 lines (56 loc) • 2.63 kB
text/typescript
import {Signature} from "@chainsafe/blst";
import {BLS_WITHDRAWAL_PREFIX} from "@lodestar/params";
import {IBeaconStateView} from "@lodestar/state-transition";
import {Slot, capella} from "@lodestar/types";
import {AggregateFast, AggregateFastElectra} from "./attestationPool.js";
/**
* Prune a Map indexed by slot to keep the most recent slots, up to `slotsRetained`
*/
export function pruneBySlot(map: Map<Slot, unknown>, slot: Slot, slotsRetained: Slot): Slot {
const lowestPermissibleSlot = Math.max(slot - slotsRetained, 0);
// No need to prune if the lowest permissible slot has not changed and the queue length is less than the maximum
if (map.size <= slotsRetained) {
return lowestPermissibleSlot;
}
// Remove the oldest slots to keep a max of `slotsRetained` slots
const slots = Array.from(map.keys());
const slotsToDelete = slots.sort((a, b) => b - a).slice(slotsRetained);
for (const slot of slotsToDelete) {
map.delete(slot);
}
return lowestPermissibleSlot;
}
/**
* De-serialize bytes into Signature.
* No need to verify Signature is valid, already run sig-verify = false
*/
export function signatureFromBytesNoCheck(signature: Uint8Array): Signature {
return Signature.fromBytes(signature);
}
/**
* Ensures that a SignedBLSToExecutionChange object is _still_ valid for block inclusion. An object valid for the pool,
* can become invalid for certain forks.
*/
export function isValidBlsToExecutionChangeForBlockInclusion(
state: IBeaconStateView,
signedBLSToExecutionChange: capella.SignedBLSToExecutionChange
): boolean {
// For each condition from https://github.com/ethereum/consensus-specs/blob/v1.6.1/specs/capella/beacon-chain.md#new-process_bls_to_execution_change
//
// 1. assert address_change.validator_index < len(state.validators):
// If valid before will always be valid in the future, no need to check
//
// 2. assert validator.withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX:
// Must be checked again, since it can already be changed by now.
const validator = state.getValidator(signedBLSToExecutionChange.message.validatorIndex);
const {withdrawalCredentials} = validator;
if (withdrawalCredentials[0] !== BLS_WITHDRAWAL_PREFIX) {
return false;
}
// 3. assert validator.withdrawal_credentials[1:] == hash(address_change.from_bls_pubkey)[1:]:
// If valid before will always be valid in the future, no need to check
return true;
}
export function isElectraAggregate(aggregate: AggregateFast): aggregate is AggregateFastElectra {
return (aggregate as AggregateFastElectra).committeeBits !== undefined;
}