mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
testing and made code more readable
This commit is contained in:
parent
e475a30421
commit
0de0cf6925
6 changed files with 135 additions and 188 deletions
|
|
@ -549,7 +549,7 @@ func exportHistory(ctx *cli.Context) error {
|
|||
if head := chain.CurrentSnapBlock(); uint64(last) > head.Number.Uint64() {
|
||||
utils.Fatalf("Export error: block number %d larger than head block %d\n", uint64(last), head.Number.Uint64())
|
||||
}
|
||||
err := utils.ExportHistoryEraE(chain, dir, uint64(first), uint64(last), uint64(era.MaxEra1Size))
|
||||
err := utils.ExportHistory(chain, dir, uint64(first), uint64(last), uint64(era.MaxEra1Size), utils.EraE)
|
||||
if err != nil {
|
||||
utils.Fatalf("Export error: %v\n", err)
|
||||
}
|
||||
|
|
|
|||
192
cmd/utils/cmd.go
192
cmd/utils/cmd.go
|
|
@ -58,6 +58,13 @@ const (
|
|||
importBatchSize = 2500
|
||||
)
|
||||
|
||||
type ExportFormat int
|
||||
|
||||
const (
|
||||
Era1 ExportFormat = iota
|
||||
EraE
|
||||
)
|
||||
|
||||
// ErrImportInterrupted is returned when the user interrupts the import process.
|
||||
var ErrImportInterrupted = errors.New("interrupted")
|
||||
|
||||
|
|
@ -405,8 +412,8 @@ func ExportAppendChain(blockchain *core.BlockChain, fn string, first uint64, las
|
|||
|
||||
// ExportHistory exports blockchain history into the specified directory,
|
||||
// following the Era format.
|
||||
func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64) error {
|
||||
log.Info("Exporting blockchain history", "dir", dir)
|
||||
func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64, f ExportFormat) error {
|
||||
log.Info("Exporting blockchain history", "dir", dir, "format", f)
|
||||
if head := bc.CurrentBlock().Number.Uint64(); head < last {
|
||||
log.Warn("Last block beyond head, setting last = head", "head", head, "last", last)
|
||||
last = head
|
||||
|
|
@ -418,6 +425,32 @@ func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64) er
|
|||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("error creating output directory: %w", err)
|
||||
}
|
||||
|
||||
var (
|
||||
filename func(string, int, common.Hash) string
|
||||
newBuilder func(io.Writer) any
|
||||
add func(any, *types.Block, types.Receipts, *big.Int) error
|
||||
)
|
||||
|
||||
if f == Era1 {
|
||||
filename = era.Filename
|
||||
newBuilder = func(w io.Writer) any { return era.NewBuilder(w) }
|
||||
add = func(b any, blk *types.Block, rcpt types.Receipts, td *big.Int) error {
|
||||
return b.(*era.Builder).Add(blk, rcpt, td)
|
||||
}
|
||||
} else {
|
||||
filename = era2.Filename
|
||||
newBuilder = func(w io.Writer) any { return era2.NewBuilder(w) }
|
||||
add = func(b any, blk *types.Block, rcpt types.Receipts, td *big.Int) error {
|
||||
return b.(*era2.Builder).Add(*blk.Header(), *blk.Body(), rcpt, td, nil)
|
||||
}
|
||||
}
|
||||
|
||||
td := new(big.Int)
|
||||
for n := uint64(0); n < first; n++ {
|
||||
td.Add(td, bc.GetHeaderByNumber(n).Difficulty)
|
||||
}
|
||||
|
||||
var (
|
||||
start = time.Now()
|
||||
reported = time.Now()
|
||||
|
|
@ -425,154 +458,67 @@ func ExportHistory(bc *core.BlockChain, dir string, first, last, step uint64) er
|
|||
buf = bytes.NewBuffer(nil)
|
||||
checksums []string
|
||||
)
|
||||
td := new(big.Int)
|
||||
for i := uint64(0); i < first; i++ {
|
||||
td.Add(td, bc.GetHeaderByNumber(i).Difficulty)
|
||||
}
|
||||
for i := first; i <= last; i += step {
|
||||
err := func() error {
|
||||
filename := filepath.Join(dir, era.Filename(network, int(i/step), common.Hash{}))
|
||||
f, err := os.Create(filename)
|
||||
|
||||
for batch := first; batch <= last; batch += step {
|
||||
idx := int(batch / step)
|
||||
tmpPath := filepath.Join(dir, filename(network, idx, common.Hash{}))
|
||||
|
||||
if err := func() error {
|
||||
f, err := os.Create(tmpPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not create era file: %w", err)
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
w := era.NewBuilder(f)
|
||||
for j := uint64(0); j < step && j <= last-i; j++ {
|
||||
var (
|
||||
n = i + j
|
||||
block = bc.GetBlockByNumber(n)
|
||||
)
|
||||
if block == nil {
|
||||
return fmt.Errorf("export failed on #%d: not found", n)
|
||||
bldr := newBuilder(f)
|
||||
|
||||
for j := uint64(0); j < step && batch+j <= last; j++ {
|
||||
n := batch + j
|
||||
blk := bc.GetBlockByNumber(n)
|
||||
if blk == nil {
|
||||
return fmt.Errorf("block #%d not found", n)
|
||||
}
|
||||
receipts := bc.GetReceiptsByHash(block.Hash())
|
||||
if receipts == nil {
|
||||
return fmt.Errorf("export failed on #%d: receipts not found", n)
|
||||
rcpt := bc.GetReceiptsByHash(blk.Hash())
|
||||
if rcpt == nil {
|
||||
return fmt.Errorf("receipts for #%d missing", n)
|
||||
}
|
||||
td.Add(td, block.Difficulty())
|
||||
if err := w.Add(block, receipts, new(big.Int).Set(td)); err != nil {
|
||||
td.Add(td, blk.Difficulty())
|
||||
if err := add(bldr, blk, rcpt, new(big.Int).Set(td)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
root, err := w.Finalize()
|
||||
if err != nil {
|
||||
return fmt.Errorf("export failed to finalize %d: %w", step/i, err)
|
||||
}
|
||||
// Set correct filename with root.
|
||||
os.Rename(filename, filepath.Join(dir, era.Filename(network, int(i/step), root)))
|
||||
|
||||
// Compute checksum of entire Era1.
|
||||
root, err := bldr.(interface{ Finalize() (common.Hash, error) }).Finalize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
final := filepath.Join(dir, filename(network, idx, root))
|
||||
if err := os.Rename(tmpPath, final); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := f.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(h, f); err != nil {
|
||||
return fmt.Errorf("unable to calculate checksum: %w", err)
|
||||
}
|
||||
checksums = append(checksums, common.BytesToHash(h.Sum(buf.Bytes()[:])).Hex())
|
||||
h.Reset()
|
||||
buf.Reset()
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if time.Since(reported) >= 8*time.Second {
|
||||
log.Info("Exporting blocks", "exported", i, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
reported = time.Now()
|
||||
}
|
||||
}
|
||||
|
||||
os.WriteFile(filepath.Join(dir, "checksums.txt"), []byte(strings.Join(checksums, "\n")), os.ModePerm)
|
||||
|
||||
log.Info("Exported blockchain to", "dir", dir)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ExportHistoryEraE(bc *core.BlockChain, dir string, first, last, step uint64) error {
|
||||
log.Info("Exporting blockchain history", "dir", dir)
|
||||
if head := bc.CurrentBlock().Number.Uint64(); head < last {
|
||||
log.Warn("Last block beyond head, setting last = head", "head", head, "last", last)
|
||||
last = head
|
||||
}
|
||||
network := "unknown"
|
||||
if name, ok := params.NetworkNames[bc.Config().ChainID.String()]; ok {
|
||||
network = name
|
||||
}
|
||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("error creating output directory: %w", err)
|
||||
}
|
||||
var (
|
||||
start = time.Now()
|
||||
reported = time.Now()
|
||||
h = sha256.New()
|
||||
buf = bytes.NewBuffer(nil)
|
||||
checksums []string
|
||||
)
|
||||
td := new(big.Int)
|
||||
for i := uint64(0); i < first; i++ {
|
||||
td.Add(td, bc.GetHeaderByNumber(i).Difficulty)
|
||||
}
|
||||
for i := first; i <= last; i += step {
|
||||
err := func() error {
|
||||
filename := filepath.Join(dir, era2.Filename(network, int(i/step), common.Hash{}))
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not create era file: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
w := era2.NewBuilder(f)
|
||||
for j := uint64(0); j < step && j <= last-i; j++ {
|
||||
var (
|
||||
n = i + j
|
||||
block = bc.GetBlockByNumber(n)
|
||||
)
|
||||
if block == nil {
|
||||
return fmt.Errorf("export failed on #%d: not found", n)
|
||||
}
|
||||
receipts := bc.GetReceiptsByHash(block.Hash())
|
||||
if receipts == nil {
|
||||
return fmt.Errorf("export failed on #%d: receipts not found", n)
|
||||
}
|
||||
td.Add(td, block.Difficulty())
|
||||
if err := w.Add(*block.Header(), *block.Body(), receipts, new(big.Int).Set(td), nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
root, err := w.Finalize()
|
||||
if err != nil {
|
||||
return fmt.Errorf("export failed to finalize %d: %w", step/i, err)
|
||||
}
|
||||
os.Rename(filename, filepath.Join(dir, era2.Filename(network, int(i/step), root)))
|
||||
if _, err := f.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(h, f); err != nil {
|
||||
return fmt.Errorf("unable to calculate checksum: %w", err)
|
||||
return err
|
||||
}
|
||||
checksums = append(checksums, common.BytesToHash(h.Sum(buf.Bytes()[:])).Hex())
|
||||
h.Reset()
|
||||
buf.Reset()
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
}(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if time.Since(reported) >= 8*time.Second {
|
||||
log.Info("Exporting blocks", "exported", i, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
log.Info("export progress", "exported", batch, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
reported = time.Now()
|
||||
}
|
||||
}
|
||||
|
||||
os.WriteFile(filepath.Join(dir, "checksums.txt"), []byte(strings.Join(checksums, "\n")), os.ModePerm)
|
||||
|
||||
log.Info("Exported blockchain to", "dir", dir)
|
||||
|
||||
_ = os.WriteFile(filepath.Join(dir, "checksums.txt"), []byte(strings.Join(checksums, "\n")), os.ModePerm)
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// ImportPreimages imports a batch of exported hash preimages into the database.
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ func TestHistoryImportAndExport(t *testing.T) {
|
|||
dir := t.TempDir()
|
||||
|
||||
// Export history to temp directory.
|
||||
if err := ExportHistory(chain, dir, 0, count, step); err != nil {
|
||||
if err := ExportHistory(chain, dir, 0, count, step, EraE); err != nil {
|
||||
t.Fatalf("error exporting history: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ import (
|
|||
"github.com/golang/snappy"
|
||||
)
|
||||
|
||||
// Type constants for the e2store entries in the Era2 format.
|
||||
const (
|
||||
TypeVersion uint16 = 0x3265
|
||||
TypeCompressedHeader uint16 = 0x08
|
||||
|
|
@ -70,7 +71,7 @@ const (
|
|||
headerSize uint64 = 8
|
||||
)
|
||||
|
||||
// temporary buffer for writing blocks until Finalize is called
|
||||
// Temporary buffer for writing blocks until the Finalize method is called.
|
||||
type buffer struct {
|
||||
headers [][]byte
|
||||
bodies [][]byte
|
||||
|
|
@ -79,7 +80,7 @@ type buffer struct {
|
|||
tds []*big.Int
|
||||
}
|
||||
|
||||
// offsets holds the offsets of the different block components in the e2store file
|
||||
// The offsets holds the offsets of the different block components in the e2store file. Eventually these offsets will be used to write the index table at the end of the file.
|
||||
type offsets struct {
|
||||
headers []uint64
|
||||
bodys []uint64
|
||||
|
|
@ -88,10 +89,10 @@ type offsets struct {
|
|||
tdoff []uint64
|
||||
}
|
||||
|
||||
// Builder is used to build an Era2 e2store file. It collects block entries and writes them to the underlying e2store.Writer.
|
||||
type Builder struct {
|
||||
w *e2store.Writer
|
||||
buf *bytes.Buffer
|
||||
snappy *snappy.Writer
|
||||
|
||||
buff buffer
|
||||
off offsets
|
||||
|
|
@ -99,6 +100,7 @@ type Builder struct {
|
|||
hashes []common.Hash
|
||||
startNum *uint64
|
||||
written uint64
|
||||
expectsProofs bool
|
||||
}
|
||||
|
||||
// NewBuilder returns a new Builder instance.
|
||||
|
|
@ -107,12 +109,19 @@ func NewBuilder(w io.Writer) *Builder {
|
|||
return &Builder{
|
||||
w: e2store.NewWriter(w),
|
||||
buf: buf,
|
||||
snappy: snappy.NewBufferedWriter(buf),
|
||||
}
|
||||
}
|
||||
|
||||
// Add writes a block entry, its reciepts, and optionally its proofs as well into the e2store file.
|
||||
func (b *Builder) Add(header types.Header, body types.Body, receipts types.Receipts, td *big.Int, proof Proof) error {
|
||||
if len(b.buff.headers) == 0 { // first block determines wether proofs are expected
|
||||
b.expectsProofs = proof != nil
|
||||
} else if b.expectsProofs && proof == nil { // every later block must follow this policy
|
||||
return fmt.Errorf("block %d missing proof: proofs required for every block", header.Number.Uint64())
|
||||
} else if !b.expectsProofs && proof != nil {
|
||||
return fmt.Errorf("unexpected proof for block %d: first block had none", header.Number.Uint64())
|
||||
}
|
||||
|
||||
eh, err := rlp.EncodeToBytes(&header)
|
||||
if err != nil {
|
||||
return fmt.Errorf("encode header: %w", err)
|
||||
|
|
@ -134,12 +143,6 @@ func (b *Builder) Add(header types.Header, body types.Body, receipts types.Recei
|
|||
return fmt.Errorf("encode proof: %w", err)
|
||||
}
|
||||
ep = buffer.Bytes()
|
||||
} else {
|
||||
noProof := &NoProof{}
|
||||
if err := noProof.EncodeRLP(&buffer); err != nil {
|
||||
return fmt.Errorf("encode no proof: %w", err)
|
||||
}
|
||||
ep = buffer.Bytes()
|
||||
}
|
||||
|
||||
return b.AddRLP(
|
||||
|
|
@ -149,7 +152,7 @@ func (b *Builder) Add(header types.Header, body types.Body, receipts types.Recei
|
|||
)
|
||||
}
|
||||
|
||||
// AddRLP takes the RLP encoded block components and writes them to the underlying e2store file
|
||||
// AddRLP takes the RLP encoded block components and writes them to the underlying e2store file.
|
||||
func (b *Builder) AddRLP(headerRLP []byte, bodyRLP []byte, receipts []byte, proof []byte, blockNum uint64, blockHash common.Hash, td *big.Int) error {
|
||||
if len(b.buff.headers) >= MaxEraESize {
|
||||
return fmt.Errorf("exceeds MaxEraESize %d", MaxEraESize)
|
||||
|
|
@ -177,7 +180,8 @@ func (b *Builder) AddRLP(headerRLP []byte, bodyRLP []byte, receipts []byte, proo
|
|||
return nil
|
||||
}
|
||||
|
||||
// Finalize writes all header entries, followed by all body entries, followed by all receipt entries.
|
||||
// Finalize writes all collected block entries to the e2store file and returns the accumulator root hash.
|
||||
// It also writes the index table at the end of the file, which contains offsets to each block entry.
|
||||
func (b *Builder) Finalize() (common.Hash, error) {
|
||||
if b.startNum == nil {
|
||||
return common.Hash{}, errors.New("no blocks added, cannot finalize")
|
||||
|
|
@ -244,7 +248,7 @@ func (b *Builder) Finalize() (common.Hash, error) {
|
|||
return accRoot, b.writeIndex()
|
||||
}
|
||||
|
||||
// Writes 32 byte big integers to little endian
|
||||
// uin256LE writes 32 byte big integers to little endian.
|
||||
func uint256LE(v *big.Int) []byte {
|
||||
b := v.FillBytes(make([]byte, 32))
|
||||
for i := 0; i < 16; i++ {
|
||||
|
|
@ -253,18 +257,16 @@ func uint256LE(v *big.Int) []byte {
|
|||
return b
|
||||
}
|
||||
|
||||
// Compresses into snappy encoding
|
||||
// SnappyWrite compresses the input data using snappy and writes it to the e2store file.
|
||||
func (b *Builder) snappyWrite(typ uint16, in []byte) error {
|
||||
var (
|
||||
buf = b.buf
|
||||
s = b.snappy
|
||||
)
|
||||
var buf = b.buf
|
||||
snappy := snappy.NewBufferedWriter(b.buf)
|
||||
buf.Reset()
|
||||
s.Reset(buf)
|
||||
if _, err := b.snappy.Write(in); err != nil {
|
||||
snappy.Reset(buf)
|
||||
if _, err := snappy.Write(in); err != nil {
|
||||
return fmt.Errorf("error snappy encoding: %w", err)
|
||||
}
|
||||
if err := s.Flush(); err != nil {
|
||||
if err := snappy.Flush(); err != nil {
|
||||
return fmt.Errorf("error flushing snappy encoding: %w", err)
|
||||
}
|
||||
n, err := b.w.Write(typ, b.buf.Bytes())
|
||||
|
|
@ -275,7 +277,7 @@ func (b *Builder) snappyWrite(typ uint16, in []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Add entry takes the e2store object and writes it into the file
|
||||
// addEntry takes the e2store object and writes it into the file.
|
||||
func (b *Builder) addEntry(typ uint16, payload []byte, compressed bool) (uint64, error) {
|
||||
offset := b.written
|
||||
var err error
|
||||
|
|
@ -293,8 +295,7 @@ func (b *Builder) addEntry(typ uint16, payload []byte, compressed bool) (uint64,
|
|||
return offset, nil
|
||||
}
|
||||
|
||||
// writeIndex takes all the offset table and writes it to the file
|
||||
// the index table contains all offsets to specific block entries
|
||||
// writeIndex takes all the offset table and writes it to the file. The index table contains all offsets to specific block entries
|
||||
func (b *Builder) writeIndex() error {
|
||||
count := uint64(len(b.off.headers))
|
||||
componentCount := uint64(3)
|
||||
|
|
|
|||
|
|
@ -38,9 +38,10 @@ type metadata struct {
|
|||
length int64 // length of the file in bytes
|
||||
}
|
||||
|
||||
// the types of components that can be present in the era file.
|
||||
// componentType represents the integer form of a specific type that can be present in the era file.
|
||||
type componentType int
|
||||
|
||||
// TypeCompressedHeader, TypeCompressedBody, TypeCompressedReceipts, TypeTotalDifficulty, and TypeProof are the different types of components that can be present in the era file.
|
||||
const (
|
||||
componentHeader componentType = iota
|
||||
componentBody
|
||||
|
|
@ -55,18 +56,19 @@ type ReadAtSeekCloser interface {
|
|||
io.Closer
|
||||
}
|
||||
|
||||
// Era object represents an era file that contains blocks and their components.
|
||||
type Era struct {
|
||||
f ReadAtSeekCloser
|
||||
s *e2store.Reader
|
||||
m metadata // metadata for the Era file
|
||||
}
|
||||
|
||||
// Filename returns a recognizable filename for erae file
|
||||
// Filename returns a recognizable filename for era file.
|
||||
func Filename(network string, epoch int, root common.Hash) string {
|
||||
return fmt.Sprintf("%s-%05d-%s.erae", network, epoch, root.Hex()[2:10])
|
||||
}
|
||||
|
||||
// Open opens the era file
|
||||
// Open accesses the era file.
|
||||
func Open(path string) (*Era, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
|
|
@ -80,7 +82,7 @@ func Open(path string) (*Era, error) {
|
|||
return e, nil
|
||||
}
|
||||
|
||||
// Close closes the era file
|
||||
// Close closes the era file safely.
|
||||
func (e *Era) Close() error {
|
||||
if e.f == nil {
|
||||
return nil
|
||||
|
|
@ -90,17 +92,17 @@ func (e *Era) Close() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Start retrieves the starting block number
|
||||
// Start retrieves the starting block number.
|
||||
func (e *Era) Start() uint64 {
|
||||
return e.m.start
|
||||
}
|
||||
|
||||
// Count retrieves the count of blocks present
|
||||
// Count retrieves the count of blocks present.
|
||||
func (e *Era) Count() uint64 {
|
||||
return e.m.count
|
||||
}
|
||||
|
||||
// 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) {
|
||||
h, err := e.GetHeader(blockNum)
|
||||
if err != nil {
|
||||
|
|
@ -113,7 +115,7 @@ func (e *Era) GetBlockByNumber(blockNum uint64) (*types.Block, error) {
|
|||
return types.NewBlockWithHeader(h).WithBody(*b), nil
|
||||
}
|
||||
|
||||
// GetHeader retrieves the header from the era file through the cached offset table
|
||||
// GetHeader retrieves the header from the era file through the cached offset table.
|
||||
func (e *Era) GetHeader(num uint64) (*types.Header, error) {
|
||||
off, err := e.headerOff(num)
|
||||
if err != nil {
|
||||
|
|
@ -130,7 +132,7 @@ func (e *Era) GetHeader(num uint64) (*types.Header, error) {
|
|||
return &h, rlp.Decode(r, &h)
|
||||
}
|
||||
|
||||
// GetBody retrieves the body from the era file through cached offset table
|
||||
// GetBody retrieves the body from the era file through cached offset table.
|
||||
func (e *Era) GetBody(num uint64) (*types.Body, error) {
|
||||
off, err := e.bodyOff(num)
|
||||
if err != nil {
|
||||
|
|
@ -147,7 +149,7 @@ func (e *Era) GetBody(num uint64) (*types.Body, error) {
|
|||
return &b, rlp.Decode(r, &b)
|
||||
}
|
||||
|
||||
// getTD retrieves the td from the era file through cached offset table
|
||||
// getTD retrieves the td from the era file through cached offset table.
|
||||
func (e *Era) getTD(blockNum uint64) (*big.Int, error) {
|
||||
off, err := e.tdOff(blockNum)
|
||||
if err != nil {
|
||||
|
|
@ -162,7 +164,7 @@ func (e *Era) getTD(blockNum uint64) (*big.Int, error) {
|
|||
return td, nil
|
||||
}
|
||||
|
||||
// GetRawBodyFrameByNumber retrieves the raw body frame in bytes of a specific block
|
||||
// GetRawBodyFrameByNumber retrieves the raw body frame in bytes of a specific block.
|
||||
func (e *Era) GetRawBodyFrameByNumber(blockNum uint64) ([]byte, error) {
|
||||
off, err := e.bodyOff(blockNum)
|
||||
if err != nil {
|
||||
|
|
@ -188,7 +190,7 @@ func (e *Era) GetRawReceiptsFrameByNumber(blockNum uint64) ([]byte, error) {
|
|||
return io.ReadAll(r)
|
||||
}
|
||||
|
||||
// GetRawProofFrameByNumber retrieves the raw proof frame in bytes of a specific block proof
|
||||
// GetRawProofFrameByNumber retrieves the raw proof frame in bytes of a specific block proof.
|
||||
func (e *Era) GetRawProofFrameByNumber(blockNum uint64) ([]byte, error) {
|
||||
off, err := e.proofOff(blockNum)
|
||||
if err != nil {
|
||||
|
|
@ -201,7 +203,7 @@ func (e *Era) GetRawProofFrameByNumber(blockNum uint64) ([]byte, error) {
|
|||
return io.ReadAll(r)
|
||||
}
|
||||
|
||||
// loadIndex loads in the index table containing all offsets and caches it
|
||||
// loadIndex loads in the index table containing all offsets and caches it.
|
||||
func (e *Era) loadIndex() error {
|
||||
var err error
|
||||
e.m.length, err = e.f.Seek(0, io.SeekEnd)
|
||||
|
|
@ -227,7 +229,7 @@ func (e *Era) loadIndex() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Getter methods to calculate offset of a specific component in the file.
|
||||
// headerOff, bodyOff, receiptOff, tdOff, and proofOff return the offsets of the respective components for a given block number.
|
||||
func (e *Era) headerOff(num uint64) (uint64, error) { return e.indexOffset(num, componentHeader) }
|
||||
func (e *Era) bodyOff(num uint64) (uint64, error) { return e.indexOffset(num, componentBody) }
|
||||
func (e *Era) receiptOff(num uint64) (uint64, error) { return e.indexOffset(num, componentReceipts) }
|
||||
|
|
@ -257,7 +259,7 @@ func (e *Era) indexOffset(n uint64, component componentType) (uint64, error) {
|
|||
return uint64(int64(rel) + indstart), nil
|
||||
}
|
||||
|
||||
// GetHeaders returns RLP-decoded headers.
|
||||
// GetHeaders returns RLP-decoded headers for a range of blocks.
|
||||
func (e *Era) GetHeaders(first, count uint64) ([]*types.Header, error) {
|
||||
if count == 0 {
|
||||
return nil, fmt.Errorf("count must be > 0")
|
||||
|
|
@ -286,7 +288,7 @@ func (e *Era) GetHeaders(first, count uint64) ([]*types.Header, error) {
|
|||
return out, nil
|
||||
}
|
||||
|
||||
// GetBodies returns RLP-decoded bodies.
|
||||
// GetHeaders returns RLP-decoded headers for a range of blocks.
|
||||
func (e *Era) GetBodies(first, count uint64) ([]*types.Body, error) {
|
||||
if count == 0 {
|
||||
return nil, fmt.Errorf("count must be > 0")
|
||||
|
|
@ -315,7 +317,7 @@ func (e *Era) GetBodies(first, count uint64) ([]*types.Body, error) {
|
|||
return out, nil
|
||||
}
|
||||
|
||||
// GetReceipts returns RLP-decoded receipts.
|
||||
// GetReceipts returns RLP-decoded receipts for a range of blocks.
|
||||
func (e *Era) GetReceipts(first, count uint64) ([]types.Receipts, error) {
|
||||
if count == 0 {
|
||||
return nil, fmt.Errorf("count must be > 0")
|
||||
|
|
|
|||
|
|
@ -58,59 +58,57 @@ type BlockProofHistoricalSummariesDeneb struct {
|
|||
Slot uint64 // 8 => 840 bytes
|
||||
}
|
||||
|
||||
type NoProof struct{}
|
||||
|
||||
// Proof is the interface for all block proof types in the era2 package.
|
||||
type Proof interface {
|
||||
EncodeRLP(w io.Writer) error
|
||||
DecodeRlP(s *rlp.Stream) error
|
||||
Variant() variant
|
||||
}
|
||||
|
||||
type hhaAlias BlockProofHistoricalHashesAccumulator // alias ⇒ no EncodeRLP method
|
||||
type hhaAlias BlockProofHistoricalHashesAccumulator
|
||||
|
||||
// EncodeRLP encodes the BlockProofHistoricalHashesAccumulator into RLP format.
|
||||
func (p *BlockProofHistoricalHashesAccumulator) EncodeRLP(w io.Writer) error {
|
||||
payload := []interface{}{uint16(proofHistoricalHashesAccumulator), hhaAlias(*p)}
|
||||
return rlp.Encode(w, payload)
|
||||
}
|
||||
|
||||
// Variant returns the variant type of the BlockProofHistoricalHashesAccumulator.
|
||||
func (p *BlockProofHistoricalHashesAccumulator) Variant() variant {
|
||||
return proofHistoricalHashesAccumulator
|
||||
}
|
||||
|
||||
type rootsAlias BlockProofHistoricalRoots
|
||||
|
||||
// EncodeRLP encodes the BlockProofHistoricalRoots into RLP format.
|
||||
func (p *BlockProofHistoricalRoots) EncodeRLP(w io.Writer) error {
|
||||
payload := []interface{}{uint16(proofHistoricalRoots), rootsAlias(*p)}
|
||||
return rlp.Encode(w, payload)
|
||||
}
|
||||
|
||||
// Variant returns the variant type of the BlockProofHistoricalRoots.
|
||||
func (*BlockProofHistoricalRoots) Variant() variant { return proofHistoricalRoots }
|
||||
|
||||
type capellaAlias BlockProofHistoricalSummariesCapella
|
||||
|
||||
// EncodeRLP encodes the BlockProofHistoricalSummariesCapella into RLP format.
|
||||
func (p *BlockProofHistoricalSummariesCapella) EncodeRLP(w io.Writer) error {
|
||||
payload := []interface{}{uint16(proofCapella), capellaAlias(*p)}
|
||||
return rlp.Encode(w, payload)
|
||||
}
|
||||
|
||||
// Variant returns the variant type of the BlockProofHistoricalSummariesCapella.
|
||||
func (*BlockProofHistoricalSummariesCapella) Variant() variant { return proofCapella }
|
||||
|
||||
type denebAlias BlockProofHistoricalSummariesDeneb
|
||||
|
||||
// EncodeRLP encodes the BlockProofHistoricalSummariesDeneb into RLP format.
|
||||
func (p *BlockProofHistoricalSummariesDeneb) EncodeRLP(w io.Writer) error {
|
||||
payload := []interface{}{uint16(proofDeneb), denebAlias(*p)}
|
||||
return rlp.Encode(w, payload)
|
||||
}
|
||||
|
||||
type NoProofAlias NoProof // alias ⇒ no EncodeRLP method
|
||||
|
||||
func (p *NoProof) EncodeRLP(w io.Writer) error {
|
||||
payload := []interface{}{uint16(proofNone), NoProofAlias(*p)}
|
||||
return rlp.Encode(w, payload)
|
||||
}
|
||||
|
||||
func (*NoProof) Variant() variant { return proofNone }
|
||||
|
||||
// Variant returns the variant type of the BlockProofHistoricalSummariesDeneb.
|
||||
func (*BlockProofHistoricalSummariesDeneb) Variant() variant { return proofDeneb }
|
||||
|
||||
func variantOf(p Proof) variant {
|
||||
|
|
|
|||
Loading…
Reference in a new issue