Skip to content

Commit

Permalink
Correctly compute fork id when timestamp fork is activated in genesis (
Browse files Browse the repository at this point in the history
  • Loading branch information
yperbasis authored and AskAlexSharov committed Sep 6, 2023
1 parent 3cb8a95 commit c57850b
Show file tree
Hide file tree
Showing 11 changed files with 30 additions and 20 deletions.
1 change: 1 addition & 0 deletions cmd/integration/commands/stages.go
Original file line number Diff line number Diff line change
Expand Up @@ -1511,6 +1511,7 @@ func newSync(ctx context.Context, db kv.RwDB, miningConfig *params.MiningConfig,
"",
chainConfig,
genesisBlock.Hash(),
genesisBlock.Time(),
engine,
1,
nil,
Expand Down
6 changes: 5 additions & 1 deletion cmd/observer/observer/crawler.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ func NewCrawler(
return nil, fmt.Errorf("unknown chain %s", chain)
}

forkFilter := forkid.NewStaticFilter(chainConfig, *genesisHash)
// TODO(yperbasis) This might be a problem for chains that have a time-based fork (Shanghai, Cancun, etc)
// in genesis already, e.g. Holesky.
genesisTime := uint64(0)

forkFilter := forkid.NewStaticFilter(chainConfig, *genesisHash, genesisTime)

diplomacy := NewDiplomacy(
database.NewDBRetrier(db, logger),
Expand Down
6 changes: 5 additions & 1 deletion cmd/observer/observer/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ func makeForksENREntry(chain string) (enr.Entry, error) {
return nil, fmt.Errorf("unknown chain %s", chain)
}

heightForks, timeForks := forkid.GatherForks(chainConfig)
// TODO(yperbasis) This might be a problem for chains that have a time-based fork (Shanghai, Cancun, etc)
// in genesis already, e.g. Holesky.
genesisTime := uint64(0)

heightForks, timeForks := forkid.GatherForks(chainConfig, genesisTime)
return eth.CurrentENREntryFromForks(heightForks, timeForks, *genesisHash, 0, 0), nil
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/sentry/sentry/eth_handshake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import (
func TestCheckPeerStatusCompatibility(t *testing.T) {
var version uint = direct.ETH66
networkID := params.MainnetChainConfig.ChainID.Uint64()
heightForks, timeForks := forkid.GatherForks(params.MainnetChainConfig, 0 /* genesisTime */)
goodReply := eth.StatusPacket{
ProtocolVersion: uint32(version),
NetworkID: networkID,
TD: big.NewInt(0),
Head: libcommon.Hash{},
Genesis: params.MainnetGenesisHash,
ForkID: forkid.NewID(params.MainnetChainConfig, params.MainnetGenesisHash, 0, 0),
ForkID: forkid.NewIDFromForks(heightForks, timeForks, params.MainnetGenesisHash, 0, 0),
}
heightForks, timeForks := forkid.GatherForks(params.MainnetChainConfig)
status := proto_sentry.StatusData{
NetworkId: networkID,
TotalDifficulty: gointerfaces.ConvertUint256IntToH256(new(uint256.Int)),
Expand Down
2 changes: 1 addition & 1 deletion cmd/sentry/sentry/sentry_grpc_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func testSentryServer(db kv.Getter, genesis *types.Genesis, genesisHash libcommo

headTd256 := new(uint256.Int)
headTd256.SetFromBig(headTd)
heightForks, timeForks := forkid.GatherForks(genesis.Config)
heightForks, timeForks := forkid.GatherForks(genesis.Config, genesis.Timestamp)
s.statusData = &proto_sentry.StatusData{
NetworkId: 1,
TotalDifficulty: gointerfaces.ConvertUint256IntToH256(headTd256),
Expand Down
3 changes: 2 additions & 1 deletion cmd/sentry/sentry/sentry_multi_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ func NewMultiClient(
nodeName string,
chainConfig *chain.Config,
genesisHash libcommon.Hash,
genesisTime uint64,
engine consensus.Engine,
networkID uint64,
sentries []direct.SentryClient,
Expand Down Expand Up @@ -322,7 +323,7 @@ func NewMultiClient(
logger: logger,
}
cs.ChainConfig = chainConfig
cs.heightForks, cs.timeForks = forkid.GatherForks(cs.ChainConfig)
cs.heightForks, cs.timeForks = forkid.GatherForks(cs.ChainConfig, genesisTime)
cs.genesisHash = genesisHash
cs.networkId = networkID
var err error
Expand Down
19 changes: 8 additions & 11 deletions core/forkid/forkid.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,6 @@ type ID struct {
// Filter is a fork id filter to validate a remotely advertised ID.
type Filter func(id ID) error

// NewID calculates the Ethereum fork ID from the chain config, genesis hash, head height and time.
func NewID(config *chain.Config, genesis libcommon.Hash, headHeight, headTime uint64) ID {
heightForks, timeForks := GatherForks(config)
return NewIDFromForks(heightForks, timeForks, genesis, headHeight, headTime)
}

func NewIDFromForks(heightForks, timeForks []uint64, genesis libcommon.Hash, headHeight, headTime uint64) ID {
// Calculate the starting checksum from the genesis hash
hash := crc32.ChecksumIEEE(genesis[:])
Expand Down Expand Up @@ -104,9 +98,9 @@ func NewFilterFromForks(heightForks, timeForks []uint64, genesis libcommon.Hash,
}

// NewStaticFilter creates a filter at block zero.
func NewStaticFilter(config *chain.Config, genesis libcommon.Hash) Filter {
heightForks, timeForks := GatherForks(config)
return newFilter(heightForks, timeForks, genesis, 0, 0)
func NewStaticFilter(config *chain.Config, genesisHash libcommon.Hash, genesisTime uint64) Filter {
heightForks, timeForks := GatherForks(config, genesisTime)
return newFilter(heightForks, timeForks, genesisHash, 0 /* headHeight */, genesisTime)
}

// Simple heuristic returning true if the value is a Unix time after 2 Dec 2022.
Expand Down Expand Up @@ -215,7 +209,7 @@ func checksumToBytes(hash uint32) [4]byte {
}

// GatherForks gathers all the known forks and creates a sorted list out of them.
func GatherForks(config *chain.Config) (heightForks []uint64, timeForks []uint64) {
func GatherForks(config *chain.Config, genesisTime uint64) (heightForks []uint64, timeForks []uint64) {
// Gather all the fork block numbers via reflection
kind := reflect.TypeOf(chain.Config{})
conf := reflect.ValueOf(config).Elem()
Expand All @@ -237,7 +231,10 @@ func GatherForks(config *chain.Config) (heightForks []uint64, timeForks []uint64
rule := conf.Field(i).Interface().(*big.Int)
if rule != nil {
if time {
timeForks = append(timeForks, rule.Uint64())
t := rule.Uint64()
if t > genesisTime {
timeForks = append(timeForks, t)
}
} else {
heightForks = append(heightForks, rule.Uint64())
}
Expand Down
5 changes: 3 additions & 2 deletions core/forkid/forkid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ func TestCreation(t *testing.T) {
}
for i, tt := range tests {
for j, ttt := range tt.cases {
if have := NewID(tt.config, tt.genesis, ttt.head, ttt.time); have != ttt.want {
heightForks, timeForks := GatherForks(tt.config, 0 /* genesisTime */)
if have := NewIDFromForks(heightForks, timeForks, tt.genesis, ttt.head, ttt.time); have != ttt.want {
t.Errorf("test %d, case %d: fork ID mismatch: have %x, want %x", i, j, have, ttt.want)
}
}
Expand Down Expand Up @@ -222,7 +223,7 @@ func TestValidation(t *testing.T) {
// fork) at block 7279999, before Petersburg. Local is incompatible.
{7279999, ID{Hash: checksumToBytes(0xa00bc324), Next: 7279999}, ErrLocalIncompatibleOrStale},
}
heightForks, timeForks := GatherForks(params.MainnetChainConfig)
heightForks, timeForks := GatherForks(params.MainnetChainConfig, 0 /* genesisTime */)
for i, tt := range tests {
filter := newFilter(heightForks, timeForks, params.MainnetGenesisHash, tt.head, 0)
if err := filter(tt.id); err != tt.err {
Expand Down
1 change: 1 addition & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere
stack.Config().NodeName(),
chainConfig,
genesis.Hash(),
genesis.Time(),
backend.engine,
backend.config.NetworkID,
sentries,
Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/erigon_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (api *ErigonImpl) Forks(ctx context.Context) (Forks, error) {
if err != nil {
return Forks{}, err
}
heightForks, timeForks := forkid.GatherForks(chainConfig)
heightForks, timeForks := forkid.GatherForks(chainConfig, genesis.Time())

return Forks{genesis.Hash(), heightForks, timeForks}, nil
}
Expand Down
1 change: 1 addition & 0 deletions turbo/stages/mock/mock_sentry.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK
"mock",
mock.ChainConfig,
mock.Genesis.Hash(),
mock.Genesis.Time(),
mock.Engine,
networkID,
sentries,
Expand Down

0 comments on commit c57850b

Please sign in to comment.