Skip to content

Commit

Permalink
Added custom chain flags to embedded consensus lightclient (erigontec…
Browse files Browse the repository at this point in the history
  • Loading branch information
Giulio2002 authored Jan 23, 2023
1 parent aa5b79f commit 635fe0c
Show file tree
Hide file tree
Showing 16 changed files with 171 additions and 70 deletions.
91 changes: 66 additions & 25 deletions cl/clparams/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ import (
"fmt"
"math"
"math/big"
"os"
"time"

libcommon "github.com/ledgerwatch/erigon-lib/common"
"gopkg.in/yaml.v2"

"github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils"
"github.com/ledgerwatch/erigon/cl/utils"
"github.com/ledgerwatch/erigon/params/networkname"
)
Expand Down Expand Up @@ -189,7 +192,7 @@ var GenesisConfigs map[NetworkType]GenesisConfig = map[NetworkType]GenesisConfig
// Trusted checkpoint sync endpoints: https://eth-clients.github.io/checkpoint-sync-endpoints/
var CheckpointSyncEndpoints = map[NetworkType][]string{
MainnetNetwork: {
"https://beaconstate.ethstaker.cc/eth/v2/debug/beacon/states/finalized",
"https://beaconstate.ethstaker.cc",
"https://sync.invis.tools/eth/v2/debug/beacon/states/finalized",
"https://mainnet-checkpoint-sync.attestant.io/eth/v2/debug/beacon/states/finalized",
"https://mainnet.checkpoint.sigp.io/eth/v2/debug/beacon/states/finalized",
Expand Down Expand Up @@ -330,14 +333,14 @@ type BeaconChainConfig struct {
SlashingProtectionPruningEpochs uint64 // SlashingProtectionPruningEpochs defines a period after which all prior epochs are pruned in the validator database.

// Fork-related values.
GenesisForkVersion []byte `yaml:"GENESIS_FORK_VERSION" spec:"true"` // GenesisForkVersion is used to track fork version between state transitions.
AltairForkVersion []byte `yaml:"ALTAIR_FORK_VERSION" spec:"true"` // AltairForkVersion is used to represent the fork version for altair.
GenesisForkVersion uint32 `yaml:"GENESIS_FORK_VERSION" spec:"true"` // GenesisForkVersion is used to track fork version between state transitions.
AltairForkVersion uint32 `yaml:"ALTAIR_FORK_VERSION" spec:"true"` // AltairForkVersion is used to represent the fork version for altair.
AltairForkEpoch uint64 `yaml:"ALTAIR_FORK_EPOCH" spec:"true"` // AltairForkEpoch is used to represent the assigned fork epoch for altair.
BellatrixForkVersion []byte `yaml:"BELLATRIX_FORK_VERSION" spec:"true"` // BellatrixForkVersion is used to represent the fork version for bellatrix.
BellatrixForkVersion uint32 `yaml:"BELLATRIX_FORK_VERSION" spec:"true"` // BellatrixForkVersion is used to represent the fork version for bellatrix.
BellatrixForkEpoch uint64 `yaml:"BELLATRIX_FORK_EPOCH" spec:"true"` // BellatrixForkEpoch is used to represent the assigned fork epoch for bellatrix.
ShardingForkVersion []byte `yaml:"SHARDING_FORK_VERSION" spec:"true"` // ShardingForkVersion is used to represent the fork version for sharding.
ShardingForkVersion uint32 `yaml:"SHARDING_FORK_VERSION" spec:"true"` // ShardingForkVersion is used to represent the fork version for sharding.
ShardingForkEpoch uint64 `yaml:"SHARDING_FORK_EPOCH" spec:"true"` // ShardingForkEpoch is used to represent the assigned fork epoch for sharding.
CapellaForkVersion []byte `yaml:"CAPELLA_FORK_VERSION" spec:"true"` // CapellaForkVersion is used to represent the fork version for capella.
CapellaForkVersion uint32 `yaml:"CAPELLA_FORK_VERSION" spec:"true"` // CapellaForkVersion is used to represent the fork version for capella.
CapellaForkEpoch uint64 `yaml:"CAPELLA_FORK_EPOCH" spec:"true"` // CapellaForkEpoch is used to represent the assigned fork epoch for capella.

ForkVersionSchedule map[[VersionLength]byte]uint64 // Schedule of fork epochs by version.
Expand Down Expand Up @@ -395,6 +398,18 @@ type BeaconChainConfig struct {
MaxBuilderEpochMissedSlots uint64 // MaxBuilderEpochMissedSlots is defines the number of total skip slot (per epoch rolling windows) to fallback from using relay/builder to local execution engine for block construction.
}

func (b *BeaconChainConfig) GetCurrentStateVersion(epoch uint64) StateVersion {
forkEpochList := []uint64{b.AltairForkEpoch, b.BellatrixForkEpoch, b.CapellaForkEpoch}
stateVersion := Phase0Version
for _, forkEpoch := range forkEpochList {
if forkEpoch > epoch {
return stateVersion
}
stateVersion++
}
return stateVersion
}

// InitializeForkSchedule initializes the schedules forks baked into the config.
func (b *BeaconChainConfig) InitializeForkSchedule() {
b.ForkVersionSchedule = configForkSchedule(b)
Expand All @@ -408,17 +423,19 @@ func toBytes4(in []byte) (ret [4]byte) {

func configForkSchedule(b *BeaconChainConfig) map[[VersionLength]byte]uint64 {
fvs := map[[VersionLength]byte]uint64{}
fvs[toBytes4(b.GenesisForkVersion)] = 0
fvs[toBytes4(b.AltairForkVersion)] = b.AltairForkEpoch
fvs[toBytes4(b.BellatrixForkVersion)] = b.BellatrixForkEpoch
fvs[utils.Uint32ToBytes4(b.GenesisForkVersion)] = 0
fvs[utils.Uint32ToBytes4(b.AltairForkVersion)] = b.AltairForkEpoch
fvs[utils.Uint32ToBytes4(b.BellatrixForkVersion)] = b.BellatrixForkEpoch
fvs[utils.Uint32ToBytes4(b.CapellaForkVersion)] = b.CapellaForkEpoch
return fvs
}

func configForkNames(b *BeaconChainConfig) map[[VersionLength]byte]string {
fvn := map[[VersionLength]byte]string{}
fvn[toBytes4(b.GenesisForkVersion)] = "phase0"
fvn[toBytes4(b.AltairForkVersion)] = "altair"
fvn[toBytes4(b.BellatrixForkVersion)] = "bellatrix"
fvn[utils.Uint32ToBytes4(b.GenesisForkVersion)] = "phase0"
fvn[utils.Uint32ToBytes4(b.AltairForkVersion)] = "altair"
fvn[utils.Uint32ToBytes4(b.BellatrixForkVersion)] = "bellatrix"
fvn[utils.Uint32ToBytes4(b.CapellaForkVersion)] = "capella"
return fvn
}

Expand Down Expand Up @@ -555,14 +572,14 @@ var MainnetBeaconConfig BeaconChainConfig = BeaconChainConfig{
SafetyDecay: 10,

// Fork related values.
GenesisForkVersion: []byte{0, 0, 0, 0},
AltairForkVersion: []byte{1, 0, 0, 0},
GenesisForkVersion: 0,
AltairForkVersion: 0x01000000,
AltairForkEpoch: 74240,
BellatrixForkVersion: []byte{2, 0, 0, 0},
BellatrixForkVersion: 0x02000000,
BellatrixForkEpoch: 144869,
CapellaForkVersion: []byte{3, 0, 0, 0},
CapellaForkVersion: 0x03000000,
CapellaForkEpoch: math.MaxUint64,
ShardingForkVersion: []byte{4, 0, 0, 0},
ShardingForkVersion: 0x04000000,
ShardingForkEpoch: math.MaxUint64,

// New values introduced in Altair hard fork 1.
Expand Down Expand Up @@ -618,20 +635,44 @@ func mainnetConfig() BeaconChainConfig {
return cfg
}

func CustomConfig(configFile string) (BeaconChainConfig, error) {
cfg := MainnetBeaconConfig
b, err := os.ReadFile(configFile) // just pass the file name
if err != nil {
return BeaconChainConfig{}, nil
}
err = yaml.Unmarshal(b, &cfg)
cfg.InitializeForkSchedule()
return cfg, err
}

func ParseGenesisSSZToGenesisConfig(genesisFile string) (GenesisConfig, error) {
cfg := GenesisConfig{}
b, err := os.ReadFile(genesisFile) // just pass the file name
if err != nil {
return GenesisConfig{}, nil
}
// Read first 2 fields of SSZ
cfg.GenesisTime = ssz_utils.UnmarshalUint64SSZ(b)
copy(cfg.GenesisValidatorRoot[:], b[8:])
return cfg, nil
}

func sepoliaConfig() BeaconChainConfig {
cfg := MainnetBeaconConfig
cfg.MinGenesisTime = 1655647200
cfg.GenesisDelay = 86400
cfg.MinGenesisActiveValidatorCount = 1300
cfg.ConfigName = "sepolia"
cfg.GenesisForkVersion = []byte{0x90, 0x00, 0x00, 0x69}

cfg.GenesisForkVersion = 0x90000069
cfg.SecondsPerETH1Block = 14
cfg.DepositChainID = uint64(SepoliaNetwork)
cfg.DepositNetworkID = uint64(SepoliaNetwork)
cfg.AltairForkEpoch = 50
cfg.AltairForkVersion = []byte{0x90, 0x00, 0x00, 0x70}
cfg.AltairForkVersion = 0x90000070
cfg.BellatrixForkEpoch = 100
cfg.BellatrixForkVersion = []byte{0x90, 0x00, 0x00, 0x71}
cfg.BellatrixForkVersion = 0x90000071
cfg.TerminalTotalDifficulty = "17000000000000000"
cfg.DepositContractAddress = "0x7f02C3E3c98b133055B8B348B2Ac625669Ed295D"
cfg.InitializeForkSchedule()
Expand All @@ -643,16 +684,16 @@ func goerliConfig() BeaconChainConfig {
cfg.MinGenesisTime = 1614588812
cfg.GenesisDelay = 1919188
cfg.ConfigName = "prater"
cfg.GenesisForkVersion = []byte{0x00, 0x00, 0x10, 0x20}
cfg.GenesisForkVersion = 0x00001020
cfg.SecondsPerETH1Block = 14
cfg.DepositChainID = uint64(GoerliNetwork)
cfg.DepositNetworkID = uint64(GoerliNetwork)
cfg.AltairForkEpoch = 36660
cfg.AltairForkVersion = []byte{0x1, 0x0, 0x10, 0x20}
cfg.CapellaForkVersion = []byte{0x3, 0x0, 0x10, 0x20}
cfg.ShardingForkVersion = []byte{0x4, 0x0, 0x10, 0x20}
cfg.AltairForkVersion = 0x1001020
cfg.CapellaForkVersion = 0x03001020
cfg.ShardingForkVersion = 0x40001020
cfg.BellatrixForkEpoch = 112260
cfg.BellatrixForkVersion = []byte{0x2, 0x0, 0x10, 0x20}
cfg.BellatrixForkVersion = 0x02001020
cfg.TerminalTotalDifficulty = "10790000"
cfg.DepositContractAddress = "0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b"
cfg.InitializeForkSchedule()
Expand Down
1 change: 1 addition & 0 deletions cl/cltypes/eth1_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ func (b *Eth1Block) DecodeSSZ(buf []byte, version clparams.StateVersion) error {
}
b.Body.Withdrawals = make([]*types.Withdrawal, withdrawalsCount)
for i := range b.Body.Withdrawals {
b.Body.Withdrawals[i] = new(types.Withdrawal)
b.Body.Withdrawals[i].DecodeSSZ(buf[(*withdrawalOffset)+uint32(i)*44:])
}
// Cache withdrawal root.
Expand Down
4 changes: 2 additions & 2 deletions cl/fork/fork.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func ComputeForkDigest(

currentEpoch := utils.GetCurrentEpoch(genesisConfig.GenesisTime, beaconConfig.SecondsPerSlot, beaconConfig.SlotsPerEpoch)
// Retrieve current fork version.
currentForkVersion := utils.BytesToBytes4(beaconConfig.GenesisForkVersion)
currentForkVersion := utils.Uint32ToBytes4(beaconConfig.GenesisForkVersion)
for _, fork := range forkList(beaconConfig.ForkVersionSchedule) {
if currentEpoch >= fork.epoch {
currentForkVersion = fork.version
Expand Down Expand Up @@ -116,7 +116,7 @@ func GetLastFork(
) [4]byte {
currentEpoch := utils.GetCurrentEpoch(genesisConfig.GenesisTime, beaconConfig.SecondsPerSlot, beaconConfig.SlotsPerEpoch)
// Retrieve current fork version.
currentFork := utils.BytesToBytes4(beaconConfig.GenesisForkVersion)
currentFork := utils.Uint32ToBytes4(beaconConfig.GenesisForkVersion)
for _, fork := range forkList(beaconConfig.ForkVersionSchedule) {
if currentEpoch >= fork.epoch {
currentFork = fork.version
Expand Down
3 changes: 1 addition & 2 deletions cl/fork/fork_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ func TestMainnetFork(t *testing.T) {
genesisCfg := clparams.GenesisConfigs[clparams.MainnetNetwork]
digest, err := ComputeForkDigest(&beaconCfg, &genesisCfg)
require.NoError(t, err)
full, err := ComputeForkId(&beaconCfg, &genesisCfg)
_, err = ComputeForkId(&beaconCfg, &genesisCfg)
require.NoError(t, err)
require.Equal(t, digest, [4]byte{74, 38, 197, 139})
require.Equal(t, full, []byte{0x4a, 0x26, 0xc5, 0x8b, 0x2, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})
}
56 changes: 31 additions & 25 deletions cl/rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,36 +204,39 @@ func (b *BeaconRpcP2P) sendBlocksRequest(topic string, reqData []byte, count uin
if respForkDigest == 0 {
return nil, fmt.Errorf("null fork digest")
}
var phase0ForkDigest, altairForkDigest, bellatrixForkDigest [4]byte
if b.beaconConfig.GenesisForkVersion != nil {
phase0ForkDigest, err = fork.ComputeForkDigestForVersion(
utils.BytesToBytes4(b.beaconConfig.GenesisForkVersion),
b.genesisConfig.GenesisValidatorRoot,
)
if err != nil {
return nil, err
}
var phase0ForkDigest, altairForkDigest, bellatrixForkDigest, capellaForkDigest [4]byte
phase0ForkDigest, err = fork.ComputeForkDigestForVersion(
utils.Uint32ToBytes4(b.beaconConfig.GenesisForkVersion),
b.genesisConfig.GenesisValidatorRoot,
)
if err != nil {
return nil, err
}

if b.beaconConfig.AltairForkVersion != nil {
altairForkDigest, err = fork.ComputeForkDigestForVersion(
utils.BytesToBytes4(b.beaconConfig.AltairForkVersion),
b.genesisConfig.GenesisValidatorRoot,
)
if err != nil {
return nil, err
}
altairForkDigest, err = fork.ComputeForkDigestForVersion(
utils.Uint32ToBytes4(b.beaconConfig.AltairForkVersion),
b.genesisConfig.GenesisValidatorRoot,
)
if err != nil {
return nil, err
}

if b.beaconConfig.BellatrixForkVersion != nil {
bellatrixForkDigest, err = fork.ComputeForkDigestForVersion(
utils.BytesToBytes4(b.beaconConfig.BellatrixForkVersion),
b.genesisConfig.GenesisValidatorRoot,
)
if err != nil {
return nil, err
}
bellatrixForkDigest, err = fork.ComputeForkDigestForVersion(
utils.Uint32ToBytes4(b.beaconConfig.BellatrixForkVersion),
b.genesisConfig.GenesisValidatorRoot,
)
if err != nil {
return nil, err
}

capellaForkDigest, err = fork.ComputeForkDigestForVersion(
utils.Uint32ToBytes4(b.beaconConfig.CapellaForkVersion),
b.genesisConfig.GenesisValidatorRoot,
)
if err != nil {
return nil, err
}

responseChunk := &cltypes.SignedBeaconBlock{}

switch respForkDigest {
Expand All @@ -243,6 +246,9 @@ func (b *BeaconRpcP2P) sendBlocksRequest(topic string, reqData []byte, count uin
err = responseChunk.DecodeSSZWithVersion(raw, int(clparams.AltairVersion))
case utils.Bytes4ToUint32(bellatrixForkDigest):
err = responseChunk.DecodeSSZWithVersion(raw, int(clparams.BellatrixVersion))
case utils.Bytes4ToUint32(capellaForkDigest):
err = responseChunk.DecodeSSZWithVersion(raw, int(clparams.CapellaVersion))

default:
return nil, fmt.Errorf("received invalid fork digest")
}
Expand Down
8 changes: 6 additions & 2 deletions cmd/erigon-cl/core/checkpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import (
"net/http"

"github.com/ledgerwatch/erigon/cl/clparams"
"github.com/ledgerwatch/erigon/cl/utils"
"github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state"
"github.com/ledgerwatch/log/v3"
)

func RetrieveBeaconState(ctx context.Context, uri string) (*state.BeaconState, error) {
func RetrieveBeaconState(ctx context.Context, beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig, uri string) (*state.BeaconState, error) {
log.Info("[Checkpoint Sync] Requesting beacon state", "uri", uri)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
if err != nil {
Expand All @@ -37,8 +38,11 @@ func RetrieveBeaconState(ctx context.Context, uri string) (*state.BeaconState, e
return nil, fmt.Errorf("checkpoint sync failed %s", err)
}

epoch := utils.GetCurrentEpoch(genesisConfig.GenesisTime, beaconConfig.SecondsPerSlot, beaconConfig.SlotsPerEpoch)

beaconState := &state.BeaconState{}
err = beaconState.DecodeSSZWithVersion(marshaled, int(clparams.BellatrixVersion))
fmt.Println(int(beaconConfig.GetCurrentStateVersion(epoch)))
err = beaconState.DecodeSSZWithVersion(marshaled, int(beaconConfig.GetCurrentStateVersion(epoch)))
if err != nil {
return nil, fmt.Errorf("checkpoint sync failed %s", err)
}
Expand Down
7 changes: 4 additions & 3 deletions cmd/erigon-cl/core/state/ssz.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,13 +354,14 @@ func (b *BeaconState) DecodeSSZWithVersion(buf []byte, version int) error {
if b.version <= clparams.AltairVersion {
return nil
}
if len(buf) <= int(executionPayloadOffset) {
return ssz_utils.ErrLowBufferSize
}
endOffset = uint32(len(buf))
if historicalSummariesOffset != 0 {
endOffset = historicalSummariesOffset
}

if len(buf) < int(endOffset) || executionPayloadOffset > endOffset {
return ssz_utils.ErrLowBufferSize
}
b.latestExecutionPayloadHeader = new(types.Header)
if err := b.latestExecutionPayloadHeader.DecodeSSZ(buf[executionPayloadOffset:endOffset], b.version); err != nil {
return err
Expand Down
7 changes: 4 additions & 3 deletions cmd/erigon-cl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
sentinelrpc "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/kv/mdbx"
"github.com/ledgerwatch/erigon/cl/clparams"
"github.com/ledgerwatch/erigon/cl/cltypes"
"github.com/ledgerwatch/erigon/cl/fork"
"github.com/ledgerwatch/erigon/cl/rpc"
Expand Down Expand Up @@ -58,7 +59,7 @@ func runConsensusLayerNode(cliCtx *cli.Context) error {
return err
}
// Fetch the checkpoint state.
cpState, err := getCheckpointState(ctx, db, cfg.CheckpointUri)
cpState, err := getCheckpointState(ctx, db, cfg.BeaconCfg, cfg.GenesisCfg, cfg.CheckpointUri)
if err != nil {
log.Error("Could not get checkpoint", "err", err)
return err
Expand Down Expand Up @@ -137,8 +138,8 @@ func startSentinel(cliCtx *cli.Context, cfg lcCli.ConsensusClientCliCfg, beaconS
return s, nil
}

func getCheckpointState(ctx context.Context, db kv.RwDB, uri string) (*state.BeaconState, error) {
state, err := core.RetrieveBeaconState(ctx, uri)
func getCheckpointState(ctx context.Context, db kv.RwDB, beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig, uri string) (*state.BeaconState, error) {
state, err := core.RetrieveBeaconState(ctx, beaconConfig, genesisConfig, uri)
if err != nil {
log.Error("[Checkpoint Sync] Failed", "reason", err)
return nil, err
Expand Down
2 changes: 0 additions & 2 deletions cmd/erigon-cl/network/backward_beacon_downloader.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package network

import (
"fmt"
"sync"

libcommon "github.com/ledgerwatch/erigon-lib/common"
Expand Down Expand Up @@ -88,7 +87,6 @@ func (b *BackwardBeaconDownloader) RequestMore() {
}
responses, err := b.rpc.SendBeaconBlocksByRangeReq(start, count)
if err != nil {
fmt.Println(err)
return
}
// Import new blocks, order is forward so reverse the whole packet
Expand Down
3 changes: 1 addition & 2 deletions cmd/lightclient/lightclient/checkpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ func (l *LightClient) BootstrapCheckpoint(ctx context.Context, finalized [32]byt
for b == nil {
b, err = l.rpc.SendLightClientBootstrapReqV1(finalized)
if err != nil {
log.Trace("[Checkpoint Sync] could not retrieve bootstrap", "err", err)
return err
log.Debug("[Checkpoint Sync] could not retrieve bootstrap", "err", err)
}
}

Expand Down
Loading

0 comments on commit 635fe0c

Please sign in to comment.