cmd/geth: add download-era command

This commit is contained in:
Felix Lange 2025-05-14 09:59:40 +02:00
parent 4159c31216
commit 37f94cbccd
2 changed files with 119 additions and 2 deletions

View file

@ -21,9 +21,12 @@ import (
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"runtime"
"slices"
"strconv"
"strings"
"sync/atomic"
"time"
@ -39,6 +42,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/internal/debug"
"github.com/ethereum/go-ethereum/internal/era"
"github.com/ethereum/go-ethereum/internal/era/eradl"
"github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
@ -190,7 +194,7 @@ This command dumps out the state for a given block (or latest, if none provided)
`,
}
pruneCommand = &cli.Command{
pruneHistoryCommand = &cli.Command{
Action: pruneHistory,
Name: "prune-history",
Usage: "Prune blockchain history (block bodies and receipts) up to the merge block",
@ -201,6 +205,38 @@ The prune-history command removes historical block bodies and receipts from the
blockchain database up to the merge block, while preserving block headers. This
helps reduce storage requirements for nodes that don't need full historical data.`,
}
downloadEraCommand = &cli.Command{
Action: downloadEra,
Name: "download-era",
Usage: "Fetches era1 files (pre-merge history) from an HTTP endpoint",
ArgsUsage: "",
Flags: slices.Concat(utils.DatabaseFlags, []cli.Flag{
eraBlockFlag,
eraEpochFlag,
eraAllFlag,
eraServerFlag,
}),
}
)
var (
eraBlockFlag = &cli.StringFlag{
Name: "block",
Usage: "Block number to fetch. (can also be a range <start>-<end>)",
}
eraEpochFlag = &cli.StringFlag{
Name: "epoch",
Usage: "Epoch number to fetch (can also be a range <start>-<end>)",
}
eraAllFlag = &cli.BoolFlag{
Name: "all",
Usage: "Download all available era1 files",
}
eraServerFlag = &cli.StringFlag{
Name: "server",
Usage: "era1 server URL",
}
)
// initGenesis will initialise the given JSON format genesis file and writes it as
@ -665,3 +701,83 @@ func pruneHistory(ctx *cli.Context) error {
return nil
}
// downladEra is the era1 file downloader tool.
func downloadEra(ctx *cli.Context) error {
flags.CheckExclusive(ctx, eraBlockFlag, eraEpochFlag, eraAllFlag)
// Resolve the network.
var network = "mainnet"
if utils.IsNetworkPreset(ctx) {
switch {
case ctx.IsSet(utils.MainnetFlag.Name):
case ctx.IsSet(utils.SepoliaFlag.Name):
network = "sepolia"
default:
return fmt.Errorf("unsupported network, no known era1 checksums")
}
}
// Resolve the destination directory.
stack, _ := makeConfigNode(ctx)
defer stack.Close()
ancients := stack.ResolveAncient("chaindata", "")
dir := filepath.Join(ancients, "era")
baseURL := ctx.String(eraServerFlag.Name)
if baseURL == "" {
return fmt.Errorf("need --%s flag to download", eraServerFlag.Name)
}
l, err := eradl.New(baseURL, network)
if err != nil {
return err
}
switch {
case ctx.IsSet(eraAllFlag.Name):
return l.DownloadAll(dir)
case ctx.IsSet(eraBlockFlag.Name):
s := ctx.String(eraBlockFlag.Name)
start, end, ok := parseRange(s)
if !ok {
return fmt.Errorf("invalid block range: %q", s)
}
return l.DownloadBlockRange(start, end, dir)
case ctx.IsSet(eraEpochFlag.Name):
s := ctx.String(eraEpochFlag.Name)
start, end, ok := parseRange(s)
if !ok {
return fmt.Errorf("invalid epoch range: %q", s)
}
return l.DownloadEpochRange(start, end, dir)
default:
return fmt.Errorf("specify one of --%s, --%s, or --%s to download", eraAllFlag.Name, eraBlockFlag.Name, eraEpochFlag.Name)
}
}
func parseRange(s string) (start uint64, end uint64, ok bool) {
if m, _ := regexp.MatchString("[0-9]+", s); m {
start, err := strconv.ParseUint(s, 10, 64)
if err != nil {
return 0, 0, false
}
end = start
return start, end, true
}
if m, _ := regexp.MatchString("[0-9]+-[0-9]+", s); m {
s1, s2, _ := strings.Cut(s, "-")
start, err := strconv.ParseUint(s1, 10, 64)
if err != nil {
return 0, 0, false
}
end, err = strconv.ParseUint(s2, 10, 64)
if err != nil {
return 0, 0, false
}
return start, end, true
}
return 0, 0, false
}

View file

@ -225,7 +225,8 @@ func init() {
removedbCommand,
dumpCommand,
dumpGenesisCommand,
pruneCommand,
pruneHistoryCommand,
downloadEraCommand,
// See accountcmd.go:
accountCommand,
walletCommand,