@@ -84,7 +84,7 @@ export async function importBlock(
8484 fullyVerifiedBlock : FullyVerifiedBlock ,
8585 opts : ImportBlockOpts
8686) : Promise < void > {
87- const { blockInput, postState , parentBlockSlot, executionStatus, dataAvailabilityStatus, indexedAttestations} =
87+ const { blockInput, postBlockState , parentBlockSlot, executionStatus, dataAvailabilityStatus, indexedAttestations} =
8888 fullyVerifiedBlock ;
8989 const block = blockInput . getBlock ( ) ;
9090 const source = blockInput . getBlockSource ( ) ;
@@ -96,7 +96,7 @@ export async function importBlock(
9696 const blockEpoch = computeEpochAtSlot ( blockSlot ) ;
9797 const prevFinalizedEpoch = this . forkChoice . getFinalizedCheckpoint ( ) . epoch ;
9898 const blockDelaySec =
99- fullyVerifiedBlock . seenTimestampSec - computeTimeAtSlot ( this . config , blockSlot , postState . genesisTime ) ;
99+ fullyVerifiedBlock . seenTimestampSec - computeTimeAtSlot ( this . config , blockSlot , postBlockState . genesisTime ) ;
100100 const recvToValLatency = Date . now ( ) / 1000 - ( opts . seenTimestampSec ?? Date . now ( ) / 1000 ) ;
101101 const fork = this . config . getForkSeq ( blockSlot ) ;
102102
@@ -119,10 +119,10 @@ export async function importBlock(
119119 // 2. Import block to fork choice
120120
121121 // Should compute checkpoint balances before forkchoice.onBlock
122- this . checkpointBalancesCache . processState ( blockRootHex , postState ) ;
122+ this . checkpointBalancesCache . processState ( blockRootHex , postBlockState ) ;
123123 const blockSummary = this . forkChoice . onBlock (
124124 block . message ,
125- postState ,
125+ postBlockState ,
126126 blockDelaySec ,
127127 currentSlot ,
128128 executionStatus ,
@@ -135,7 +135,7 @@ export async function importBlock(
135135 // Post-Gloas: blockSummary.payloadStatus is always PENDING, so payloadPresent = false (block state only, no payload processing yet)
136136 const payloadPresent = ! isGloasBlock ( blockSummary ) ;
137137 // processState manages both block state and payload state variants together for memory/disk management
138- this . regen . processBlockState ( blockRootHex , postState ) ;
138+ this . regen . processBlockState ( blockRootHex , postBlockState ) ;
139139
140140 // For Gloas blocks, create PayloadEnvelopeInput so it's available for later payload import
141141 if ( fork >= ForkSeq . gloas ) {
@@ -154,6 +154,23 @@ export async function importBlock(
154154 } ) ;
155155 }
156156
157+ // For Gloas blocks whose envelope was pre-verified during state transition (sync/batch path),
158+ // immediately transition the block to FULL status in fork choice and cache the payload state.
159+ // Mirrors steps 6–7 of importExecutionPayload, but reuses the already-computed postEnvelopeState.
160+ if ( fullyVerifiedBlock . postEnvelopeState !== null ) {
161+ // TODO GLOAS: this.unfinalizedPayloadEnvelopeWrites.push(payloadInput)
162+ // need a payloadInput in fullyVerifiedBlock
163+ const { postEnvelopeState} = fullyVerifiedBlock ;
164+ this . regen . processPayloadState ( postEnvelopeState ) ;
165+ this . forkChoice . onExecutionPayload (
166+ blockRootHex ,
167+ toRootHex ( postEnvelopeState . latestBlockHash ) ,
168+ // TODO GLOAS: this is not right but we don't need to track it as part of consensus spec, lighthouse also does not track it
169+ 0 ,
170+ toRootHex ( postEnvelopeState . hashTreeRoot ( ) )
171+ ) ;
172+ }
173+
157174 this . metrics ?. importBlock . bySource . inc ( { source : source . source } ) ;
158175 this . logger . verbose ( "Added block to forkchoice and state cache" , { slot : blockSlot , root : blockRootHex } ) ;
159176
@@ -171,7 +188,7 @@ export async function importBlock(
171188 ( opts . importAttestations !== AttestationImportOpt . Skip && blockEpoch >= currentEpoch - FORK_CHOICE_ATT_EPOCH_LIMIT )
172189 ) {
173190 const attestations = block . message . body . attestations ;
174- const rootCache = new RootCache ( postState ) ;
191+ const rootCache = new RootCache ( postBlockState ) ;
175192 const invalidAttestationErrorsByCode = new Map < string , { error : Error ; count : number } > ( ) ;
176193
177194 const addAttestation = fork >= ForkSeq . electra ? addAttestationPostElectra : addAttestationPreElectra ;
@@ -185,7 +202,7 @@ export async function importBlock(
185202 const attDataRoot = toRootHex ( ssz . phase0 . AttestationData . hashTreeRoot ( indexedAttestation . data ) ) ;
186203 addAttestation . call (
187204 this ,
188- postState ,
205+ postBlockState ,
189206 target ,
190207 attDataRoot ,
191208 attestation as Attestation < ForkPostElectra > ,
@@ -300,7 +317,7 @@ export async function importBlock(
300317
301318 if ( newHead . blockRoot !== oldHead . blockRoot ) {
302319 // Set head state as strong reference
303- this . regen . updateHeadState ( newHead , postState ) ;
320+ this . regen . updateHeadState ( newHead , postBlockState ) ;
304321
305322 try {
306323 this . emitter . emit ( routes . events . EventType . head , {
@@ -372,7 +389,7 @@ export async function importBlock(
372389 try {
373390 this . lightClientServer ?. onImportBlockHead (
374391 block . message as BeaconBlock < ForkPostAltair > ,
375- postState ,
392+ postBlockState ,
376393 parentBlockSlot
377394 ) ;
378395 } catch ( e ) {
@@ -393,11 +410,11 @@ export async function importBlock(
393410 // and the block is weak and can potentially be reorged out.
394411 let shouldOverrideFcu = false ;
395412
396- if ( blockSlot >= currentSlot && postState . isExecutionStateType ) {
413+ if ( blockSlot >= currentSlot && postBlockState . isExecutionStateType ) {
397414 let notOverrideFcuReason = NotReorgedReason . Unknown ;
398415 const proposalSlot = blockSlot + 1 ;
399416 try {
400- const proposerIndex = postState . getBeaconProposer ( proposalSlot ) ;
417+ const proposerIndex = postBlockState . getBeaconProposer ( proposalSlot ) ;
401418 const feeRecipient = this . beaconProposerCache . get ( proposerIndex ) ;
402419
403420 if ( feeRecipient ) {
@@ -477,20 +494,20 @@ export async function importBlock(
477494 }
478495 }
479496
480- if ( ! postState . isStateValidatorsNodesPopulated ( ) ) {
481- this . logger . verbose ( "After importBlock caching postState without SSZ cache" , { slot : postState . slot } ) ;
497+ if ( ! postBlockState . isStateValidatorsNodesPopulated ( ) ) {
498+ this . logger . verbose ( "After importBlock caching postBlockState without SSZ cache" , { slot : postBlockState . slot } ) ;
482499 }
483500
484501 // Cache shufflings when crossing an epoch boundary
485502 const parentEpoch = computeEpochAtSlot ( parentBlockSlot ) ;
486503 if ( parentEpoch < blockEpoch ) {
487- this . shufflingCache . processState ( postState ) ;
504+ this . shufflingCache . processState ( postBlockState ) ;
488505 this . logger . verbose ( "Processed shuffling for next epoch" , { parentEpoch, blockEpoch, slot : blockSlot } ) ;
489506 }
490507
491508 if ( blockSlot % SLOTS_PER_EPOCH === 0 ) {
492509 // Cache state to preserve epoch transition work
493- const checkpointState = postState ;
510+ const checkpointState = postBlockState ;
494511 const cp = getCheckpointFromState ( checkpointState ) ;
495512 this . regen . addCheckpointState ( cp , checkpointState , payloadPresent ) ;
496513 // consumers should not mutate state ever
@@ -584,7 +601,7 @@ export async function importBlock(
584601 this . validatorMonitor ?. registerSyncAggregateInBlock (
585602 blockEpoch ,
586603 ( block as altair . SignedBeaconBlock ) . message . body . syncAggregate ,
587- fullyVerifiedBlock . postState . currentSyncCommitteeIndexed . validatorIndices
604+ fullyVerifiedBlock . postBlockState . currentSyncCommitteeIndexed . validatorIndices
588605 ) ;
589606 }
590607
0 commit comments