mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 22:56: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"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -39,6 +42,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/internal/debug"
|
"github.com/ethereum/go-ethereum/internal/debug"
|
||||||
"github.com/ethereum/go-ethereum/internal/era"
|
"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/internal/flags"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"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,
|
Action: pruneHistory,
|
||||||
Name: "prune-history",
|
Name: "prune-history",
|
||||||
Usage: "Prune blockchain history (block bodies and receipts) up to the merge block",
|
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
|
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.`,
|
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
|
// 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
|
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,
|
removedbCommand,
|
||||||
dumpCommand,
|
dumpCommand,
|
||||||
dumpGenesisCommand,
|
dumpGenesisCommand,
|
||||||
pruneCommand,
|
pruneHistoryCommand,
|
||||||
|
downloadEraCommand,
|
||||||
// See accountcmd.go:
|
// See accountcmd.go:
|
||||||
accountCommand,
|
accountCommand,
|
||||||
walletCommand,
|
walletCommand,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue