@@ -10,6 +10,12 @@ import {
1010 MAX_COMMITTEES_PER_SLOT ,
1111 MIN_ATTESTATION_INCLUSION_DELAY ,
1212 SLOTS_PER_EPOCH ,
13+ TIMELY_HEAD_FLAG_INDEX ,
14+ TIMELY_HEAD_WEIGHT ,
15+ TIMELY_SOURCE_FLAG_INDEX ,
16+ TIMELY_SOURCE_WEIGHT ,
17+ TIMELY_TARGET_FLAG_INDEX ,
18+ TIMELY_TARGET_WEIGHT ,
1319 isForkPostDeneb ,
1420 isForkPostElectra ,
1521} from "@lodestar/params" ;
@@ -18,9 +24,11 @@ import {
1824 CachedBeaconStateAltair ,
1925 CachedBeaconStatePhase0 ,
2026 EffectiveBalanceIncrements ,
27+ RootCache ,
2128 computeEpochAtSlot ,
2229 computeSlotsSinceEpochStart ,
2330 computeStartSlotAtEpoch ,
31+ getAttestationParticipationStatus ,
2432 getBlockRootAtSlot ,
2533} from "@lodestar/state-transition" ;
2634import {
@@ -123,6 +131,11 @@ const MAX_ATTESTATIONS_PER_GROUP_ELECTRA = Math.min(
123131 MAX_ATTESTATIONS_ELECTRA
124132) ;
125133
134+ /** Same to https://github.com/ethereum/consensus-specs/blob/v1.5.0/specs/altair/beacon-chain.md#has_flag */
135+ const TIMELY_SOURCE = 1 << TIMELY_SOURCE_FLAG_INDEX ;
136+ const TIMELY_TARGET = 1 << TIMELY_TARGET_FLAG_INDEX ;
137+ const TIMELY_HEAD = 1 << TIMELY_HEAD_FLAG_INDEX ;
138+
126139export enum ScannedSlotsTerminationReason {
127140 MaxConsolidationReached = "max_consolidation_reached" ,
128141 ScannedAllSlots = "scanned_all_slots" ,
@@ -346,6 +359,7 @@ export class AggregatedAttestationPool {
346359 const stateSlot = state . slot ;
347360 const stateEpoch = state . epochCtx . epoch ;
348361 const statePrevEpoch = stateEpoch - 1 ;
362+ const rootCache = new RootCache ( state ) ;
349363
350364 const notSeenValidatorsFn = getNotSeenValidatorsFn ( state ) ;
351365 const validateAttestationDataFn = getValidateAttestationDataFn ( forkChoice , state ) ;
@@ -466,7 +480,22 @@ export class AggregatedAttestationPool {
466480
467481 // after all committees are processed, we have a list of sameAttDataCons
468482 for ( const consolidation of sameAttDataCons ) {
469- const score = consolidation . totalNewSeenEffectiveBalance / inclusionDistance ;
483+ // Score attestations by profitability to maximize proposer reward
484+ const flags = getAttestationParticipationStatus (
485+ ForkSeq [ fork ] ,
486+ consolidation . attData ,
487+ inclusionDistance ,
488+ stateEpoch ,
489+ rootCache
490+ ) ;
491+
492+ const weight =
493+ ( ( flags & TIMELY_SOURCE ) === TIMELY_SOURCE ? TIMELY_SOURCE_WEIGHT : 0 ) +
494+ ( ( flags & TIMELY_TARGET ) === TIMELY_TARGET ? TIMELY_TARGET_WEIGHT : 0 ) +
495+ ( ( flags & TIMELY_HEAD ) === TIMELY_HEAD ? TIMELY_HEAD_WEIGHT : 0 ) ;
496+
497+ const score = consolidation . totalNewSeenEffectiveBalance * weight ;
498+
470499 consolidations . set ( consolidation , score ) ;
471500 // Stop accumulating attestations there are enough that may have good scoring
472501 if ( consolidations . size >= MAX_ATTESTATIONS_ELECTRA * 2 ) {
0 commit comments