Skip to content

Commit eff7c3b

Browse files
authored
core/forkid: skip genesis forks by time (#28034)
* core/forkid: skip genesis forks by time * core/forkid: add comment about skipping non-zero fork times * core/forkid: skip all time based forks in genesis using loop * core/forkid: simplify logic for dropping time-based forks
1 parent f260a9e commit eff7c3b

File tree

3 files changed

+15
-18
lines changed

3 files changed

+15
-18
lines changed

cmd/devp2p/nodesetcmd.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"strings"
2626
"time"
2727

28+
"github.com/ethereum/go-ethereum/core"
2829
"github.com/ethereum/go-ethereum/core/forkid"
2930
"github.com/ethereum/go-ethereum/p2p/enr"
3031
"github.com/ethereum/go-ethereum/params"
@@ -228,13 +229,13 @@ func ethFilter(args []string) (nodeFilter, error) {
228229
var filter forkid.Filter
229230
switch args[0] {
230231
case "mainnet":
231-
filter = forkid.NewStaticFilter(params.MainnetChainConfig, params.MainnetGenesisHash)
232+
filter = forkid.NewStaticFilter(params.MainnetChainConfig, core.DefaultGenesisBlock().ToBlock())
232233
case "goerli":
233-
filter = forkid.NewStaticFilter(params.GoerliChainConfig, params.GoerliGenesisHash)
234+
filter = forkid.NewStaticFilter(params.GoerliChainConfig, core.DefaultGoerliGenesisBlock().ToBlock())
234235
case "sepolia":
235-
filter = forkid.NewStaticFilter(params.SepoliaChainConfig, params.SepoliaGenesisHash)
236+
filter = forkid.NewStaticFilter(params.SepoliaChainConfig, core.DefaultSepoliaGenesisBlock().ToBlock())
236237
case "holesky":
237-
filter = forkid.NewStaticFilter(params.HoleskyChainConfig, params.HoleskyGenesisHash)
238+
filter = forkid.NewStaticFilter(params.HoleskyChainConfig, core.DefaultHoleskyGenesisBlock().ToBlock())
238239
default:
239240
return nil, fmt.Errorf("unknown network %q", args[0])
240241
}

core/forkid/forkid.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"reflect"
2727
"strings"
2828

29-
"github.com/ethereum/go-ethereum/common"
3029
"github.com/ethereum/go-ethereum/core/types"
3130
"github.com/ethereum/go-ethereum/log"
3231
"github.com/ethereum/go-ethereum/params"
@@ -78,7 +77,7 @@ func NewID(config *params.ChainConfig, genesis *types.Block, head, time uint64)
7877
hash := crc32.ChecksumIEEE(genesis.Hash().Bytes())
7978

8079
// Calculate the current fork checksum and the next fork block
81-
forksByBlock, forksByTime := gatherForks(config)
80+
forksByBlock, forksByTime := gatherForks(config, genesis.Time())
8281
for _, fork := range forksByBlock {
8382
if fork <= head {
8483
// Fork already passed, checksum the previous hash and the fork number
@@ -88,10 +87,6 @@ func NewID(config *params.ChainConfig, genesis *types.Block, head, time uint64)
8887
return ID{Hash: checksumToBytes(hash), Next: fork}
8988
}
9089
for _, fork := range forksByTime {
91-
if fork <= genesis.Time() {
92-
// Fork active in genesis, skip in forkid calculation
93-
continue
94-
}
9590
if fork <= time {
9691
// Fork already passed, checksum the previous hash and fork timestamp
9792
hash = checksumUpdate(hash, fork)
@@ -119,7 +114,7 @@ func NewIDWithChain(chain Blockchain) ID {
119114
func NewFilter(chain Blockchain) Filter {
120115
return newFilter(
121116
chain.Config(),
122-
chain.Genesis().Hash(),
117+
chain.Genesis(),
123118
func() (uint64, uint64) {
124119
head := chain.CurrentHeader()
125120
return head.Number.Uint64(), head.Time
@@ -128,22 +123,22 @@ func NewFilter(chain Blockchain) Filter {
128123
}
129124

130125
// NewStaticFilter creates a filter at block zero.
131-
func NewStaticFilter(config *params.ChainConfig, genesis common.Hash) Filter {
126+
func NewStaticFilter(config *params.ChainConfig, genesis *types.Block) Filter {
132127
head := func() (uint64, uint64) { return 0, 0 }
133128
return newFilter(config, genesis, head)
134129
}
135130

136131
// newFilter is the internal version of NewFilter, taking closures as its arguments
137132
// instead of a chain. The reason is to allow testing it without having to simulate
138133
// an entire blockchain.
139-
func newFilter(config *params.ChainConfig, genesis common.Hash, headfn func() (uint64, uint64)) Filter {
134+
func newFilter(config *params.ChainConfig, genesis *types.Block, headfn func() (uint64, uint64)) Filter {
140135
// Calculate the all the valid fork hash and fork next combos
141136
var (
142-
forksByBlock, forksByTime = gatherForks(config)
137+
forksByBlock, forksByTime = gatherForks(config, genesis.Time())
143138
forks = append(append([]uint64{}, forksByBlock...), forksByTime...)
144139
sums = make([][4]byte, len(forks)+1) // 0th is the genesis
145140
)
146-
hash := crc32.ChecksumIEEE(genesis[:])
141+
hash := crc32.ChecksumIEEE(genesis.Hash().Bytes())
147142
sums[0] = checksumToBytes(hash)
148143
for i, fork := range forks {
149144
hash = checksumUpdate(hash, fork)
@@ -244,7 +239,7 @@ func checksumToBytes(hash uint32) [4]byte {
244239

245240
// gatherForks gathers all the known forks and creates two sorted lists out of
246241
// them, one for the block number based forks and the second for the timestamps.
247-
func gatherForks(config *params.ChainConfig) ([]uint64, []uint64) {
242+
func gatherForks(config *params.ChainConfig, genesis uint64) ([]uint64, []uint64) {
248243
// Gather all the fork block numbers via reflection
249244
kind := reflect.TypeOf(params.ChainConfig{})
250245
conf := reflect.ValueOf(config).Elem()
@@ -294,7 +289,8 @@ func gatherForks(config *params.ChainConfig) ([]uint64, []uint64) {
294289
if len(forksByBlock) > 0 && forksByBlock[0] == 0 {
295290
forksByBlock = forksByBlock[1:]
296291
}
297-
if len(forksByTime) > 0 && forksByTime[0] == 0 {
292+
// Skip any forks before genesis.
293+
for len(forksByTime) > 0 && forksByTime[0] <= genesis {
298294
forksByTime = forksByTime[1:]
299295
}
300296
return forksByBlock, forksByTime

core/forkid/forkid_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ func TestValidation(t *testing.T) {
357357
//{params.MainnetChainConfig, 20999999, 1677999999, ID{Hash: checksumToBytes(0x71147644), Next: 1678000000}, ErrLocalIncompatibleOrStale},
358358
}
359359
for i, tt := range tests {
360-
filter := newFilter(tt.config, params.MainnetGenesisHash, func() (uint64, uint64) { return tt.head, tt.time })
360+
filter := newFilter(tt.config, core.DefaultGenesisBlock().ToBlock(), func() (uint64, uint64) { return tt.head, tt.time })
361361
if err := filter(tt.id); err != tt.err {
362362
t.Errorf("test %d: validation error mismatch: have %v, want %v", i, err, tt.err)
363363
}

0 commit comments

Comments
 (0)