Skip to content

Commit 2295640

Browse files
eth/catalyst: implement kintsugi-spec v3 (#24067)
1 parent f5f5c08 commit 2295640

File tree

8 files changed

+97
-59
lines changed

8 files changed

+97
-59
lines changed

core/forkid/forkid_test.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package forkid
1919
import (
2020
"bytes"
2121
"math"
22+
"math/big"
2223
"testing"
2324

2425
"github.com/ethereum/go-ethereum/common"
@@ -29,6 +30,8 @@ import (
2930
// TestCreation tests that different genesis and fork rule combinations result in
3031
// the correct fork ID.
3132
func TestCreation(t *testing.T) {
33+
mergeConfig := *params.MainnetChainConfig
34+
mergeConfig.MergeForkBlock = big.NewInt(15000000)
3235
type testcase struct {
3336
head uint64
3437
want ID
@@ -65,7 +68,7 @@ func TestCreation(t *testing.T) {
6568
{12964999, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block
6669
{12965000, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block
6770
{13772999, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block
68-
{13773000, ID{Hash: checksumToBytes(0x20c327fc), Next: 0}}, /// First Arrow Glacier block
71+
{13773000, ID{Hash: checksumToBytes(0x20c327fc), Next: 0}}, // First Arrow Glacier block
6972
{20000000, ID{Hash: checksumToBytes(0x20c327fc), Next: 0}}, // Future Arrow Glacier block
7073
},
7174
},
@@ -133,6 +136,38 @@ func TestCreation(t *testing.T) {
133136
{6000000, ID{Hash: checksumToBytes(0xB8C6299D), Next: 0}}, // Future London block
134137
},
135138
},
139+
// Merge test cases
140+
{
141+
&mergeConfig,
142+
params.MainnetGenesisHash,
143+
[]testcase{
144+
{0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Unsynced
145+
{1149999, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Last Frontier block
146+
{1150000, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // First Homestead block
147+
{1919999, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // Last Homestead block
148+
{1920000, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // First DAO block
149+
{2462999, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // Last DAO block
150+
{2463000, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // First Tangerine block
151+
{2674999, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // Last Tangerine block
152+
{2675000, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // First Spurious block
153+
{4369999, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // Last Spurious block
154+
{4370000, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // First Byzantium block
155+
{7279999, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // Last Byzantium block
156+
{7280000, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // First and last Constantinople, first Petersburg block
157+
{9068999, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // Last Petersburg block
158+
{9069000, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // First Istanbul and first Muir Glacier block
159+
{9199999, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // Last Istanbul and first Muir Glacier block
160+
{9200000, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // First Muir Glacier block
161+
{12243999, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block
162+
{12244000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block
163+
{12964999, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block
164+
{12965000, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block
165+
{13772999, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block
166+
{13773000, ID{Hash: checksumToBytes(0x20c327fc), Next: 15000000}}, // First Arrow Glacier block
167+
{15000000, ID{Hash: checksumToBytes(0xe3abe201), Next: 0}}, // First Merge Start block
168+
{20000000, ID{Hash: checksumToBytes(0xe3abe201), Next: 0}}, // Future Merge Start block
169+
},
170+
},
136171
}
137172
for i, tt := range tests {
138173
for j, ttt := range tt.cases {

eth/catalyst/api.go

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,14 @@ import (
4343
)
4444

4545
var (
46-
VALID = GenericStringResponse{"VALID"}
47-
SUCCESS = GenericStringResponse{"SUCCESS"}
48-
INVALID = ForkChoiceResponse{Status: "INVALID", PayloadID: nil}
49-
SYNCING = ForkChoiceResponse{Status: "INVALID", PayloadID: nil}
50-
UnknownHeader = rpc.CustomError{Code: -32000, Message: "unknown header"}
51-
UnknownPayload = rpc.CustomError{Code: -32001, Message: "unknown payload"}
52-
InvalidPayloadID = rpc.CustomError{Code: 1, Message: "invalid payload id"}
46+
VALID = GenericStringResponse{"VALID"}
47+
SUCCESS = GenericStringResponse{"SUCCESS"}
48+
INVALID = ForkChoiceResponse{Status: "INVALID", PayloadID: nil}
49+
SYNCING = ForkChoiceResponse{Status: "SYNCING", PayloadID: nil}
50+
GenericServerError = rpc.CustomError{Code: -32000, ValidationError: "Server error"}
51+
UnknownPayload = rpc.CustomError{Code: -32001, ValidationError: "Unknown payload"}
52+
InvalidTB = rpc.CustomError{Code: -32002, ValidationError: "Invalid terminal block"}
53+
InvalidPayloadID = rpc.CustomError{Code: 1, ValidationError: "invalid payload id"}
5354
)
5455

5556
// Register adds catalyst APIs to the full node.
@@ -232,7 +233,7 @@ func computePayloadId(headBlockHash common.Hash, params *PayloadAttributesV1) []
232233
hasher.Write(headBlockHash[:])
233234
binary.Write(hasher, binary.BigEndian, params.Timestamp)
234235
hasher.Write(params.Random[:])
235-
hasher.Write(params.FeeRecipient[:])
236+
hasher.Write(params.SuggestedFeeRecipient[:])
236237
return hasher.Sum([]byte{})[:8]
237238
}
238239

@@ -308,7 +309,7 @@ func (api *ConsensusAPI) assembleBlock(parentHash common.Hash, params *PayloadAt
308309
log.Warn("Producing block too far in the future", "diff", common.PrettyDuration(diff))
309310
}
310311
pending := api.eth.TxPool().Pending(true)
311-
coinbase := params.FeeRecipient
312+
coinbase := params.SuggestedFeeRecipient
312313
num := parent.Number()
313314
header := &types.Header{
314315
ParentHash: parent.Hash(),
@@ -419,10 +420,10 @@ func ExecutableDataToBlock(params ExecutableDataV1) (*types.Block, error) {
419420
header := &types.Header{
420421
ParentHash: params.ParentHash,
421422
UncleHash: types.EmptyUncleHash,
422-
Coinbase: params.Coinbase,
423+
Coinbase: params.FeeRecipient,
423424
Root: params.StateRoot,
424425
TxHash: types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)),
425-
ReceiptHash: params.ReceiptRoot,
426+
ReceiptHash: params.ReceiptsRoot,
426427
Bloom: types.BytesToBloom(params.LogsBloom),
427428
Difficulty: common.Big0,
428429
Number: number,
@@ -444,14 +445,14 @@ func BlockToExecutableData(block *types.Block, random common.Hash) *ExecutableDa
444445
return &ExecutableDataV1{
445446
BlockHash: block.Hash(),
446447
ParentHash: block.ParentHash(),
447-
Coinbase: block.Coinbase(),
448+
FeeRecipient: block.Coinbase(),
448449
StateRoot: block.Root(),
449450
Number: block.NumberU64(),
450451
GasLimit: block.GasLimit(),
451452
GasUsed: block.GasUsed(),
452453
BaseFeePerGas: block.BaseFee(),
453454
Timestamp: block.Time(),
454-
ReceiptRoot: block.ReceiptHash(),
455+
ReceiptsRoot: block.ReceiptHash(),
455456
LogsBloom: block.Bloom().Bytes(),
456457
Transactions: encodeTransactions(block.Transactions()),
457458
Random: random,
@@ -475,11 +476,11 @@ func (api *ConsensusAPI) checkTerminalTotalDifficulty(head common.Hash) error {
475476
// make sure the parent has enough terminal total difficulty
476477
newHeadBlock := api.eth.BlockChain().GetBlockByHash(head)
477478
if newHeadBlock == nil {
478-
return &UnknownHeader
479+
return &GenericServerError
479480
}
480481
td := api.eth.BlockChain().GetTd(newHeadBlock.Hash(), newHeadBlock.NumberU64())
481482
if td != nil && td.Cmp(api.eth.BlockChain().Config().TerminalTotalDifficulty) < 0 {
482-
return errors.New("total difficulty not reached yet")
483+
return &InvalidTB
483484
}
484485
return nil
485486
}
@@ -494,7 +495,7 @@ func (api *ConsensusAPI) setHead(newHead common.Hash) error {
494495
}
495496
newHeadHeader := api.les.BlockChain().GetHeaderByHash(newHead)
496497
if newHeadHeader == nil {
497-
return &UnknownHeader
498+
return &GenericServerError
498499
}
499500
if err := api.les.BlockChain().SetChainHead(newHeadHeader); err != nil {
500501
return err
@@ -508,15 +509,11 @@ func (api *ConsensusAPI) setHead(newHead common.Hash) error {
508509
}
509510
headBlock := api.eth.BlockChain().CurrentBlock()
510511
if headBlock.Hash() == newHead {
511-
// Trigger the transition if it's the first `NewHead` event.
512-
if merger := api.merger(); !merger.PoSFinalized() {
513-
merger.FinalizePoS()
514-
}
515512
return nil
516513
}
517514
newHeadBlock := api.eth.BlockChain().GetBlockByHash(newHead)
518515
if newHeadBlock == nil {
519-
return &UnknownHeader
516+
return &GenericServerError
520517
}
521518
if err := api.eth.BlockChain().SetChainHead(newHeadBlock); err != nil {
522519
return err

eth/catalyst/api_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,9 @@ func TestFullAPI(t *testing.T) {
374374
ethservice.TxPool().AddLocal(tx)
375375

376376
params := PayloadAttributesV1{
377-
Timestamp: parent.Time() + 1,
378-
Random: crypto.Keccak256Hash([]byte{byte(i)}),
379-
FeeRecipient: parent.Coinbase(),
377+
Timestamp: parent.Time() + 1,
378+
Random: crypto.Keccak256Hash([]byte{byte(i)}),
379+
SuggestedFeeRecipient: parent.Coinbase(),
380380
}
381381
fcState := ForkchoiceStateV1{
382382
HeadBlockHash: parent.Hash(),

eth/catalyst/api_types.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ import (
2727

2828
// Structure described at https://github.com/ethereum/execution-apis/pull/74
2929
type PayloadAttributesV1 struct {
30-
Timestamp uint64 `json:"timestamp" gencodec:"required"`
31-
Random common.Hash `json:"random" gencodec:"required"`
32-
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
30+
Timestamp uint64 `json:"timestamp" gencodec:"required"`
31+
Random common.Hash `json:"random" gencodec:"required"`
32+
SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
3333
}
3434

3535
// JSON type overrides for PayloadAttributesV1.
@@ -42,9 +42,9 @@ type payloadAttributesMarshaling struct {
4242
// Structure described at https://github.com/ethereum/execution-apis/src/engine/specification.md
4343
type ExecutableDataV1 struct {
4444
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
45-
Coinbase common.Address `json:"coinbase" gencodec:"required"`
45+
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
4646
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
47-
ReceiptRoot common.Hash `json:"receiptRoot" gencodec:"required"`
47+
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
4848
LogsBloom []byte `json:"logsBloom" gencodec:"required"`
4949
Random common.Hash `json:"random" gencodec:"required"`
5050
Number uint64 `json:"blockNumber" gencodec:"required"`

eth/catalyst/gen_blockparams.go

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

eth/catalyst/gen_ed.go

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)