mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
This adds a geth subcommand for downloading era1 files and placing them into the correct location. The tool can be used even while geth is already running on the datadir. Downloads are checked against a hard-coded list of checksums for mainnet and sepolia. ``` ./geth download-era --server $SERVER --block 333333 ./geth download-era --server $SERVER --block 333333-444444 ./geth download-era --server $SERVER --epoch 0-10 ./geth download-era --server $SERVER --all ``` The implementation reuses the file downloader we already had for fetching build tools. I've done some refactoring on it to make sure it can support the new use case, and there are some changes to the build here as well.
134 lines
3.9 KiB
Go
134 lines
3.9 KiB
Go
// Copyright 2021 The go-ethereum Authors
|
|
// This file is part of the go-ethereum library.
|
|
//
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
package build
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/ethereum/go-ethereum/internal/download"
|
|
)
|
|
|
|
type GoToolchain struct {
|
|
Root string // GOROOT
|
|
|
|
// Cross-compilation variables. These are set when running the go tool.
|
|
GOARCH string
|
|
GOOS string
|
|
CC string
|
|
}
|
|
|
|
// Go creates an invocation of the go command.
|
|
func (g *GoToolchain) Go(command string, args ...string) *exec.Cmd {
|
|
tool := g.goTool(command, args...)
|
|
|
|
// Configure environment for cross build.
|
|
if g.GOARCH != "" && g.GOARCH != runtime.GOARCH {
|
|
tool.Env = append(tool.Env, "CGO_ENABLED=1")
|
|
tool.Env = append(tool.Env, "GOARCH="+g.GOARCH)
|
|
}
|
|
if g.GOOS != "" && g.GOOS != runtime.GOOS {
|
|
tool.Env = append(tool.Env, "GOOS="+g.GOOS)
|
|
}
|
|
// Configure C compiler.
|
|
if g.CC != "" {
|
|
tool.Env = append(tool.Env, "CC="+g.CC)
|
|
} else if os.Getenv("CC") != "" {
|
|
tool.Env = append(tool.Env, "CC="+os.Getenv("CC"))
|
|
}
|
|
// CKZG by default is not portable, append the necessary build flags to make
|
|
// it not rely on modern CPU instructions and enable linking against.
|
|
tool.Env = append(tool.Env, "CGO_CFLAGS=-O2 -g -D__BLST_PORTABLE__")
|
|
|
|
return tool
|
|
}
|
|
|
|
func (g *GoToolchain) goTool(command string, args ...string) *exec.Cmd {
|
|
if g.Root == "" {
|
|
g.Root = runtime.GOROOT()
|
|
}
|
|
tool := exec.Command(filepath.Join(g.Root, "bin", "go"), command) // nolint: gosec
|
|
tool.Args = append(tool.Args, args...)
|
|
tool.Env = append(tool.Env, "GOROOT="+g.Root)
|
|
|
|
// Forward environment variables to the tool, but skip compiler target settings.
|
|
// TODO: what about GOARM?
|
|
skip := map[string]struct{}{"GOROOT": {}, "GOARCH": {}, "GOOS": {}, "GOBIN": {}, "CC": {}}
|
|
for _, e := range os.Environ() {
|
|
if i := strings.IndexByte(e, '='); i >= 0 {
|
|
if _, ok := skip[e[:i]]; ok {
|
|
continue
|
|
}
|
|
}
|
|
tool.Env = append(tool.Env, e)
|
|
}
|
|
return tool
|
|
}
|
|
|
|
// DownloadGo downloads the Go binary distribution and unpacks it into a temporary
|
|
// directory. It returns the GOROOT of the unpacked toolchain.
|
|
func DownloadGo(csdb *download.ChecksumDB) string {
|
|
version, err := csdb.FindVersion("golang")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
// Shortcut: if the Go version that runs this script matches the
|
|
// requested version exactly, there is no need to download anything.
|
|
activeGo := strings.TrimPrefix(runtime.Version(), "go")
|
|
if activeGo == version {
|
|
log.Printf("-dlgo version matches active Go version %s, skipping download.", activeGo)
|
|
return runtime.GOROOT()
|
|
}
|
|
|
|
ucache, err := os.UserCacheDir()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// For Arm architecture, GOARCH includes ISA version.
|
|
os := runtime.GOOS
|
|
arch := runtime.GOARCH
|
|
if arch == "arm" {
|
|
arch = "armv6l"
|
|
}
|
|
file := fmt.Sprintf("go%s.%s-%s", version, os, arch)
|
|
if os == "windows" {
|
|
file += ".zip"
|
|
} else {
|
|
file += ".tar.gz"
|
|
}
|
|
url := "https://golang.org/dl/" + file
|
|
dst := filepath.Join(ucache, file)
|
|
if err := csdb.DownloadFile(url, dst); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
godir := filepath.Join(ucache, fmt.Sprintf("geth-go-%s-%s-%s", version, os, arch))
|
|
if err := ExtractArchive(dst, godir); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
goroot, err := filepath.Abs(filepath.Join(godir, "go"))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
return goroot
|
|
}
|