diff --git a/beacon/merkle/merkle.go b/beacon/merkle/merkle.go deleted file mode 100644 index 30896f9b01..0000000000 --- a/beacon/merkle/merkle.go +++ /dev/null @@ -1,67 +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 merkle implements proof verifications in binary merkle trees. -package merkle - -import ( - "crypto/sha256" - "errors" - "reflect" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -// Value represents either a 32 byte leaf value or hash node in a binary merkle tree/partial proof. -type Value [32]byte - -// Values represent a series of merkle tree leaves/nodes. -type Values []Value - -var valueT = reflect.TypeOf(Value{}) - -// UnmarshalJSON parses a merkle value in hex syntax. -func (m *Value) UnmarshalJSON(input []byte) error { - return hexutil.UnmarshalFixedJSON(valueT, input, m[:]) -} - -// VerifyProof verifies a Merkle proof branch for a single value in a -// binary Merkle tree (index is a generalized tree index). -func VerifyProof(root common.Hash, index uint64, branch Values, value Value) error { - hasher := sha256.New() - for _, sibling := range branch { - hasher.Reset() - if index&1 == 0 { - hasher.Write(value[:]) - hasher.Write(sibling[:]) - } else { - hasher.Write(sibling[:]) - hasher.Write(value[:]) - } - hasher.Sum(value[:0]) - if index >>= 1; index == 0 { - return errors.New("branch has extra items") - } - } - if index != 1 { - return errors.New("branch is missing items") - } - if common.Hash(value) != root { - return errors.New("root mismatch") - } - return nil -} diff --git a/beacon/params/params.go b/beacon/params/params.go deleted file mode 100644 index ee9feb1acb..0000000000 --- a/beacon/params/params.go +++ /dev/null @@ -1,44 +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 params - -const ( - EpochLength = 32 - SyncPeriodLength = 8192 - - BLSSignatureSize = 96 - BLSPubkeySize = 48 - - SyncCommitteeSize = 512 - SyncCommitteeBitmaskSize = SyncCommitteeSize / 8 - SyncCommitteeSupermajority = (SyncCommitteeSize*2 + 2) / 3 -) - -const ( - StateIndexGenesisTime = 32 - StateIndexGenesisValidators = 33 - StateIndexForkVersion = 141 - StateIndexLatestHeader = 36 - StateIndexBlockRoots = 37 - StateIndexStateRoots = 38 - StateIndexHistoricRoots = 39 - StateIndexFinalBlock = 105 - StateIndexSyncCommittee = 54 - StateIndexNextSyncCommittee = 55 - StateIndexExecPayload = 56 - StateIndexExecHead = 908 -) diff --git a/beacon/types/committee.go b/beacon/types/committee.go deleted file mode 100644 index 9d3b9ff9e9..0000000000 --- a/beacon/types/committee.go +++ /dev/null @@ -1,214 +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) -} - -// 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 - Signature [params.BLSSignatureSize]byte -} - -type jsonSyncAggregate struct { - Signers hexutil.Bytes `json:"sync_committee_bits"` - Signature hexutil.Bytes `json:"sync_committee_signature"` -} - -// MarshalJSON implements json.Marshaler. -func (s *SyncAggregate) MarshalJSON() ([]byte, error) { - return json.Marshal(&jsonSyncAggregate{ - Signers: s.Signers[:], - Signature: s.Signature[:], - }) -} - -// UnmarshalJSON implements json.Marshaler. -func (s *SyncAggregate) UnmarshalJSON(input []byte) error { - var sc jsonSyncAggregate - if err := json.Unmarshal(input, &sc); err != nil { - return err - } - if len(sc.Signers) != params.SyncCommitteeBitmaskSize { - return fmt.Errorf("invalid signature bitmask size %d", len(sc.Signers)) - } - if len(sc.Signature) != params.BLSSignatureSize { - return fmt.Errorf("invalid signature size %d", len(sc.Signature)) - } - copy(s.Signers[:], sc.Signers) - copy(s.Signature[:], sc.Signature) - return nil -} - -// 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 3e5f7a6fba..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" - "github.com/go-yaml/yaml" -) - -// 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/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/update.go b/beacon/types/update.go deleted file mode 100644 index 06c1b61792..0000000000 --- a/beacon/types/update.go +++ /dev/null @@ -1,118 +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" -) - -// 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 -} diff --git a/common/types.go b/common/types.go index bdfd964237..3712df2fee 100644 --- a/common/types.go +++ b/common/types.go @@ -26,7 +26,6 @@ import ( "math/big" "math/rand" "reflect" - "strconv" "strings" "github.com/ethereum/go-ethereum/common/hexutil" @@ -443,22 +442,3 @@ func (addr AddressEIP55) String() string { func (addr AddressEIP55) MarshalJSON() ([]byte, error) { return json.Marshal(addr.String()) } - -type Decimal uint64 - -func isString(input []byte) bool { - return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' -} - -// UnmarshalJSON parses a hash in hex syntax. -func (d *Decimal) UnmarshalJSON(input []byte) error { - if !isString(input) { - return &json.UnmarshalTypeError{Value: "non-string", Type: reflect.TypeOf(uint64(0))} - } - if i, err := strconv.ParseInt(string(input[1:len(input)-1]), 10, 64); err == nil { - *d = Decimal(i) - return nil - } else { - return err - } -} diff --git a/go.mod b/go.mod index aec45bc1ef..a32d65a0ce 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,6 @@ require ( github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff github.com/gballet/go-verkle v0.0.0-20220902153445-097bd83b7732 github.com/go-stack/stack v1.8.1 - github.com/go-yaml/yaml v2.1.0+incompatible github.com/gofrs/flock v0.8.1 github.com/golang-jwt/jwt/v4 v4.3.0 github.com/golang/protobuf v1.5.2 @@ -52,7 +51,6 @@ require ( github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 - github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 github.com/rs/cors v1.7.0 github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/status-im/keycard-go v0.2.0 @@ -100,7 +98,6 @@ require ( github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect - github.com/kilic/bls12-381 v0.1.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect diff --git a/go.sum b/go.sum index 3c35d378bc..2d02b123f4 100644 --- a/go.sum +++ b/go.sum @@ -164,8 +164,6 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyL github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= -github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= @@ -272,8 +270,6 @@ github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYb github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= -github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= -github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= @@ -379,8 +375,6 @@ github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8u github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 h1:cZC+usqsYgHtlBaGulVnZ1hfKAi8iWtujBnRLQE698c= -github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= @@ -538,7 +532,6 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=