@@ -81,8 +81,10 @@ var caps = []string{
81
81
"engine_exchangeTransitionConfigurationV1" ,
82
82
"engine_getPayloadV1" ,
83
83
"engine_getPayloadV2" ,
84
+ "engine_getPayloadV3" ,
84
85
"engine_newPayloadV1" ,
85
86
"engine_newPayloadV2" ,
87
+ "engine_newPayloadV3" ,
86
88
"engine_getPayloadBodiesByHashV1" ,
87
89
"engine_getPayloadBodiesByRangeV1" ,
88
90
}
@@ -405,23 +407,13 @@ func (api *ConsensusAPI) GetPayloadV2(payloadID engine.PayloadID) (*engine.Execu
405
407
return api .getPayload (payloadID )
406
408
}
407
409
408
- func (api * ConsensusAPI ) getPayload (payloadID engine.PayloadID ) (* engine.ExecutionPayloadEnvelope , error ) {
409
- log .Trace ("Engine API request received" , "method" , "GetPayload" , "id" , payloadID )
410
- data := api .localBlocks .get (payloadID , false )
411
- if data == nil {
412
- return nil , engine .UnknownPayload
413
- }
414
- return data , nil
410
+ // GetPayloadV3 returns a cached payload by id.
411
+ func (api * ConsensusAPI ) GetPayloadV3 (payloadID engine.PayloadID ) (* engine.ExecutionPayloadEnvelope , error ) {
412
+ return api .getPayload (payloadID )
415
413
}
416
414
417
- // getFullPayload returns a cached payload by it. The difference is that this
418
- // function always expects a non-empty payload, but can also return empty one
419
- // if no transaction is executable.
420
- //
421
- // Note, this function is not a part of standard engine API, meant to be used
422
- // by consensus client mock in dev mode.
423
- func (api * ConsensusAPI ) getFullPayload (payloadID engine.PayloadID ) (* engine.ExecutionPayloadEnvelope , error ) {
424
- log .Trace ("Engine API request received" , "method" , "GetFullPayload" , "id" , payloadID )
415
+ func (api * ConsensusAPI ) getPayload (payloadID engine.PayloadID ) (* engine.ExecutionPayloadEnvelope , error ) {
416
+ log .Trace ("Engine API request received" , "method" , "GetPayload" , "id" , payloadID )
425
417
data := api .localBlocks .get (payloadID , true )
426
418
if data == nil {
427
419
return nil , engine .UnknownPayload
@@ -434,7 +426,7 @@ func (api *ConsensusAPI) NewPayloadV1(params engine.ExecutableData) (engine.Payl
434
426
if params .Withdrawals != nil {
435
427
return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("withdrawals not supported in V1" ))
436
428
}
437
- return api .newPayload (params )
429
+ return api .newPayload (params , nil )
438
430
}
439
431
440
432
// NewPayloadV2 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
@@ -446,10 +438,29 @@ func (api *ConsensusAPI) NewPayloadV2(params engine.ExecutableData) (engine.Payl
446
438
} else if params .Withdrawals != nil {
447
439
return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("non-nil withdrawals pre-shanghai" ))
448
440
}
449
- return api .newPayload (params )
441
+ if api .eth .BlockChain ().Config ().IsCancun (new (big.Int ).SetUint64 (params .Number ), params .Timestamp ) {
442
+ return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("newPayloadV2 called post-cancun" ))
443
+ }
444
+ return api .newPayload (params , nil )
450
445
}
451
446
452
- func (api * ConsensusAPI ) newPayload (params engine.ExecutableData ) (engine.PayloadStatusV1 , error ) {
447
+ // NewPayloadV3 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
448
+ func (api * ConsensusAPI ) NewPayloadV3 (params engine.ExecutableData , versionedHashes * []common.Hash ) (engine.PayloadStatusV1 , error ) {
449
+ if ! api .eth .BlockChain ().Config ().IsCancun (new (big.Int ).SetUint64 (params .Number ), params .Timestamp ) {
450
+ return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("newPayloadV3 called pre-cancun" ))
451
+ }
452
+
453
+ if params .ExcessDataGas == nil {
454
+ return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (fmt .Errorf ("nil excessDataGas post-cancun" ))
455
+ }
456
+ var hashes []common.Hash
457
+ if versionedHashes != nil {
458
+ hashes = * versionedHashes
459
+ }
460
+ return api .newPayload (params , hashes )
461
+ }
462
+
463
+ func (api * ConsensusAPI ) newPayload (params engine.ExecutableData , versionedHashes []common.Hash ) (engine.PayloadStatusV1 , error ) {
453
464
// The locking here is, strictly, not required. Without these locks, this can happen:
454
465
//
455
466
// 1. NewPayload( execdata-N ) is invoked from the CL. It goes all the way down to
@@ -467,9 +478,9 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData) (engine.Payloa
467
478
defer api .newPayloadLock .Unlock ()
468
479
469
480
log .Trace ("Engine API request received" , "method" , "NewPayload" , "number" , params .Number , "hash" , params .BlockHash )
470
- block , err := engine .ExecutableDataToBlock (params )
481
+ block , err := engine .ExecutableDataToBlock (params , versionedHashes )
471
482
if err != nil {
472
- log .Debug ("Invalid NewPayload params" , "params" , params , "error" , err )
483
+ log .Warn ("Invalid NewPayload params" , "params" , params , "error" , err )
473
484
return engine.PayloadStatusV1 {Status : engine .INVALID }, nil
474
485
}
475
486
// Stash away the last update to warn the user if the beacon client goes offline
@@ -730,8 +741,8 @@ func (api *ConsensusAPI) ExchangeCapabilities([]string) []string {
730
741
return caps
731
742
}
732
743
733
- // GetPayloadBodiesByHashV1 implements engine_getPayloadBodiesByHashV1 which
734
- // allows for retrieval of a list of block bodies by the engine api.
744
+ // GetPayloadBodiesByHashV1 implements engine_getPayloadBodiesByHashV1 which allows for retrieval of a list
745
+ // of block bodies by the engine api.
735
746
func (api * ConsensusAPI ) GetPayloadBodiesByHashV1 (hashes []common.Hash ) []* engine.ExecutionPayloadBodyV1 {
736
747
var bodies = make ([]* engine.ExecutionPayloadBodyV1 , len (hashes ))
737
748
for i , hash := range hashes {
@@ -741,8 +752,8 @@ func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engin
741
752
return bodies
742
753
}
743
754
744
- // GetPayloadBodiesByRangeV1 implements engine_getPayloadBodiesByRangeV1 which
745
- // allows for retrieval of a range of block bodies by the engine api.
755
+ // GetPayloadBodiesByRangeV1 implements engine_getPayloadBodiesByRangeV1 which allows for retrieval of a range
756
+ // of block bodies by the engine api.
746
757
func (api * ConsensusAPI ) GetPayloadBodiesByRangeV1 (start , count hexutil.Uint64 ) ([]* engine.ExecutionPayloadBodyV1 , error ) {
747
758
if start == 0 || count == 0 {
748
759
return nil , engine .InvalidParams .With (fmt .Errorf ("invalid start or count, start: %v count: %v" , start , count ))
@@ -768,19 +779,23 @@ func getBody(block *types.Block) *engine.ExecutionPayloadBodyV1 {
768
779
if block == nil {
769
780
return nil
770
781
}
782
+
771
783
var (
772
784
body = block .Body ()
773
785
txs = make ([]hexutil.Bytes , len (body .Transactions ))
774
786
withdrawals = body .Withdrawals
775
787
)
788
+
776
789
for j , tx := range body .Transactions {
777
790
data , _ := tx .MarshalBinary ()
778
791
txs [j ] = hexutil .Bytes (data )
779
792
}
793
+
780
794
// Post-shanghai withdrawals MUST be set to empty slice instead of nil
781
795
if withdrawals == nil && block .Header ().WithdrawalsHash != nil {
782
796
withdrawals = make ([]* types.Withdrawal , 0 )
783
797
}
798
+
784
799
return & engine.ExecutionPayloadBodyV1 {
785
800
TransactionData : txs ,
786
801
Withdrawals : withdrawals ,
0 commit comments