mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-05 10:32:19 +00:00
93 lines
2.1 KiB
Go
93 lines
2.1 KiB
Go
package freezeblocks
|
|
|
|
import (
|
|
"bytes"
|
|
"sync"
|
|
|
|
"github.com/ledgerwatch/erigon/cl/clparams"
|
|
"github.com/ledgerwatch/erigon/cl/cltypes"
|
|
"github.com/ledgerwatch/erigon/cl/persistence/format/snapshot_format"
|
|
"github.com/pierrec/lz4"
|
|
)
|
|
|
|
var buffersPool = sync.Pool{
|
|
New: func() interface{} { return &bytes.Buffer{} },
|
|
}
|
|
|
|
var lz4ReaderPool = sync.Pool{
|
|
New: func() interface{} {
|
|
return lz4.NewReader(nil)
|
|
},
|
|
}
|
|
|
|
type BeaconSnapshotReader interface {
|
|
// ReadBlock reads the block at the given slot.
|
|
// If the block is not present, it returns nil.
|
|
ReadBlock(slot uint64) (*cltypes.SignedBeaconBlock, error)
|
|
RawBlockSSZ(slot uint64) ([]byte, error)
|
|
|
|
FrozenSlots() uint64
|
|
}
|
|
|
|
type beaconSnapshotReader struct {
|
|
sn *CaplinSnapshots
|
|
|
|
eth1Getter snapshot_format.ExecutionBlockReaderByNumber
|
|
cfg *clparams.BeaconChainConfig
|
|
}
|
|
|
|
func NewBeaconSnapshotReader(snapshots *CaplinSnapshots, eth1Getter snapshot_format.ExecutionBlockReaderByNumber, cfg *clparams.BeaconChainConfig) BeaconSnapshotReader {
|
|
return &beaconSnapshotReader{sn: snapshots, eth1Getter: eth1Getter, cfg: cfg}
|
|
}
|
|
|
|
func (r *beaconSnapshotReader) FrozenSlots() uint64 {
|
|
return r.sn.BlocksAvailable()
|
|
}
|
|
|
|
func (r *beaconSnapshotReader) ReadBlock(slot uint64) (*cltypes.SignedBeaconBlock, error) {
|
|
buf, err := r.RawBlockSSZ(slot)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if buf == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
// Use pooled buffers and readers to avoid allocations.
|
|
buffer := buffersPool.Get().(*bytes.Buffer)
|
|
defer buffersPool.Put(buffer)
|
|
buffer.Reset()
|
|
buffer.Write(buf)
|
|
|
|
lzReader := lz4ReaderPool.Get().(*lz4.Reader)
|
|
defer lz4ReaderPool.Put(lzReader)
|
|
lzReader.Reset(buffer)
|
|
|
|
return snapshot_format.ReadBlockFromSnapshot(lzReader, r.eth1Getter, r.cfg)
|
|
}
|
|
|
|
func (r *beaconSnapshotReader) RawBlockSSZ(slot uint64) ([]byte, error) {
|
|
view := r.sn.View()
|
|
defer view.Close()
|
|
|
|
var buf []byte
|
|
|
|
seg, ok := view.BeaconBlocksSegment(slot)
|
|
if !ok {
|
|
return nil, nil
|
|
}
|
|
|
|
if seg.idxSlot == nil {
|
|
return nil, nil
|
|
}
|
|
blockOffset := seg.idxSlot.OrdinalLookup(slot - seg.idxSlot.BaseDataID())
|
|
|
|
gg := seg.seg.MakeGetter()
|
|
gg.Reset(blockOffset)
|
|
if !gg.HasNext() {
|
|
return nil, nil
|
|
}
|
|
buf, _ = gg.Next(buf)
|
|
return buf, nil
|
|
}
|