@@ -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"
@@ -165,10 +166,10 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
165166 finalBlock := api .eth .BlockChain ().GetBlockByHash (update .FinalizedBlockHash )
166167 if finalBlock == nil {
167168 log .Warn ("Final block not available in database" , "hash" , update .FinalizedBlockHash )
168- return beacon .STATUS_INVALID , errors . New ( "final block not available" )
169+ return beacon .STATUS_INVALID , & beacon . InvalidForkChoiceState
169170 } else if rawdb .ReadCanonicalHash (api .eth .ChainDb (), finalBlock .NumberU64 ()) != update .FinalizedBlockHash {
170171 log .Warn ("Final block not in canonical chain" , "number" , block .NumberU64 (), "hash" , update .HeadBlockHash )
171- return beacon .STATUS_INVALID , errors . New ( "final block not canonical" )
172+ return beacon .STATUS_INVALID , & beacon . InvalidForkChoiceState
172173 }
173174 // Set the finalized block
174175 api .eth .BlockChain ().SetFinalized (finalBlock )
@@ -178,11 +179,11 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
178179 safeBlock := api .eth .BlockChain ().GetBlockByHash (update .SafeBlockHash )
179180 if safeBlock == nil {
180181 log .Warn ("Safe block not available in database" )
181- return beacon .STATUS_INVALID , errors . New ( "safe head not available" )
182+ return beacon .STATUS_INVALID , & beacon . InvalidForkChoiceState
182183 }
183184 if rawdb .ReadCanonicalHash (api .eth .ChainDb (), safeBlock .NumberU64 ()) != update .SafeBlockHash {
184185 log .Warn ("Safe block not in canonical chain" )
185- return beacon .STATUS_INVALID , errors . New ( "safe head not canonical" )
186+ return beacon .STATUS_INVALID , & beacon . InvalidForkChoiceState
186187 }
187188 }
188189
@@ -200,13 +201,15 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
200201 // Create an empty block first which can be used as a fallback
201202 empty , err := api .eth .Miner ().GetSealingBlockSync (update .HeadBlockHash , payloadAttributes .Timestamp , payloadAttributes .SuggestedFeeRecipient , payloadAttributes .Random , true )
202203 if err != nil {
203- return valid (nil ), err
204+ log .Error ("Failed to create empty sealing payload" , "err" , err )
205+ return valid (nil ), & beacon .InvalidPayloadAttributes
204206 }
205207 // Send a request to generate a full block in the background.
206208 // The result can be obtained via the returned channel.
207209 resCh , err := api .eth .Miner ().GetSealingBlockAsync (update .HeadBlockHash , payloadAttributes .Timestamp , payloadAttributes .SuggestedFeeRecipient , payloadAttributes .Random , false )
208210 if err != nil {
209- return valid (nil ), err
211+ log .Error ("Failed to create async sealing payload" , "err" , err )
212+ return valid (nil ), & beacon .InvalidPayloadAttributes
210213 }
211214 id := computePayloadId (update .HeadBlockHash , payloadAttributes )
212215 api .localBlocks .put (id , & payload {empty : empty , result : resCh })
@@ -303,7 +306,7 @@ func (api *ConsensusAPI) NewPayloadV1(params beacon.ExecutableDataV1) (beacon.Pa
303306 }
304307 if block .Time () <= parent .Time () {
305308 log .Warn ("Invalid timestamp" , "parent" , block .Time (), "block" , block .Time ())
306- return api .invalid (errors .New ("invalid timestamp" )), nil
309+ return api .invalid (errors .New ("invalid timestamp" ), parent ), nil
307310 }
308311 if ! api .eth .BlockChain ().HasBlockAndState (block .ParentHash (), block .NumberU64 ()- 1 ) {
309312 api .remoteBlocks .put (block .Hash (), block .Header ())
@@ -313,7 +316,7 @@ func (api *ConsensusAPI) NewPayloadV1(params beacon.ExecutableDataV1) (beacon.Pa
313316 log .Trace ("Inserting block without sethead" , "hash" , block .Hash (), "number" , block .Number )
314317 if err := api .eth .BlockChain ().InsertBlockWithoutSetHead (block ); err != nil {
315318 log .Warn ("NewPayloadV1: inserting block failed" , "error" , err )
316- return api .invalid (err ), nil
319+ return api .invalid (err , parent ), nil
317320 }
318321 // We've accepted a valid payload from the beacon client. Mark the local
319322 // chain transitions to notify other subsystems (e.g. downloader) of the
@@ -339,9 +342,13 @@ func computePayloadId(headBlockHash common.Hash, params *beacon.PayloadAttribute
339342 return out
340343}
341344
342- // invalid returns a response "INVALID" with the latest valid hash set to the current head.
343- func (api * ConsensusAPI ) invalid (err error ) beacon.PayloadStatusV1 {
344- currentHash := api .eth .BlockChain ().CurrentHeader ().Hash ()
345+ // invalid returns a response "INVALID" with the latest valid hash supplied by latest or to the current head
346+ // if no latestValid block was provided.
347+ func (api * ConsensusAPI ) invalid (err error , latestValid * types.Block ) beacon.PayloadStatusV1 {
348+ currentHash := api .eth .BlockChain ().CurrentBlock ().Hash ()
349+ if latestValid != nil {
350+ currentHash = latestValid .Hash ()
351+ }
345352 errorMsg := err .Error ()
346353 return beacon.PayloadStatusV1 {Status : beacon .INVALID , LatestValidHash : & currentHash , ValidationError : & errorMsg }
347354}
0 commit comments