@@ -20,7 +20,6 @@ package catalyst
20
20
import (
21
21
"errors"
22
22
"fmt"
23
- "math/big"
24
23
"sync"
25
24
"time"
26
25
@@ -34,6 +33,7 @@ import (
34
33
"github.com/ethereum/go-ethereum/log"
35
34
"github.com/ethereum/go-ethereum/miner"
36
35
"github.com/ethereum/go-ethereum/node"
36
+ "github.com/ethereum/go-ethereum/params/forks"
37
37
"github.com/ethereum/go-ethereum/rpc"
38
38
)
39
39
@@ -184,47 +184,43 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, pa
184
184
}
185
185
186
186
// 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" ))
191
197
}
192
198
}
193
- return api .forkchoiceUpdated (update , payloadAttributes )
199
+ return api .forkchoiceUpdated (update , params )
194
200
}
195
201
196
202
// 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" ))
201
217
}
202
218
}
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 )
228
224
}
229
225
230
226
func (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
457
453
458
454
// NewPayloadV2 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
459
455
func (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 {
461
460
if params .Withdrawals == nil {
462
461
return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil withdrawals post-shanghai" ))
463
462
}
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" ))
466
470
}
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" ))
469
473
}
470
474
return api .newPayload (params , nil , nil )
471
475
}
472
476
473
477
// NewPayloadV3 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
474
478
func (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
+ }
475
482
if params .ExcessBlobGas == nil {
476
483
return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil excessBlobGas post-cancun" ))
477
484
}
478
485
if params .BlobGasUsed == nil {
479
486
return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil params.BlobGasUsed post-cancun" ))
480
487
}
488
+
481
489
if versionedHashes == nil {
482
490
return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil versionedHashes post-cancun" ))
483
491
}
484
492
if beaconRoot == nil {
485
493
return engine.PayloadStatusV1 {Status : engine .INVALID }, engine .InvalidParams .With (errors .New ("nil parentBeaconBlockRoot post-cancun" ))
486
494
}
487
495
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 " ))
490
498
}
491
-
492
499
return api .newPayload (params , versionedHashes , beaconRoot )
493
500
}
494
501
0 commit comments