@@ -29,6 +29,7 @@ import (
29
29
"github.com/ethereum/go-ethereum/common/hexutil"
30
30
"github.com/ethereum/go-ethereum/core/beacon"
31
31
"github.com/ethereum/go-ethereum/core/rawdb"
32
+ "github.com/ethereum/go-ethereum/core/types"
32
33
"github.com/ethereum/go-ethereum/eth"
33
34
"github.com/ethereum/go-ethereum/log"
34
35
"github.com/ethereum/go-ethereum/node"
@@ -165,10 +166,10 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
165
166
finalBlock := api .eth .BlockChain ().GetBlockByHash (update .FinalizedBlockHash )
166
167
if finalBlock == nil {
167
168
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
169
170
} else if rawdb .ReadCanonicalHash (api .eth .ChainDb (), finalBlock .NumberU64 ()) != update .FinalizedBlockHash {
170
171
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
172
173
}
173
174
// Set the finalized block
174
175
api .eth .BlockChain ().SetFinalized (finalBlock )
@@ -178,11 +179,11 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
178
179
safeBlock := api .eth .BlockChain ().GetBlockByHash (update .SafeBlockHash )
179
180
if safeBlock == nil {
180
181
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
182
183
}
183
184
if rawdb .ReadCanonicalHash (api .eth .ChainDb (), safeBlock .NumberU64 ()) != update .SafeBlockHash {
184
185
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
186
187
}
187
188
}
188
189
@@ -200,13 +201,15 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
200
201
// Create an empty block first which can be used as a fallback
201
202
empty , err := api .eth .Miner ().GetSealingBlockSync (update .HeadBlockHash , payloadAttributes .Timestamp , payloadAttributes .SuggestedFeeRecipient , payloadAttributes .Random , true )
202
203
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
204
206
}
205
207
// Send a request to generate a full block in the background.
206
208
// The result can be obtained via the returned channel.
207
209
resCh , err := api .eth .Miner ().GetSealingBlockAsync (update .HeadBlockHash , payloadAttributes .Timestamp , payloadAttributes .SuggestedFeeRecipient , payloadAttributes .Random , false )
208
210
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
210
213
}
211
214
id := computePayloadId (update .HeadBlockHash , payloadAttributes )
212
215
api .localBlocks .put (id , & payload {empty : empty , result : resCh })
@@ -303,7 +306,7 @@ func (api *ConsensusAPI) NewPayloadV1(params beacon.ExecutableDataV1) (beacon.Pa
303
306
}
304
307
if block .Time () <= parent .Time () {
305
308
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
307
310
}
308
311
if ! api .eth .BlockChain ().HasBlockAndState (block .ParentHash (), block .NumberU64 ()- 1 ) {
309
312
api .remoteBlocks .put (block .Hash (), block .Header ())
@@ -313,7 +316,7 @@ func (api *ConsensusAPI) NewPayloadV1(params beacon.ExecutableDataV1) (beacon.Pa
313
316
log .Trace ("Inserting block without sethead" , "hash" , block .Hash (), "number" , block .Number )
314
317
if err := api .eth .BlockChain ().InsertBlockWithoutSetHead (block ); err != nil {
315
318
log .Warn ("NewPayloadV1: inserting block failed" , "error" , err )
316
- return api .invalid (err ), nil
319
+ return api .invalid (err , parent ), nil
317
320
}
318
321
// We've accepted a valid payload from the beacon client. Mark the local
319
322
// chain transitions to notify other subsystems (e.g. downloader) of the
@@ -339,9 +342,13 @@ func computePayloadId(headBlockHash common.Hash, params *beacon.PayloadAttribute
339
342
return out
340
343
}
341
344
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
+ }
345
352
errorMsg := err .Error ()
346
353
return beacon.PayloadStatusV1 {Status : beacon .INVALID , LatestValidHash : & currentHash , ValidationError : & errorMsg }
347
354
}
0 commit comments