beacon/light: always use rlp encoding in canonicalStore

This commit is contained in:
Zsolt Felfoldi 2023-12-05 04:50:34 +01:00
parent 0bf9f8e4bf
commit 3b38b3b8ac
2 changed files with 8 additions and 46 deletions

View file

@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/common/lru"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
) )
// canonicalStore stores instances of the given type in a database and caches // canonicalStore stores instances of the given type in a database and caches
@ -33,18 +34,13 @@ type canonicalStore[T any] struct {
keyPrefix []byte keyPrefix []byte
periods periodRange periods periodRange
cache *lru.Cache[uint64, T] cache *lru.Cache[uint64, T]
encode func(T) ([]byte, error)
decode func([]byte) (T, error)
} }
// newCanonicalStore creates a new canonicalStore and loads all keys associated // newCanonicalStore creates a new canonicalStore and loads all keys associated
// with the keyPrefix in order to determine the ranges available in the database. // with the keyPrefix in order to determine the ranges available in the database.
func newCanonicalStore[T any](db ethdb.Iteratee, keyPrefix []byte, func newCanonicalStore[T any](db ethdb.Iteratee, keyPrefix []byte) (*canonicalStore[T], error) {
encode func(T) ([]byte, error), decode func([]byte) (T, error)) (*canonicalStore[T], error) {
cs := &canonicalStore[T]{ cs := &canonicalStore[T]{
keyPrefix: keyPrefix, keyPrefix: keyPrefix,
encode: encode,
decode: decode,
cache: lru.NewCache[uint64, T](100), cache: lru.NewCache[uint64, T](100),
} }
var ( var (
@ -81,7 +77,7 @@ func (cs *canonicalStore[T]) add(backend ethdb.KeyValueWriter, period uint64, va
if !cs.periods.canExpand(period) { if !cs.periods.canExpand(period) {
return fmt.Errorf("period expansion is not allowed, first: %d, next: %d, period: %d", cs.periods.Start, cs.periods.End, period) return fmt.Errorf("period expansion is not allowed, first: %d, next: %d, period: %d", cs.periods.Start, cs.periods.End, period)
} }
enc, err := cs.encode(value) enc, err := rlp.EncodeToBytes(value)
if err != nil { if err != nil {
return err return err
} }
@ -107,7 +103,7 @@ func (cs *canonicalStore[T]) deleteFrom(db ethdb.KeyValueWriter, fromPeriod uint
// get returns the item at the given period or the null value of the given type // get returns the item at the given period or the null value of the given type
// if no item is present. // if no item is present.
func (cs *canonicalStore[T]) get(backend ethdb.KeyValueReader, period uint64) (T, bool) { func (cs *canonicalStore[T]) get(backend ethdb.KeyValueReader, period uint64) (T, bool) {
var null T var null, value T
if !cs.periods.contains(period) { if !cs.periods.contains(period) {
return null, false return null, false
} }
@ -119,8 +115,7 @@ func (cs *canonicalStore[T]) get(backend ethdb.KeyValueReader, period uint64) (T
log.Error("Canonical store value not found", "period", period, "start", cs.periods.Start, "end", cs.periods.End) log.Error("Canonical store value not found", "period", period, "start", cs.periods.Start, "end", cs.periods.End)
return null, false return null, false
} }
value, err := cs.decode(enc) if err := rlp.DecodeBytes(enc, &value); err != nil {
if err != nil {
log.Error("Error decoding canonical store value", "error", err) log.Error("Error decoding canonical store value", "error", err)
return null, false return null, false
} }

View file

@ -31,7 +31,6 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
) )
var ( var (
@ -90,38 +89,6 @@ func NewCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signer
// newCommitteeChain creates a new CommitteeChain with the option of replacing the // newCommitteeChain creates a new CommitteeChain with the option of replacing the
// clock source and signature verification for testing purposes. // clock source and signature verification for testing purposes.
func newCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool, sigVerifier committeeSigVerifier, clock mclock.Clock, unixNano func() int64) *CommitteeChain { func newCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool, sigVerifier committeeSigVerifier, clock mclock.Clock, unixNano func() int64) *CommitteeChain {
var (
fixedCommitteeRootEncoder = func(root common.Hash) ([]byte, error) {
return root[:], nil
}
fixedCommitteeRootDecoder = func(enc []byte) (root common.Hash, err error) {
if len(enc) != common.HashLength {
return common.Hash{}, errors.New("incorrect length for committee root entry in the database")
}
return common.BytesToHash(enc), nil
}
committeeEncoder = func(committee *types.SerializedSyncCommittee) ([]byte, error) {
return committee[:], nil
}
committeeDecoder = func(enc []byte) (*types.SerializedSyncCommittee, error) {
if len(enc) == types.SerializedSyncCommitteeSize {
committee := new(types.SerializedSyncCommittee)
copy(committee[:], enc)
return committee, nil
}
return nil, errors.New("incorrect length for serialized committee entry in the database")
}
updateEncoder = func(update *types.LightClientUpdate) ([]byte, error) {
return rlp.EncodeToBytes(update)
}
updateDecoder = func(enc []byte) (*types.LightClientUpdate, error) {
update := new(types.LightClientUpdate)
if err := rlp.DecodeBytes(enc, update); err != nil {
return nil, err
}
return update, nil
}
)
s := &CommitteeChain{ s := &CommitteeChain{
committeeCache: lru.NewCache[uint64, syncCommittee](10), committeeCache: lru.NewCache[uint64, syncCommittee](10),
db: db, db: db,
@ -138,13 +105,13 @@ func newCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signer
} }
var err1, err2, err3 error var err1, err2, err3 error
if s.fixedCommitteeRoots, err1 = newCanonicalStore[common.Hash](db, rawdb.FixedCommitteeRootKey, fixedCommitteeRootEncoder, fixedCommitteeRootDecoder); err1 != nil { if s.fixedCommitteeRoots, err1 = newCanonicalStore[common.Hash](db, rawdb.FixedCommitteeRootKey); err1 != nil {
log.Error("Error creating fixed committee root store", "error", err1) log.Error("Error creating fixed committee root store", "error", err1)
} }
if s.committees, err2 = newCanonicalStore[*types.SerializedSyncCommittee](db, rawdb.SyncCommitteeKey, committeeEncoder, committeeDecoder); err2 != nil { if s.committees, err2 = newCanonicalStore[*types.SerializedSyncCommittee](db, rawdb.SyncCommitteeKey); err2 != nil {
log.Error("Error creating committee store", "error", err2) log.Error("Error creating committee store", "error", err2)
} }
if s.updates, err3 = newCanonicalStore[*types.LightClientUpdate](db, rawdb.BestUpdateKey, updateEncoder, updateDecoder); err3 != nil { if s.updates, err3 = newCanonicalStore[*types.LightClientUpdate](db, rawdb.BestUpdateKey); err3 != nil {
log.Error("Error creating update store", "error", err3) log.Error("Error creating update store", "error", err3)
} }
if err1 != nil || err2 != nil || err3 != nil || !s.checkConstraints() { if err1 != nil || err2 != nil || err3 != nil || !s.checkConstraints() {