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  }