mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
cmd/geth: add download-era command
This commit is contained in:
parent
4159c31216
commit
37f94cbccd
2 changed files with 119 additions and 2 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,7 +225,8 @@ func init() {
|
|||
removedbCommand,
|
||||
dumpCommand,
|
||||
dumpGenesisCommand,
|
||||
pruneCommand,
|
||||
pruneHistoryCommand,
|
||||
downloadEraCommand,
|
||||
// See accountcmd.go:
|
||||
accountCommand,
|
||||
walletCommand,
|
||||
|
|
|
|||
Loading…
Reference in a new issue