Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added persistence in LightClient #6056

Merged
merged 1 commit into from
Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 39 additions & 6 deletions cmd/lightclient/lightclient/lightclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ import (

lru "github.com/hashicorp/golang-lru"
"github.com/ledgerwatch/erigon-lib/gointerfaces/remote"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/cl/clparams"
"github.com/ledgerwatch/erigon/cl/cltypes"
"github.com/ledgerwatch/erigon/cl/rpc/consensusrpc"
"github.com/ledgerwatch/erigon/cl/utils"
"github.com/ledgerwatch/erigon/core/rawdb"
"github.com/ledgerwatch/log/v3"
)

Expand All @@ -39,13 +41,13 @@ type LightClient struct {
verbose bool
highestSeen uint64 // Highest ETH1 block seen
recentHashesCache *lru.Cache
db kv.RwDB
sentinel consensusrpc.SentinelClient
execution remote.ETHBACKENDServer
store *LightClientStore
lastValidated *cltypes.LightClientUpdate
}

func NewLightClient(ctx context.Context, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig,
func NewLightClient(ctx context.Context, db kv.RwDB, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig,
execution remote.ETHBACKENDServer, sentinel consensusrpc.SentinelClient,
highestSeen uint64, verbose bool) (*LightClient, error) {
recentHashesCache, err := lru.New(maxRecentHashes)
Expand All @@ -59,6 +61,7 @@ func NewLightClient(ctx context.Context, genesisConfig *clparams.GenesisConfig,
execution: execution,
verbose: verbose,
highestSeen: highestSeen,
db: db,
}, err
}

Expand All @@ -67,6 +70,12 @@ func (l *LightClient) Start() {
log.Error("No trusted setup")
return
}
tx, err := l.db.BeginRw(l.ctx)
if err != nil {
log.Error("Could not open MDBX transaction", "err", err)
return
}
defer tx.Rollback()
logPeers := time.NewTicker(time.Minute)
go l.chainTip.StartLoop()
for {
Expand Down Expand Up @@ -126,18 +135,42 @@ func (l *LightClient) Start() {
}
// log new validated segment
if len(updates) > 0 {
l.lastValidated = updates[len(updates)-1]
lastValidated := updates[len(updates)-1]
// Save to Database
if lastValidated.HasNextSyncCommittee() {
if err := rawdb.WriteLightClientUpdate(tx, lastValidated); err != nil {
log.Warn("Could not write lightclient update to db", "err", err)
}
// Process it as a full LightClientUpdate
} else if lastValidated.IsFinalityUpdate() {
if err := rawdb.WriteLightClientFinalityUpdate(tx, &cltypes.LightClientFinalityUpdate{
AttestedHeader: lastValidated.AttestedHeader,
FinalizedHeader: lastValidated.FinalizedHeader,
FinalityBranch: lastValidated.FinalityBranch,
SyncAggregate: lastValidated.SyncAggregate,
SignatureSlot: lastValidated.SignatureSlot,
}); err != nil {
log.Warn("Could not write finality lightclient update to db", "err", err)
}
} else if err := rawdb.WriteLightClientOptimisticUpdate(tx, &cltypes.LightClientOptimisticUpdate{
AttestedHeader: lastValidated.AttestedHeader,
SyncAggregate: lastValidated.SyncAggregate,
SignatureSlot: lastValidated.SignatureSlot,
}); err != nil {
log.Warn("Could not write optimistic lightclient update to db", "err", err)
}

if l.verbose {
log.Info("[LightClient] Validated Chain Segments",
"elapsed", time.Since(start), "from", updates[0].AttestedHeader.Slot-1,
"to", l.lastValidated.AttestedHeader.Slot)
"to", lastValidated.AttestedHeader.Slot)
}
prev, curr := l.chainTip.GetLastBlocks()
if prev == nil {
continue
}
// Skip if we went out of sync and weird network stuff happen
if prev.Slot != l.lastValidated.AttestedHeader.Slot {
if prev.Slot != lastValidated.AttestedHeader.Slot {
continue
}
// Validate update against block N-1
Expand All @@ -146,7 +179,7 @@ func (l *LightClient) Start() {
log.Warn("[LightClient] Could not retrive body root of block N-1", "err", err)
continue
}
if !bytes.Equal(prevRoot[:], l.lastValidated.AttestedHeader.BodyRoot[:]) {
if !bytes.Equal(prevRoot[:], lastValidated.AttestedHeader.BodyRoot[:]) {
log.Warn("[LightClient] Could validate block N-1")
continue
}
Expand Down
6 changes: 4 additions & 2 deletions cmd/lightclient/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"
"os"

"github.com/ledgerwatch/erigon-lib/kv/memdb"
"github.com/ledgerwatch/log/v3"
"github.com/urfave/cli/v2"

Expand Down Expand Up @@ -50,6 +51,7 @@ func runLightClientNode(cliCtx *cli.Context) error {
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(lcCfg.LogLvl), log.StderrHandler))
log.Info("[LightClient]", "chain", cliCtx.String(flags.LightClientChain.Name))
log.Info("[LightClient] Running lightclient", "cfg", lcCfg)
db := memdb.New()
sentinel, err := service.StartSentinelService(&sentinel.SentinelConfig{
IpAddr: lcCfg.Addr,
Port: int(lcCfg.Port),
Expand All @@ -58,7 +60,7 @@ func runLightClientNode(cliCtx *cli.Context) error {
NetworkConfig: lcCfg.NetworkCfg,
BeaconConfig: lcCfg.BeaconCfg,
NoDiscovery: lcCfg.NoDiscovery,
}, &service.ServerConfig{Network: lcCfg.ServerProtocol, Addr: lcCfg.ServerAddr}, nil)
}, db, &service.ServerConfig{Network: lcCfg.ServerProtocol, Addr: lcCfg.ServerAddr}, nil)
if err != nil {
log.Error("Could not start sentinel", "err", err)
}
Expand All @@ -71,7 +73,7 @@ func runLightClientNode(cliCtx *cli.Context) error {
return err
}
log.Info("Finalized Checkpoint", "Epoch", bs.FinalizedCheckpoint.Epoch)
lc, err := lightclient.NewLightClient(ctx, lcCfg.GenesisCfg, lcCfg.BeaconCfg, nil, sentinel, 0, true)
lc, err := lightclient.NewLightClient(ctx, db, lcCfg.GenesisCfg, lcCfg.BeaconCfg, nil, sentinel, 0, true)
if err != nil {
log.Error("Could not make Lightclient", "err", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/sentinel/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func runSentinelNode(cliCtx *cli.Context) error {
NetworkConfig: lcCfg.NetworkCfg,
BeaconConfig: lcCfg.BeaconCfg,
NoDiscovery: lcCfg.NoDiscovery,
}, &service.ServerConfig{Network: lcCfg.ServerProtocol, Addr: lcCfg.ServerAddr}, nil)
}, nil, &service.ServerConfig{Network: lcCfg.ServerProtocol, Addr: lcCfg.ServerAddr}, nil)
if err != nil {
log.Error("Could not start sentinel", "err", err)
return err
Expand Down
4 changes: 4 additions & 0 deletions cmd/sentinel/sentinel/sentinel.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"net"
"strings"

"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/cl/cltypes"
"github.com/ledgerwatch/erigon/cl/fork"
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication"
Expand All @@ -46,6 +47,7 @@ type Sentinel struct {
cfg *SentinelConfig
peers *peers.Peers
MetadataV2 *cltypes.MetadataV2
db kv.RoDB

discoverConfig discover.Config
pubsub *pubsub.PubSub
Expand Down Expand Up @@ -160,10 +162,12 @@ func (s *Sentinel) pubsubOptions() []pubsub.Option {
func New(
ctx context.Context,
cfg *SentinelConfig,
db kv.RoDB,
) (*Sentinel, error) {
s := &Sentinel{
ctx: ctx,
cfg: cfg,
db: db,
}

// Setup discovery
Expand Down
5 changes: 3 additions & 2 deletions cmd/sentinel/sentinel/service/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net"
"time"

"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/cl/rpc/consensusrpc"
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinel"
"github.com/ledgerwatch/log/v3"
Expand All @@ -19,9 +20,9 @@ type ServerConfig struct {
Addr string
}

func StartSentinelService(cfg *sentinel.SentinelConfig, srvCfg *ServerConfig, creds credentials.TransportCredentials) (consensusrpc.SentinelClient, error) {
func StartSentinelService(cfg *sentinel.SentinelConfig, db kv.RoDB, srvCfg *ServerConfig, creds credentials.TransportCredentials) (consensusrpc.SentinelClient, error) {
ctx := context.Background()
sent, err := sentinel.New(context.Background(), cfg)
sent, err := sentinel.New(context.Background(), cfg, db)
if err != nil {
return nil, err
}
Expand Down
43 changes: 43 additions & 0 deletions core/rawdb/accessors_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
libcommon "github.com/ledgerwatch/erigon-lib/common/cmp"
"github.com/ledgerwatch/erigon-lib/common/dbg"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/cl/cltypes"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/common/dbutils"
"github.com/ledgerwatch/erigon/core/types"
Expand Down Expand Up @@ -1869,3 +1870,45 @@ func ReadVerkleNode(tx kv.RwTx, root common.Hash) (verkle.VerkleNode, error) {
}
return verkle.ParseNode(encoded, 0, root[:])
}

func WriteLightClientUpdate(tx kv.RwTx, update *cltypes.LightClientUpdate) error {
key := make([]byte, 4)
binary.BigEndian.PutUint32(key, uint32(update.SignatureSlot/8192))

encoded, err := update.MarshalSSZ()
if err != nil {
return err
}
return tx.Put(kv.LightClientUpdates, key, encoded)
}

func WriteLightClientFinalityUpdate(tx kv.RwTx, update *cltypes.LightClientFinalityUpdate) error {
encoded, err := update.MarshalSSZ()
if err != nil {
return err
}
return tx.Put(kv.LightClient, kv.LightClientFinalityUpdate, encoded)
}

func WriteLightClientOptimisticUpdate(tx kv.RwTx, update *cltypes.LightClientOptimisticUpdate) error {
encoded, err := update.MarshalSSZ()
if err != nil {
return err
}
return tx.Put(kv.LightClient, kv.LightClientOptimisticUpdate, encoded)
}

func ReadLightClientUpdate(tx kv.RwTx, period uint32) (*cltypes.LightClientUpdate, error) {
key := make([]byte, 4)
binary.BigEndian.PutUint32(key, period)

encoded, err := tx.GetOne(kv.LightClientUpdates, key)
if err != nil {
return nil, err
}
update := &cltypes.LightClientUpdate{}
if err = update.UnmarshalSSZ(encoded); err != nil {
return nil, err
}
return update, nil
}
5 changes: 3 additions & 2 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
prototypes "github.com/ledgerwatch/erigon-lib/gointerfaces/types"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/kv/kvcache"
"github.com/ledgerwatch/erigon-lib/kv/memdb"
"github.com/ledgerwatch/erigon-lib/kv/remotedbserver"
libstate "github.com/ledgerwatch/erigon-lib/state"
txpool2 "github.com/ledgerwatch/erigon-lib/txpool"
Expand Down Expand Up @@ -509,12 +510,12 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere
GenesisConfig: genesisCfg,
NetworkConfig: networkCfg,
BeaconConfig: beaconCfg,
}, &service.ServerConfig{Network: "tcp", Addr: fmt.Sprintf("%s:%d", config.SentinelAddr, config.SentinelPort)}, creds)
}, chainKv, &service.ServerConfig{Network: "tcp", Addr: fmt.Sprintf("%s:%d", config.SentinelAddr, config.SentinelPort)}, creds)
if err != nil {
return nil, err
}

lc, err := lightclient.NewLightClient(ctx, genesisCfg, beaconCfg, ethBackendRPC, client, currentBlockNumber, false)
lc, err := lightclient.NewLightClient(ctx, memdb.New(), genesisCfg, beaconCfg, ethBackendRPC, client, currentBlockNumber, false)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/ledgerwatch/erigon
go 1.18

require (
github.com/ledgerwatch/erigon-lib v0.0.0-20221114105902-10e842853bb4
github.com/ledgerwatch/erigon-lib v0.0.0-20221115124415-2e09a741f07b
github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20221026024915-f6abfe5c120e
github.com/ledgerwatch/log/v3 v3.6.0
github.com/ledgerwatch/secp256k1 v1.0.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -558,8 +558,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3PYPwICLl+/9oulQauOuETfgFvhBDffs0=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
github.com/ledgerwatch/erigon-lib v0.0.0-20221114105902-10e842853bb4 h1:lUsHWLgwyCV+9G5/g6pML/bwWFwWsEz72PuqrUfm6kw=
github.com/ledgerwatch/erigon-lib v0.0.0-20221114105902-10e842853bb4/go.mod h1:NJybmPjoS9/TbvwTn3bJww3lrxxc7i8Ny+zq2EmDIpg=
github.com/ledgerwatch/erigon-lib v0.0.0-20221115124415-2e09a741f07b h1:LN3EjK0/Iw4o0b9trWFei96GVNeGmGMXJdYdB7m1N2U=
github.com/ledgerwatch/erigon-lib v0.0.0-20221115124415-2e09a741f07b/go.mod h1:NJybmPjoS9/TbvwTn3bJww3lrxxc7i8Ny+zq2EmDIpg=
github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20221026024915-f6abfe5c120e h1:VRfm6Ylg0WTnjzFs7mU5qOyZGZTPhnlpwtMPrcD7n+U=
github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20221026024915-f6abfe5c120e/go.mod h1:3AuPxZc85jkehh/HA9h8gabv5MSi3kb/ddtzBsTVJFo=
github.com/ledgerwatch/log/v3 v3.6.0 h1:JBUSK1epPyutUrz7KYDTcJtQLEHnehECRpKbM1ugy5M=
Expand Down