mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
beacon/light: made PeriodRange a parent struct of canonicalStore
This commit is contained in:
parent
fcb1d9cb15
commit
1657e4ea5b
1 changed files with 48 additions and 48 deletions
|
|
@ -148,41 +148,41 @@ func NewCommitteeChain(db ethdb.KeyValueStore, forks types.Forks, signerThreshol
|
||||||
}
|
}
|
||||||
|
|
||||||
// check validity constraints
|
// check validity constraints
|
||||||
if !s.updates.periodRange.IsEmpty() {
|
if !s.updates.IsEmpty() {
|
||||||
if !s.genesisInit {
|
if !s.genesisInit {
|
||||||
log.Crit("Inconsistent database error: updates present but genesis data is not initialized")
|
log.Crit("Inconsistent database error: updates present but genesis data is not initialized")
|
||||||
}
|
}
|
||||||
if s.fixedRoots.periodRange.IsEmpty() || s.updates.periodRange.First < s.fixedRoots.periodRange.First ||
|
if s.fixedRoots.IsEmpty() || s.updates.First < s.fixedRoots.First ||
|
||||||
s.updates.periodRange.First >= s.fixedRoots.periodRange.AfterLast {
|
s.updates.First >= s.fixedRoots.AfterLast {
|
||||||
log.Crit("Inconsistent database error: first update is not in the fixed roots range")
|
log.Crit("Inconsistent database error: first update is not in the fixed roots range")
|
||||||
}
|
}
|
||||||
if s.committees.periodRange.First > s.updates.periodRange.First || s.committees.periodRange.AfterLast <= s.updates.periodRange.AfterLast {
|
if s.committees.First > s.updates.First || s.committees.AfterLast <= s.updates.AfterLast {
|
||||||
log.Crit("Inconsistent database error: missing committees in update range")
|
log.Crit("Inconsistent database error: missing committees in update range")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !s.committees.periodRange.IsEmpty() {
|
if !s.committees.IsEmpty() {
|
||||||
if s.fixedRoots.periodRange.IsEmpty() || s.committees.periodRange.First < s.fixedRoots.periodRange.First ||
|
if s.fixedRoots.IsEmpty() || s.committees.First < s.fixedRoots.First ||
|
||||||
s.committees.periodRange.First >= s.fixedRoots.periodRange.AfterLast {
|
s.committees.First >= s.fixedRoots.AfterLast {
|
||||||
log.Crit("Inconsistent database error: first committee is not in the fixed roots range")
|
log.Crit("Inconsistent database error: first committee is not in the fixed roots range")
|
||||||
}
|
}
|
||||||
if s.committees.periodRange.AfterLast > s.fixedRoots.periodRange.AfterLast && s.committees.periodRange.AfterLast > s.updates.periodRange.AfterLast+1 {
|
if s.committees.AfterLast > s.fixedRoots.AfterLast && s.committees.AfterLast > s.updates.AfterLast+1 {
|
||||||
log.Crit("Inconsistent database error: last committee is neither in the fixed roots range nor proven by updates")
|
log.Crit("Inconsistent database error: last committee is neither in the fixed roots range nor proven by updates")
|
||||||
}
|
}
|
||||||
log.Trace("Sync committee chain loaded", "first period", s.committees.periodRange.First, "last period", s.committees.periodRange.AfterLast-1)
|
log.Trace("Sync committee chain loaded", "first period", s.committees.First, "last period", s.committees.AfterLast-1)
|
||||||
}
|
}
|
||||||
// roll back invalid updates (might be necessary if forks have been changed since last time)
|
// roll back invalid updates (might be necessary if forks have been changed since last time)
|
||||||
var batch ethdb.Batch
|
var batch ethdb.Batch
|
||||||
for !s.updates.periodRange.IsEmpty() {
|
for !s.updates.IsEmpty() {
|
||||||
if update := s.updates.get(s.updates.periodRange.AfterLast - 1); update == nil || s.verifyUpdate(update) {
|
if update := s.updates.get(s.updates.AfterLast - 1); update == nil || s.verifyUpdate(update) {
|
||||||
if update == nil {
|
if update == nil {
|
||||||
log.Crit("Sync committee update missing", "period", s.updates.periodRange.AfterLast-1)
|
log.Crit("Sync committee update missing", "period", s.updates.AfterLast-1)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if batch == nil {
|
if batch == nil {
|
||||||
batch = s.db.NewBatch()
|
batch = s.db.NewBatch()
|
||||||
}
|
}
|
||||||
s.rollback(batch, s.updates.periodRange.AfterLast)
|
s.rollback(batch, s.updates.AfterLast)
|
||||||
}
|
}
|
||||||
if batch != nil {
|
if batch != nil {
|
||||||
if err := batch.Write(); err != nil {
|
if err := batch.Write(); err != nil {
|
||||||
|
|
@ -241,11 +241,11 @@ func (s *CommitteeChain) AddFixedRoot(period uint64, root common.Hash) error {
|
||||||
|
|
||||||
batch := s.db.NewBatch()
|
batch := s.db.NewBatch()
|
||||||
oldRoot := s.getCommitteeRoot(period)
|
oldRoot := s.getCommitteeRoot(period)
|
||||||
if !s.fixedRoots.periodRange.CanExpand(period) {
|
if !s.fixedRoots.CanExpand(period) {
|
||||||
if root != oldRoot {
|
if root != oldRoot {
|
||||||
return ErrInvalidPeriod
|
return ErrInvalidPeriod
|
||||||
}
|
}
|
||||||
for p := s.fixedRoots.periodRange.AfterLast; p <= period; p++ {
|
for p := s.fixedRoots.AfterLast; p <= period; p++ {
|
||||||
s.fixedRoots.add(batch, p, s.getCommitteeRoot(p))
|
s.fixedRoots.add(batch, p, s.getCommitteeRoot(p))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -265,16 +265,16 @@ func (s *CommitteeChain) DeleteFixedRootsFrom(period uint64) error {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
if period >= s.fixedRoots.periodRange.AfterLast {
|
if period >= s.fixedRoots.AfterLast {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
batch := s.db.NewBatch()
|
batch := s.db.NewBatch()
|
||||||
s.fixedRoots.deleteFrom(batch, period)
|
s.fixedRoots.deleteFrom(batch, period)
|
||||||
if s.updates.periodRange.IsEmpty() || period <= s.updates.periodRange.First {
|
if s.updates.IsEmpty() || period <= s.updates.First {
|
||||||
s.updates.deleteFrom(batch, period)
|
s.updates.deleteFrom(batch, period)
|
||||||
s.deleteCommitteesFrom(batch, period)
|
s.deleteCommitteesFrom(batch, period)
|
||||||
} else {
|
} else {
|
||||||
fromPeriod := s.updates.periodRange.AfterLast + 1
|
fromPeriod := s.updates.AfterLast + 1
|
||||||
if period > fromPeriod {
|
if period > fromPeriod {
|
||||||
fromPeriod = period
|
fromPeriod = period
|
||||||
}
|
}
|
||||||
|
|
@ -298,7 +298,7 @@ func (s *CommitteeChain) AddCommittee(period uint64, committee *types.Serialized
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
if !s.committees.periodRange.CanExpand(period) {
|
if !s.committees.CanExpand(period) {
|
||||||
return ErrInvalidPeriod
|
return ErrInvalidPeriod
|
||||||
}
|
}
|
||||||
root := s.getCommitteeRoot(period)
|
root := s.getCommitteeRoot(period)
|
||||||
|
|
@ -308,7 +308,7 @@ func (s *CommitteeChain) AddCommittee(period uint64, committee *types.Serialized
|
||||||
if root != committee.Root() {
|
if root != committee.Root() {
|
||||||
return ErrWrongCommitteeRoot
|
return ErrWrongCommitteeRoot
|
||||||
}
|
}
|
||||||
if !s.committees.periodRange.Includes(period) {
|
if !s.committees.Includes(period) {
|
||||||
s.committees.add(nil, period, committee)
|
s.committees.add(nil, period, committee)
|
||||||
s.syncCommitteeCache.Remove(period)
|
s.syncCommitteeCache.Remove(period)
|
||||||
}
|
}
|
||||||
|
|
@ -323,7 +323,7 @@ func (s *CommitteeChain) InsertUpdate(update *types.LightClientUpdate, nextCommi
|
||||||
return ErrNotInitialized
|
return ErrNotInitialized
|
||||||
}
|
}
|
||||||
period := update.Header.SyncPeriod()
|
period := update.Header.SyncPeriod()
|
||||||
if !s.updates.periodRange.CanExpand(period) || !s.committees.periodRange.Includes(period) {
|
if !s.updates.CanExpand(period) || !s.committees.Includes(period) {
|
||||||
return ErrInvalidPeriod
|
return ErrInvalidPeriod
|
||||||
}
|
}
|
||||||
if s.minimumUpdateScore.BetterThan(update.Score()) {
|
if s.minimumUpdateScore.BetterThan(update.Score()) {
|
||||||
|
|
@ -338,13 +338,13 @@ func (s *CommitteeChain) InsertUpdate(update *types.LightClientUpdate, nextCommi
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if s.fixedRoots.periodRange.Includes(period+1) && reorg {
|
if s.fixedRoots.Includes(period+1) && reorg {
|
||||||
return ErrCannotReorg
|
return ErrCannotReorg
|
||||||
}
|
}
|
||||||
if !s.verifyUpdate(update) {
|
if !s.verifyUpdate(update) {
|
||||||
return ErrInvalidUpdate
|
return ErrInvalidUpdate
|
||||||
}
|
}
|
||||||
addCommittee := !s.committees.periodRange.Includes(period+1) || reorg
|
addCommittee := !s.committees.Includes(period+1) || reorg
|
||||||
if addCommittee {
|
if addCommittee {
|
||||||
if nextCommittee == nil {
|
if nextCommittee == nil {
|
||||||
return ErrNeedCommittee
|
return ErrNeedCommittee
|
||||||
|
|
@ -374,13 +374,13 @@ func (s *CommitteeChain) NextSyncPeriod() (uint64, bool) {
|
||||||
s.lock.RLock()
|
s.lock.RLock()
|
||||||
defer s.lock.RUnlock()
|
defer s.lock.RUnlock()
|
||||||
|
|
||||||
if !s.genesisInit || s.committees.periodRange.IsEmpty() {
|
if !s.genesisInit || s.committees.IsEmpty() {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
if !s.updates.periodRange.IsEmpty() {
|
if !s.updates.IsEmpty() {
|
||||||
return s.updates.periodRange.AfterLast, true
|
return s.updates.AfterLast, true
|
||||||
}
|
}
|
||||||
return s.committees.periodRange.AfterLast - 1, true
|
return s.committees.AfterLast - 1, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CommitteeChain) rollback(batch ethdb.Batch, period uint64) {
|
func (s *CommitteeChain) rollback(batch ethdb.Batch, period uint64) {
|
||||||
|
|
@ -468,12 +468,12 @@ func (s *CommitteeChain) verifyUpdate(update *types.LightClientUpdate) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
type canonicalStore[T any] struct {
|
type canonicalStore[T any] struct {
|
||||||
db ethdb.KeyValueStore
|
types.PeriodRange
|
||||||
keyPrefix []byte
|
db ethdb.KeyValueStore
|
||||||
cache *lru.Cache[uint64, T]
|
keyPrefix []byte
|
||||||
periodRange types.PeriodRange //TODO make it a parent struct?
|
cache *lru.Cache[uint64, T]
|
||||||
encode func(T) ([]byte, error)
|
encode func(T) ([]byte, error)
|
||||||
decode func([]byte) (T, error)
|
decode func([]byte) (T, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCanonicalStore[T any](db ethdb.KeyValueStore, keyPrefix []byte,
|
func newCanonicalStore[T any](db ethdb.KeyValueStore, keyPrefix []byte,
|
||||||
|
|
@ -491,15 +491,15 @@ func newCanonicalStore[T any](db ethdb.KeyValueStore, keyPrefix []byte,
|
||||||
)
|
)
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
period := binary.BigEndian.Uint64(iter.Key()[kl : kl+8])
|
period := binary.BigEndian.Uint64(iter.Key()[kl : kl+8])
|
||||||
if cs.periodRange.First == 0 {
|
if cs.First == 0 {
|
||||||
cs.periodRange.First = period
|
cs.First = period
|
||||||
} else if cs.periodRange.AfterLast != period {
|
} else if cs.AfterLast != period {
|
||||||
if iter.Next() {
|
if iter.Next() {
|
||||||
log.Error("Gap in the canonical chain database")
|
log.Error("Gap in the canonical chain database")
|
||||||
}
|
}
|
||||||
break // continuity guaranteed
|
break // continuity guaranteed
|
||||||
}
|
}
|
||||||
cs.periodRange.AfterLast = period + 1
|
cs.AfterLast = period + 1
|
||||||
}
|
}
|
||||||
iter.Release()
|
iter.Release()
|
||||||
return cs
|
return cs
|
||||||
|
|
@ -516,8 +516,8 @@ func (cs *canonicalStore[T]) getDbKey(period uint64) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *canonicalStore[T]) add(batch ethdb.Batch, period uint64, value T) {
|
func (cs *canonicalStore[T]) add(batch ethdb.Batch, period uint64, value T) {
|
||||||
if !cs.periodRange.CanExpand(period) {
|
if !cs.CanExpand(period) {
|
||||||
log.Error("Cannot expand canonical store", "range.first", cs.periodRange.First, "range.afterLast", cs.periodRange.AfterLast, "new period", period)
|
log.Error("Cannot expand canonical store", "range.first", cs.First, "range.afterLast", cs.AfterLast, "new period", period)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
enc, err := cs.encode(value)
|
enc, err := cs.encode(value)
|
||||||
|
|
@ -534,25 +534,25 @@ func (cs *canonicalStore[T]) add(batch ethdb.Batch, period uint64, value T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error writing into canonical store value database", "error", err)
|
log.Error("Error writing into canonical store value database", "error", err)
|
||||||
}
|
}
|
||||||
cs.periodRange.Expand(period)
|
cs.Expand(period)
|
||||||
}
|
}
|
||||||
|
|
||||||
// should only be used in batch mode
|
// should only be used in batch mode
|
||||||
func (cs *canonicalStore[T]) deleteFrom(batch ethdb.Batch, fromPeriod uint64) (deleted types.PeriodRange) {
|
func (cs *canonicalStore[T]) deleteFrom(batch ethdb.Batch, fromPeriod uint64) (deleted types.PeriodRange) {
|
||||||
if fromPeriod >= cs.periodRange.AfterLast {
|
if fromPeriod >= cs.AfterLast {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if fromPeriod < cs.periodRange.First {
|
if fromPeriod < cs.First {
|
||||||
fromPeriod = cs.periodRange.First
|
fromPeriod = cs.First
|
||||||
}
|
}
|
||||||
deleted = types.PeriodRange{First: fromPeriod, AfterLast: cs.periodRange.AfterLast}
|
deleted = types.PeriodRange{First: fromPeriod, AfterLast: cs.AfterLast}
|
||||||
for period := fromPeriod; period < cs.periodRange.AfterLast; period++ {
|
for period := fromPeriod; period < cs.AfterLast; period++ {
|
||||||
batch.Delete(cs.getDbKey(period))
|
batch.Delete(cs.getDbKey(period))
|
||||||
}
|
}
|
||||||
if fromPeriod > cs.periodRange.First {
|
if fromPeriod > cs.First {
|
||||||
cs.periodRange.AfterLast = fromPeriod
|
cs.AfterLast = fromPeriod
|
||||||
} else {
|
} else {
|
||||||
cs.periodRange = types.PeriodRange{}
|
cs.PeriodRange = types.PeriodRange{}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue