mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 11:46:44 +00:00
interna/era,cmd: simplify era interace, fix era.ReadDir, fix lints
This commit is contained in:
parent
216409ed06
commit
f188ed19e9
8 changed files with 55 additions and 49 deletions
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
@ -517,19 +518,21 @@ func importHistory(ctx *cli.Context) error {
|
||||||
network = networks[0]
|
network = networks[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
format := ctx.String(utils.EraFormatFlag.Name)
|
var (
|
||||||
|
format = ctx.String(utils.EraFormatFlag.Name)
|
||||||
|
from func(era.ReadAtSeekCloser) (era.Era, error)
|
||||||
|
)
|
||||||
switch format {
|
switch format {
|
||||||
case "era1", "era":
|
case "era1", "era":
|
||||||
if err := utils.ImportHistory(chain, dir, network, onedb.From, onedb.NewIterator); err != nil {
|
from = onedb.From
|
||||||
return err
|
|
||||||
}
|
|
||||||
case "erae":
|
case "erae":
|
||||||
if err := utils.ImportHistory(chain, dir, network, execdb.From, execdb.NewIterator); err != nil {
|
from = execdb.From
|
||||||
return err
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown --era.format %q (expected 'era1' or 'erae')", format)
|
return fmt.Errorf("unknown --era.format %q (expected 'era1' or 'erae')", format)
|
||||||
}
|
}
|
||||||
|
if err := utils.ImportHistory(chain, dir, network, from); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("Import done in %v\n", time.Since(start))
|
fmt.Printf("Import done in %v\n", time.Since(start))
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -562,19 +565,24 @@ func exportHistory(ctx *cli.Context) error {
|
||||||
utils.Fatalf("Export error: block number %d larger than head block %d\n", uint64(last), head.Number.Uint64())
|
utils.Fatalf("Export error: block number %d larger than head block %d\n", uint64(last), head.Number.Uint64())
|
||||||
}
|
}
|
||||||
|
|
||||||
format := ctx.String(utils.EraFormatFlag.Get(ctx))
|
var (
|
||||||
|
format = ctx.String(utils.EraFormatFlag.Get(ctx))
|
||||||
|
filename func(network string, epoch int, root common.Hash) string
|
||||||
|
newBuilder func(w io.Writer) era.Builder
|
||||||
|
)
|
||||||
switch format {
|
switch format {
|
||||||
case "era1", "era":
|
case "era1", "era":
|
||||||
if err := utils.ExportHistory(chain, dir, uint64(first), uint64(last), uint64(era.MaxSize), onedb.NewBuilder, onedb.Filename); err != nil {
|
newBuilder = func(w io.Writer) era.Builder { return onedb.NewBuilder(w) }
|
||||||
utils.Fatalf("Export error: %v\n", err)
|
filename = func(network string, epoch int, root common.Hash) string { return onedb.Filename(network, epoch, root) }
|
||||||
}
|
|
||||||
case "erae":
|
case "erae":
|
||||||
if err := utils.ExportHistory(chain, dir, uint64(first), uint64(last), uint64(era.MaxSize), execdb.NewBuilder, execdb.Filename); err != nil {
|
newBuilder = func(w io.Writer) era.Builder { return execdb.NewBuilder(w) }
|
||||||
utils.Fatalf("Export error: %v\n", err)
|
filename = func(network string, epoch int, root common.Hash) string { return execdb.Filename(network, epoch, root) }
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown archive format %q (use 'era1' or 'erae')", format)
|
return fmt.Errorf("unknown archive format %q (use 'era1' or 'erae')", format)
|
||||||
}
|
}
|
||||||
|
if err := utils.ExportHistory(chain, dir, uint64(first), uint64(last), uint64(era.MaxSize), newBuilder, filename); err != nil {
|
||||||
|
utils.Fatalf("Export error: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("Export done in %v\n", time.Since(start))
|
fmt.Printf("Export done in %v\n", time.Since(start))
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,7 @@ func readList(filename string) ([]string, error) {
|
||||||
// ImportHistory imports Era1 files containing historical block information,
|
// ImportHistory imports Era1 files containing historical block information,
|
||||||
// starting from genesis. The assumption is held that the provided chain
|
// starting from genesis. The assumption is held that the provided chain
|
||||||
// segment in Era1 file should all be canonical and verified.
|
// segment in Era1 file should all be canonical and verified.
|
||||||
func ImportHistory(chain *core.BlockChain, dir string, network string, from era.FromFn, iterator era.NewIteratorFn) error {
|
func ImportHistory(chain *core.BlockChain, dir string, network string, from func(f era.ReadAtSeekCloser) (era.Era, error)) error {
|
||||||
if chain.CurrentSnapBlock().Number.BitLen() != 0 {
|
if chain.CurrentSnapBlock().Number.BitLen() != 0 {
|
||||||
return errors.New("history import only supported when starting from genesis")
|
return errors.New("history import only supported when starting from genesis")
|
||||||
}
|
}
|
||||||
|
|
@ -305,7 +305,7 @@ func ImportHistory(chain *core.BlockChain, dir string, network string, from era.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error opening era: %w", err)
|
return fmt.Errorf("error opening era: %w", err)
|
||||||
}
|
}
|
||||||
it, err := iterator(e)
|
it, err := e.Iterator()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error creating iterator: %w", err)
|
return fmt.Errorf("error creating iterator: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -417,7 +417,7 @@ func ExportAppendChain(blockchain *core.BlockChain, fn string, first uint64, las
|
||||||
|
|
||||||
// ExportHistory exports blockchain history into the specified directory,
|
// ExportHistory exports blockchain history into the specified directory,
|
||||||
// following the Era format.
|
// following the Era format.
|
||||||
func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64, builderfn era.NewBuilderFn, filename era.FilenameFn) error {
|
func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64, newBuilder func(io.Writer) era.Builder, filename func(network string, epoch int, root common.Hash) string) error {
|
||||||
log.Info("Exporting blockchain history", "dir", dir)
|
log.Info("Exporting blockchain history", "dir", dir)
|
||||||
if head := bc.CurrentBlock().Number.Uint64(); head < last {
|
if head := bc.CurrentBlock().Number.Uint64(); head < last {
|
||||||
log.Warn("Last block beyond head, setting last = head", "head", head, "last", last)
|
log.Warn("Last block beyond head, setting last = head", "head", head, "last", last)
|
||||||
|
|
@ -455,7 +455,7 @@ func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64, bu
|
||||||
}
|
}
|
||||||
defer fh.Close()
|
defer fh.Close()
|
||||||
|
|
||||||
bldr := builderfn(fh)
|
bldr := newBuilder(fh)
|
||||||
|
|
||||||
for j := uint64(0); j < step && batch+j <= last; j++ {
|
for j := uint64(0); j < step && batch+j <= last; j++ {
|
||||||
n := batch + j
|
n := batch + j
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/era"
|
||||||
"github.com/ethereum/go-ethereum/internal/era/onedb"
|
"github.com/ethereum/go-ethereum/internal/era/onedb"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
|
|
@ -89,7 +90,7 @@ func TestHistoryImportAndExport(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
|
|
||||||
// Export history to temp directory.
|
// Export history to temp directory.
|
||||||
if err := ExportHistory(chain, dir, 0, count, step); err != nil {
|
if err := ExportHistory(chain, dir, 0, count, step, onedb.NewBuilder, onedb.Filename); err != nil {
|
||||||
t.Fatalf("error exporting history: %v", err)
|
t.Fatalf("error exporting history: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,7 +102,7 @@ func TestHistoryImportAndExport(t *testing.T) {
|
||||||
checksums := strings.Split(string(b), "\n")
|
checksums := strings.Split(string(b), "\n")
|
||||||
|
|
||||||
// Verify each Era.
|
// Verify each Era.
|
||||||
entries, _ := onedb.ReadDir(dir, "mainnet")
|
entries, _ := era.ReadDir(dir, "mainnet")
|
||||||
for i, filename := range entries {
|
for i, filename := range entries {
|
||||||
func() {
|
func() {
|
||||||
f, err := os.Open(filepath.Join(dir, filename))
|
f, err := os.Open(filepath.Join(dir, filename))
|
||||||
|
|
@ -170,7 +171,7 @@ func TestHistoryImportAndExport(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to initialize chain: %v", err)
|
t.Fatalf("unable to initialize chain: %v", err)
|
||||||
}
|
}
|
||||||
if err := ImportHistory(imported, dir, "mainnet"); err != nil {
|
if err := ImportHistory(imported, dir, "mainnet", onedb.From); err != nil {
|
||||||
t.Fatalf("failed to import chain: %v", err)
|
t.Fatalf("failed to import chain: %v", err)
|
||||||
}
|
}
|
||||||
if have, want := imported.CurrentHeader(), chain.CurrentHeader(); have.Hash() != want.Hash() {
|
if have, want := imported.CurrentHeader(), chain.CurrentHeader(); have.Hash() != want.Hash() {
|
||||||
|
|
|
||||||
|
|
@ -59,45 +59,34 @@ type Era interface {
|
||||||
Close() error
|
Close() error
|
||||||
Start() uint64
|
Start() uint64
|
||||||
Count() uint64
|
Count() uint64
|
||||||
|
Iterator() (Iterator, error)
|
||||||
GetBlockByNumber(num uint64) (*types.Block, error)
|
GetBlockByNumber(num uint64) (*types.Block, error)
|
||||||
GetRawBodyByNumber(num uint64) ([]byte, error)
|
GetRawBodyByNumber(num uint64) ([]byte, error)
|
||||||
GetRawReceiptsByNumber(num uint64) ([]byte, error)
|
GetRawReceiptsByNumber(num uint64) ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBuilderFn defines a function type for creating a new Builder.
|
|
||||||
type NewBuilderFn func(w io.Writer) Builder
|
|
||||||
|
|
||||||
// FilenameFn defines a function type for generating a filename based on network, epoch, and root hash.
|
|
||||||
type FilenameFn func(network string, epoch int, root common.Hash) string
|
|
||||||
|
|
||||||
// FromFn defines a function type for creating an Era from a ReadAtSeekCloser.
|
|
||||||
type FromFn func(f ReadAtSeekCloser) (Era, error)
|
|
||||||
|
|
||||||
// NewIteratorFn defines a function type for creating a new Iterator from an Era.
|
|
||||||
type NewIteratorFn func(e Era) (Iterator, error)
|
|
||||||
|
|
||||||
// ReadDir reads all the era1 files in a directory for a given network.
|
// ReadDir reads all the era1 files in a directory for a given network.
|
||||||
// Format: <network>-<epoch>-<hexroot>.erae or <network>-<epoch>-<hexroot>.era1
|
// Format: <network>-<epoch>-<hexroot>.erae or <network>-<epoch>-<hexroot>.era1
|
||||||
func ReadDir(dir, network string) ([]string, error) {
|
func ReadDir(dir, network string) ([]string, error) {
|
||||||
entries, err := os.ReadDir(dir)
|
entries, err := os.ReadDir(dir)
|
||||||
var directoryExtension string
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error reading directory %s: %w", dir, err)
|
return nil, fmt.Errorf("error reading directory %s: %w", dir, err)
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
next = uint64(0)
|
next = uint64(0)
|
||||||
eras []string
|
eras []string
|
||||||
|
dirType string
|
||||||
)
|
)
|
||||||
for i, entry := range entries {
|
fmt.Println("entries", entries)
|
||||||
fileExtension := path.Ext(entry.Name())
|
for _, entry := range entries {
|
||||||
if i == 0 {
|
ext := path.Ext(entry.Name())
|
||||||
directoryExtension = fileExtension
|
if ext != ".erae" && ext != ".era1" {
|
||||||
} else if directoryExtension != fileExtension {
|
|
||||||
return nil, fmt.Errorf("directory %s contains mixed era file formats", dir)
|
|
||||||
}
|
|
||||||
if fileExtension != ".erae" || fileExtension != ".era1" {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if dirType == "" {
|
||||||
|
dirType = ext
|
||||||
|
}
|
||||||
parts := strings.Split(entry.Name(), "-")
|
parts := strings.Split(entry.Name(), "-")
|
||||||
if len(parts) != 3 || parts[0] != network {
|
if len(parts) != 3 || parts[0] != network {
|
||||||
// Invalid era1 filename, skip.
|
// Invalid era1 filename, skip.
|
||||||
|
|
@ -108,6 +97,9 @@ func ReadDir(dir, network string) ([]string, error) {
|
||||||
} else if epoch != next {
|
} else if epoch != next {
|
||||||
return nil, fmt.Errorf("missing epoch %d", next)
|
return nil, fmt.Errorf("missing epoch %d", next)
|
||||||
}
|
}
|
||||||
|
if dirType != ext {
|
||||||
|
return nil, fmt.Errorf("directory %s contains mixed era file formats: want %s, have %s", dir, dirType, ext)
|
||||||
|
}
|
||||||
next += 1
|
next += 1
|
||||||
eras = append(eras, entry.Name())
|
eras = append(eras, entry.Name())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,6 @@ type Builder struct {
|
||||||
written uint64
|
written uint64
|
||||||
expectsProofs bool
|
expectsProofs bool
|
||||||
isPreMerge bool
|
isPreMerge bool
|
||||||
numPreMerge int // number of pre-merge blocks
|
|
||||||
finalTD *big.Int // final total difficulty, used for pre-merge and merge straddling files
|
finalTD *big.Int // final total difficulty, used for pre-merge and merge straddling files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,11 @@ func (e *Era) Count() uint64 {
|
||||||
return e.m.count
|
return e.m.count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterator returns an iterator over the era file.
|
||||||
|
func (e *Era) Iterator() (era.Iterator, error) {
|
||||||
|
return NewIterator(e)
|
||||||
|
}
|
||||||
|
|
||||||
// GetBlockByNumber retrieves the block if present within the era file.
|
// GetBlockByNumber retrieves the block if present within the era file.
|
||||||
func (e *Era) GetBlockByNumber(blockNum uint64) (*types.Block, error) {
|
func (e *Era) GetBlockByNumber(blockNum uint64) (*types.Block, error) {
|
||||||
h, err := e.GetHeader(blockNum)
|
h, err := e.GetHeader(blockNum)
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,11 @@ func (e *Era) Close() error {
|
||||||
return e.f.Close()
|
return e.f.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterator returns an iterator over the era file.
|
||||||
|
func (e *Era) Iterator() (era.Iterator, error) {
|
||||||
|
return NewIterator(e)
|
||||||
|
}
|
||||||
|
|
||||||
// GetBlockByNumber returns the block for the given block number.
|
// GetBlockByNumber returns the block for the given block number.
|
||||||
func (e *Era) GetBlockByNumber(num uint64) (*types.Block, error) {
|
func (e *Era) GetBlockByNumber(num uint64) (*types.Block, error) {
|
||||||
if e.m.start > num || e.m.start+e.m.count <= num {
|
if e.m.start > num || e.m.start+e.m.count <= num {
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,3 @@ func (p *BlockProofHistoricalSummariesDeneb) EncodeRLP(w io.Writer) error {
|
||||||
|
|
||||||
// Variant returns the variant type of the BlockProofHistoricalSummariesDeneb.
|
// Variant returns the variant type of the BlockProofHistoricalSummariesDeneb.
|
||||||
func (*BlockProofHistoricalSummariesDeneb) Variant() variant { return proofDeneb }
|
func (*BlockProofHistoricalSummariesDeneb) Variant() variant { return proofDeneb }
|
||||||
|
|
||||||
func variantOf(p Proof) variant {
|
|
||||||
return p.Variant()
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue