github.com/ethereum/go-ethereum@v1.16.1/beacon/blsync/client.go (about) 1 // Copyright 2024 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package blsync 18 19 import ( 20 "github.com/ethereum/go-ethereum/beacon/light" 21 "github.com/ethereum/go-ethereum/beacon/light/api" 22 "github.com/ethereum/go-ethereum/beacon/light/request" 23 "github.com/ethereum/go-ethereum/beacon/light/sync" 24 "github.com/ethereum/go-ethereum/beacon/params" 25 "github.com/ethereum/go-ethereum/beacon/types" 26 "github.com/ethereum/go-ethereum/common" 27 "github.com/ethereum/go-ethereum/common/mclock" 28 "github.com/ethereum/go-ethereum/ethdb/memorydb" 29 "github.com/ethereum/go-ethereum/event" 30 "github.com/ethereum/go-ethereum/log" 31 "github.com/ethereum/go-ethereum/rpc" 32 ) 33 34 type Client struct { 35 urls []string 36 customHeader map[string]string 37 config *params.ClientConfig 38 scheduler *request.Scheduler 39 blockSync *beaconBlockSync 40 engineRPC *rpc.Client 41 42 chainHeadSub event.Subscription 43 engineClient *engineClient 44 } 45 46 func NewClient(config params.ClientConfig) *Client { 47 // create data structures 48 var ( 49 db = memorydb.New() 50 committeeChain = light.NewCommitteeChain(db, &config.ChainConfig, config.Threshold, !config.NoFilter) 51 headTracker = light.NewHeadTracker(committeeChain, config.Threshold, func(checkpoint common.Hash) { 52 if saved, err := config.SaveCheckpointToFile(checkpoint); saved { 53 log.Debug("Saved beacon checkpoint", "file", config.CheckpointFile, "checkpoint", checkpoint) 54 } else if err != nil { 55 log.Error("Failed to save beacon checkpoint", "file", config.CheckpointFile, "checkpoint", checkpoint, "error", err) 56 } 57 }) 58 ) 59 headSync := sync.NewHeadSync(headTracker, committeeChain) 60 61 // set up scheduler and sync modules 62 scheduler := request.NewScheduler() 63 checkpointInit := sync.NewCheckpointInit(committeeChain, config.Checkpoint) 64 forwardSync := sync.NewForwardUpdateSync(committeeChain) 65 beaconBlockSync := newBeaconBlockSync(headTracker) 66 scheduler.RegisterTarget(headTracker) 67 scheduler.RegisterTarget(committeeChain) 68 scheduler.RegisterModule(checkpointInit, "checkpointInit") 69 scheduler.RegisterModule(forwardSync, "forwardSync") 70 scheduler.RegisterModule(headSync, "headSync") 71 scheduler.RegisterModule(beaconBlockSync, "beaconBlockSync") 72 73 return &Client{ 74 scheduler: scheduler, 75 urls: config.Apis, 76 customHeader: config.CustomHeader, 77 config: &config, 78 blockSync: beaconBlockSync, 79 } 80 } 81 82 func (c *Client) SetEngineRPC(engine *rpc.Client) { 83 c.engineRPC = engine 84 } 85 86 func (c *Client) Start() error { 87 headCh := make(chan types.ChainHeadEvent, 16) 88 c.chainHeadSub = c.blockSync.SubscribeChainHead(headCh) 89 c.engineClient = startEngineClient(c.config, c.engineRPC, headCh) 90 91 c.scheduler.Start() 92 for _, url := range c.urls { 93 beaconApi := api.NewBeaconLightApi(url, c.customHeader) 94 c.scheduler.RegisterServer(request.NewServer(api.NewApiServer(beaconApi), &mclock.System{})) 95 } 96 return nil 97 } 98 99 func (c *Client) Stop() error { 100 c.engineClient.stop() 101 c.chainHeadSub.Unsubscribe() 102 c.scheduler.Stop() 103 return nil 104 }