Compare commits

...

66 Commits
blobs ... light

Author SHA1 Message Date
Raul Jordan
4aa372a65f tree test 2021-11-25 11:04:11 -05:00
Raul Jordan
f89b7624cf more prog 2021-11-21 18:46:17 -05:00
Raul Jordan
b854b51e21 need to investigate best finalized routine 2021-11-20 22:26:55 -05:00
Raul Jordan
6832f79cf2 begin proof verification 2021-11-20 22:11:12 -05:00
Raul Jordan
f3e6c83d66 working at runtime 2021-11-20 21:43:55 -05:00
Raul Jordan
82453961ee add pb 2021-11-20 17:47:58 -05:00
Raul Jordan
b1d3ea83bd stage 2021-11-20 17:47:23 -05:00
Raul Jordan
98ab265b6b sync 2021-11-20 17:45:43 -05:00
Raul Jordan
8e115672c5 add ztyp 2021-11-20 17:44:48 -05:00
Raul Jordan
4778ec7434 del 2021-11-20 17:44:26 -05:00
Raul Jordan
fac8526eb6 fully working 2021-11-20 17:43:16 -05:00
Raul Jordan
93fc666f83 begin using ztyp 2021-11-20 16:57:52 -05:00
Raul Jordan
b5bd461627 minimal node/tree backing implementation 2021-11-20 12:22:10 -05:00
Raul Jordan
8fecc5af7f builds 2021-11-20 01:44:35 -05:00
Raul Jordan
03e40edf2c refactor 2021-11-20 01:02:34 -05:00
Raul Jordan
7a2b8e4e6a Merge branch 'develop' into light 2021-11-01 22:14:13 -04:00
Raul Jordan
e13cdf493e empt 2021-10-31 13:25:14 -04:00
Raul Jordan
fdd9c535b4 viz 2021-10-31 13:20:46 -04:00
Raul Jordan
ba728d4929 gaz 2021-10-31 12:20:01 -05:00
Raul Jordan
cd5eb0a2ef light go 2021-10-31 13:19:18 -04:00
Raul Jordan
6d44428e9c build protos 2021-10-31 12:18:53 -05:00
Raul Jordan
cefb5cec55 dep 2021-10-31 12:06:51 -05:00
Raul Jordan
815debee38 p 2021-10-31 13:00:50 -04:00
Raul Jordan
fc6c17cc75 p 2021-10-31 13:00:18 -04:00
Raul Jordan
df0e9fa3d7 dep 2021-10-31 12:59:35 -04:00
Raul Jordan
0287bc65c7 add build files 2021-10-31 11:59:13 -05:00
Raul Jordan
35c3225579 rem build 2021-10-31 12:53:42 -04:00
Raul Jordan
f238f872a1 use les 2021-10-31 12:48:44 -04:00
Raul Jordan
24f105b804 light 2021-10-30 22:58:54 -04:00
Raul Jordan
f98354f59f handle public key 2021-10-30 22:52:34 -04:00
Raul Jordan
2aea4e49f4 gen 2021-10-30 22:41:33 -04:00
Raul Jordan
a8e8338973 add 2021-10-30 22:36:30 -04:00
Raul Jordan
ed78d15ed6 check nil 2021-10-30 22:20:48 -04:00
Raul Jordan
d5cf0a2e54 blk 2021-10-30 22:19:40 -04:00
Raul Jordan
b89bb3fa30 genesis 2021-10-30 22:15:07 -04:00
Raul Jordan
be722f2c5c compiles 2021-10-30 22:07:39 -04:00
Raul Jordan
09c99b25bc light server updates 2021-10-30 22:02:32 -04:00
Raul Jordan
24ff40fbf5 regen 2021-10-30 17:02:20 -05:00
Raul Jordan
d96491ffa9 service wait for sync 2021-10-30 17:59:23 -04:00
Raul Jordan
5121a50bb4 service definitions 2021-10-30 17:54:54 -04:00
Raul Jordan
1c6d914ea1 add in functional endpoints 2021-10-30 17:36:24 -04:00
Raul Jordan
71adada879 database additions 2021-10-30 17:30:28 -04:00
Raul Jordan
5790aa66e0 light updater builds 2021-10-30 17:06:37 -04:00
Raul Jordan
8e6bb39d2f add in generated 2021-10-30 15:58:39 -05:00
Raul Jordan
ad06914f45 no expr 2021-10-30 16:56:17 -04:00
Raul Jordan
259e07d5c9 Merge branch 'light' of github.com:prysmaticlabs/prysm into light 2021-10-30 16:55:31 -04:00
Raul Jordan
f6cf77acd8 fix 2021-10-30 16:55:27 -04:00
Raul Jordan
40a36fb02d workspace 2021-10-30 15:54:31 -05:00
Raul Jordan
2e65be12b8 protos 2021-10-30 16:48:22 -04:00
Raul Jordan
4a237e11bc sync dev 2021-10-30 16:28:10 -04:00
Raul Jordan
4d9eafe110 add proto 2021-10-24 22:28:16 -04:00
Raul Jordan
7b1b9a564b type align 2021-10-24 22:22:41 -04:00
Raul Jordan
341cced53f more changes to updater 2021-10-24 22:17:47 -04:00
Raul Jordan
a3ad254b78 updater changes 2021-10-21 09:57:40 -04:00
Raul Jordan
a7fc25f2e0 start les update 2021-10-18 23:00:03 -04:00
Raul Jordan
9551a6c4b8 begin updater server 2021-10-18 00:18:49 -04:00
Raul Jordan
d39113af60 add in generated ssz tree 2021-10-18 00:05:57 -04:00
Raul Jordan
d27334746b attempt 2021-10-11 00:28:24 -04:00
Raul Jordan
d00c7a0ce8 add in test 2021-10-11 00:23:29 -04:00
Raul Jordan
c7826856a5 check in ferran ssz 2021-10-11 00:15:24 -04:00
Raul Jordan
1bec9ae9e6 add in generated ssz 2021-10-11 00:11:39 -04:00
Raul Jordan
17ed9356ff client server files 2021-10-09 17:10:51 -04:00
Raul Jordan
c493290027 split up files 2021-10-09 17:08:16 -04:00
Raul Jordan
30c07a8a1a les server running 2021-10-08 17:33:26 -04:00
Raul Jordan
b7fb8a8dcd begin les 2021-10-06 13:07:52 -04:00
Raul Jordan
bd108c3244 start les 2021-10-04 09:36:41 -04:00
29 changed files with 2732 additions and 4 deletions

View File

@@ -147,7 +147,6 @@ type Database interface {
io.Closer
backup.BackupExporter
HeadAccessDatabase
DatabasePath() string
ClearDB() error
}

View File

@@ -13,6 +13,7 @@ go_library(
"finalized_block_roots.go",
"genesis.go",
"kv.go",
"light.go",
"log.go",
"migration.go",
"migration_archived_index.go",

View File

@@ -0,0 +1,32 @@
load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"service.go",
"update_comparison.go",
"updater.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/light",
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/core/feed:go_default_library",
"//beacon-chain/core/feed/state:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/db/iface:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/sync:go_default_library",
"//config/params:go_default_library",
"//encoding/bytesutil:go_default_library",
"//network/forks:go_default_library",
"//proto/eth/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/block:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
)

View File

@@ -0,0 +1,209 @@
package light
import (
"context"
"fmt"
"sync"
"time"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db/iface"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
syncSrv "github.com/prysmaticlabs/prysm/beacon-chain/sync"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/io/file"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
block2 "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
"github.com/prysmaticlabs/prysm/time/slots"
)
type UpdatesFetcher interface {
BestUpdateForPeriod(ctx context.Context, period uint64) (*ethpb.LightClientUpdate, error)
LatestFinalizedUpdate(ctx context.Context) *ethpb.LightClientUpdate
LatestNonFinalizedUpdate(ctx context.Context) *ethpb.LightClientUpdate
}
type Config struct {
StateGen stategen.StateManager
Database iface.Database
HeadFetcher blockchain.HeadFetcher
FinalizationFetcher blockchain.FinalizationFetcher
StateNotifier statefeed.Notifier
TimeFetcher blockchain.TimeFetcher
SyncChecker syncSrv.Checker
}
type Service struct {
cfg *Config
cancelFunc context.CancelFunc
prevHeadData map[[32]byte]*ethpb.SyncAttestedData
lock sync.RWMutex
genesisTime time.Time
finalizedByEpoch map[types.Epoch]*ethpb.LightClientFinalizedCheckpoint
bestUpdateByPeriod map[uint64]*ethpb.LightClientUpdate
latestFinalizedUpdate *ethpb.LightClientUpdate
latestNonFinalizedUpdate *ethpb.LightClientUpdate
}
// New --
func New(ctx context.Context, cfg *Config) *Service {
return &Service{
cfg: cfg,
prevHeadData: make(map[[32]byte]*ethpb.SyncAttestedData),
finalizedByEpoch: make(map[types.Epoch]*ethpb.LightClientFinalizedCheckpoint),
bestUpdateByPeriod: make(map[uint64]*ethpb.LightClientUpdate),
}
}
func (s *Service) Start() {
go s.run()
}
func (s *Service) Stop() error {
s.cancelFunc()
return nil
}
func (s *Service) Status() error {
return nil
}
func (s *Service) BestUpdateForPeriod(ctx context.Context, period uint64) (*ethpb.LightClientUpdate, error) {
s.lock.RLock()
defer s.lock.RUnlock()
update, ok := s.bestUpdateByPeriod[period]
if !ok {
return nil, fmt.Errorf("no update found for period %d", period)
}
return update, nil
}
func (s *Service) LatestFinalizedUpdate(ctx context.Context) *ethpb.LightClientUpdate {
s.lock.RLock()
defer s.lock.RUnlock()
return s.latestFinalizedUpdate
}
func (s *Service) LatestNonFinalizedUpdate(ctx context.Context) *ethpb.LightClientUpdate {
return s.latestNonFinalizedUpdate
}
func (s *Service) run() {
ctx, cancel := context.WithCancel(context.Background())
s.cancelFunc = cancel
s.waitForChainInitialization(ctx)
s.waitForSync(ctx)
// Initialize the service from finalized (state, block) data.
log.Info("Initializing from finalized data")
if err := s.initializeFromFinalizedData(ctx); err != nil {
log.Fatal(err)
}
log.Info("Beginning subscriptions")
// Begin listening for new chain head and finalized checkpoint events.
go s.subscribeHeadEvent(ctx)
go s.subscribeFinalizedEvent(ctx)
}
func (s *Service) waitForChainInitialization(ctx context.Context) {
stateChannel := make(chan *feed.Event, 1)
stateSub := s.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
defer stateSub.Unsubscribe()
defer close(stateChannel)
for {
select {
case stateEvent := <-stateChannel:
// Wait for us to receive the genesis time via a chain started notification.
if stateEvent.Type == statefeed.Initialized {
// Alternatively, if the chain has already started, we then read the genesis
// time value from this data.
data, ok := stateEvent.Data.(*statefeed.InitializedData)
if !ok {
log.Error(
"Could not receive chain start notification, want *statefeed.ChainStartedData",
)
return
}
s.genesisTime = data.StartTime
log.WithField("genesisTime", s.genesisTime).Info(
"Received chain initialization event",
)
return
}
case err := <-stateSub.Err():
log.WithError(err).Error(
"Could not subscribe to state events",
)
return
case <-ctx.Done():
return
}
}
}
func (s *Service) waitForSync(ctx context.Context) {
slotTicker := slots.NewSlotTicker(s.genesisTime, params.BeaconConfig().SecondsPerSlot)
defer slotTicker.Done()
for {
select {
case <-slotTicker.C():
if slots.ToEpoch(slots.SinceGenesis(s.genesisTime)) < 6 {
continue
}
return
case <-ctx.Done():
return
}
}
}
func (s *Service) finalizedBlockOrGenesis(ctx context.Context, cpt *ethpb.Checkpoint) (block2.SignedBeaconBlock, error) {
checkpointRoot := bytesutil.ToBytes32(cpt.Root)
block, err := s.cfg.Database.Block(ctx, checkpointRoot)
if err != nil {
return nil, err
}
if block == nil || block.IsNil() {
return s.cfg.Database.GenesisBlock(ctx)
}
return block, nil
}
func (s *Service) finalizedStateOrGenesis(ctx context.Context, cpt *ethpb.Checkpoint) (state.BeaconState, error) {
checkpointRoot := bytesutil.ToBytes32(cpt.Root)
st, err := s.cfg.StateGen.StateByRoot(ctx, checkpointRoot)
if err != nil {
return nil, err
}
if st == nil || st.IsNil() {
return s.cfg.Database.GenesisState(ctx)
}
return st, nil
}
func (s *Service) initializeFromFinalizedData(ctx context.Context) error {
cpt, err := s.cfg.Database.FinalizedCheckpoint(ctx)
if err != nil {
return err
}
finalizedBlock, err := s.finalizedBlockOrGenesis(ctx, cpt)
if err != nil {
return err
}
finalizedState, err := s.finalizedStateOrGenesis(ctx, cpt)
if err != nil {
return err
}
enc, err := finalizedState.MarshalSSZ()
if err != nil {
return err
}
if err := file.WriteFile("/tmp/state.ssz", enc); err != nil {
return err
}
return s.onFinalized(ctx, finalizedBlock, finalizedState)
}

View File

@@ -0,0 +1,120 @@
package light
import (
"context"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/encoding/ssz"
v1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
"github.com/prysmaticlabs/prysm/time/slots"
)
const (
finalizedCheckpointStateIndex = 20
nextSyncCommitteeStateIndex = 23
)
func (s *Service) subscribeFinalizedEvent(ctx context.Context) {
stateChan := make(chan *feed.Event, 1)
sub := s.cfg.StateNotifier.StateFeed().Subscribe(stateChan)
defer sub.Unsubscribe()
for {
select {
case ev := <-stateChan:
if ev.Type == statefeed.FinalizedCheckpoint {
blk, beaconState, err := s.parseFinalizedEvent(ctx, ev.Data)
if err != nil {
log.Error(err)
continue
}
if err := s.onFinalized(ctx, blk, beaconState); err != nil {
log.Error(err)
continue
}
}
}
}
}
func (s *Service) parseFinalizedEvent(
ctx context.Context, eventData interface{},
) (block.SignedBeaconBlock, state.BeaconState, error) {
finalizedCheckpoint, ok := eventData.(*v1.EventFinalizedCheckpoint)
if !ok {
return nil, nil, errors.New("expected finalized checkpoint event")
}
checkpointRoot := bytesutil.ToBytes32(finalizedCheckpoint.Block)
blk, err := s.cfg.Database.Block(ctx, checkpointRoot)
if err != nil {
return nil, nil, err
}
if blk == nil || blk.IsNil() {
return nil, nil, err
}
st, err := s.cfg.StateGen.StateByRoot(ctx, checkpointRoot)
if err != nil {
return nil, nil, err
}
if st == nil || st.IsNil() {
return nil, nil, err
}
return blk, st, nil
}
func (s *Service) onFinalized(
ctx context.Context, signedBlock block.SignedBeaconBlock, postState state.BeaconStateAltair,
) error {
if _, ok := postState.InnerStateUnsafe().(*ethpb.BeaconStateAltair); !ok {
return errors.New("expected an Altair beacon state")
}
blk := signedBlock.Block()
header, err := block.BeaconBlockHeaderFromBlockInterface(blk)
if err != nil {
return err
}
tb, err := ssz.NewTreeBackedState(postState)
if err != nil {
return err
}
proof, gIndex, err := tb.Proof(nextSyncCommitteeStateIndex)
if err != nil {
return err
}
nextSyncCommittee, err := postState.NextSyncCommittee()
if err != nil {
return err
}
root, err := postState.HashTreeRoot(ctx)
if err != nil {
return err
}
nextSyncCommitteeRoot, err := nextSyncCommittee.HashTreeRoot()
if err != nil {
return err
}
log.Info("On finalized update")
log.Infof("Header state root %#x, state hash tree root %#x", header.StateRoot, root)
log.Infof("Generating proof against root %#x with gindex %d and leaf root %#x", root, gIndex, nextSyncCommitteeRoot)
log.Info("-----")
log.Infof("Proof with length %d", len(proof))
for _, elem := range proof {
log.Infof("%#x", bytesutil.Trunc(elem))
}
log.Info("-----")
s.lock.Lock()
defer s.lock.Unlock()
currentEpoch := slots.ToEpoch(blk.Slot())
s.finalizedByEpoch[currentEpoch] = &ethpb.LightClientFinalizedCheckpoint{
Header: header,
NextSyncCommittee: nextSyncCommittee,
NextSyncCommitteeBranch: proof,
}
return nil
}

View File

@@ -0,0 +1,154 @@
package light
import (
"context"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/encoding/ssz"
"github.com/prysmaticlabs/prysm/network/forks"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
"github.com/prysmaticlabs/prysm/time/slots"
)
func (s *Service) subscribeHeadEvent(ctx context.Context) {
stateChan := make(chan *feed.Event, 1)
sub := s.cfg.StateNotifier.StateFeed().Subscribe(stateChan)
defer sub.Unsubscribe()
for {
select {
case ev := <-stateChan:
if ev.Type == statefeed.NewHead {
head, beaconState, err := s.getChainHeadAndState(ctx)
if err != nil {
log.Error(err)
continue
}
if err := s.onHead(ctx, head, beaconState); err != nil {
log.Error(err)
continue
}
}
case <-sub.Err():
return
case <-ctx.Done():
return
}
}
}
func (s *Service) getChainHeadAndState(ctx context.Context) (block.SignedBeaconBlock, state.BeaconState, error) {
head, err := s.cfg.HeadFetcher.HeadBlock(ctx)
if err != nil {
return nil, nil, err
}
if head == nil || head.IsNil() {
return nil, nil, errors.New("head block is nil")
}
st, err := s.cfg.HeadFetcher.HeadState(ctx)
if err != nil {
return nil, nil, errors.New("head state is nil")
}
if st == nil || st.IsNil() {
return nil, nil, err
}
return head, st, nil
}
func (s *Service) onHead(ctx context.Context, head block.SignedBeaconBlock, postState state.BeaconStateAltair) error {
if _, ok := postState.InnerStateUnsafe().(*ethpb.BeaconStateAltair); !ok {
return errors.New("expected an Altair beacon state")
}
blk := head.Block()
tb, err := ssz.NewTreeBackedState(postState)
if err != nil {
return err
}
header, err := block.BeaconBlockHeaderFromBlockInterface(blk)
if err != nil {
return err
}
finalityBranch, _, err := tb.Proof(finalizedCheckpointStateIndex)
if err != nil {
return err
}
nextSyncCommitteeBranch, gIndex, err := tb.Proof(nextSyncCommitteeStateIndex)
if err != nil {
return err
}
stRoot, err := postState.HashTreeRoot(ctx)
if err != nil {
return err
}
blkRoot, err := blk.HashTreeRoot()
if err != nil {
return err
}
log.Infof("On head, generating sync committee proof for root %#x and index %d, block root %#x, header state root %#x", stRoot[:], gIndex, blkRoot, header.StateRoot)
nextSyncCommittee, err := postState.NextSyncCommittee()
if err != nil {
return err
}
s.lock.Lock()
s.prevHeadData[blkRoot] = &ethpb.SyncAttestedData{
Header: header,
FinalityCheckpoint: postState.FinalizedCheckpoint(),
FinalityBranch: finalityBranch,
NextSyncCommittee: nextSyncCommittee,
NextSyncCommitteeBranch: nextSyncCommitteeBranch,
}
s.lock.Unlock()
syncAttestedBlockRoot, err := helpers.BlockRootAtSlot(postState, postState.Slot()-1)
if err != nil {
return err
}
fork, err := forks.Fork(slots.ToEpoch(blk.Slot()))
if err != nil {
return err
}
syncAggregate, err := blk.Body().SyncAggregate()
if err != nil {
return err
}
sigData := &signatureData{
slot: blk.Slot(),
forkVersion: fork.CurrentVersion,
syncAggregate: syncAggregate,
}
s.lock.Lock()
syncAttestedData, ok := s.prevHeadData[bytesutil.ToBytes32(syncAttestedBlockRoot)]
if !ok {
s.lock.Unlock()
log.Info("Got useless data, skipping")
return nil // Useless data.
}
s.lock.Unlock()
commmitteePeriodWithFinalized, err := s.persistBestFinalizedUpdate(ctx, syncAttestedData, sigData)
if err != nil {
return err
}
if err := s.persistBestNonFinalizedUpdate(ctx, syncAttestedData, sigData, commmitteePeriodWithFinalized); err != nil {
return err
}
s.lock.Lock()
if len(s.prevHeadData) > PrevDataMaxSize {
for k := range s.prevHeadData {
delete(s.prevHeadData, k)
if len(s.prevHeadData) <= PrevDataMaxSize {
break
}
}
}
s.lock.Unlock()
return nil
}

View File

@@ -0,0 +1,50 @@
package light
import (
"bytes"
"github.com/prysmaticlabs/prysm/config/params"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
)
func isBetterUpdate(prevUpdate *ethpb.LightClientUpdate, newUpdate *ethpb.LightClientUpdate) bool {
prevIsFinalized := isFinalizedUpdate(prevUpdate)
newIsFinalized := isFinalizedUpdate(newUpdate)
// newUpdate becomes finalized, it's better.
if newIsFinalized && !prevIsFinalized {
return true
}
// newUpdate is no longer finalized, it's worse.
if !newIsFinalized && prevIsFinalized {
return false
}
return hasMoreBits(newUpdate, prevUpdate)
}
func isLatestBestFinalizedUpdate(prevUpdate *ethpb.LightClientUpdate, newUpdate *ethpb.LightClientUpdate) bool {
if newUpdate.FinalityHeader.Slot > prevUpdate.FinalityHeader.Slot {
return true
}
if newUpdate.FinalityHeader.Slot < prevUpdate.FinalityHeader.Slot {
return false
}
return hasMoreBits(newUpdate, prevUpdate)
}
func isLatestBestNonFinalizedUpdate(prevUpdate *ethpb.LightClientUpdate, newUpdate *ethpb.LightClientUpdate) bool {
if newUpdate.Header.Slot > prevUpdate.Header.Slot {
return true
}
if newUpdate.Header.Slot < prevUpdate.Header.Slot {
return false
}
return hasMoreBits(newUpdate, prevUpdate)
}
func isFinalizedUpdate(update *ethpb.LightClientUpdate) bool {
return !bytes.Equal(params.BeaconConfig().ZeroHash[:], update.FinalityHeader.StateRoot)
}
func hasMoreBits(a *ethpb.LightClientUpdate, b *ethpb.LightClientUpdate) bool {
return a.SyncCommitteeBits.Count() > b.SyncCommitteeBits.Count()
}

View File

@@ -0,0 +1,134 @@
package light
import (
"context"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/time/slots"
"github.com/sirupsen/logrus"
)
// Precomputed values for generalized indices.
const (
FinalizedRootIndex = 105
NextSyncCommitteeIndex = 55
PrevDataMaxSize = 64
)
var log = logrus.WithField("prefix", "light")
type signatureData struct {
slot types.Slot
forkVersion []byte
syncAggregate *ethpb.SyncAggregate
}
func (s *Service) persistBestFinalizedUpdate(ctx context.Context, syncAttestedData *ethpb.SyncAttestedData, sigData *signatureData) (uint64, error) {
finalizedEpoch := syncAttestedData.FinalityCheckpoint.Epoch
s.lock.RLock()
finalizedData := s.finalizedByEpoch[finalizedEpoch]
s.lock.RUnlock()
if finalizedData == nil {
return 0, nil
}
committeePeriod := slots.SyncCommitteePeriod(slots.ToEpoch(syncAttestedData.Header.Slot))
signaturePeriod := slots.SyncCommitteePeriod(slots.ToEpoch(sigData.slot))
if committeePeriod != signaturePeriod {
return 0, nil
}
newUpdate := &ethpb.LightClientUpdate{
Header: finalizedData.Header,
NextSyncCommittee: finalizedData.NextSyncCommittee,
NextSyncCommitteeBranch: finalizedData.NextSyncCommitteeBranch,
FinalityHeader: syncAttestedData.Header,
FinalityBranch: syncAttestedData.FinalityBranch,
SyncCommitteeBits: sigData.syncAggregate.SyncCommitteeBits,
SyncCommitteeSignature: sigData.syncAggregate.SyncCommitteeSignature,
ForkVersion: sigData.forkVersion,
}
s.lock.RLock()
prevBestUpdate := s.bestUpdateByPeriod[committeePeriod]
s.lock.RUnlock()
if prevBestUpdate == nil || isBetterUpdate(prevBestUpdate, newUpdate) {
s.lock.Lock()
s.bestUpdateByPeriod[committeePeriod] = newUpdate
s.lock.Unlock()
}
s.lock.RLock()
prevLatestUpdate := s.latestFinalizedUpdate
s.lock.RUnlock()
if prevLatestUpdate == nil || isLatestBestFinalizedUpdate(prevLatestUpdate, newUpdate) {
s.lock.Lock()
s.latestFinalizedUpdate = newUpdate
s.lock.Unlock()
log.Info("Putting latest best finalized update")
rt, err := newUpdate.NextSyncCommittee.HashTreeRoot()
if err != nil {
return 0, err
}
log.Infof("Header state root %#x, state hash tree root %#x", newUpdate.Header.StateRoot, newUpdate.Header.StateRoot)
log.Infof("Generating proof against root %#x with gindex %d and leaf root %#x", newUpdate.Header.StateRoot, 55, rt)
log.Info("-----")
log.Infof("Proof with length %d", len(newUpdate.NextSyncCommitteeBranch))
for _, elem := range newUpdate.NextSyncCommitteeBranch {
log.Infof("%#x", bytesutil.Trunc(elem))
}
log.Info("-----")
}
return committeePeriod, nil
}
func (s *Service) persistBestNonFinalizedUpdate(ctx context.Context, syncAttestedData *ethpb.SyncAttestedData, sigData *signatureData, period uint64) error {
committeePeriod := slots.SyncCommitteePeriod(slots.ToEpoch(syncAttestedData.Header.Slot))
signaturePeriod := slots.SyncCommitteePeriod(slots.ToEpoch(sigData.slot))
if committeePeriod != signaturePeriod {
return nil
}
newUpdate := &ethpb.LightClientUpdate{
Header: syncAttestedData.Header,
NextSyncCommittee: syncAttestedData.NextSyncCommittee,
NextSyncCommitteeBranch: syncAttestedData.NextSyncCommitteeBranch,
FinalityHeader: nil,
FinalityBranch: nil,
SyncCommitteeBits: sigData.syncAggregate.SyncCommitteeBits,
SyncCommitteeSignature: sigData.syncAggregate.SyncCommitteeSignature,
ForkVersion: sigData.forkVersion,
}
// Optimization: If there's already a finalized update for this committee period, no need to
// create a non-finalized update>
if committeePeriod != period {
s.lock.RLock()
prevBestUpdate := s.bestUpdateByPeriod[committeePeriod]
s.lock.RUnlock()
if prevBestUpdate == nil || isBetterUpdate(prevBestUpdate, newUpdate) {
s.lock.Lock()
s.bestUpdateByPeriod[committeePeriod] = newUpdate
s.lock.Unlock()
}
}
// Store the latest update here overall. Not checking it's the best
s.lock.RLock()
prevLatestUpdate := s.latestNonFinalizedUpdate
s.lock.RUnlock()
if prevLatestUpdate == nil || isLatestBestNonFinalizedUpdate(prevLatestUpdate, newUpdate) {
// TODO: Don't store nextCommittee, that can be fetched through getBestUpdates()
s.lock.Lock()
s.latestNonFinalizedUpdate = newUpdate
s.lock.Unlock()
}
return nil
}

View File

@@ -26,6 +26,7 @@ go_library(
"//beacon-chain/forkchoice:go_default_library",
"//beacon-chain/forkchoice/protoarray:go_default_library",
"//beacon-chain/gateway:go_default_library",
"//beacon-chain/light:go_default_library",
"//beacon-chain/node/registration:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/slashings:go_default_library",

View File

@@ -28,6 +28,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/gateway"
"github.com/prysmaticlabs/prysm/beacon-chain/light"
"github.com/prysmaticlabs/prysm/beacon-chain/node/registration"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
@@ -193,6 +194,10 @@ func New(cliCtx *cli.Context, opts ...Option) (*BeaconNode, error) {
return nil, err
}
if err := beacon.registerLightClientServer(); err != nil {
return nil, err
}
if err := beacon.registerSlasherService(); err != nil {
return nil, err
}
@@ -681,6 +686,11 @@ func (b *BeaconNode) registerRPCService() error {
return err
}
var lightService *light.Service
if err := b.services.FetchService(&lightService); err != nil {
return err
}
var slasherService *slasher.Service
if features.Get().EnableSlasher {
if err := b.services.FetchService(&slasherService); err != nil {
@@ -757,6 +767,7 @@ func (b *BeaconNode) registerRPCService() error {
StateGen: b.stateGen,
EnableDebugRPCEndpoints: enableDebugRPCEndpoints,
MaxMsgSize: maxMsgSize,
LightUpdatesFetcher: lightService,
})
return b.services.RegisterService(rpcService)
@@ -866,3 +877,25 @@ func (b *BeaconNode) registerDeterminsticGenesisService() error {
}
return nil
}
func (b *BeaconNode) registerLightClientServer() error {
var chainService *blockchain.Service
if err := b.services.FetchService(&chainService); err != nil {
return err
}
var syncService *initialsync.Service
if err := b.services.FetchService(&syncService); err != nil {
return err
}
svc := light.New(b.ctx, &light.Config{
Database: b.db,
StateGen: b.stateGen,
HeadFetcher: chainService,
FinalizationFetcher: chainService,
StateNotifier: b,
TimeFetcher: chainService,
SyncChecker: syncService,
})
return b.services.RegisterService(svc)
}

View File

@@ -29,6 +29,7 @@ go_library(
"//beacon-chain/rpc/eth/validator:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/beacon:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/debug:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/light:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/node:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
"//beacon-chain/rpc/statefetcher:go_default_library",

View File

@@ -0,0 +1,17 @@
load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["server.go"],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/rpc/prysm/v1alpha1/light",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/db/iface:go_default_library",
"//beacon-chain/db/kv:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@io_bazel_rules_go//proto/wkt:empty_go_proto",
"@org_golang_google_grpc//codes:go_default_library",
"@org_golang_google_grpc//status:go_default_library",
],
)

View File

@@ -0,0 +1,38 @@
package light
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/prysmaticlabs/prysm/beacon-chain/light"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
log "github.com/sirupsen/logrus"
)
type Server struct {
Fetcher light.UpdatesFetcher
}
// BestUpdates GET /eth/v1alpha1/lightclient/best_update/:periods.
func (s *Server) BestUpdates(ctx context.Context, req *ethpb.BestUpdatesRequest) (*ethpb.BestUpdatesResponse, error) {
updates := make([]*ethpb.LightClientUpdate, 0)
for _, period := range req.SyncCommitteePeriods {
update, err := s.Fetcher.BestUpdateForPeriod(ctx, period)
if err != nil {
log.Error(err)
continue
}
updates = append(updates, update)
}
return &ethpb.BestUpdatesResponse{Updates: updates}, nil
}
// LatestUpdateFinalized GET /eth/v1alpha1/lightclient/latest_update_finalized/
func (s *Server) LatestUpdateFinalized(ctx context.Context, _ *empty.Empty) (*ethpb.LightClientUpdate, error) {
return s.Fetcher.LatestFinalizedUpdate(ctx), nil
}
// LatestUpdateNonFinalized /eth/v1alpha1/lightclient/latest_update_nonfinalized/
func (s *Server) LatestUpdateNonFinalized(ctx context.Context, _ *empty.Empty) (*ethpb.LightClientUpdate, error) {
return s.Fetcher.LatestNonFinalizedUpdate(ctx), nil
}

View File

@@ -20,6 +20,7 @@ import (
opfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/operation"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/light"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/synccommittee"
@@ -33,6 +34,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/eth/validator"
beaconv1alpha1 "github.com/prysmaticlabs/prysm/beacon-chain/rpc/prysm/v1alpha1/beacon"
debugv1alpha1 "github.com/prysmaticlabs/prysm/beacon-chain/rpc/prysm/v1alpha1/debug"
lightserver "github.com/prysmaticlabs/prysm/beacon-chain/rpc/prysm/v1alpha1/light"
nodev1alpha1 "github.com/prysmaticlabs/prysm/beacon-chain/rpc/prysm/v1alpha1/node"
validatorv1alpha1 "github.com/prysmaticlabs/prysm/beacon-chain/rpc/prysm/v1alpha1/validator"
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/statefetcher"
@@ -108,6 +110,7 @@ type Config struct {
OperationNotifier opfeed.Notifier
StateGen *stategen.State
MaxMsgSize int
LightUpdatesFetcher light.UpdatesFetcher
}
// NewService instantiates a new RPC service instance that will
@@ -279,6 +282,10 @@ func (s *Service) Start() {
VoluntaryExitsPool: s.cfg.ExitPool,
V1Alpha1ValidatorServer: validatorServer,
}
lightClientServer := &lightserver.Server{
Fetcher: s.cfg.LightUpdatesFetcher,
}
ethpbv1alpha1.RegisterLightClientServer(s.grpcServer, lightClientServer)
ethpbv1alpha1.RegisterNodeServer(s.grpcServer, nodeServer)
ethpbservice.RegisterBeaconNodeServer(s.grpcServer, nodeServerV1)
ethpbv1alpha1.RegisterHealthServer(s.grpcServer, nodeServer)

50
cmd/light/BUILD.bazel Normal file
View File

@@ -0,0 +1,50 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"client.go",
"main.go",
"process_update.go",
"server.go",
"validate_update.go",
],
importpath = "github.com/prysmaticlabs/prysm/cmd/light",
visibility = ["//visibility:private"],
deps = [
"//beacon-chain/core/signing:go_default_library",
"//config/params:go_default_library",
"//container/trie:go_default_library",
"//crypto/bls/blst:go_default_library",
"//crypto/bls/common:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/eth/service:go_default_library",
"//proto/eth/v1:go_default_library",
"//proto/eth/v2:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
],
)
go_binary(
name = "light",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = ["client_test.go"],
embed = [":go_default_library"],
deps = [
"//proto/prysm/v1alpha1:go_default_library",
"//testing/require:go_default_library",
],
)

3
cmd/light/client.go Normal file
View File

@@ -0,0 +1,3 @@
package main
type Client struct{}

25
cmd/light/client_test.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"fmt"
"testing"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/require"
)
func TestProveCheckpoint(t *testing.T) {
root := [32]byte{1}
check := &ethpb.Checkpoint{
Epoch: 1,
Root: root[:],
}
tr, err := check.GetTree()
require.NoError(t, err)
a, err := tr.Get(0)
require.NoError(t, err)
b, err := tr.Get(1)
require.NoError(t, err)
fmt.Println(a.Hash())
fmt.Println(b.Hash())
}

71
cmd/light/main.go Normal file
View File

@@ -0,0 +1,71 @@
package main
import (
"context"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/encoding/ssz"
v1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
v2 "github.com/prysmaticlabs/prysm/proto/eth/v2"
v1alpha1 "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/emptypb"
)
// Precomputed values for generalized indices.
const (
FinalizedRootIndex = 105
FinalizedRootIndexFloorLog2 = 6
NextSyncCommitteeIndex = 55
NextSyncCommitteeIndexFloorLog2 = 5
)
var log = logrus.WithField("prefix", "light")
type LightClientSnapshot struct {
Header *v1.BeaconBlockHeader
CurrentSyncCommittee *v2.SyncCommittee
NextSyncCommittee *v2.SyncCommittee
}
type LightClientUpdate struct {
Header *v1.BeaconBlockHeader
NextSyncCommittee *v2.SyncCommittee
NextSyncCommitteeBranch [NextSyncCommitteeIndexFloorLog2][32]byte
FinalityHeader *v1.BeaconBlockHeader
FinalityBranch [FinalizedRootIndexFloorLog2][32]byte
SyncCommitteeBits bitfield.Bitvector512
SyncCommitteeSignature [96]byte
ForkVersion *v1alpha1.Version
}
type Store struct {
Snapshot *LightClientSnapshot
ValidUpdates []*LightClientUpdate
}
func main() {
conn, err := grpc.Dial("localhost:4000", grpc.WithInsecure())
if err != nil {
log.Fatalf("fail to dial: %v", err)
}
ctx := context.Background()
lesClient := v1alpha1.NewLightClientClient(conn)
update, err := lesClient.LatestUpdateFinalized(ctx, &emptypb.Empty{})
if err != nil {
log.Fatalf("could not get latest update: %v", err)
}
// Attempt to verify a merkle proof of the next sync committee branch vs. the state root.
root := bytesutil.ToBytes32(update.Header.StateRoot)
leaf, err := update.NextSyncCommittee.HashTreeRoot()
if err != nil {
log.Fatalf("could not hash tree root: %v", err)
}
log.Infof("Verifying proof with root %#x, leaf %#x", root, leaf)
validProof := ssz.VerifyProof(root, update.NextSyncCommitteeBranch, leaf, NextSyncCommitteeIndex)
if !validProof {
log.Error("could not verify merkle proof")
}
}

View File

@@ -0,0 +1,54 @@
package main
import (
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/time/slots"
)
func applyLightClientUpdate(snapshot *LightClientSnapshot, update *LightClientUpdate) {
snapshotPeriod := slots.ToEpoch(snapshot.Header.Slot) / params.BeaconConfig().EpochsPerSyncCommitteePeriod
updatePeriod := slots.ToEpoch(update.Header.Slot) / params.BeaconConfig().EpochsPerSyncCommitteePeriod
if updatePeriod == snapshotPeriod+1 {
snapshot.CurrentSyncCommittee = snapshot.NextSyncCommittee
} else {
snapshot.Header = update.Header
}
}
func processLightClientUpdate(
store *Store,
update *LightClientUpdate,
currentSlot types.Slot,
genesisValidatorsRoot [32]byte,
) error {
if err := validateLightClientUpdate(store.Snapshot, update, genesisValidatorsRoot); err != nil {
return err
}
store.ValidUpdates = append(store.ValidUpdates, update)
updateTimeout := uint64(params.BeaconConfig().SlotsPerEpoch) * uint64(params.BeaconConfig().EpochsPerSyncCommitteePeriod)
sumParticipantBits := update.SyncCommitteeBits.Count()
hasQuorum := sumParticipantBits*3 >= uint64(len(update.SyncCommitteeBits))*2
if hasQuorum && !isEmptyBlockHeader(update.FinalityHeader) {
// Apply update if (1) 2/3 quorum is reached and (2) we have a finality proof.
// Note that (2) means that the current light client design needs finality.
// It may be changed to re-organizable light client design. See the on-going issue consensus-specs#2182.
applyLightClientUpdate(store.Snapshot, update)
store.ValidUpdates = make([]*LightClientUpdate, 0)
} else if currentSlot > store.Snapshot.Header.Slot.Add(updateTimeout) {
// Forced best update when the update timeout has elapsed
// Use the update that has the highest sum of sync committee bits.
updateWithHighestSumBits := store.ValidUpdates[0]
highestSumBitsUpdate := updateWithHighestSumBits.SyncCommitteeBits.Count()
for _, validUpdate := range store.ValidUpdates {
sumUpdateBits := validUpdate.SyncCommitteeBits.Count()
if sumUpdateBits > highestSumBitsUpdate {
highestSumBitsUpdate = sumUpdateBits
updateWithHighestSumBits = validUpdate
}
}
applyLightClientUpdate(store.Snapshot, updateWithHighestSumBits)
store.ValidUpdates = make([]*LightClientUpdate, 0)
}
return nil
}

3
cmd/light/server.go Normal file
View File

@@ -0,0 +1,3 @@
package main
type Server struct{}

View File

@@ -0,0 +1,151 @@
package main
import (
"math"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/container/trie"
"github.com/prysmaticlabs/prysm/crypto/bls/blst"
"github.com/prysmaticlabs/prysm/crypto/bls/common"
v1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
v2 "github.com/prysmaticlabs/prysm/proto/eth/v2"
v1alpha1 "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/time/slots"
"google.golang.org/protobuf/proto"
)
func validateLightClientUpdate(
snapshot *LightClientSnapshot,
update *LightClientUpdate,
genesisValidatorsRoot [32]byte,
) error {
if update.Header.Slot <= snapshot.Header.Slot {
return errors.New("wrong")
}
snapshotPeriod := slots.ToEpoch(snapshot.Header.Slot) / params.BeaconConfig().EpochsPerSyncCommitteePeriod
updatePeriod := slots.ToEpoch(update.Header.Slot) / params.BeaconConfig().EpochsPerSyncCommitteePeriod
if updatePeriod != snapshotPeriod || updatePeriod != snapshotPeriod+1 {
return errors.New("unwanted")
}
// Verify finality headers.
var signedHeader *v1.BeaconBlockHeader
if isEmptyBlockHeader(update.FinalityHeader) {
signedHeader = update.Header
// Check if branch is empty.
for _, elem := range update.FinalityBranch {
if elem != [32]byte{} {
return errors.New("branch not empty")
}
}
} else {
leaf, err := update.Header.HashTreeRoot()
if err != nil {
return err
}
depth := FinalizedRootIndexFloorLog2
index := getSubtreeIndex(FinalizedRootIndex)
root := update.FinalityHeader.StateRoot
merkleBranch := make([][]byte, len(update.FinalityBranch))
for i, item := range update.FinalityBranch {
merkleBranch[i] = item[:]
}
if !trie.VerifyMerkleBranch(root, leaf[:], int(index), merkleBranch, uint64(depth)) {
return errors.New("does not verify")
}
}
// Verify update next sync committee if the update period incremented.
var syncCommittee *v2.SyncCommittee
if updatePeriod == snapshotPeriod {
syncCommittee = snapshot.CurrentSyncCommittee
for _, elem := range update.NextSyncCommitteeBranch {
if elem != [32]byte{} {
return errors.New("branch not empty")
}
}
} else {
syncCommittee = snapshot.NextSyncCommittee
v1Sync := &v1alpha1.SyncCommittee{
Pubkeys: syncCommittee.Pubkeys,
AggregatePubkey: syncCommittee.AggregatePubkey,
}
leaf, err := v1Sync.HashTreeRoot()
if err != nil {
return err
}
depth := NextSyncCommitteeIndexFloorLog2
index := getSubtreeIndex(NextSyncCommitteeIndex)
root := update.Header.StateRoot
merkleBranch := make([][]byte, len(update.NextSyncCommitteeBranch))
for i, item := range update.NextSyncCommitteeBranch {
merkleBranch[i] = item[:]
}
if !trie.VerifyMerkleBranch(root, leaf[:], int(index), merkleBranch, uint64(depth)) {
return errors.New("does not verify")
}
}
// Verify sync committee has sufficient participants
if update.SyncCommitteeBits.Count() < params.BeaconConfig().MinSyncCommitteeParticipants {
return errors.New("insufficient participants")
}
// Verify sync committee aggregate signature
participantPubkeys := make([][]byte, 0)
for i, pubKey := range syncCommittee.Pubkeys {
bit := update.SyncCommitteeBits.BitAt(uint64(i))
if bit {
participantPubkeys = append(participantPubkeys, pubKey)
}
}
domain, err := signing.ComputeDomain(
params.BeaconConfig().DomainSyncCommittee,
[]byte(update.ForkVersion.Version),
genesisValidatorsRoot[:],
)
if err != nil {
return err
}
signingRoot, err := signing.ComputeSigningRoot(signedHeader, domain)
if err != nil {
return err
}
sig, err := blst.SignatureFromBytes(update.SyncCommitteeSignature[:])
if err != nil {
return err
}
pubKeys := make([]common.PublicKey, 0)
for _, pubkey := range participantPubkeys {
pk, err := blst.PublicKeyFromBytes(pubkey)
if err != nil {
return err
}
pubKeys = append(pubKeys, pk)
}
if !sig.FastAggregateVerify(pubKeys, signingRoot) {
return errors.New("failed to verify")
}
return nil
}
func isEmptyBlockHeader(header *v1.BeaconBlockHeader) bool {
emptyRoot := params.BeaconConfig().ZeroHash
return proto.Equal(header, &v1.BeaconBlockHeader{
Slot: 0,
ProposerIndex: 0,
ParentRoot: emptyRoot[:],
StateRoot: emptyRoot[:],
BodyRoot: emptyRoot[:],
})
}
func getSubtreeIndex(index uint64) uint64 {
return index % uint64(math.Pow(2, floorLog2(index)))
}
func floorLog2(x uint64) float64 {
return math.Floor(math.Log2(float64(x)))
}

View File

@@ -22,7 +22,7 @@ const (
// Genesis Fork Epoch for the mainnet config.
genesisForkEpoch = 0
// Altair Fork Epoch for mainnet config.
mainnetAltairForkEpoch = 74240 // Oct 27, 2021, 10:56:23am UTC
mainnetAltairForkEpoch = 1 // Oct 27, 2021, 10:56:23am UTC
)
var mainnetNetworkConfig = &NetworkConfig{
@@ -97,8 +97,8 @@ var mainnetBeaconConfig = &BeaconChainConfig{
// Time parameter constants.
MinAttestationInclusionDelay: 1,
SecondsPerSlot: 12,
SlotsPerEpoch: 32,
SecondsPerSlot: 4,
SlotsPerEpoch: 4,
SqrRootSlotsPerEpoch: 5,
MinSeedLookahead: 1,
MaxSeedLookahead: 4,

197
encoding/ssz/tree/state.go Normal file
View File

@@ -0,0 +1,197 @@
package tree
import (
"bytes"
"sort"
"github.com/pkg/errors"
"github.com/protolambda/ztyp/codec"
"github.com/protolambda/ztyp/tree"
"github.com/protolambda/ztyp/view"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
)
var (
BLSPubkeyType = view.BasicVectorType(view.ByteType, 48)
ValidatorType = view.ContainerType("Validator", []view.FieldDef{
{"pubkey", BLSPubkeyType},
{"withdrawal_credentials", view.RootType},
{"effective_balance", view.Uint64Type},
{"slashed", view.BoolType},
{"activation_eligibility_epoch", view.Uint64Type},
{"activation_epoch", view.Uint64Type},
{"exit_epoch", view.Uint64Type},
{"withdrawable_epoch", view.Uint64Type},
})
ForkType = view.ContainerType("Fork", []view.FieldDef{
{"previous_version", view.Bytes4Type},
{"current_version", view.Bytes4Type},
{"epoch", view.Uint64Type},
})
BeaconBlockHeaderType = view.ContainerType("BeaconBlockHeader", []view.FieldDef{
{"slot", view.Uint64Type},
{"proposer_index", view.Uint64Type},
{"parent_root", view.RootType},
{"state_root", view.RootType},
{"body_root", view.RootType},
})
BlockRootsType = view.VectorType(view.RootType, 8192)
StateRootsType = view.VectorType(view.RootType, 8192)
HistoricalRootsType = view.ListType(view.RootType, 16777216)
Eth1DataType = view.ContainerType("Eth1Data", []view.FieldDef{
{"deposit_root", view.RootType},
{"deposit_count", view.Uint64Type},
{"block_hash", view.RootType},
})
Eth1DataVotesType = view.ComplexListType(Eth1DataType, 2048)
ValidatorsType = view.ComplexListType(ValidatorType, 1099511627776)
BalancesType = view.BasicListType(view.Uint64Type, 1099511627776)
RandaoMixesType = view.VectorType(view.RootType, 65536)
SlashingsType = view.BasicVectorType(view.Uint64Type, 8192)
ParticipationType = view.BasicListType(view.ByteType, 1099511627776)
JustificationBitsType = view.BitVectorType(4)
CheckpointType = view.ContainerType("Checkpoint", []view.FieldDef{
{"epoch", view.Uint64Type},
{"root", view.RootType},
})
InactivityScoresType = view.BasicListType(view.Uint64Type, 1099511627776)
SyncCommitteeKeysType = view.VectorType(BLSPubkeyType, 512)
SyncCommitteeType = view.ContainerType("SyncCommittee", []view.FieldDef{
{"pubkeys", SyncCommitteeKeysType},
{"aggregate_pubkey", BLSPubkeyType},
})
BeaconStateAltairType = view.ContainerType("BeaconStateAltair", []view.FieldDef{
{"genesis_time", view.Uint64Type},
{"genesis_validators_root", view.RootType},
{"slot", view.Uint64Type},
{"fork", ForkType},
{"latest_block_header", BeaconBlockHeaderType},
{"block_roots", BlockRootsType},
{"state_roots", StateRootsType},
{"historical_roots", HistoricalRootsType},
{"eth1_data", Eth1DataType},
{"eth1_data_votes", Eth1DataVotesType},
{"eth1_deposit_index", view.Uint64Type},
{"validators", ValidatorsType},
{"balances", BalancesType},
{"randao_mixes", RandaoMixesType},
{"slashings", SlashingsType},
{"previous_epoch_participation", ParticipationType},
{"current_epoch_participation", ParticipationType},
{"justification_bits", JustificationBitsType},
{"previous_justified_checkpoint", CheckpointType},
{"current_justified_checkpoint", CheckpointType},
{"finalized_checkpoint", CheckpointType},
{"inactivity_scores", InactivityScoresType},
{"current_sync_committee", SyncCommitteeType},
{"next_sync_committee", SyncCommitteeType},
})
)
type TreeBackedState struct {
beaconState view.View
}
func NewTreeBackedState(beaconState state.BeaconState) (*TreeBackedState, error) {
enc, err := beaconState.MarshalSSZ()
if err != nil {
return nil, err
}
dec := codec.NewDecodingReader(bytes.NewReader(enc), uint64(len(enc)))
treeBacked, err := BeaconStateAltairType.Deserialize(dec)
if err != nil {
return nil, err
}
return &TreeBackedState{beaconState: treeBacked}, nil
}
func VerifyProof(root [32]byte, proof [][]byte, leaf tree.Root, generalizedIndex tree.Gindex64) bool {
h := leaf
hFn := tree.GetHashFn()
idx := generalizedIndex
for _, elem := range proof {
if idx%2 == 0 {
h = hFn(h, bytesutil.ToBytes32(elem))
} else {
h = hFn(bytesutil.ToBytes32(elem), h)
}
idx = idx / 2
}
return h == root
}
func (tb *TreeBackedState) View() view.View {
return tb.beaconState
}
func (tb *TreeBackedState) Proof(
fieldIndex uint64,
) (proof [][]byte, generalizedIdx tree.Gindex64, err error) {
cont, ok := tb.beaconState.(*view.ContainerView)
if !ok {
err = errors.New("not a container")
return
}
depth := tree.CoverDepth(cont.FieldCount())
generalizedIdx, err = tree.ToGindex64(fieldIndex, depth)
if err != nil {
return
}
leaves := make(map[tree.Gindex64]struct{})
leaves[generalizedIdx] = struct{}{}
leavesSorted := make([]tree.Gindex64, 0, len(leaves))
for g := range leaves {
leavesSorted = append(leavesSorted, g)
}
sort.Slice(leavesSorted, func(i, j int) bool {
return leavesSorted[i] < leavesSorted[j]
})
// Mark every gindex that is between the root and the leaves.
interest := make(map[tree.Gindex64]struct{})
for _, g := range leavesSorted {
iter, _ := g.BitIter()
n := tree.Gindex64(1)
for {
right, ok := iter.Next()
if !ok {
break
}
n *= 2
if right {
n += 1
}
interest[n] = struct{}{}
}
}
witness := make(map[tree.Gindex64]struct{})
// For every gindex that is covered, check if the sibling is covered, and if not, it's a witness
for g := range interest {
if _, ok := interest[g^1]; !ok {
witness[g^1] = struct{}{}
}
}
witnessSorted := make([]tree.Gindex64, 0, len(witness))
for g := range witness {
witnessSorted = append(witnessSorted, g)
}
sort.Slice(witnessSorted, func(i, j int) bool {
return witnessSorted[i] < witnessSorted[j]
})
node := tb.beaconState.Backing()
hFn := tree.GetHashFn()
proof = make([][]byte, 0, len(witnessSorted))
for i := len(witnessSorted) - 1; i >= 0; i-- {
g := witnessSorted[i]
n, err2 := node.Getter(g)
if err2 != nil {
err = err2
return
}
root := n.MerkleRoot(hFn)
proof = append(proof, root[:])
}
return
}

View File

@@ -0,0 +1,71 @@
package tree
import (
"bytes"
"context"
"fmt"
"testing"
"github.com/protolambda/ztyp/codec"
"github.com/protolambda/ztyp/tree"
"github.com/protolambda/ztyp/view"
stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
"github.com/prysmaticlabs/prysm/io/file"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/require"
)
func TestProof_SimpleField(t *testing.T) {
runProofTest(t, 0 /* genesis time */)
}
func TestProof_FinalizedCheckpoint(t *testing.T) {
runProofTest(t, 20 /* finalized checkpoint */)
}
func runProofTest(t testing.TB, fieldIndex uint64) {
data, err := file.ReadFileAsBytes("/tmp/state.ssz")
require.NoError(t, err)
dec := codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data)))
treeBacked, err := BeaconStateAltairType.Deserialize(dec)
require.NoError(t, err)
tb := &TreeBackedState{beaconState: treeBacked}
// Get a proof of the field.
proof, gIndex, err := tb.Proof(fieldIndex)
require.NoError(t, err)
root := tb.beaconState.HashTreeRoot(tree.GetHashFn())
leaf, err := tb.View().Backing().Getter(gIndex)
require.NoError(t, err)
// Verify the Merkle proof using the state root, leaf for the finalized checkpoint,
// and the generalized index of the field in the state.
valid := VerifyProof(root, proof, leaf.MerkleRoot(tree.GetHashFn()), gIndex)
require.Equal(t, true, valid)
}
func TestPrysmSSZComparison(t *testing.T) {
data, err := file.ReadFileAsBytes("/tmp/state.ssz")
require.NoError(t, err)
protoState := &ethpb.BeaconStateAltair{}
require.NoError(t, protoState.UnmarshalSSZ(data))
prysmBeaconState, err := stateAltair.InitializeFromProto(protoState)
require.NoError(t, err)
dec := codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data)))
ztypBeaconState, err := BeaconStateAltairType.Deserialize(dec)
require.NoError(t, err)
hFn := tree.GetHashFn()
ztypItem := ztypBeaconState.(*view.ContainerView)
ztypRoot := ztypItem.HashTreeRoot(hFn)
prysmRoot, err := prysmBeaconState.HashTreeRoot(context.Background())
require.NoError(t, err)
require.Equal(
t,
fmt.Sprintf("%#x", prysmRoot),
ztypRoot.String(),
)
}

1
go.mod
View File

@@ -79,6 +79,7 @@ require (
github.com/prometheus/procfs v0.7.0 // indirect
github.com/prometheus/prom2json v1.3.0
github.com/prometheus/tsdb v0.10.0 // indirect
github.com/protolambda/ztyp v0.1.9 // indirect
github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d
github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7
github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c

2
go.sum
View File

@@ -1191,6 +1191,8 @@ github.com/prometheus/prom2json v1.3.0/go.mod h1:rMN7m0ApCowcoDlypBHlkNbp5eJQf/+
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=
github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4=
github.com/protolambda/ztyp v0.1.9 h1:TEQvOTihEf89grFJMOZA1DrJ4B6M1Cg35U3WRSTdgew=
github.com/protolambda/ztyp v0.1.9/go.mod h1:NAGmX7+zlkxxv7F5ATHrdXwZFtkQjAUinDgg7RAV29k=
github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d h1:1dN7YAqMN3oAJ0LceWcyv/U4jHLh+5urnSnr4br6zg4=
github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d/go.mod h1:kOmQ/zdobQf7HUohDTifDNFEZfNaSCIY5fkONPL+dWU=
github.com/prysmaticlabs/go-bitfield v0.0.0-20210108222456-8e92c3709aa0/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=

912
proto/prysm/v1alpha1/light_client.pb.go generated Executable file
View File

@@ -0,0 +1,912 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.15.8
// source: proto/prysm/v1alpha1/light_client.proto
package eth
import (
context "context"
reflect "reflect"
sync "sync"
proto "github.com/golang/protobuf/proto"
empty "github.com/golang/protobuf/ptypes/empty"
github_com_prysmaticlabs_go_bitfield "github.com/prysmaticlabs/go-bitfield"
_ "github.com/prysmaticlabs/prysm/proto/eth/ext"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type BestUpdatesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
SyncCommitteePeriods []uint64 `protobuf:"varint,1,rep,packed,name=sync_committee_periods,json=syncCommitteePeriods,proto3" json:"sync_committee_periods,omitempty"`
}
func (x *BestUpdatesRequest) Reset() {
*x = BestUpdatesRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BestUpdatesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BestUpdatesRequest) ProtoMessage() {}
func (x *BestUpdatesRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BestUpdatesRequest.ProtoReflect.Descriptor instead.
func (*BestUpdatesRequest) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_light_client_proto_rawDescGZIP(), []int{0}
}
func (x *BestUpdatesRequest) GetSyncCommitteePeriods() []uint64 {
if x != nil {
return x.SyncCommitteePeriods
}
return nil
}
type BestUpdatesResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Updates []*LightClientUpdate `protobuf:"bytes,1,rep,name=updates,proto3" json:"updates,omitempty"`
}
func (x *BestUpdatesResponse) Reset() {
*x = BestUpdatesResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BestUpdatesResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BestUpdatesResponse) ProtoMessage() {}
func (x *BestUpdatesResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BestUpdatesResponse.ProtoReflect.Descriptor instead.
func (*BestUpdatesResponse) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_light_client_proto_rawDescGZIP(), []int{1}
}
func (x *BestUpdatesResponse) GetUpdates() []*LightClientUpdate {
if x != nil {
return x.Updates
}
return nil
}
type LightClientUpdate struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Header *BeaconBlockHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
NextSyncCommittee *SyncCommittee `protobuf:"bytes,2,opt,name=next_sync_committee,json=nextSyncCommittee,proto3" json:"next_sync_committee,omitempty"`
NextSyncCommitteeBranch [][]byte `protobuf:"bytes,3,rep,name=next_sync_committee_branch,json=nextSyncCommitteeBranch,proto3" json:"next_sync_committee_branch,omitempty" ssz-size:"5,32"`
FinalityHeader *BeaconBlockHeader `protobuf:"bytes,4,opt,name=finality_header,json=finalityHeader,proto3" json:"finality_header,omitempty"`
FinalityBranch [][]byte `protobuf:"bytes,5,rep,name=finality_branch,json=finalityBranch,proto3" json:"finality_branch,omitempty" ssz-size:"6,32"`
SyncCommitteeBits github_com_prysmaticlabs_go_bitfield.Bitvector512 `protobuf:"bytes,6,opt,name=sync_committee_bits,json=syncCommitteeBits,proto3" json:"sync_committee_bits,omitempty" cast-type:"github.com/prysmaticlabs/go-bitfield.Bitvector512" ssz-size:"64"`
SyncCommitteeSignature []byte `protobuf:"bytes,7,opt,name=sync_committee_signature,json=syncCommitteeSignature,proto3" json:"sync_committee_signature,omitempty" ssz-size:"96"`
ForkVersion []byte `protobuf:"bytes,8,opt,name=fork_version,json=forkVersion,proto3" json:"fork_version,omitempty" ssz-size:"4"`
}
func (x *LightClientUpdate) Reset() {
*x = LightClientUpdate{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LightClientUpdate) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LightClientUpdate) ProtoMessage() {}
func (x *LightClientUpdate) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LightClientUpdate.ProtoReflect.Descriptor instead.
func (*LightClientUpdate) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_light_client_proto_rawDescGZIP(), []int{2}
}
func (x *LightClientUpdate) GetHeader() *BeaconBlockHeader {
if x != nil {
return x.Header
}
return nil
}
func (x *LightClientUpdate) GetNextSyncCommittee() *SyncCommittee {
if x != nil {
return x.NextSyncCommittee
}
return nil
}
func (x *LightClientUpdate) GetNextSyncCommitteeBranch() [][]byte {
if x != nil {
return x.NextSyncCommitteeBranch
}
return nil
}
func (x *LightClientUpdate) GetFinalityHeader() *BeaconBlockHeader {
if x != nil {
return x.FinalityHeader
}
return nil
}
func (x *LightClientUpdate) GetFinalityBranch() [][]byte {
if x != nil {
return x.FinalityBranch
}
return nil
}
func (x *LightClientUpdate) GetSyncCommitteeBits() github_com_prysmaticlabs_go_bitfield.Bitvector512 {
if x != nil {
return x.SyncCommitteeBits
}
return github_com_prysmaticlabs_go_bitfield.Bitvector512(nil)
}
func (x *LightClientUpdate) GetSyncCommitteeSignature() []byte {
if x != nil {
return x.SyncCommitteeSignature
}
return nil
}
func (x *LightClientUpdate) GetForkVersion() []byte {
if x != nil {
return x.ForkVersion
}
return nil
}
type ClientSnapshot struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Header *BeaconBlockHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
CurrentSyncCommittee *SyncCommittee `protobuf:"bytes,2,opt,name=current_sync_committee,json=currentSyncCommittee,proto3" json:"current_sync_committee,omitempty"`
NextSyncCommittee *SyncCommittee `protobuf:"bytes,3,opt,name=next_sync_committee,json=nextSyncCommittee,proto3" json:"next_sync_committee,omitempty"`
}
func (x *ClientSnapshot) Reset() {
*x = ClientSnapshot{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ClientSnapshot) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ClientSnapshot) ProtoMessage() {}
func (x *ClientSnapshot) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ClientSnapshot.ProtoReflect.Descriptor instead.
func (*ClientSnapshot) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_light_client_proto_rawDescGZIP(), []int{3}
}
func (x *ClientSnapshot) GetHeader() *BeaconBlockHeader {
if x != nil {
return x.Header
}
return nil
}
func (x *ClientSnapshot) GetCurrentSyncCommittee() *SyncCommittee {
if x != nil {
return x.CurrentSyncCommittee
}
return nil
}
func (x *ClientSnapshot) GetNextSyncCommittee() *SyncCommittee {
if x != nil {
return x.NextSyncCommittee
}
return nil
}
type SyncAttestedData struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Header *BeaconBlockHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
FinalityCheckpoint *Checkpoint `protobuf:"bytes,2,opt,name=finality_checkpoint,json=finalityCheckpoint,proto3" json:"finality_checkpoint,omitempty"`
FinalityBranch [][]byte `protobuf:"bytes,3,rep,name=finality_branch,json=finalityBranch,proto3" json:"finality_branch,omitempty" ssz-size:"6,32"`
NextSyncCommittee *SyncCommittee `protobuf:"bytes,4,opt,name=next_sync_committee,json=nextSyncCommittee,proto3" json:"next_sync_committee,omitempty"`
NextSyncCommitteeBranch [][]byte `protobuf:"bytes,5,rep,name=next_sync_committee_branch,json=nextSyncCommitteeBranch,proto3" json:"next_sync_committee_branch,omitempty" ssz-size:"5,32"`
}
func (x *SyncAttestedData) Reset() {
*x = SyncAttestedData{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SyncAttestedData) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SyncAttestedData) ProtoMessage() {}
func (x *SyncAttestedData) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SyncAttestedData.ProtoReflect.Descriptor instead.
func (*SyncAttestedData) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_light_client_proto_rawDescGZIP(), []int{4}
}
func (x *SyncAttestedData) GetHeader() *BeaconBlockHeader {
if x != nil {
return x.Header
}
return nil
}
func (x *SyncAttestedData) GetFinalityCheckpoint() *Checkpoint {
if x != nil {
return x.FinalityCheckpoint
}
return nil
}
func (x *SyncAttestedData) GetFinalityBranch() [][]byte {
if x != nil {
return x.FinalityBranch
}
return nil
}
func (x *SyncAttestedData) GetNextSyncCommittee() *SyncCommittee {
if x != nil {
return x.NextSyncCommittee
}
return nil
}
func (x *SyncAttestedData) GetNextSyncCommitteeBranch() [][]byte {
if x != nil {
return x.NextSyncCommitteeBranch
}
return nil
}
type LightClientFinalizedCheckpoint struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Header *BeaconBlockHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
NextSyncCommittee *SyncCommittee `protobuf:"bytes,2,opt,name=next_sync_committee,json=nextSyncCommittee,proto3" json:"next_sync_committee,omitempty"`
NextSyncCommitteeBranch [][]byte `protobuf:"bytes,3,rep,name=next_sync_committee_branch,json=nextSyncCommitteeBranch,proto3" json:"next_sync_committee_branch,omitempty" ssz-size:"5,32"`
}
func (x *LightClientFinalizedCheckpoint) Reset() {
*x = LightClientFinalizedCheckpoint{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LightClientFinalizedCheckpoint) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LightClientFinalizedCheckpoint) ProtoMessage() {}
func (x *LightClientFinalizedCheckpoint) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_light_client_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LightClientFinalizedCheckpoint.ProtoReflect.Descriptor instead.
func (*LightClientFinalizedCheckpoint) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_light_client_proto_rawDescGZIP(), []int{5}
}
func (x *LightClientFinalizedCheckpoint) GetHeader() *BeaconBlockHeader {
if x != nil {
return x.Header
}
return nil
}
func (x *LightClientFinalizedCheckpoint) GetNextSyncCommittee() *SyncCommittee {
if x != nil {
return x.NextSyncCommittee
}
return nil
}
func (x *LightClientFinalizedCheckpoint) GetNextSyncCommitteeBranch() [][]byte {
if x != nil {
return x.NextSyncCommitteeBranch
}
return nil
}
var File_proto_prysm_v1alpha1_light_client_proto protoreflect.FileDescriptor
var file_proto_prysm_v1alpha1_light_client_proto_rawDesc = []byte{
0x0a, 0x27, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x63, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x65, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x1a, 0x1b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x65, 0x78, 0x74, 0x2f,
0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70,
0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x26, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x61,
0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x1a, 0x27, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x73, 0x74,
0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f,
0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x1a, 0x29, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f,
0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4a, 0x0a,
0x12, 0x42, 0x65, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x04, 0x52, 0x14, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74,
0x65, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x22, 0x59, 0x0a, 0x13, 0x42, 0x65, 0x73,
0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x42, 0x0a, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x07, 0x75, 0x70, 0x64,
0x61, 0x74, 0x65, 0x73, 0x22, 0xd1, 0x04, 0x0a, 0x11, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x40, 0x0a, 0x06, 0x68, 0x65,
0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68,
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65,
0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x13,
0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
0x74, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x65, 0x74, 0x68, 0x65,
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x52,
0x11, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74,
0x65, 0x65, 0x12, 0x45, 0x0a, 0x1a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f,
0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68,
0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x08, 0x8a, 0xb5, 0x18, 0x04, 0x35, 0x2c, 0x33, 0x32,
0x52, 0x17, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
0x74, 0x65, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x51, 0x0a, 0x0f, 0x66, 0x69, 0x6e,
0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f,
0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0e, 0x66, 0x69,
0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x0f,
0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18,
0x05, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x08, 0x8a, 0xb5, 0x18, 0x04, 0x36, 0x2c, 0x33, 0x32, 0x52,
0x0e, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12,
0x6b, 0x0a, 0x13, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
0x65, 0x5f, 0x62, 0x69, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x3b, 0x8a, 0xb5,
0x18, 0x02, 0x31, 0x36, 0x82, 0xb5, 0x18, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73,
0x2f, 0x67, 0x6f, 0x2d, 0x62, 0x69, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x42, 0x69, 0x74,
0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x31, 0x32, 0x38, 0x52, 0x11, 0x73, 0x79, 0x6e, 0x63, 0x43,
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x42, 0x69, 0x74, 0x73, 0x12, 0x40, 0x0a, 0x18,
0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x73,
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06,
0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x16, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d,
0x69, 0x74, 0x74, 0x65, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x28,
0x0a, 0x0c, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08,
0x20, 0x01, 0x28, 0x0c, 0x42, 0x05, 0x8a, 0xb5, 0x18, 0x01, 0x34, 0x52, 0x0b, 0x66, 0x6f, 0x72,
0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x84, 0x02, 0x0a, 0x0e, 0x43, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x40, 0x0a, 0x06, 0x68,
0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48,
0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x5a, 0x0a,
0x16, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f,
0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e,
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
0x74, 0x65, 0x65, 0x52, 0x14, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x79, 0x6e, 0x63,
0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x12, 0x54, 0x0a, 0x13, 0x6e, 0x65, 0x78,
0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53,
0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x52, 0x11, 0x6e, 0x65,
0x78, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x22,
0xf8, 0x02, 0x0a, 0x10, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64,
0x44, 0x61, 0x74, 0x61, 0x12, 0x40, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61,
0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06,
0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x13, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69,
0x74, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63,
0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x12, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79,
0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x0f, 0x66, 0x69,
0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x03, 0x20,
0x03, 0x28, 0x0c, 0x42, 0x08, 0x8a, 0xb5, 0x18, 0x04, 0x36, 0x2c, 0x33, 0x32, 0x52, 0x0e, 0x66,
0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x54, 0x0a,
0x13, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69,
0x74, 0x74, 0x65, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x65, 0x74, 0x68,
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65,
0x52, 0x11, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
0x74, 0x65, 0x65, 0x12, 0x45, 0x0a, 0x1a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63,
0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63,
0x68, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x08, 0x8a, 0xb5, 0x18, 0x04, 0x35, 0x2c, 0x33,
0x32, 0x52, 0x17, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69,
0x74, 0x74, 0x65, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x22, 0xff, 0x01, 0x0a, 0x1e, 0x4c,
0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69,
0x7a, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x40, 0x0a,
0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e,
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63,
0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12,
0x54, 0x0a, 0x13, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d,
0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x65,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74,
0x65, 0x65, 0x52, 0x11, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d,
0x69, 0x74, 0x74, 0x65, 0x65, 0x12, 0x45, 0x0a, 0x1a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x79,
0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x62, 0x72, 0x61,
0x6e, 0x63, 0x68, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x08, 0x8a, 0xb5, 0x18, 0x04, 0x35,
0x2c, 0x33, 0x32, 0x52, 0x17, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d,
0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x32, 0xda, 0x03, 0x0a,
0x0b, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x96, 0x01, 0x0a,
0x0b, 0x42, 0x65, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x29, 0x2e, 0x65,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x42, 0x65, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x22, 0x25, 0x2f, 0x65, 0x74,
0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74,
0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x62, 0x65, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61,
0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x94, 0x01, 0x0a, 0x15, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x12,
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x12, 0x31, 0x2f, 0x65, 0x74, 0x68, 0x2f,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x63, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x2f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61,
0x74, 0x65, 0x5f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x9a, 0x01, 0x0a,
0x18, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x6e,
0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x1a, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x36, 0x12, 0x34, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x6c,
0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x6e,
0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x93, 0x01, 0x0a, 0x19, 0x6f, 0x72,
0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0b, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73,
0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79,
0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa,
0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x56,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_proto_prysm_v1alpha1_light_client_proto_rawDescOnce sync.Once
file_proto_prysm_v1alpha1_light_client_proto_rawDescData = file_proto_prysm_v1alpha1_light_client_proto_rawDesc
)
func file_proto_prysm_v1alpha1_light_client_proto_rawDescGZIP() []byte {
file_proto_prysm_v1alpha1_light_client_proto_rawDescOnce.Do(func() {
file_proto_prysm_v1alpha1_light_client_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_prysm_v1alpha1_light_client_proto_rawDescData)
})
return file_proto_prysm_v1alpha1_light_client_proto_rawDescData
}
var file_proto_prysm_v1alpha1_light_client_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_proto_prysm_v1alpha1_light_client_proto_goTypes = []interface{}{
(*BestUpdatesRequest)(nil), // 0: ethereum.eth.v1alpha1.BestUpdatesRequest
(*BestUpdatesResponse)(nil), // 1: ethereum.eth.v1alpha1.BestUpdatesResponse
(*LightClientUpdate)(nil), // 2: ethereum.eth.v1alpha1.LightClientUpdate
(*ClientSnapshot)(nil), // 3: ethereum.eth.v1alpha1.ClientSnapshot
(*SyncAttestedData)(nil), // 4: ethereum.eth.v1alpha1.SyncAttestedData
(*LightClientFinalizedCheckpoint)(nil), // 5: ethereum.eth.v1alpha1.LightClientFinalizedCheckpoint
(*BeaconBlockHeader)(nil), // 6: ethereum.eth.v1alpha1.BeaconBlockHeader
(*SyncCommittee)(nil), // 7: ethereum.eth.v1alpha1.SyncCommittee
(*Checkpoint)(nil), // 8: ethereum.eth.v1alpha1.Checkpoint
(*empty.Empty)(nil), // 9: google.protobuf.Empty
}
var file_proto_prysm_v1alpha1_light_client_proto_depIdxs = []int32{
2, // 0: ethereum.eth.v1alpha1.BestUpdatesResponse.updates:type_name -> ethereum.eth.v1alpha1.LightClientUpdate
6, // 1: ethereum.eth.v1alpha1.LightClientUpdate.header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
7, // 2: ethereum.eth.v1alpha1.LightClientUpdate.next_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
6, // 3: ethereum.eth.v1alpha1.LightClientUpdate.finality_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
6, // 4: ethereum.eth.v1alpha1.ClientSnapshot.header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
7, // 5: ethereum.eth.v1alpha1.ClientSnapshot.current_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
7, // 6: ethereum.eth.v1alpha1.ClientSnapshot.next_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
6, // 7: ethereum.eth.v1alpha1.SyncAttestedData.header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
8, // 8: ethereum.eth.v1alpha1.SyncAttestedData.finality_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
7, // 9: ethereum.eth.v1alpha1.SyncAttestedData.next_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
6, // 10: ethereum.eth.v1alpha1.LightClientFinalizedCheckpoint.header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
7, // 11: ethereum.eth.v1alpha1.LightClientFinalizedCheckpoint.next_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
0, // 12: ethereum.eth.v1alpha1.LightClient.BestUpdates:input_type -> ethereum.eth.v1alpha1.BestUpdatesRequest
9, // 13: ethereum.eth.v1alpha1.LightClient.LatestUpdateFinalized:input_type -> google.protobuf.Empty
9, // 14: ethereum.eth.v1alpha1.LightClient.LatestUpdateNonFinalized:input_type -> google.protobuf.Empty
1, // 15: ethereum.eth.v1alpha1.LightClient.BestUpdates:output_type -> ethereum.eth.v1alpha1.BestUpdatesResponse
2, // 16: ethereum.eth.v1alpha1.LightClient.LatestUpdateFinalized:output_type -> ethereum.eth.v1alpha1.LightClientUpdate
2, // 17: ethereum.eth.v1alpha1.LightClient.LatestUpdateNonFinalized:output_type -> ethereum.eth.v1alpha1.LightClientUpdate
15, // [15:18] is the sub-list for method output_type
12, // [12:15] is the sub-list for method input_type
12, // [12:12] is the sub-list for extension type_name
12, // [12:12] is the sub-list for extension extendee
0, // [0:12] is the sub-list for field type_name
}
func init() { file_proto_prysm_v1alpha1_light_client_proto_init() }
func file_proto_prysm_v1alpha1_light_client_proto_init() {
if File_proto_prysm_v1alpha1_light_client_proto != nil {
return
}
file_proto_prysm_v1alpha1_attestation_proto_init()
file_proto_prysm_v1alpha1_beacon_state_proto_init()
file_proto_prysm_v1alpha1_beacon_block_proto_init()
file_proto_prysm_v1alpha1_sync_committee_proto_init()
if !protoimpl.UnsafeEnabled {
file_proto_prysm_v1alpha1_light_client_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BestUpdatesRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_prysm_v1alpha1_light_client_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BestUpdatesResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_prysm_v1alpha1_light_client_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LightClientUpdate); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_prysm_v1alpha1_light_client_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ClientSnapshot); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_prysm_v1alpha1_light_client_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SyncAttestedData); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_prysm_v1alpha1_light_client_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LightClientFinalizedCheckpoint); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_prysm_v1alpha1_light_client_proto_rawDesc,
NumEnums: 0,
NumMessages: 6,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_prysm_v1alpha1_light_client_proto_goTypes,
DependencyIndexes: file_proto_prysm_v1alpha1_light_client_proto_depIdxs,
MessageInfos: file_proto_prysm_v1alpha1_light_client_proto_msgTypes,
}.Build()
File_proto_prysm_v1alpha1_light_client_proto = out.File
file_proto_prysm_v1alpha1_light_client_proto_rawDesc = nil
file_proto_prysm_v1alpha1_light_client_proto_goTypes = nil
file_proto_prysm_v1alpha1_light_client_proto_depIdxs = nil
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// LightClientClient is the client API for LightClient service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type LightClientClient interface {
BestUpdates(ctx context.Context, in *BestUpdatesRequest, opts ...grpc.CallOption) (*BestUpdatesResponse, error)
LatestUpdateFinalized(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*LightClientUpdate, error)
LatestUpdateNonFinalized(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*LightClientUpdate, error)
}
type lightClientClient struct {
cc grpc.ClientConnInterface
}
func NewLightClientClient(cc grpc.ClientConnInterface) LightClientClient {
return &lightClientClient{cc}
}
func (c *lightClientClient) BestUpdates(ctx context.Context, in *BestUpdatesRequest, opts ...grpc.CallOption) (*BestUpdatesResponse, error) {
out := new(BestUpdatesResponse)
err := c.cc.Invoke(ctx, "/ethereum.eth.v1alpha1.LightClient/BestUpdates", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *lightClientClient) LatestUpdateFinalized(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*LightClientUpdate, error) {
out := new(LightClientUpdate)
err := c.cc.Invoke(ctx, "/ethereum.eth.v1alpha1.LightClient/LatestUpdateFinalized", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *lightClientClient) LatestUpdateNonFinalized(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*LightClientUpdate, error) {
out := new(LightClientUpdate)
err := c.cc.Invoke(ctx, "/ethereum.eth.v1alpha1.LightClient/LatestUpdateNonFinalized", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// LightClientServer is the server API for LightClient service.
type LightClientServer interface {
BestUpdates(context.Context, *BestUpdatesRequest) (*BestUpdatesResponse, error)
LatestUpdateFinalized(context.Context, *empty.Empty) (*LightClientUpdate, error)
LatestUpdateNonFinalized(context.Context, *empty.Empty) (*LightClientUpdate, error)
}
// UnimplementedLightClientServer can be embedded to have forward compatible implementations.
type UnimplementedLightClientServer struct {
}
func (*UnimplementedLightClientServer) BestUpdates(context.Context, *BestUpdatesRequest) (*BestUpdatesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method BestUpdates not implemented")
}
func (*UnimplementedLightClientServer) LatestUpdateFinalized(context.Context, *empty.Empty) (*LightClientUpdate, error) {
return nil, status.Errorf(codes.Unimplemented, "method LatestUpdateFinalized not implemented")
}
func (*UnimplementedLightClientServer) LatestUpdateNonFinalized(context.Context, *empty.Empty) (*LightClientUpdate, error) {
return nil, status.Errorf(codes.Unimplemented, "method LatestUpdateNonFinalized not implemented")
}
func RegisterLightClientServer(s *grpc.Server, srv LightClientServer) {
s.RegisterService(&_LightClient_serviceDesc, srv)
}
func _LightClient_BestUpdates_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(BestUpdatesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LightClientServer).BestUpdates(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.eth.v1alpha1.LightClient/BestUpdates",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LightClientServer).BestUpdates(ctx, req.(*BestUpdatesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _LightClient_LatestUpdateFinalized_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(empty.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LightClientServer).LatestUpdateFinalized(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.eth.v1alpha1.LightClient/LatestUpdateFinalized",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LightClientServer).LatestUpdateFinalized(ctx, req.(*empty.Empty))
}
return interceptor(ctx, in, info, handler)
}
func _LightClient_LatestUpdateNonFinalized_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(empty.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LightClientServer).LatestUpdateNonFinalized(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.eth.v1alpha1.LightClient/LatestUpdateNonFinalized",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LightClientServer).LatestUpdateNonFinalized(ctx, req.(*empty.Empty))
}
return interceptor(ctx, in, info, handler)
}
var _LightClient_serviceDesc = grpc.ServiceDesc{
ServiceName: "ethereum.eth.v1alpha1.LightClient",
HandlerType: (*LightClientServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "BestUpdates",
Handler: _LightClient_BestUpdates_Handler,
},
{
MethodName: "LatestUpdateFinalized",
Handler: _LightClient_LatestUpdateFinalized_Handler,
},
{
MethodName: "LatestUpdateNonFinalized",
Handler: _LightClient_LatestUpdateNonFinalized_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proto/prysm/v1alpha1/light_client.proto",
}

View File

@@ -0,0 +1,301 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: proto/prysm/v1alpha1/light_client.proto
/*
Package eth is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package eth
import (
"context"
"io"
"net/http"
emptypb "github.com/golang/protobuf/ptypes/empty"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
github_com_prysmaticlabs_eth2_types "github.com/prysmaticlabs/eth2-types"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join
var _ = github_com_prysmaticlabs_eth2_types.Epoch(0)
var _ = emptypb.Empty{}
func request_LightClient_BestUpdates_0(ctx context.Context, marshaler runtime.Marshaler, client LightClientClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq BestUpdatesRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.BestUpdates(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_LightClient_BestUpdates_0(ctx context.Context, marshaler runtime.Marshaler, server LightClientServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq BestUpdatesRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.BestUpdates(ctx, &protoReq)
return msg, metadata, err
}
func request_LightClient_LatestUpdateFinalized_0(ctx context.Context, marshaler runtime.Marshaler, client LightClientClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := client.LatestUpdateFinalized(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_LightClient_LatestUpdateFinalized_0(ctx context.Context, marshaler runtime.Marshaler, server LightClientServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := server.LatestUpdateFinalized(ctx, &protoReq)
return msg, metadata, err
}
func request_LightClient_LatestUpdateNonFinalized_0(ctx context.Context, marshaler runtime.Marshaler, client LightClientClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := client.LatestUpdateNonFinalized(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_LightClient_LatestUpdateNonFinalized_0(ctx context.Context, marshaler runtime.Marshaler, server LightClientServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := server.LatestUpdateNonFinalized(ctx, &protoReq)
return msg, metadata, err
}
// RegisterLightClientHandlerServer registers the http handlers for service LightClient to "mux".
// UnaryRPC :call LightClientServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterLightClientHandlerFromEndpoint instead.
func RegisterLightClientHandlerServer(ctx context.Context, mux *runtime.ServeMux, server LightClientServer) error {
mux.Handle("POST", pattern_LightClient_BestUpdates_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.v1alpha1.LightClient/BestUpdates")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_LightClient_BestUpdates_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_LightClient_BestUpdates_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_LightClient_LatestUpdateFinalized_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.v1alpha1.LightClient/LatestUpdateFinalized")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_LightClient_LatestUpdateFinalized_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_LightClient_LatestUpdateFinalized_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_LightClient_LatestUpdateNonFinalized_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.v1alpha1.LightClient/LatestUpdateNonFinalized")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_LightClient_LatestUpdateNonFinalized_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_LightClient_LatestUpdateNonFinalized_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterLightClientHandlerFromEndpoint is same as RegisterLightClientHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterLightClientHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterLightClientHandler(ctx, mux, conn)
}
// RegisterLightClientHandler registers the http handlers for service LightClient to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterLightClientHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterLightClientHandlerClient(ctx, mux, NewLightClientClient(conn))
}
// RegisterLightClientHandlerClient registers the http handlers for service LightClient
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "LightClientClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "LightClientClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "LightClientClient" to call the correct interceptors.
func RegisterLightClientHandlerClient(ctx context.Context, mux *runtime.ServeMux, client LightClientClient) error {
mux.Handle("POST", pattern_LightClient_BestUpdates_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.v1alpha1.LightClient/BestUpdates")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_LightClient_BestUpdates_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_LightClient_BestUpdates_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_LightClient_LatestUpdateFinalized_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.v1alpha1.LightClient/LatestUpdateFinalized")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_LightClient_LatestUpdateFinalized_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_LightClient_LatestUpdateFinalized_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_LightClient_LatestUpdateNonFinalized_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.v1alpha1.LightClient/LatestUpdateNonFinalized")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_LightClient_LatestUpdateNonFinalized_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_LightClient_LatestUpdateNonFinalized_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_LightClient_BestUpdates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "lightclient", "best_update"}, ""))
pattern_LightClient_LatestUpdateFinalized_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "lightclient", "latest_update_finalized"}, ""))
pattern_LightClient_LatestUpdateNonFinalized_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "lightclient", "latest_update_nonfinalized"}, ""))
)
var (
forward_LightClient_BestUpdates_0 = runtime.ForwardResponseMessage
forward_LightClient_LatestUpdateFinalized_0 = runtime.ForwardResponseMessage
forward_LightClient_LatestUpdateNonFinalized_0 = runtime.ForwardResponseMessage
)

View File

@@ -0,0 +1,91 @@
// Copyright 2021 Prysmatic Labs.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package ethereum.eth.v1alpha1;
import "proto/eth/ext/options.proto";
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
import "proto/prysm/v1alpha1/attestation.proto";
import "proto/prysm/v1alpha1/beacon_state.proto";
import "proto/prysm/v1alpha1/beacon_block.proto";
import "proto/prysm/v1alpha1/sync_committee.proto";
option csharp_namespace = "Ethereum.Eth.V1alpha1";
option go_package = "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1;eth";
option java_multiple_files = true;
option java_outer_classname = "LightClient";
option java_package = "org.ethereum.eth.v1alpha1";
option php_namespace = "Ethereum\\Eth\\v1alpha1";
service LightClient {
rpc BestUpdates(BestUpdatesRequest) returns (BestUpdatesResponse) {
option (google.api.http) = {
post: "/eth/v1alpha1/lightclient/best_update",
body: "*"
};
}
rpc LatestUpdateFinalized(google.protobuf.Empty) returns (LightClientUpdate) {
option (google.api.http) = {
get: "/eth/v1alpha1/lightclient/latest_update_finalized",
};
}
rpc LatestUpdateNonFinalized(google.protobuf.Empty) returns (LightClientUpdate) {
option (google.api.http) = {
get: "/eth/v1alpha1/lightclient/latest_update_nonfinalized",
};
}
}
message BestUpdatesRequest {
repeated uint64 sync_committee_periods = 1;
}
message BestUpdatesResponse {
repeated LightClientUpdate updates = 1;
}
message LightClientUpdate {
ethereum.eth.v1alpha1.BeaconBlockHeader header = 1;
ethereum.eth.v1alpha1.SyncCommittee next_sync_committee = 2;
repeated bytes next_sync_committee_branch = 3 [(ethereum.eth.ext.ssz_size) = "5,32"];
ethereum.eth.v1alpha1.BeaconBlockHeader finality_header = 4;
repeated bytes finality_branch = 5 [(ethereum.eth.ext.ssz_size) = "6,32"];
bytes sync_committee_bits = 6 [(ethereum.eth.ext.ssz_size) = "sync_committee_aggregate_bytes.size", (ethereum.eth.ext.cast_type) = "sync_committee_aggregate_bits.type"];
bytes sync_committee_signature = 7 [(ethereum.eth.ext.ssz_size) = "96"];
bytes fork_version = 8 [(ethereum.eth.ext.ssz_size) = "4"];
}
message ClientSnapshot {
ethereum.eth.v1alpha1.BeaconBlockHeader header = 1;
ethereum.eth.v1alpha1.SyncCommittee current_sync_committee = 2;
ethereum.eth.v1alpha1.SyncCommittee next_sync_committee = 3;
}
message SyncAttestedData {
ethereum.eth.v1alpha1.BeaconBlockHeader header = 1;
ethereum.eth.v1alpha1.Checkpoint finality_checkpoint = 2;
repeated bytes finality_branch = 3 [(ethereum.eth.ext.ssz_size) = "6,32"];
ethereum.eth.v1alpha1.SyncCommittee next_sync_committee = 4;
repeated bytes next_sync_committee_branch = 5 [(ethereum.eth.ext.ssz_size) = "5,32"];
}
message LightClientFinalizedCheckpoint {
ethereum.eth.v1alpha1.BeaconBlockHeader header = 1;
ethereum.eth.v1alpha1.SyncCommittee next_sync_committee = 2;
repeated bytes next_sync_committee_branch = 3 [(ethereum.eth.ext.ssz_size) = "5,32"];
}