mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-03 09:37:38 +00:00
281 lines
8.4 KiB
Go
281 lines
8.4 KiB
Go
package beacon_indicies
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
|
"github.com/ledgerwatch/erigon-lib/kv"
|
|
"github.com/ledgerwatch/erigon/cl/cltypes"
|
|
"github.com/ledgerwatch/erigon/cl/persistence/base_encoding"
|
|
_ "modernc.org/sqlite"
|
|
)
|
|
|
|
func WriteHighestFinalized(tx kv.RwTx, slot uint64) error {
|
|
return tx.Put(kv.HighestFinalized, kv.HighestFinalizedKey, base_encoding.Encode64ToBytes4(slot))
|
|
}
|
|
|
|
func ReadHighestFinalized(tx kv.Tx) (uint64, error) {
|
|
val, err := tx.GetOne(kv.HighestFinalized, kv.HighestFinalizedKey)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if len(val) == 0 {
|
|
return 0, nil
|
|
}
|
|
return base_encoding.Decode64FromBytes4(val), nil
|
|
}
|
|
|
|
// WriteBlockRootSlot writes the slot associated with a block root.
|
|
func WriteHeaderSlot(tx kv.RwTx, blockRoot libcommon.Hash, slot uint64) error {
|
|
return tx.Put(kv.BlockRootToSlot, blockRoot[:], base_encoding.Encode64ToBytes4(slot))
|
|
}
|
|
|
|
func ReadBlockSlotByBlockRoot(tx kv.Tx, blockRoot libcommon.Hash) (*uint64, error) {
|
|
slotBytes, err := tx.GetOne(kv.BlockRootToSlot, blockRoot[:])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(slotBytes) == 0 {
|
|
return nil, nil
|
|
}
|
|
slot := new(uint64)
|
|
*slot = base_encoding.Decode64FromBytes4(slotBytes)
|
|
return slot, nil
|
|
}
|
|
|
|
// WriteBlockRootSlot writes the slot associated with a block root.
|
|
func WriteStateRoot(tx kv.RwTx, blockRoot libcommon.Hash, stateRoot libcommon.Hash) error {
|
|
if err := tx.Put(kv.BlockRootToStateRoot, blockRoot[:], stateRoot[:]); err != nil {
|
|
return err
|
|
}
|
|
return tx.Put(kv.StateRootToBlockRoot, stateRoot[:], blockRoot[:])
|
|
}
|
|
|
|
func ReadStateRootByBlockRoot(ctx context.Context, tx kv.Tx, blockRoot libcommon.Hash) (libcommon.Hash, error) {
|
|
var stateRoot libcommon.Hash
|
|
|
|
sRoot, err := tx.GetOne(kv.BlockRootToStateRoot, blockRoot[:])
|
|
if err != nil {
|
|
return libcommon.Hash{}, err
|
|
}
|
|
|
|
copy(stateRoot[:], sRoot)
|
|
|
|
return stateRoot, nil
|
|
}
|
|
|
|
func ReadBlockRootByStateRoot(tx kv.Tx, stateRoot libcommon.Hash) (libcommon.Hash, error) {
|
|
var blockRoot libcommon.Hash
|
|
|
|
bRoot, err := tx.GetOne(kv.StateRootToBlockRoot, stateRoot[:])
|
|
if err != nil {
|
|
return libcommon.Hash{}, err
|
|
}
|
|
|
|
copy(blockRoot[:], bRoot)
|
|
|
|
return blockRoot, nil
|
|
}
|
|
|
|
func ReadCanonicalBlockRoot(tx kv.Tx, slot uint64) (libcommon.Hash, error) {
|
|
var blockRoot libcommon.Hash
|
|
|
|
bRoot, err := tx.GetOne(kv.CanonicalBlockRoots, base_encoding.Encode64ToBytes4(slot))
|
|
if err != nil {
|
|
return libcommon.Hash{}, err
|
|
}
|
|
|
|
copy(blockRoot[:], bRoot)
|
|
return blockRoot, nil
|
|
}
|
|
|
|
func WriteLastBeaconSnapshot(tx kv.RwTx, slot uint64) error {
|
|
return tx.Put(kv.LastBeaconSnapshot, []byte(kv.LastBeaconSnapshotKey), base_encoding.Encode64ToBytes4(slot))
|
|
}
|
|
|
|
func ReadLastBeaconSnapshot(tx kv.Tx) (uint64, error) {
|
|
val, err := tx.GetOne(kv.LastBeaconSnapshot, []byte(kv.LastBeaconSnapshotKey))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if len(val) == 0 {
|
|
return 0, nil
|
|
}
|
|
return base_encoding.Decode64FromBytes4(val), nil
|
|
}
|
|
|
|
func MarkRootCanonical(ctx context.Context, tx kv.RwTx, slot uint64, blockRoot libcommon.Hash) error {
|
|
return tx.Put(kv.CanonicalBlockRoots, base_encoding.Encode64ToBytes4(slot), blockRoot[:])
|
|
}
|
|
|
|
func WriteExecutionBlockNumber(tx kv.RwTx, blockRoot libcommon.Hash, blockNumber uint64) error {
|
|
return tx.Put(kv.BlockRootToBlockNumber, blockRoot[:], base_encoding.Encode64ToBytes4(blockNumber))
|
|
}
|
|
|
|
func WriteExecutionBlockHash(tx kv.RwTx, blockRoot, blockHash libcommon.Hash) error {
|
|
return tx.Put(kv.BlockRootToBlockHash, blockRoot[:], blockHash[:])
|
|
}
|
|
|
|
func ReadExecutionBlockNumber(tx kv.Tx, blockRoot libcommon.Hash) (*uint64, error) {
|
|
val, err := tx.GetOne(kv.BlockRootToBlockNumber, blockRoot[:])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(val) == 0 {
|
|
return nil, nil
|
|
}
|
|
ret := new(uint64)
|
|
*ret = base_encoding.Decode64FromBytes4(val)
|
|
return ret, nil
|
|
}
|
|
|
|
func ReadExecutionBlockHash(tx kv.Tx, blockRoot libcommon.Hash) (libcommon.Hash, error) {
|
|
val, err := tx.GetOne(kv.BlockRootToBlockHash, blockRoot[:])
|
|
if err != nil {
|
|
return libcommon.Hash{}, err
|
|
}
|
|
if len(val) == 0 {
|
|
return libcommon.Hash{}, nil
|
|
}
|
|
return libcommon.BytesToHash(val), nil
|
|
}
|
|
|
|
func WriteBeaconBlockHeader(ctx context.Context, tx kv.RwTx, signedHeader *cltypes.SignedBeaconBlockHeader) error {
|
|
headersBytes, err := signedHeader.EncodeSSZ(nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
blockRoot, err := signedHeader.Header.HashSSZ()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return tx.Put(kv.BeaconBlockHeaders, blockRoot[:], headersBytes)
|
|
}
|
|
|
|
func WriteBeaconBlockHeaderAndIndicies(ctx context.Context, tx kv.RwTx, signedHeader *cltypes.SignedBeaconBlockHeader, forceCanonical bool) error {
|
|
blockRoot, err := signedHeader.Header.HashSSZ()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := WriteBeaconBlockHeader(ctx, tx, signedHeader); err != nil {
|
|
return err
|
|
}
|
|
if err := WriteHeaderSlot(tx, blockRoot, signedHeader.Header.Slot); err != nil {
|
|
return err
|
|
}
|
|
if err := WriteStateRoot(tx, blockRoot, signedHeader.Header.Root); err != nil {
|
|
return err
|
|
}
|
|
if err := WriteParentBlockRoot(ctx, tx, blockRoot, signedHeader.Header.ParentRoot); err != nil {
|
|
return err
|
|
}
|
|
if forceCanonical {
|
|
if err := MarkRootCanonical(ctx, tx, signedHeader.Header.Slot, blockRoot); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func ReadParentBlockRoot(ctx context.Context, tx kv.Tx, blockRoot libcommon.Hash) (libcommon.Hash, error) {
|
|
var parentRoot libcommon.Hash
|
|
|
|
pRoot, err := tx.GetOne(kv.BlockRootToParentRoot, blockRoot[:])
|
|
if err != nil {
|
|
return libcommon.Hash{}, err
|
|
}
|
|
|
|
copy(parentRoot[:], pRoot)
|
|
|
|
return parentRoot, nil
|
|
}
|
|
|
|
func WriteParentBlockRoot(ctx context.Context, tx kv.RwTx, blockRoot, parentRoot libcommon.Hash) error {
|
|
return tx.Put(kv.BlockRootToParentRoot, blockRoot[:], parentRoot[:])
|
|
}
|
|
|
|
func TruncateCanonicalChain(ctx context.Context, tx kv.RwTx, slot uint64) error {
|
|
return tx.ForEach(kv.CanonicalBlockRoots, base_encoding.Encode64ToBytes4(slot), func(k, _ []byte) error {
|
|
return tx.Delete(kv.CanonicalBlockRoots, k)
|
|
})
|
|
}
|
|
|
|
func PruneSignedHeaders(tx kv.RwTx, from uint64) error {
|
|
cursor, err := tx.RwCursor(kv.BeaconBlockHeaders)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for k, _, err := cursor.Seek(base_encoding.Encode64ToBytes4(from)); err == nil && k != nil; k, _, err = cursor.Prev() {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := cursor.DeleteCurrent(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func RangeBlockRoots(ctx context.Context, tx kv.Tx, fromSlot, toSlot uint64, fn func(slot uint64, beaconBlockRoot libcommon.Hash) bool) error {
|
|
cursor, err := tx.Cursor(kv.CanonicalBlockRoots)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for k, v, err := cursor.Seek(base_encoding.Encode64ToBytes4(fromSlot)); err == nil && k != nil && base_encoding.Decode64FromBytes4(k) <= toSlot; k, v, err = cursor.Next() {
|
|
if !fn(base_encoding.Decode64FromBytes4(k), libcommon.BytesToHash(v)) {
|
|
break
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
func PruneBlockRoots(ctx context.Context, tx kv.RwTx, fromSlot, toSlot uint64) error {
|
|
cursor, err := tx.RwCursor(kv.CanonicalBlockRoots)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for k, _, err := cursor.Seek(base_encoding.Encode64ToBytes4(fromSlot)); err == nil && k != nil && base_encoding.Decode64FromBytes4(k) <= toSlot; k, _, err = cursor.Next() {
|
|
if err := cursor.DeleteCurrent(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
func ReadBeaconBlockRootsInSlotRange(ctx context.Context, tx kv.Tx, fromSlot, count uint64) ([]libcommon.Hash, []uint64, error) {
|
|
blockRoots := make([]libcommon.Hash, 0, count)
|
|
slots := make([]uint64, 0, count)
|
|
cursor, err := tx.Cursor(kv.CanonicalBlockRoots)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
currentCount := uint64(0)
|
|
for k, v, err := cursor.Seek(base_encoding.Encode64ToBytes4(fromSlot)); err == nil && k != nil && currentCount != count; k, v, err = cursor.Next() {
|
|
currentCount++
|
|
blockRoots = append(blockRoots, libcommon.BytesToHash(v))
|
|
slots = append(slots, base_encoding.Decode64FromBytes4(k))
|
|
}
|
|
return blockRoots, slots, err
|
|
}
|
|
|
|
func ReadSignedHeaderByBlockRoot(ctx context.Context, tx kv.Tx, blockRoot libcommon.Hash) (*cltypes.SignedBeaconBlockHeader, bool, error) {
|
|
h := &cltypes.SignedBeaconBlockHeader{Header: &cltypes.BeaconBlockHeader{}}
|
|
headerBytes, err := tx.GetOne(kv.BeaconBlockHeaders, blockRoot[:])
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
if len(headerBytes) == 0 {
|
|
return nil, false, nil
|
|
}
|
|
if err := h.DecodeSSZ(headerBytes, 0); err != nil {
|
|
return nil, false, fmt.Errorf("failed to decode BeaconHeader: %v", err)
|
|
}
|
|
canonical, err := ReadCanonicalBlockRoot(tx, h.Header.Slot)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
return h, canonical == blockRoot, nil
|
|
}
|