@@ -29,6 +29,7 @@ import (
2929 "github.com/ethereum/go-ethereum/common/hexutil"
3030 "github.com/ethereum/go-ethereum/core/beacon"
3131 "github.com/ethereum/go-ethereum/core/rawdb"
32+ "github.com/ethereum/go-ethereum/core/types"
3233 "github.com/ethereum/go-ethereum/eth"
3334 "github.com/ethereum/go-ethereum/log"
3435 "github.com/ethereum/go-ethereum/node"
@@ -172,10 +173,10 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
172173 finalBlock := api .eth .BlockChain ().GetBlockByHash (update .FinalizedBlockHash )
173174 if finalBlock == nil {
174175 log .Warn ("Final block not available in database" , "hash" , update .FinalizedBlockHash )
175- return beacon .STATUS_INVALID , errors . New ( "final block not available" )
176+ return beacon .STATUS_INVALID , & beacon . InvalidForkChoiceState
176177 } else if rawdb .ReadCanonicalHash (api .eth .ChainDb (), finalBlock .NumberU64 ()) != update .FinalizedBlockHash {
177178 log .Warn ("Final block not in canonical chain" , "number" , block .NumberU64 (), "hash" , update .HeadBlockHash )
178- return beacon .STATUS_INVALID , errors . New ( "final block not canonical" )
179+ return beacon .STATUS_INVALID , & beacon . InvalidForkChoiceState
179180 }
180181 // Set the finalized block
181182 api .eth .BlockChain ().SetFinalized (finalBlock )
@@ -185,11 +186,11 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
185186 safeBlock := api .eth .BlockChain ().GetBlockByHash (update .SafeBlockHash )
186187 if safeBlock == nil {
187188 log .Warn ("Safe block not available in database" )
188- return beacon .STATUS_INVALID , errors . New ( "safe head not available" )
189+ return beacon .STATUS_INVALID , & beacon . InvalidForkChoiceState
189190 }
190191 if rawdb .ReadCanonicalHash (api .eth .ChainDb (), safeBlock .NumberU64 ()) != update .SafeBlockHash {
191192 log .Warn ("Safe block not in canonical chain" )
192- return beacon .STATUS_INVALID , errors . New ( "safe head not canonical" )
193+ return beacon .STATUS_INVALID , & beacon . InvalidForkChoiceState
193194 }
194195 }
195196
@@ -207,13 +208,15 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
207208 // Create an empty block first which can be used as a fallback
208209 empty , err := api .eth .Miner ().GetSealingBlockSync (update .HeadBlockHash , payloadAttributes .Timestamp , payloadAttributes .SuggestedFeeRecipient , payloadAttributes .Random , true )
209210 if err != nil {
210- return valid (nil ), err
211+ log .Error ("Failed to create empty sealing payload" , "err" , err )
212+ return valid (nil ), & beacon .InvalidPayloadAttributes
211213 }
212214 // Send a request to generate a full block in the background.
213215 // The result can be obtained via the returned channel.
214216 resCh , err := api .eth .Miner ().GetSealingBlockAsync (update .HeadBlockHash , payloadAttributes .Timestamp , payloadAttributes .SuggestedFeeRecipient , payloadAttributes .Random , false )
215217 if err != nil {
216- return valid (nil ), err
218+ log .Error ("Failed to create async sealing payload" , "err" , err )
219+ return valid (nil ), & beacon .InvalidPayloadAttributes
217220 }
218221 id := computePayloadId (update .HeadBlockHash , payloadAttributes )
219222 api .localBlocks .put (id , & payload {empty : empty , result : resCh })
@@ -310,7 +313,7 @@ func (api *ConsensusAPI) NewPayloadV1(params beacon.ExecutableDataV1) (beacon.Pa
310313 }
311314 if block .Time () <= parent .Time () {
312315 log .Warn ("Invalid timestamp" , "parent" , block .Time (), "block" , block .Time ())
313- return api .invalid (errors .New ("invalid timestamp" )), nil
316+ return api .invalid (errors .New ("invalid timestamp" ), parent ), nil
314317 }
315318 if ! api .eth .BlockChain ().HasBlockAndState (block .ParentHash (), block .NumberU64 ()- 1 ) {
316319 api .remoteBlocks .put (block .Hash (), block .Header ())
@@ -320,7 +323,7 @@ func (api *ConsensusAPI) NewPayloadV1(params beacon.ExecutableDataV1) (beacon.Pa
320323 log .Trace ("Inserting block without sethead" , "hash" , block .Hash (), "number" , block .Number )
321324 if err := api .eth .BlockChain ().InsertBlockWithoutSetHead (block ); err != nil {
322325 log .Warn ("NewPayloadV1: inserting block failed" , "error" , err )
323- return api .invalid (err ), nil
326+ return api .invalid (err , parent ), nil
324327 }
325328 // We've accepted a valid payload from the beacon client. Mark the local
326329 // chain transitions to notify other subsystems (e.g. downloader) of the
@@ -346,9 +349,13 @@ func computePayloadId(headBlockHash common.Hash, params *beacon.PayloadAttribute
346349 return out
347350}
348351
349- // invalid returns a response "INVALID" with the latest valid hash set to the current head.
350- func (api * ConsensusAPI ) invalid (err error ) beacon.PayloadStatusV1 {
351- currentHash := api .eth .BlockChain ().CurrentHeader ().Hash ()
352+ // invalid returns a response "INVALID" with the latest valid hash supplied by latest or to the current head
353+ // if no latestValid block was provided.
354+ func (api * ConsensusAPI ) invalid (err error , latestValid * types.Block ) beacon.PayloadStatusV1 {
355+ currentHash := api .eth .BlockChain ().CurrentBlock ().Hash ()
356+ if latestValid != nil {
357+ currentHash = latestValid .Hash ()
358+ }
352359 errorMsg := err .Error ()
353360 return beacon.PayloadStatusV1 {Status : beacon .INVALID , LatestValidHash : & currentHash , ValidationError : & errorMsg }
354361}
0 commit comments