mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
beacon/light: added comments and removed unused code
This commit is contained in:
parent
574f085715
commit
8ff38966c4
5 changed files with 68 additions and 74 deletions
|
|
@ -23,13 +23,12 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/beacon/params"
|
"github.com/ethereum/go-ethereum/beacon/params"
|
||||||
"github.com/ethereum/go-ethereum/beacon/types"
|
"github.com/ethereum/go-ethereum/beacon/types"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"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 checkpointKey = []byte("checkpoint-") // block root -> RLP(CheckpointData)
|
// CheckpointData contains a sync committee where light sync can be started,
|
||||||
|
// together with a proof through a beacon header and corresponding state.
|
||||||
|
// Note: CheckpointData is fetched from a server based on a known checkpoint hash.
|
||||||
type CheckpointData struct {
|
type CheckpointData struct {
|
||||||
Header types.Header
|
Header types.Header
|
||||||
CommitteeRoot common.Hash
|
CommitteeRoot common.Hash
|
||||||
|
|
@ -37,6 +36,7 @@ type CheckpointData struct {
|
||||||
CommitteeBranch merkle.Values
|
CommitteeBranch merkle.Values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate verifies the proof included in CheckpointData.
|
||||||
func (c *CheckpointData) Validate() error {
|
func (c *CheckpointData) Validate() error {
|
||||||
if c.CommitteeRoot != c.Committee.Root() {
|
if c.CommitteeRoot != c.Committee.Root() {
|
||||||
return errors.New("wrong committee root")
|
return errors.New("wrong committee root")
|
||||||
|
|
@ -44,7 +44,8 @@ func (c *CheckpointData) Validate() error {
|
||||||
return merkle.VerifyProof(c.Header.StateRoot, params.StateIndexSyncCommittee, c.CommitteeBranch, merkle.Value(c.CommitteeRoot))
|
return merkle.VerifyProof(c.Header.StateRoot, params.StateIndexSyncCommittee, c.CommitteeBranch, merkle.Value(c.CommitteeRoot))
|
||||||
}
|
}
|
||||||
|
|
||||||
// expected to be validated already
|
// InitChain initializes a CommitteeChain based on the checkpoint.
|
||||||
|
// Note that the checkpoint is expected to be already validated.
|
||||||
func (c *CheckpointData) InitChain(chain *CommitteeChain) {
|
func (c *CheckpointData) InitChain(chain *CommitteeChain) {
|
||||||
must := func(err error) {
|
must := func(err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -60,51 +61,3 @@ func (c *CheckpointData) InitChain(chain *CommitteeChain) {
|
||||||
must(chain.AddFixedRoot(period+1, common.Hash(c.CommitteeBranch[0])))
|
must(chain.AddFixedRoot(period+1, common.Hash(c.CommitteeBranch[0])))
|
||||||
must(chain.AddCommittee(period, c.Committee))
|
must(chain.AddCommittee(period, c.Committee))
|
||||||
}
|
}
|
||||||
|
|
||||||
type CheckpointStore struct {
|
|
||||||
chain *CommitteeChain
|
|
||||||
db ethdb.KeyValueStore
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCheckpointStore(db ethdb.KeyValueStore, chain *CommitteeChain) *CheckpointStore {
|
|
||||||
return &CheckpointStore{
|
|
||||||
db: db,
|
|
||||||
chain: chain,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCheckpointKey(checkpoint common.Hash) []byte {
|
|
||||||
var (
|
|
||||||
kl = len(checkpointKey)
|
|
||||||
key = make([]byte, kl+32)
|
|
||||||
)
|
|
||||||
copy(key[:kl], checkpointKey)
|
|
||||||
copy(key[kl:], checkpoint[:])
|
|
||||||
return key
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cs *CheckpointStore) Get(checkpoint common.Hash) *CheckpointData {
|
|
||||||
if enc, err := cs.db.Get(getCheckpointKey(checkpoint)); err == nil {
|
|
||||||
c := new(CheckpointData)
|
|
||||||
if err := rlp.DecodeBytes(enc, c); err != nil {
|
|
||||||
log.Error("Error decoding stored checkpoint", "error", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if committee := cs.chain.committees.get(c.Header.SyncPeriod()); committee != nil && committee.Root() == c.CommitteeRoot {
|
|
||||||
c.Committee = committee
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
log.Error("Missing committee for stored checkpoint", "period", c.Header.SyncPeriod())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cs *CheckpointStore) Store(c *CheckpointData) {
|
|
||||||
enc, err := rlp.EncodeToBytes(c)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Error encoding checkpoint for storage", "error", err)
|
|
||||||
}
|
|
||||||
if err := cs.db.Put(getCheckpointKey(c.Header.Hash()), enc); err != nil {
|
|
||||||
log.Error("Error storing checkpoint in database", "error", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -47,16 +47,25 @@ var (
|
||||||
syncCommitteeKey = []byte("committee-") // bigEndian64(syncPeriod) -> serialized committee
|
syncCommitteeKey = []byte("committee-") // bigEndian64(syncPeriod) -> serialized committee
|
||||||
)
|
)
|
||||||
|
|
||||||
// CommitteeChain maintains a chain of sync committee updates and a small
|
// CommitteeChain is a passive data structure that can validate, hold and update
|
||||||
// set of best known signed heads. It is used in all client configurations
|
// a chain of beacon light sync committees and updates. It requires at least one
|
||||||
// operating on a beacon chain. It can sync its update chain and receive signed
|
// externally set fixed committee root at the beginning of the chain which can
|
||||||
// heads from either an ODR or beacon node API backend and propagate/serve this
|
// be set either based on a CheckpointData or a trusted source (a local beacon
|
||||||
// data to subscribed peers. Received signed heads are validated based on the
|
// full node). This makes the structure useful for both light client and light
|
||||||
// known sync committee chain and added to the local set if valid or placed in a
|
// server setups.
|
||||||
// deferred queue if the committees are not synced up to the period of the new
|
//
|
||||||
// head yet.
|
// It always maintains the following consistency constraints:
|
||||||
// Sync committee chain is either initialized from a weak subjectivity checkpoint
|
// - a committee can only be present if its root hash matches an existing fixed
|
||||||
// or controlled by a BeaconChain that is driven by a trusted source (beacon node API).
|
// root or if it is proven by an update at the previous period
|
||||||
|
// - an update can only be present if a committee is present at the same period
|
||||||
|
// and the update signature is valid and has enough participants.
|
||||||
|
// The committee at the next period (proven by the update) should also be
|
||||||
|
// present (note that this means they can only be added together if neither
|
||||||
|
// is present yet). If a fixed root is present at the next period then the
|
||||||
|
// update can only be present if it proves the same committee root.
|
||||||
|
//
|
||||||
|
// Once synced to the current sync period, CommitteeChain can also validate
|
||||||
|
// signed beacon headers.
|
||||||
type CommitteeChain struct {
|
type CommitteeChain struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
db ethdb.KeyValueStore
|
db ethdb.KeyValueStore
|
||||||
|
|
@ -74,7 +83,7 @@ type CommitteeChain struct {
|
||||||
enforceTime bool
|
enforceTime bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCommitteeChain creates a new CommitteeChain
|
// NewCommitteeChain creates a new CommitteeChain.
|
||||||
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 {
|
||||||
s := &CommitteeChain{
|
s := &CommitteeChain{
|
||||||
fixedRoots: newCanonicalStore[common.Hash](db, fixedRootKey, func(root common.Hash) ([]byte, error) {
|
fixedRoots: newCanonicalStore[common.Hash](db, fixedRootKey, func(root common.Hash) ([]byte, error) {
|
||||||
|
|
@ -162,6 +171,7 @@ func NewCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signer
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset resets the committee chain.
|
||||||
func (s *CommitteeChain) Reset() {
|
func (s *CommitteeChain) Reset() {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
@ -173,6 +183,9 @@ func (s *CommitteeChain) Reset() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddFixedRoot sets a fixed committee root at the given period.
|
||||||
|
// Note that the period where the first committee is added has to have a fixed
|
||||||
|
// root which can either come from a CheckpointData or a trusted source.
|
||||||
func (s *CommitteeChain) AddFixedRoot(period uint64, root common.Hash) error {
|
func (s *CommitteeChain) AddFixedRoot(period uint64, root common.Hash) error {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
@ -199,6 +212,9 @@ func (s *CommitteeChain) AddFixedRoot(period uint64, root common.Hash) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteFixedRootsFrom deletes fixed roots starting from the given period.
|
||||||
|
// It also maintains chain consistency, meaning that it also deletes updates and
|
||||||
|
// committees if they are no longer supported by a valid update chain.
|
||||||
func (s *CommitteeChain) DeleteFixedRootsFrom(period uint64) error {
|
func (s *CommitteeChain) DeleteFixedRootsFrom(period uint64) error {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
@ -225,6 +241,7 @@ func (s *CommitteeChain) DeleteFixedRootsFrom(period uint64) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deleteCommitteesFrom deletes committees starting from the given period.
|
||||||
func (s *CommitteeChain) deleteCommitteesFrom(batch ethdb.Batch, period uint64) {
|
func (s *CommitteeChain) deleteCommitteesFrom(batch ethdb.Batch, period uint64) {
|
||||||
deleted := s.committees.deleteFrom(batch, period)
|
deleted := s.committees.deleteFrom(batch, period)
|
||||||
for period := deleted.First; period < deleted.AfterLast; period++ {
|
for period := deleted.First; period < deleted.AfterLast; period++ {
|
||||||
|
|
@ -232,10 +249,12 @@ func (s *CommitteeChain) deleteCommitteesFrom(batch ethdb.Batch, period uint64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCommittee returns the committee at the given period.
|
||||||
func (s *CommitteeChain) GetCommittee(period uint64) *types.SerializedSyncCommittee {
|
func (s *CommitteeChain) GetCommittee(period uint64) *types.SerializedSyncCommittee {
|
||||||
return s.committees.get(period)
|
return s.committees.get(period)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddCommittee adds a committee at the given period if possible.
|
||||||
func (s *CommitteeChain) AddCommittee(period uint64, committee *types.SerializedSyncCommittee) error {
|
func (s *CommitteeChain) AddCommittee(period uint64, committee *types.SerializedSyncCommittee) error {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
@ -257,10 +276,12 @@ func (s *CommitteeChain) AddCommittee(period uint64, committee *types.Serialized
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUpdate returns the update at the given period.
|
||||||
func (s *CommitteeChain) GetUpdate(period uint64) *types.LightClientUpdate {
|
func (s *CommitteeChain) GetUpdate(period uint64) *types.LightClientUpdate {
|
||||||
return s.updates.get(period)
|
return s.updates.get(period)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InsertUpdate adds a new update if possible.
|
||||||
func (s *CommitteeChain) InsertUpdate(update *types.LightClientUpdate, nextCommittee *types.SerializedSyncCommittee) error {
|
func (s *CommitteeChain) InsertUpdate(update *types.LightClientUpdate, nextCommittee *types.SerializedSyncCommittee) error {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
@ -313,6 +334,8 @@ func (s *CommitteeChain) InsertUpdate(update *types.LightClientUpdate, nextCommi
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NextSyncPeriod returns the next period where an update can be added and also
|
||||||
|
// whether the chain is initialized at all.
|
||||||
func (s *CommitteeChain) NextSyncPeriod() (uint64, bool) {
|
func (s *CommitteeChain) NextSyncPeriod() (uint64, bool) {
|
||||||
s.lock.RLock()
|
s.lock.RLock()
|
||||||
defer s.lock.RUnlock()
|
defer s.lock.RUnlock()
|
||||||
|
|
@ -326,6 +349,8 @@ func (s *CommitteeChain) NextSyncPeriod() (uint64, bool) {
|
||||||
return s.committees.AfterLast - 1, true
|
return s.committees.AfterLast - 1, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rollback removes all committees and fixed roots from the given period and updates
|
||||||
|
// starting from the previous period.
|
||||||
func (s *CommitteeChain) rollback(batch ethdb.Batch, period uint64) {
|
func (s *CommitteeChain) rollback(batch ethdb.Batch, period uint64) {
|
||||||
s.deleteCommitteesFrom(batch, period)
|
s.deleteCommitteesFrom(batch, period)
|
||||||
s.fixedRoots.deleteFrom(batch, period)
|
s.fixedRoots.deleteFrom(batch, period)
|
||||||
|
|
@ -335,6 +360,9 @@ func (s *CommitteeChain) rollback(batch ethdb.Batch, period uint64) {
|
||||||
s.updates.deleteFrom(batch, period)
|
s.updates.deleteFrom(batch, period)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getCommitteeRoot returns the committee root at the given period, either fixed,
|
||||||
|
// proven by a previous update or both. It returns an empty hash if the committee
|
||||||
|
// root is unknown.
|
||||||
func (s *CommitteeChain) getCommitteeRoot(period uint64) common.Hash {
|
func (s *CommitteeChain) getCommitteeRoot(period uint64) common.Hash {
|
||||||
if root := s.fixedRoots.get(period); root != (common.Hash{}) || period == 0 {
|
if root := s.fixedRoots.get(period); root != (common.Hash{}) || period == 0 {
|
||||||
return root
|
return root
|
||||||
|
|
@ -345,8 +373,7 @@ func (s *CommitteeChain) getCommitteeRoot(period uint64) common.Hash {
|
||||||
return common.Hash{}
|
return common.Hash{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSyncCommittee returns the deserialized sync committee at the given period
|
// getSyncCommittee returns the deserialized sync committee at the given period.
|
||||||
// of the current local committee chain (tracker mutex lock expected).
|
|
||||||
func (s *CommitteeChain) getSyncCommittee(period uint64) syncCommittee {
|
func (s *CommitteeChain) getSyncCommittee(period uint64) syncCommittee {
|
||||||
if c, ok := s.syncCommitteeCache.Get(period); ok {
|
if c, ok := s.syncCommitteeCache.Get(period); ok {
|
||||||
return c
|
return c
|
||||||
|
|
@ -364,9 +391,9 @@ func (s *CommitteeChain) getSyncCommittee(period uint64) syncCommittee {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifySignedHeader returns true if the given signed head has a valid signature
|
// VerifySignedHeader returns true if the given signed header has a valid signature
|
||||||
// according to the local committee chain. The caller should ensure that the
|
// according to the local committee chain. The caller should ensure that the
|
||||||
// committees advertised by the same source where the signed head came from are
|
// committees advertised by the same source where the signed header came from are
|
||||||
// synced before verifying the signature.
|
// synced before verifying the signature.
|
||||||
// The age of the header is also returned (the time elapsed since the beginning
|
// The age of the header is also returned (the time elapsed since the beginning
|
||||||
// of the given slot, according to the local system clock). If enforceTime is
|
// of the given slot, according to the local system clock). If enforceTime is
|
||||||
|
|
@ -378,7 +405,6 @@ func (s *CommitteeChain) VerifySignedHeader(head types.SignedHeader) (bool, time
|
||||||
return s.verifySignedHeader(head)
|
return s.verifySignedHeader(head)
|
||||||
}
|
}
|
||||||
|
|
||||||
// (rlock required)
|
|
||||||
func (s *CommitteeChain) verifySignedHeader(head types.SignedHeader) (bool, time.Duration) {
|
func (s *CommitteeChain) verifySignedHeader(head types.SignedHeader) (bool, time.Duration) {
|
||||||
var (
|
var (
|
||||||
slotTime = int64(time.Second) * int64(s.config.GenesisTime+head.Header.Slot*12)
|
slotTime = int64(time.Second) * int64(s.config.GenesisTime+head.Header.Slot*12)
|
||||||
|
|
@ -400,7 +426,6 @@ func (s *CommitteeChain) verifySignedHeader(head types.SignedHeader) (bool, time
|
||||||
// verifyUpdate checks whether the header signature is correct and the update
|
// verifyUpdate checks whether the header signature is correct and the update
|
||||||
// fits into the specified constraints (assumes that the update has been
|
// fits into the specified constraints (assumes that the update has been
|
||||||
// successfully validated previously)
|
// successfully validated previously)
|
||||||
// (rlock required)
|
|
||||||
func (s *CommitteeChain) verifyUpdate(update *types.LightClientUpdate) bool {
|
func (s *CommitteeChain) verifyUpdate(update *types.LightClientUpdate) bool {
|
||||||
// Note: SignatureSlot determines the sync period of the committee used for signature
|
// Note: SignatureSlot determines the sync period of the committee used for signature
|
||||||
// verification. Though in reality SignatureSlot is always bigger than update.Header.Slot,
|
// verification. Though in reality SignatureSlot is always bigger than update.Header.Slot,
|
||||||
|
|
@ -413,6 +438,8 @@ func (s *CommitteeChain) verifyUpdate(update *types.LightClientUpdate) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// canonicalStore stores instances of the given type in a database and caches
|
||||||
|
// them in memory, associated with a continuous range of period numbers.
|
||||||
type canonicalStore[T any] struct {
|
type canonicalStore[T any] struct {
|
||||||
Range
|
Range
|
||||||
db ethdb.KeyValueStore
|
db ethdb.KeyValueStore
|
||||||
|
|
@ -422,6 +449,7 @@ type canonicalStore[T any] struct {
|
||||||
decode func([]byte) (T, error)
|
decode func([]byte) (T, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newCanonicalStore creates a new canonicalStore.
|
||||||
func newCanonicalStore[T any](db ethdb.KeyValueStore, keyPrefix []byte,
|
func newCanonicalStore[T any](db ethdb.KeyValueStore, keyPrefix []byte,
|
||||||
encode func(T) ([]byte, error), decode func([]byte) (T, error)) *canonicalStore[T] {
|
encode func(T) ([]byte, error), decode func([]byte) (T, error)) *canonicalStore[T] {
|
||||||
cs := &canonicalStore[T]{
|
cs := &canonicalStore[T]{
|
||||||
|
|
@ -451,6 +479,7 @@ func newCanonicalStore[T any](db ethdb.KeyValueStore, keyPrefix []byte,
|
||||||
return cs
|
return cs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getDbKey returns the database key belonging to the given period.
|
||||||
func (cs *canonicalStore[T]) getDbKey(period uint64) []byte {
|
func (cs *canonicalStore[T]) getDbKey(period uint64) []byte {
|
||||||
var (
|
var (
|
||||||
kl = len(cs.keyPrefix)
|
kl = len(cs.keyPrefix)
|
||||||
|
|
@ -461,6 +490,8 @@ func (cs *canonicalStore[T]) getDbKey(period uint64) []byte {
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add adds the given item to the database. It also ensures that the range remains
|
||||||
|
// continuous. Can be used both in batch mode and as a standalone operation.
|
||||||
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.CanExpand(period) {
|
if !cs.CanExpand(period) {
|
||||||
log.Error("Cannot expand canonical store", "range.first", cs.First, "range.afterLast", cs.AfterLast, "new period", period)
|
log.Error("Cannot expand canonical store", "range.first", cs.First, "range.afterLast", cs.AfterLast, "new period", period)
|
||||||
|
|
@ -484,7 +515,8 @@ func (cs *canonicalStore[T]) add(batch ethdb.Batch, period uint64, value T) {
|
||||||
cs.Expand(period)
|
cs.Expand(period)
|
||||||
}
|
}
|
||||||
|
|
||||||
// should only be used in batch mode
|
// deleteFrom removes items starting from the given period. Can only be used in
|
||||||
|
// batch mode.
|
||||||
func (cs *canonicalStore[T]) deleteFrom(batch ethdb.Batch, fromPeriod uint64) (deleted Range) {
|
func (cs *canonicalStore[T]) deleteFrom(batch ethdb.Batch, fromPeriod uint64) (deleted Range) {
|
||||||
if fromPeriod >= cs.AfterLast {
|
if fromPeriod >= cs.AfterLast {
|
||||||
return
|
return
|
||||||
|
|
@ -505,6 +537,8 @@ func (cs *canonicalStore[T]) deleteFrom(batch ethdb.Batch, fromPeriod uint64) (d
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get returns the item at the given period or the null value of the given type
|
||||||
|
// if no item is present.
|
||||||
func (cs *canonicalStore[T]) get(period uint64) T {
|
func (cs *canonicalStore[T]) get(period uint64) T {
|
||||||
if value, ok := cs.cache.Get(period); ok {
|
if value, ok := cs.cache.Get(period); ok {
|
||||||
return value
|
return value
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
package light
|
package light
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"crypto/rand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,23 +16,29 @@
|
||||||
|
|
||||||
package light
|
package light
|
||||||
|
|
||||||
|
// Range represents a (possibly zero-length) range of integers (sync periods).
|
||||||
type Range struct {
|
type Range struct {
|
||||||
First uint64
|
First uint64
|
||||||
AfterLast uint64
|
AfterLast uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsEmpty returns true if the length of the range is zero.
|
||||||
func (a Range) IsEmpty() bool {
|
func (a Range) IsEmpty() bool {
|
||||||
return a.AfterLast == a.First
|
return a.AfterLast == a.First
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Includes returns true if the range includes the given period.
|
||||||
func (a Range) Includes(period uint64) bool {
|
func (a Range) Includes(period uint64) bool {
|
||||||
return period >= a.First && period < a.AfterLast
|
return period >= a.First && period < a.AfterLast
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CanExpand returns true if the range can be expanded with the given period
|
||||||
|
// (either the range is empty or the new period is right before or after the range).
|
||||||
func (a Range) CanExpand(period uint64) bool {
|
func (a Range) CanExpand(period uint64) bool {
|
||||||
return a.IsEmpty() || (period+1 >= a.First && period <= a.AfterLast)
|
return a.IsEmpty() || (period+1 >= a.First && period <= a.AfterLast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expand expands the range with the given period (assumes that CanExpand returned true).
|
||||||
func (a *Range) Expand(period uint64) {
|
func (a *Range) Expand(period uint64) {
|
||||||
if a.IsEmpty() {
|
if a.IsEmpty() {
|
||||||
a.First, a.AfterLast = period, period+1
|
a.First, a.AfterLast = period, period+1
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,9 @@
|
||||||
package light
|
package light
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"math/rand"
|
mrand "math/rand"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/beacon/merkle"
|
"github.com/ethereum/go-ethereum/beacon/merkle"
|
||||||
"github.com/ethereum/go-ethereum/beacon/params"
|
"github.com/ethereum/go-ethereum/beacon/params"
|
||||||
|
|
@ -73,7 +74,7 @@ func GenerateTestCheckpoint(period uint64, committee *types.SerializedSyncCommit
|
||||||
|
|
||||||
func makeBitmask(signerCount int) (bitmask [params.SyncCommitteeBitmaskSize]byte) {
|
func makeBitmask(signerCount int) (bitmask [params.SyncCommitteeBitmaskSize]byte) {
|
||||||
for i := 0; i < params.SyncCommitteeSize; i++ {
|
for i := 0; i < params.SyncCommitteeSize; i++ {
|
||||||
if rand.Intn(params.SyncCommitteeSize-i) < signerCount {
|
if mrand.Intn(params.SyncCommitteeSize-i) < signerCount {
|
||||||
bitmask[i/8] += byte(1) << (i & 7)
|
bitmask[i/8] += byte(1) << (i & 7)
|
||||||
signerCount--
|
signerCount--
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue