diff --git a/beacon/types/committee.go b/beacon/types/committee.go
deleted file mode 100644
index 5f89c27554..0000000000
--- a/beacon/types/committee.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2023 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package types
-
-import (
- "crypto/sha256"
- "encoding/json"
- "fmt"
- "math/bits"
-
- "github.com/ethereum/go-ethereum/beacon/params"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- bls "github.com/protolambda/bls12-381-util"
-)
-
-// SerializedSyncCommitteeSize is the size of the sync committee plus the
-// aggregate public key.
-const SerializedSyncCommitteeSize = (params.SyncCommitteeSize + 1) * params.BLSPubkeySize
-
-// SerializedSyncCommittee is the serialized version of a sync committee
-// plus the aggregate public key.
-type SerializedSyncCommittee [SerializedSyncCommitteeSize]byte
-
-// jsonSyncCommittee is the JSON representation of a sync committee.
-//
-// See data structure definition here:
-// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#syncaggregate
-type jsonSyncCommittee struct {
- Pubkeys []hexutil.Bytes `json:"pubkeys"`
- Aggregate hexutil.Bytes `json:"aggregate_pubkey"`
-}
-
-// MarshalJSON implements json.Marshaler.
-func (s *SerializedSyncCommittee) MarshalJSON() ([]byte, error) {
- sc := jsonSyncCommittee{Pubkeys: make([]hexutil.Bytes, params.SyncCommitteeSize)}
- for i := range sc.Pubkeys {
- sc.Pubkeys[i] = make(hexutil.Bytes, params.BLSPubkeySize)
- copy(sc.Pubkeys[i][:], s[i*params.BLSPubkeySize:(i+1)*params.BLSPubkeySize])
- }
- sc.Aggregate = make(hexutil.Bytes, params.BLSPubkeySize)
- copy(sc.Aggregate[:], s[params.SyncCommitteeSize*params.BLSPubkeySize:])
- return json.Marshal(&sc)
-}
-
-// UnmarshalJSON implements json.Marshaler.
-func (s *SerializedSyncCommittee) UnmarshalJSON(input []byte) error {
- var sc jsonSyncCommittee
- if err := json.Unmarshal(input, &sc); err != nil {
- return err
- }
- if len(sc.Pubkeys) != params.SyncCommitteeSize {
- return fmt.Errorf("invalid number of pubkeys %d", len(sc.Pubkeys))
- }
- for i, key := range sc.Pubkeys {
- if len(key) != params.BLSPubkeySize {
- return fmt.Errorf("pubkey %d has invalid size %d", i, len(key))
- }
- copy(s[i*params.BLSPubkeySize:], key[:])
- }
- if len(sc.Aggregate) != params.BLSPubkeySize {
- return fmt.Errorf("invalid aggregate pubkey size %d", len(sc.Aggregate))
- }
- copy(s[params.SyncCommitteeSize*params.BLSPubkeySize:], sc.Aggregate[:])
- return nil
-}
-
-// Root calculates the root hash of the binary tree representation of a sync
-// committee provided in serialized format.
-//
-// TODO(zsfelfoldi): Get rid of this when SSZ encoding lands.
-func (s *SerializedSyncCommittee) Root() common.Hash {
- var (
- hasher = sha256.New()
- padding [64 - params.BLSPubkeySize]byte
- data [params.SyncCommitteeSize]common.Hash
- l = params.SyncCommitteeSize
- )
- for i := range data {
- hasher.Reset()
- hasher.Write(s[i*params.BLSPubkeySize : (i+1)*params.BLSPubkeySize])
- hasher.Write(padding[:])
- hasher.Sum(data[i][:0])
- }
- for l > 1 {
- for i := 0; i < l/2; i++ {
- hasher.Reset()
- hasher.Write(data[i*2][:])
- hasher.Write(data[i*2+1][:])
- hasher.Sum(data[i][:0])
- }
- l /= 2
- }
- hasher.Reset()
- hasher.Write(s[SerializedSyncCommitteeSize-params.BLSPubkeySize : SerializedSyncCommitteeSize])
- hasher.Write(padding[:])
- hasher.Sum(data[1][:0])
- hasher.Reset()
- hasher.Write(data[0][:])
- hasher.Write(data[1][:])
- hasher.Sum(data[0][:0])
- return data[0]
-}
-
-// Deserialize splits open the pubkeys into proper BLS key types.
-func (s *SerializedSyncCommittee) Deserialize() (*SyncCommittee, error) {
- sc := new(SyncCommittee)
- for i := 0; i <= params.SyncCommitteeSize; i++ {
- key := new(bls.Pubkey)
-
- var bytes [params.BLSPubkeySize]byte
- copy(bytes[:], s[i*params.BLSPubkeySize:(i+1)*params.BLSPubkeySize])
-
- if err := key.Deserialize(&bytes); err != nil {
- return nil, err
- }
- if i < params.SyncCommitteeSize {
- sc.keys[i] = key
- } else {
- sc.aggregate = key
- }
- }
- return sc, nil
-}
-
-// SyncCommittee is a set of sync committee signer pubkeys and the aggregate key.
-//
-// See data structure definition here:
-// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#syncaggregate
-type SyncCommittee struct {
- keys [params.SyncCommitteeSize]*bls.Pubkey
- aggregate *bls.Pubkey
-}
-
-// VerifySignature returns true if the given sync aggregate is a valid signature
-// or the given hash.
-func (sc *SyncCommittee) VerifySignature(signingRoot common.Hash, signature *SyncAggregate) bool {
- var (
- sig bls.Signature
- keys = make([]*bls.Pubkey, 0, params.SyncCommitteeSize)
- )
- if err := sig.Deserialize(&signature.Signature); err != nil {
- return false
- }
- for i, key := range sc.keys {
- if signature.Signers[i/8]&(byte(1)<<(i%8)) != 0 {
- keys = append(keys, key)
- }
- }
- return bls.FastAggregateVerify(keys, signingRoot[:], &sig)
-}
-
-//go:generate go run github.com/fjl/gencodec -type SyncAggregate -field-override syncAggregateMarshaling -out gen_syncaggregate_json.go
-
-// SyncAggregate represents an aggregated BLS signature with Signers referring
-// to a subset of the corresponding sync committee.
-//
-// See data structure definition here:
-// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#syncaggregate
-type SyncAggregate struct {
- Signers [params.SyncCommitteeBitmaskSize]byte `gencodec:"required" json:"sync_committee_bits"`
- Signature [params.BLSSignatureSize]byte `gencodec:"required" json:"sync_committee_signature"`
-}
-
-type syncAggregateMarshaling struct {
- Signers hexutil.Bytes
- Signature hexutil.Bytes
-}
-
-// SignerCount returns the number of signers in the aggregate signature.
-func (s *SyncAggregate) SignerCount() int {
- var count int
- for _, v := range s.Signers {
- count += bits.OnesCount8(v)
- }
- return count
-}
diff --git a/beacon/types/config.go b/beacon/types/config.go
deleted file mode 100644
index 8cb8808b6f..0000000000
--- a/beacon/types/config.go
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2022 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package types
-
-import (
- "crypto/sha256"
- "fmt"
- "os"
- "sort"
- "strconv"
- "strings"
-
- "github.com/ethereum/go-ethereum/beacon/merkle"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "gopkg.in/yaml.v3"
-)
-
-// syncCommitteeDomain specifies the signatures specific use to avoid clashes
-// across signing different data structures.
-const syncCommitteeDomain = 7
-
-// Fork describes a single beacon chain fork and also stores the calculated
-// signature domain used after this fork.
-type Fork struct {
- // Name of the fork in the chain config (config.yaml) file{
- Name string
-
- // Epoch when given fork version is activated
- Epoch uint64
-
- // Fork version, see https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types
- Version []byte
-
- // calculated by computeDomain, based on fork version and genesis validators root
- domain merkle.Value
-}
-
-// computeDomain returns the signature domain based on the given fork version
-// and genesis validator set root.
-func (f *Fork) computeDomain(genesisValidatorsRoot common.Hash) {
- var (
- hasher = sha256.New()
- forkVersion32 merkle.Value
- forkDataRoot merkle.Value
- )
- copy(forkVersion32[:], f.Version)
- hasher.Write(forkVersion32[:])
- hasher.Write(genesisValidatorsRoot[:])
- hasher.Sum(forkDataRoot[:0])
-
- f.domain[0] = syncCommitteeDomain
- copy(f.domain[4:], forkDataRoot[:28])
-}
-
-// Forks is the list of all beacon chain forks in the chain configuration.
-type Forks []*Fork
-
-// domain returns the signature domain for the given epoch (assumes that domains
-// have already been calculated).
-func (f Forks) domain(epoch uint64) (merkle.Value, error) {
- for i := len(f) - 1; i >= 0; i-- {
- if epoch >= f[i].Epoch {
- return f[i].domain, nil
- }
- }
- return merkle.Value{}, fmt.Errorf("unknown fork for epoch %d", epoch)
-}
-
-// SigningRoot calculates the signing root of the given header.
-func (f Forks) SigningRoot(header Header) (common.Hash, error) {
- domain, err := f.domain(header.Epoch())
- if err != nil {
- return common.Hash{}, err
- }
- var (
- signingRoot common.Hash
- headerHash = header.Hash()
- hasher = sha256.New()
- )
- hasher.Write(headerHash[:])
- hasher.Write(domain[:])
- hasher.Sum(signingRoot[:0])
-
- return signingRoot, nil
-}
-
-func (f Forks) Len() int { return len(f) }
-func (f Forks) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
-func (f Forks) Less(i, j int) bool { return f[i].Epoch < f[j].Epoch }
-
-// ChainConfig contains the beacon chain configuration.
-type ChainConfig struct {
- GenesisTime uint64 // Unix timestamp of slot 0
- GenesisValidatorsRoot common.Hash // Root hash of the genesis validator set, used for signature domain calculation
- Forks Forks
-}
-
-// AddFork adds a new item to the list of forks.
-func (c *ChainConfig) AddFork(name string, epoch uint64, version []byte) *ChainConfig {
- fork := &Fork{
- Name: name,
- Epoch: epoch,
- Version: version,
- }
- fork.computeDomain(c.GenesisValidatorsRoot)
-
- c.Forks = append(c.Forks, fork)
- sort.Sort(c.Forks)
-
- return c
-}
-
-// LoadForks parses the beacon chain configuration file (config.yaml) and extracts
-// the list of forks.
-func (c *ChainConfig) LoadForks(path string) error {
- file, err := os.ReadFile(path)
- if err != nil {
- return fmt.Errorf("failed to read beacon chain config file: %v", err)
- }
- config := make(map[string]string)
- if err := yaml.Unmarshal(file, &config); err != nil {
- return fmt.Errorf("failed to parse beacon chain config file: %v", err)
- }
- var (
- versions = make(map[string][]byte)
- epochs = make(map[string]uint64)
- )
- epochs["GENESIS"] = 0
-
- for key, value := range config {
- if strings.HasSuffix(key, "_FORK_VERSION") {
- name := key[:len(key)-len("_FORK_VERSION")]
- if v, err := hexutil.Decode(value); err == nil {
- versions[name] = v
- } else {
- return fmt.Errorf("failed to decode hex fork id %q in beacon chain config file: %v", value, err)
- }
- }
- if strings.HasSuffix(key, "_FORK_EPOCH") {
- name := key[:len(key)-len("_FORK_EPOCH")]
- if v, err := strconv.ParseUint(value, 10, 64); err == nil {
- epochs[name] = v
- } else {
- return fmt.Errorf("failed to parse epoch number %q in beacon chain config file: %v", value, err)
- }
- }
- }
- for name, epoch := range epochs {
- if version, ok := versions[name]; ok {
- delete(versions, name)
- c.AddFork(name, epoch, version)
- } else {
- return fmt.Errorf("fork id missing for %q in beacon chain config file", name)
- }
- }
- for name := range versions {
- return fmt.Errorf("epoch number missing for fork %q in beacon chain config file", name)
- }
- sort.Sort(c.Forks)
- return nil
-}
diff --git a/beacon/types/gen_header_json.go b/beacon/types/gen_header_json.go
deleted file mode 100644
index 9b3ffea06f..0000000000
--- a/beacon/types/gen_header_json.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package types
-
-import (
- "encoding/json"
- "errors"
-
- "github.com/ethereum/go-ethereum/common"
-)
-
-var _ = (*headerMarshaling)(nil)
-
-// MarshalJSON marshals as JSON.
-func (h Header) MarshalJSON() ([]byte, error) {
- type Header struct {
- Slot common.Decimal `gencodec:"required" json:"slot"`
- ProposerIndex common.Decimal `gencodec:"required" json:"proposer_index"`
- ParentRoot common.Hash `gencodec:"required" json:"parent_root"`
- StateRoot common.Hash `gencodec:"required" json:"state_root"`
- BodyRoot common.Hash `gencodec:"required" json:"body_root"`
- }
- var enc Header
- enc.Slot = common.Decimal(h.Slot)
- enc.ProposerIndex = common.Decimal(h.ProposerIndex)
- enc.ParentRoot = h.ParentRoot
- enc.StateRoot = h.StateRoot
- enc.BodyRoot = h.BodyRoot
- return json.Marshal(&enc)
-}
-
-// UnmarshalJSON unmarshals from JSON.
-func (h *Header) UnmarshalJSON(input []byte) error {
- type Header struct {
- Slot *common.Decimal `gencodec:"required" json:"slot"`
- ProposerIndex *common.Decimal `gencodec:"required" json:"proposer_index"`
- ParentRoot *common.Hash `gencodec:"required" json:"parent_root"`
- StateRoot *common.Hash `gencodec:"required" json:"state_root"`
- BodyRoot *common.Hash `gencodec:"required" json:"body_root"`
- }
- var dec Header
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.Slot == nil {
- return errors.New("missing required field 'slot' for Header")
- }
- h.Slot = uint64(*dec.Slot)
- if dec.ProposerIndex == nil {
- return errors.New("missing required field 'proposer_index' for Header")
- }
- h.ProposerIndex = uint64(*dec.ProposerIndex)
- if dec.ParentRoot == nil {
- return errors.New("missing required field 'parent_root' for Header")
- }
- h.ParentRoot = *dec.ParentRoot
- if dec.StateRoot == nil {
- return errors.New("missing required field 'state_root' for Header")
- }
- h.StateRoot = *dec.StateRoot
- if dec.BodyRoot == nil {
- return errors.New("missing required field 'body_root' for Header")
- }
- h.BodyRoot = *dec.BodyRoot
- return nil
-}
diff --git a/beacon/types/gen_syncaggregate_json.go b/beacon/types/gen_syncaggregate_json.go
deleted file mode 100644
index 1547ec5f01..0000000000
--- a/beacon/types/gen_syncaggregate_json.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package types
-
-import (
- "encoding/json"
- "errors"
-
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-var _ = (*syncAggregateMarshaling)(nil)
-
-// MarshalJSON marshals as JSON.
-func (s SyncAggregate) MarshalJSON() ([]byte, error) {
- type SyncAggregate struct {
- Signers hexutil.Bytes `gencodec:"required" json:"sync_committee_bits"`
- Signature hexutil.Bytes `gencodec:"required" json:"sync_committee_signature"`
- }
- var enc SyncAggregate
- enc.Signers = s.Signers[:]
- enc.Signature = s.Signature[:]
- return json.Marshal(&enc)
-}
-
-// UnmarshalJSON unmarshals from JSON.
-func (s *SyncAggregate) UnmarshalJSON(input []byte) error {
- type SyncAggregate struct {
- Signers *hexutil.Bytes `gencodec:"required" json:"sync_committee_bits"`
- Signature *hexutil.Bytes `gencodec:"required" json:"sync_committee_signature"`
- }
- var dec SyncAggregate
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.Signers == nil {
- return errors.New("missing required field 'sync_committee_bits' for SyncAggregate")
- }
- if len(*dec.Signers) != len(s.Signers) {
- return errors.New("field 'sync_committee_bits' has wrong length, need 64 items")
- }
- copy(s.Signers[:], *dec.Signers)
- if dec.Signature == nil {
- return errors.New("missing required field 'sync_committee_signature' for SyncAggregate")
- }
- if len(*dec.Signature) != len(s.Signature) {
- return errors.New("field 'sync_committee_signature' has wrong length, need 96 items")
- }
- copy(s.Signature[:], *dec.Signature)
- return nil
-}
diff --git a/beacon/types/header.go b/beacon/types/header.go
deleted file mode 100644
index 2ddc4575f1..0000000000
--- a/beacon/types/header.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2022 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Package types implements a few types of the beacon chain for light client usage.
-package types
-
-import (
- "crypto/sha256"
- "encoding/binary"
-
- "github.com/ethereum/go-ethereum/beacon/merkle"
- "github.com/ethereum/go-ethereum/beacon/params"
- "github.com/ethereum/go-ethereum/common"
-)
-
-//go:generate go run github.com/fjl/gencodec -type Header -field-override headerMarshaling -out gen_header_json.go
-
-const (
- headerIndexSlot = 8
- headerIndexProposerIndex = 9
- headerIndexParentRoot = 10
- headerIndexStateRoot = 11
- headerIndexBodyRoot = 12
-)
-
-// Header defines a beacon header.
-//
-// See data structure definition here:
-// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblockheader
-type Header struct {
- // Monotonically increasing slot number for the beacon block (may be gapped)
- Slot uint64 `gencodec:"required" json:"slot"`
-
- // Index into the validator table who created the beacon block
- ProposerIndex uint64 `gencodec:"required" json:"proposer_index"`
-
- // SSZ hash of the parent beacon header
- ParentRoot common.Hash `gencodec:"required" json:"parent_root"`
-
- // SSZ hash of the beacon state (https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#beacon-state)
- StateRoot common.Hash `gencodec:"required" json:"state_root"`
-
- // SSZ hash of the beacon block body (https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#beaconblockbody)
- BodyRoot common.Hash `gencodec:"required" json:"body_root"`
-}
-
-// headerMarshaling is a field type overrides for gencodec.
-type headerMarshaling struct {
- Slot common.Decimal
- ProposerIndex common.Decimal
-}
-
-// Hash calculates the block root of the header.
-//
-// TODO(zsfelfoldi): Remove this when an SSZ encoder lands.
-func (h *Header) Hash() common.Hash {
- var values [16]merkle.Value // values corresponding to indices 8 to 15 of the beacon header tree
- binary.LittleEndian.PutUint64(values[headerIndexSlot][:8], h.Slot)
- binary.LittleEndian.PutUint64(values[headerIndexProposerIndex][:8], h.ProposerIndex)
- values[headerIndexParentRoot] = merkle.Value(h.ParentRoot)
- values[headerIndexStateRoot] = merkle.Value(h.StateRoot)
- values[headerIndexBodyRoot] = merkle.Value(h.BodyRoot)
- hasher := sha256.New()
- for i := 7; i > 0; i-- {
- hasher.Reset()
- hasher.Write(values[i*2][:])
- hasher.Write(values[i*2+1][:])
- hasher.Sum(values[i][:0])
- }
- return common.Hash(values[1])
-}
-
-// Epoch returns the epoch the header belongs to.
-func (h *Header) Epoch() uint64 {
- return h.Slot / params.EpochLength
-}
-
-// SyncPeriod returns the sync period the header belongs to.
-func (h *Header) SyncPeriod() uint64 {
- return SyncPeriod(h.Slot)
-}
-
-// SyncPeriodStart returns the first slot of the given period.
-func SyncPeriodStart(period uint64) uint64 {
- return period * params.SyncPeriodLength
-}
-
-// SyncPeriod returns the sync period that the given slot belongs to.
-func SyncPeriod(slot uint64) uint64 {
- return slot / params.SyncPeriodLength
-}
-
-// SignedHeader represents a beacon header signed by a sync committee.
-//
-// This structure is created from either an optimistic update or an instant update:
-// - https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientoptimisticupdate
-// - https://github.com/zsfelfoldi/beacon-APIs/blob/instant_update/apis/beacon/light_client/instant_update.yaml
-type SignedHeader struct {
- // Beacon header being signed
- Header Header
-
- // Sync committee BLS signature aggregate
- Signature SyncAggregate
-
- // Slot in which the signature has been created (newer than Header.Slot,
- // determines the signing sync committee)
- SignatureSlot uint64
-}
diff --git a/beacon/types/light_sync.go b/beacon/types/light_sync.go
deleted file mode 100644
index 3284081e4d..0000000000
--- a/beacon/types/light_sync.go
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2022 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package types
-
-import (
- "errors"
- "fmt"
-
- "github.com/ethereum/go-ethereum/beacon/merkle"
- "github.com/ethereum/go-ethereum/beacon/params"
- "github.com/ethereum/go-ethereum/common"
-)
-
-// BootstrapData contains a sync committee where light sync can be started,
-// together with a proof through a beacon header and corresponding state.
-// Note: BootstrapData is fetched from a server based on a known checkpoint hash.
-type BootstrapData struct {
- Header Header
- CommitteeRoot common.Hash
- Committee *SerializedSyncCommittee `rlp:"-"`
- CommitteeBranch merkle.Values
-}
-
-// Validate verifies the proof included in BootstrapData.
-func (c *BootstrapData) Validate() error {
- if c.CommitteeRoot != c.Committee.Root() {
- return errors.New("wrong committee root")
- }
- return merkle.VerifyProof(c.Header.StateRoot, params.StateIndexSyncCommittee, c.CommitteeBranch, merkle.Value(c.CommitteeRoot))
-}
-
-// LightClientUpdate is a proof of the next sync committee root based on a header
-// signed by the sync committee of the given period. Optionally, the update can
-// prove quasi-finality by the signed header referring to a previous, finalized
-// header from the same period, and the finalized header referring to the next
-// sync committee root.
-//
-// See data structure definition here:
-// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientupdate
-type LightClientUpdate struct {
- AttestedHeader SignedHeader // Arbitrary header out of the period signed by the sync committee
- NextSyncCommitteeRoot common.Hash // Sync committee of the next period advertised in the current one
- NextSyncCommitteeBranch merkle.Values // Proof for the next period's sync committee
-
- FinalizedHeader *Header `rlp:"nil"` // Optional header to announce a point of finality
- FinalityBranch merkle.Values // Proof for the announced finality
-
- score *UpdateScore // Weight of the update to compare between competing ones
-}
-
-// Validate verifies the validity of the update.
-func (update *LightClientUpdate) Validate() error {
- period := update.AttestedHeader.Header.SyncPeriod()
- if SyncPeriod(update.AttestedHeader.SignatureSlot) != period {
- return errors.New("signature slot and signed header are from different periods")
- }
- if update.FinalizedHeader != nil {
- if update.FinalizedHeader.SyncPeriod() != period {
- return errors.New("finalized header is from different period")
- }
- if err := merkle.VerifyProof(update.AttestedHeader.Header.StateRoot, params.StateIndexFinalBlock, update.FinalityBranch, merkle.Value(update.FinalizedHeader.Hash())); err != nil {
- return fmt.Errorf("invalid finalized header proof: %w", err)
- }
- }
- if err := merkle.VerifyProof(update.AttestedHeader.Header.StateRoot, params.StateIndexNextSyncCommittee, update.NextSyncCommitteeBranch, merkle.Value(update.NextSyncCommitteeRoot)); err != nil {
- return fmt.Errorf("invalid next sync committee proof: %w", err)
- }
- return nil
-}
-
-// Score returns the UpdateScore describing the proof strength of the update
-// Note: thread safety can be ensured by always calling Score on a newly received
-// or decoded update before making it potentially available for other threads
-func (update *LightClientUpdate) Score() UpdateScore {
- if update.score == nil {
- update.score = &UpdateScore{
- SignerCount: uint32(update.AttestedHeader.Signature.SignerCount()),
- SubPeriodIndex: uint32(update.AttestedHeader.Header.Slot & 0x1fff),
- FinalizedHeader: update.FinalizedHeader != nil,
- }
- }
- return *update.score
-}
-
-// UpdateScore allows the comparison between updates at the same period in order
-// to find the best update chain that provides the strongest proof of being canonical.
-//
-// UpdateScores have a tightly packed binary encoding format for efficient p2p
-// protocol transmission. Each UpdateScore is encoded in 3 bytes.
-// When interpreted as a 24 bit little indian unsigned integer:
-// - the lowest 10 bits contain the number of signers in the header signature aggregate
-// - the next 13 bits contain the "sub-period index" which is he signed header's
-// slot modulo params.SyncPeriodLength (which is correlated with the risk of the chain being
-// re-orged before the previous period boundary in case of non-finalized updates)
-// - the highest bit is set when the update is finalized (meaning that the finality
-// header referenced by the signed header is in the same period as the signed
-// header, making reorgs before the period boundary impossible
-type UpdateScore struct {
- SignerCount uint32 // number of signers in the header signature aggregate
- SubPeriodIndex uint32 // signed header's slot modulo params.SyncPeriodLength
- FinalizedHeader bool // update is considered finalized if has finalized header from the same period and 2/3 signatures
-}
-
-// finalized returns true if the update has a header signed by at least 2/3 of
-// the committee, referring to a finalized header that refers to the next sync
-// committee. This condition is a close approximation of the actual finality
-// condition that can only be verified by full beacon nodes.
-func (u *UpdateScore) finalized() bool {
- return u.FinalizedHeader && u.SignerCount >= params.SyncCommitteeSupermajority
-}
-
-// BetterThan returns true if update u is considered better than w.
-func (u UpdateScore) BetterThan(w UpdateScore) bool {
- var (
- uFinalized = u.finalized()
- wFinalized = w.finalized()
- )
- if uFinalized != wFinalized {
- return uFinalized
- }
- return u.SignerCount > w.SignerCount
-}