@@ -20,7 +20,6 @@ package catalyst
2020import (
2121 "errors"
2222 "fmt"
23- "math/big"
2423 "sync"
2524 "time"
2625
@@ -34,6 +33,7 @@ import (
3433 "github.com/ethereum/go-ethereum/log"
3534 "github.com/ethereum/go-ethereum/miner"
3635 "github.com/ethereum/go-ethereum/node"
36+ "github.com/ethereum/go-ethereum/params/forks"
3737 "github.com/ethereum/go-ethereum/rpc"
3838)
3939
@@ -184,47 +184,43 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, pa
184184}
185185
186186// ForkchoiceUpdatedV2 is equivalent to V1 with the addition of withdrawals in the payload attributes.
187- func (api * ConsensusAPI ) ForkchoiceUpdatedV2 (update engine.ForkchoiceStateV1 , payloadAttributes * engine.PayloadAttributes ) (engine.ForkChoiceResponse , error ) {
188- if payloadAttributes != nil {
189- if err := api .verifyPayloadAttributes (payloadAttributes ); err != nil {
190- return engine .STATUS_INVALID , engine .InvalidParams .With (err )
187+ func (api * ConsensusAPI ) ForkchoiceUpdatedV2 (update engine.ForkchoiceStateV1 , params * engine.PayloadAttributes ) (engine.ForkChoiceResponse , error ) {
188+ if params != nil {
189+ if params .Withdrawals == nil {
190+ return engine .STATUS_INVALID , engine .InvalidParams .With (errors .New ("missing withdrawals" ))
191+ }
192+ if params .BeaconRoot != nil {
193+ return engine .STATUS_INVALID , engine .InvalidParams .With (errors .New ("unexpected beacon root" ))
194+ }
195+ if api .eth .BlockChain ().Config ().LatestFork (params .Timestamp ) != forks .Shanghai {
196+ return engine .STATUS_INVALID , engine .UnsupportedFork .With (errors .New ("forkchoiceUpdatedV2 must only be called for shanghai payloads" ))
191197 }
192198 }
193- return api .forkchoiceUpdated (update , payloadAttributes )
199+ return api .forkchoiceUpdated (update , params )
194200}
195201
196202// ForkchoiceUpdatedV3 is equivalent to V2 with the addition of parent beacon block root in the payload attributes.
197- func (api * ConsensusAPI ) ForkchoiceUpdatedV3 (update engine.ForkchoiceStateV1 , payloadAttributes * engine.PayloadAttributes ) (engine.ForkChoiceResponse , error ) {
198- if payloadAttributes != nil {
199- if err := api .verifyPayloadAttributes (payloadAttributes ); err != nil {
200- return engine .STATUS_INVALID , engine .InvalidParams .With (err )
203+ func (api * ConsensusAPI ) ForkchoiceUpdatedV3 (update engine.ForkchoiceStateV1 , params * engine.PayloadAttributes ) (engine.ForkChoiceResponse , error ) {
204+ if params != nil {
205+ // TODO(matt): according to https://github.com/ethereum/execution-apis/pull/498,
206+ // payload attributes that are invalid should return error
207+ // engine.InvalidPayloadAttributes. Once hive updates this, we should update
208+ // on our end.
209+ if params .Withdrawals == nil {
210+ return engine .STATUS_INVALID , engine .InvalidParams .With (errors .New ("missing withdrawals" ))
211+ }
212+ if params .BeaconRoot == nil {
213+ return engine .STATUS_INVALID , engine .InvalidParams .With (errors .New ("missing beacon root" ))
214+ }
215+ if api .eth .BlockChain ().Config ().LatestFork (params .Timestamp ) != forks .Cancun {
216+ return engine .STATUS_INVALID , engine .UnsupportedFork .With (errors .New ("forkchoiceUpdatedV3 must only be called for cancun payloads" ))
201217 }
202218 }
203- return api .forkchoiceUpdated (update , payloadAttributes )
204- }
205-
206- func (api * ConsensusAPI ) verifyPayloadAttributes (attr * engine.PayloadAttributes ) error {
207- c := api .eth .BlockChain ().Config ()
208-
209- // Verify withdrawals attribute for Shanghai.
210- if err := checkAttribute (c .IsShanghai , attr .Withdrawals != nil , c .LondonBlock , attr .Timestamp ); err != nil {
211- return fmt .Errorf ("invalid withdrawals: %w" , err )
212- }
213- // Verify beacon root attribute for Cancun.
214- if err := checkAttribute (c .IsCancun , attr .BeaconRoot != nil , c .LondonBlock , attr .Timestamp ); err != nil {
215- return fmt .Errorf ("invalid parent beacon block root: %w" , err )
216- }
217- return nil
218- }
219-
220- func checkAttribute (active func (* big.Int , uint64 ) bool , exists bool , block * big.Int , time uint64 ) error {
221- if active (block , time ) && ! exists {
222- return errors .New ("fork active, missing expected attribute" )
223- }
224- if ! active (block , time ) && exists {
225- return errors .New ("fork inactive, unexpected attribute set" )
226- }
227- return nil
219+ // TODO(matt): the spec requires that fcu is applied when called on a valid
220+ // hash, even if params are wrong. To do this we need to split up
221+ // forkchoiceUpdate into a function that only updates the head and then a
222+ // function that kicks off block construction.
223+ return api .forkchoiceUpdated (update , params )
228224}
229225
230226func (api * ConsensusAPI ) forkchoiceUpdated (update engine.ForkchoiceStateV1 , payloadAttributes * engine.PayloadAttributes ) (engine.ForkChoiceResponse , error ) {
@@ -457,38 +453,49 @@ func (api *ConsensusAPI) NewPayloadV1(params engine.ExecutableData) (engine.Payl
457453
458454// NewPayloadV2 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
459455func (api * ConsensusAPI ) NewPayloadV2 (params engine.ExecutableData ) (engine.PayloadStatusV1 , error ) {
460- if api .eth .BlockChain ().Config ().IsShanghai (new (big.Int ).SetUint64 (params .Number ), params .Timestamp ) {
456+ if api .eth .BlockChain ().Config ().IsCancun (api .eth .BlockChain ().Config ().LondonBlock , params .Timestamp ) {
457+ return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("can't use new payload v2 post-shanghai" ))
458+ }
459+ if api .eth .BlockChain ().Config ().LatestFork (params .Timestamp ) == forks .Shanghai {
461460 if params .Withdrawals == nil {
462461 return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil withdrawals post-shanghai" ))
463462 }
464- } else if params .Withdrawals != nil {
465- return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("non-nil withdrawals pre-shanghai" ))
463+ } else {
464+ if params .Withdrawals != nil {
465+ return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("non-nil withdrawals pre-shanghai" ))
466+ }
467+ }
468+ if params .ExcessBlobGas != nil {
469+ return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("non-nil excessBlobGas pre-cancun" ))
466470 }
467- if api . eth . BlockChain (). Config (). IsCancun ( new (big. Int ). SetUint64 ( params .Number ), params . Timestamp ) {
468- return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("newPayloadV2 called post -cancun" ))
471+ if params .BlobGasUsed != nil {
472+ return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("non-nil params.BlobGasUsed pre -cancun" ))
469473 }
470474 return api .newPayload (params , nil , nil )
471475}
472476
473477// NewPayloadV3 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
474478func (api * ConsensusAPI ) NewPayloadV3 (params engine.ExecutableData , versionedHashes []common.Hash , beaconRoot * common.Hash ) (engine.PayloadStatusV1 , error ) {
479+ if params .Withdrawals == nil {
480+ return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil withdrawals post-shanghai" ))
481+ }
475482 if params .ExcessBlobGas == nil {
476483 return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil excessBlobGas post-cancun" ))
477484 }
478485 if params .BlobGasUsed == nil {
479486 return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil params.BlobGasUsed post-cancun" ))
480487 }
488+
481489 if versionedHashes == nil {
482490 return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil versionedHashes post-cancun" ))
483491 }
484492 if beaconRoot == nil {
485493 return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil parentBeaconBlockRoot post-cancun" ))
486494 }
487495
488- if ! api .eth .BlockChain ().Config ().IsCancun ( new (big. Int ). SetUint64 ( params .Number ), params . Timestamp ) {
489- return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .UnsupportedFork .With (errors .New ("newPayloadV3 called pre- cancun" ))
496+ if api .eth .BlockChain ().Config ().LatestFork ( params .Timestamp ) != forks . Cancun {
497+ return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .UnsupportedFork .With (errors .New ("newPayloadV3 must only be called for cancun payloads " ))
490498 }
491-
492499 return api .newPayload (params , versionedHashes , beaconRoot )
493500}
494501
0 commit comments