github.com/ethereum/go-ethereum@v1.16.1/cmd/blsync/main.go (about) 1 // Copyright 2024 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU 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 // go-ethereum 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 General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "context" 21 "fmt" 22 "os" 23 "slices" 24 25 "github.com/ethereum/go-ethereum/beacon/blsync" 26 "github.com/ethereum/go-ethereum/cmd/utils" 27 "github.com/ethereum/go-ethereum/internal/debug" 28 "github.com/ethereum/go-ethereum/internal/flags" 29 "github.com/ethereum/go-ethereum/log" 30 "github.com/ethereum/go-ethereum/node" 31 "github.com/ethereum/go-ethereum/rpc" 32 "github.com/urfave/cli/v2" 33 ) 34 35 func main() { 36 app := flags.NewApp("beacon light syncer tool") 37 app.Flags = slices.Concat([]cli.Flag{ 38 utils.BeaconApiFlag, 39 utils.BeaconApiHeaderFlag, 40 utils.BeaconThresholdFlag, 41 utils.BeaconNoFilterFlag, 42 utils.BeaconConfigFlag, 43 utils.BeaconGenesisRootFlag, 44 utils.BeaconGenesisTimeFlag, 45 utils.BeaconCheckpointFlag, 46 utils.BeaconCheckpointFileFlag, 47 //TODO datadir for optional permanent database 48 utils.MainnetFlag, 49 utils.SepoliaFlag, 50 utils.HoleskyFlag, 51 utils.HoodiFlag, 52 utils.BlsyncApiFlag, 53 utils.BlsyncJWTSecretFlag, 54 }, 55 debug.Flags, 56 ) 57 app.Before = func(ctx *cli.Context) error { 58 flags.MigrateGlobalFlags(ctx) 59 return debug.Setup(ctx) 60 } 61 app.After = func(ctx *cli.Context) error { 62 debug.Exit() 63 return nil 64 } 65 app.Action = sync 66 67 if err := app.Run(os.Args); err != nil { 68 fmt.Fprintln(os.Stderr, err) 69 os.Exit(1) 70 } 71 } 72 73 func sync(ctx *cli.Context) error { 74 // set up blsync 75 client := blsync.NewClient(utils.MakeBeaconLightConfig(ctx)) 76 client.SetEngineRPC(makeRPCClient(ctx)) 77 client.Start() 78 79 // run until stopped 80 <-ctx.Done() 81 client.Stop() 82 return nil 83 } 84 85 func makeRPCClient(ctx *cli.Context) *rpc.Client { 86 if !ctx.IsSet(utils.BlsyncApiFlag.Name) { 87 log.Warn("No engine API target specified, performing a dry run") 88 return nil 89 } 90 if !ctx.IsSet(utils.BlsyncJWTSecretFlag.Name) { 91 utils.Fatalf("JWT secret parameter missing") //TODO use default if datadir is specified 92 } 93 94 engineApiUrl, jwtFileName := ctx.String(utils.BlsyncApiFlag.Name), ctx.String(utils.BlsyncJWTSecretFlag.Name) 95 var jwtSecret [32]byte 96 if jwt, err := node.ObtainJWTSecret(jwtFileName); err == nil { 97 copy(jwtSecret[:], jwt) 98 } else { 99 utils.Fatalf("Error loading or generating JWT secret: %v", err) 100 } 101 auth := node.NewJWTAuth(jwtSecret) 102 cl, err := rpc.DialOptions(context.Background(), engineApiUrl, rpc.WithHTTPAuth(auth)) 103 if err != nil { 104 utils.Fatalf("Could not create RPC client: %v", err) 105 } 106 return cl 107 }