mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
beacon: fixed issues with electra light sync
This commit is contained in:
parent
4da69b3782
commit
f8b07baee2
7 changed files with 65 additions and 29 deletions
|
|
@ -140,7 +140,7 @@ func (ec *engineClient) callForkchoiceUpdated(fork string, event types.ChainHead
|
||||||
|
|
||||||
var method string
|
var method string
|
||||||
switch fork {
|
switch fork {
|
||||||
case "deneb":
|
case "deneb", "electra":
|
||||||
method = "engine_forkchoiceUpdatedV3"
|
method = "engine_forkchoiceUpdatedV3"
|
||||||
case "capella":
|
case "capella":
|
||||||
method = "engine_forkchoiceUpdatedV2"
|
method = "engine_forkchoiceUpdatedV2"
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type CommitteeUpdate struct {
|
type CommitteeUpdate struct {
|
||||||
Version string
|
|
||||||
Update types.LightClientUpdate
|
Update types.LightClientUpdate
|
||||||
NextSyncCommittee types.SerializedSyncCommittee
|
NextSyncCommittee types.SerializedSyncCommittee
|
||||||
}
|
}
|
||||||
|
|
@ -81,9 +80,9 @@ func (u *CommitteeUpdate) UnmarshalJSON(input []byte) error {
|
||||||
if err := json.Unmarshal(input, &dec); err != nil {
|
if err := json.Unmarshal(input, &dec); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
u.Version = dec.Version
|
|
||||||
u.NextSyncCommittee = dec.Data.NextSyncCommittee
|
u.NextSyncCommittee = dec.Data.NextSyncCommittee
|
||||||
u.Update = types.LightClientUpdate{
|
u.Update = types.LightClientUpdate{
|
||||||
|
Version: dec.Version,
|
||||||
AttestedHeader: types.SignedHeader{
|
AttestedHeader: types.SignedHeader{
|
||||||
Header: dec.Data.Header.Beacon,
|
Header: dec.Data.Header.Beacon,
|
||||||
Signature: dec.Data.SyncAggregate,
|
Signature: dec.Data.SyncAggregate,
|
||||||
|
|
@ -206,7 +205,7 @@ func (api *BeaconLightApi) GetOptimisticUpdate() (types.OptimisticUpdate, error)
|
||||||
|
|
||||||
func decodeOptimisticUpdate(enc []byte) (types.OptimisticUpdate, error) {
|
func decodeOptimisticUpdate(enc []byte) (types.OptimisticUpdate, error) {
|
||||||
var data struct {
|
var data struct {
|
||||||
Version string
|
Version string `json:"version"`
|
||||||
Data struct {
|
Data struct {
|
||||||
Attested jsonHeaderWithExecProof `json:"attested_header"`
|
Attested jsonHeaderWithExecProof `json:"attested_header"`
|
||||||
Aggregate types.SyncAggregate `json:"sync_aggregate"`
|
Aggregate types.SyncAggregate `json:"sync_aggregate"`
|
||||||
|
|
@ -259,7 +258,7 @@ func (api *BeaconLightApi) GetFinalityUpdate() (types.FinalityUpdate, error) {
|
||||||
|
|
||||||
func decodeFinalityUpdate(enc []byte) (types.FinalityUpdate, error) {
|
func decodeFinalityUpdate(enc []byte) (types.FinalityUpdate, error) {
|
||||||
var data struct {
|
var data struct {
|
||||||
Version string
|
Version string `json:"version"`
|
||||||
Data struct {
|
Data struct {
|
||||||
Attested jsonHeaderWithExecProof `json:"attested_header"`
|
Attested jsonHeaderWithExecProof `json:"attested_header"`
|
||||||
Finalized jsonHeaderWithExecProof `json:"finalized_header"`
|
Finalized jsonHeaderWithExecProof `json:"finalized_header"`
|
||||||
|
|
@ -289,6 +288,7 @@ func decodeFinalityUpdate(enc []byte) (types.FinalityUpdate, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.FinalityUpdate{
|
return types.FinalityUpdate{
|
||||||
|
Version: data.Version,
|
||||||
Attested: types.HeaderWithExecProof{
|
Attested: types.HeaderWithExecProof{
|
||||||
Header: data.Data.Attested.Beacon,
|
Header: data.Data.Attested.Beacon,
|
||||||
PayloadHeader: attestedExecHeader,
|
PayloadHeader: attestedExecHeader,
|
||||||
|
|
@ -355,6 +355,7 @@ func (api *BeaconLightApi) GetCheckpointData(checkpointHash common.Hash) (*types
|
||||||
// See data structure definition here:
|
// See data structure definition here:
|
||||||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientbootstrap
|
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientbootstrap
|
||||||
type bootstrapData struct {
|
type bootstrapData struct {
|
||||||
|
Version string `json:"version"`
|
||||||
Data struct {
|
Data struct {
|
||||||
Header jsonBeaconHeader `json:"header"`
|
Header jsonBeaconHeader `json:"header"`
|
||||||
Committee *types.SerializedSyncCommittee `json:"current_sync_committee"`
|
Committee *types.SerializedSyncCommittee `json:"current_sync_committee"`
|
||||||
|
|
@ -374,6 +375,7 @@ func (api *BeaconLightApi) GetCheckpointData(checkpointHash common.Hash) (*types
|
||||||
return nil, fmt.Errorf("invalid checkpoint block header, have %v want %v", header.Hash(), checkpointHash)
|
return nil, fmt.Errorf("invalid checkpoint block header, have %v want %v", header.Hash(), checkpointHash)
|
||||||
}
|
}
|
||||||
checkpoint := &types.BootstrapData{
|
checkpoint := &types.BootstrapData{
|
||||||
|
Version: data.Version,
|
||||||
Header: header,
|
Header: header,
|
||||||
CommitteeBranch: data.Data.CommitteeBranch,
|
CommitteeBranch: data.Data.CommitteeBranch,
|
||||||
CommitteeRoot: data.Data.Committee.Root(),
|
CommitteeRoot: data.Data.Committee.Root(),
|
||||||
|
|
@ -395,7 +397,7 @@ func (api *BeaconLightApi) GetBeaconBlock(blockRoot common.Hash) (*types.BeaconB
|
||||||
}
|
}
|
||||||
|
|
||||||
var beaconBlockMessage struct {
|
var beaconBlockMessage struct {
|
||||||
Version string
|
Version string `json:"version"`
|
||||||
Data struct {
|
Data struct {
|
||||||
Message json.RawMessage `json:"message"`
|
Message json.RawMessage `json:"message"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,10 @@ func GenerateTestUpdate(config *params.ChainConfig, period uint64, committee, ne
|
||||||
var attestedHeader types.Header
|
var attestedHeader types.Header
|
||||||
if finalizedHeader {
|
if finalizedHeader {
|
||||||
update.FinalizedHeader = new(types.Header)
|
update.FinalizedHeader = new(types.Header)
|
||||||
*update.FinalizedHeader, update.NextSyncCommitteeBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+100, params.StateIndexNextSyncCommittee, merkle.Value(update.NextSyncCommitteeRoot))
|
*update.FinalizedHeader, update.NextSyncCommitteeBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+100, params.StateIndexNextSyncCommittee(""), merkle.Value(update.NextSyncCommitteeRoot))
|
||||||
attestedHeader, update.FinalityBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+200, params.StateIndexFinalBlock, merkle.Value(update.FinalizedHeader.Hash()))
|
attestedHeader, update.FinalityBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+200, params.StateIndexFinalBlock(""), merkle.Value(update.FinalizedHeader.Hash()))
|
||||||
} else {
|
} else {
|
||||||
attestedHeader, update.NextSyncCommitteeBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+2000, params.StateIndexNextSyncCommittee, merkle.Value(update.NextSyncCommitteeRoot))
|
attestedHeader, update.NextSyncCommitteeBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+2000, params.StateIndexNextSyncCommittee(""), merkle.Value(update.NextSyncCommitteeRoot))
|
||||||
}
|
}
|
||||||
update.AttestedHeader = GenerateTestSignedHeader(attestedHeader, config, committee, attestedHeader.Slot+1, signerCount)
|
update.AttestedHeader = GenerateTestSignedHeader(attestedHeader, config, committee, attestedHeader.Slot+1, signerCount)
|
||||||
return update
|
return update
|
||||||
|
|
@ -63,7 +63,7 @@ func GenerateTestSignedHeader(header types.Header, config *params.ChainConfig, c
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateTestCheckpoint(period uint64, committee *types.SerializedSyncCommittee) *types.BootstrapData {
|
func GenerateTestCheckpoint(period uint64, committee *types.SerializedSyncCommittee) *types.BootstrapData {
|
||||||
header, branch := makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+200, params.StateIndexSyncCommittee, merkle.Value(committee.Root()))
|
header, branch := makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+200, params.StateIndexSyncCommittee(""), merkle.Value(committee.Root()))
|
||||||
return &types.BootstrapData{
|
return &types.BootstrapData{
|
||||||
Header: header,
|
Header: header,
|
||||||
Committee: committee,
|
Committee: committee,
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@ var (
|
||||||
AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}).
|
AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}).
|
||||||
AddFork("BELLATRIX", 100, []byte{144, 0, 0, 113}).
|
AddFork("BELLATRIX", 100, []byte{144, 0, 0, 113}).
|
||||||
AddFork("CAPELLA", 56832, []byte{144, 0, 0, 114}).
|
AddFork("CAPELLA", 56832, []byte{144, 0, 0, 114}).
|
||||||
AddFork("DENEB", 132608, []byte{144, 0, 0, 115})
|
AddFork("DENEB", 132608, []byte{144, 0, 0, 115}).
|
||||||
|
AddFork("ELECTRA", 222464, []byte{144, 0, 0, 116})
|
||||||
|
|
||||||
HoleskyLightConfig = (&ChainConfig{
|
HoleskyLightConfig = (&ChainConfig{
|
||||||
GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"),
|
GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"),
|
||||||
|
|
@ -52,5 +53,6 @@ var (
|
||||||
AddFork("ALTAIR", 0, []byte{2, 1, 112, 0}).
|
AddFork("ALTAIR", 0, []byte{2, 1, 112, 0}).
|
||||||
AddFork("BELLATRIX", 0, []byte{3, 1, 112, 0}).
|
AddFork("BELLATRIX", 0, []byte{3, 1, 112, 0}).
|
||||||
AddFork("CAPELLA", 256, []byte{4, 1, 112, 0}).
|
AddFork("CAPELLA", 256, []byte{4, 1, 112, 0}).
|
||||||
AddFork("DENEB", 29696, []byte{5, 1, 112, 0})
|
AddFork("DENEB", 29696, []byte{5, 1, 112, 0}).
|
||||||
|
AddFork("ELECTRA", 115968, []byte{6, 1, 112, 0})
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,39 @@ const (
|
||||||
StateIndexBlockRoots = 37
|
StateIndexBlockRoots = 37
|
||||||
StateIndexStateRoots = 38
|
StateIndexStateRoots = 38
|
||||||
StateIndexHistoricRoots = 39
|
StateIndexHistoricRoots = 39
|
||||||
StateIndexFinalBlock = 105
|
StateIndexFinalBlockOld = 105
|
||||||
StateIndexSyncCommittee = 54
|
StateIndexFinalBlockElectra = 169
|
||||||
StateIndexNextSyncCommittee = 55
|
StateIndexSyncCommitteeOld = 54
|
||||||
|
StateIndexSyncCommitteeElectra = 86
|
||||||
|
StateIndexNextSyncCommitteeOld = 55
|
||||||
|
StateIndexNextSyncCommitteeElectra = 87
|
||||||
StateIndexExecPayload = 56
|
StateIndexExecPayload = 56
|
||||||
StateIndexExecHead = 908
|
StateIndexExecHead = 908
|
||||||
|
|
||||||
BodyIndexExecPayload = 25
|
BodyIndexExecPayload = 25
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func StateIndexFinalBlock(forkName string) uint64 {
|
||||||
|
switch forkName {
|
||||||
|
case "bellatrix", "capella", "deneb":
|
||||||
|
return StateIndexFinalBlockOld
|
||||||
|
default:
|
||||||
|
return StateIndexFinalBlockElectra
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func StateIndexSyncCommittee(forkName string) uint64 {
|
||||||
|
switch forkName {
|
||||||
|
case "bellatrix", "capella", "deneb":
|
||||||
|
return StateIndexSyncCommitteeOld
|
||||||
|
default:
|
||||||
|
return StateIndexSyncCommitteeElectra
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func StateIndexNextSyncCommittee(forkName string) uint64 {
|
||||||
|
switch forkName {
|
||||||
|
case "bellatrix", "capella", "deneb":
|
||||||
|
return StateIndexNextSyncCommitteeOld
|
||||||
|
default:
|
||||||
|
return StateIndexNextSyncCommitteeElectra
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,7 @@ func (b *BeaconBlock) ExecutionRequestsList() [][]byte {
|
||||||
|
|
||||||
func marshalRequests(spec *zrntcommon.Spec, items ...zrntcommon.SpecObj) (list [][]byte) {
|
func marshalRequests(spec *zrntcommon.Spec, items ...zrntcommon.SpecObj) (list [][]byte) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
list = [][]byte{}
|
||||||
for typ, data := range items {
|
for typ, data := range items {
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
buf.WriteByte(byte(typ))
|
buf.WriteByte(byte(typ))
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ type HeadInfo struct {
|
||||||
// together with a proof through a beacon header and corresponding state.
|
// together with a proof through a beacon header and corresponding state.
|
||||||
// Note: BootstrapData is fetched from a server based on a known checkpoint hash.
|
// Note: BootstrapData is fetched from a server based on a known checkpoint hash.
|
||||||
type BootstrapData struct {
|
type BootstrapData struct {
|
||||||
|
Version string
|
||||||
Header Header
|
Header Header
|
||||||
CommitteeRoot common.Hash
|
CommitteeRoot common.Hash
|
||||||
Committee *SerializedSyncCommittee `rlp:"-"`
|
Committee *SerializedSyncCommittee `rlp:"-"`
|
||||||
|
|
@ -47,7 +48,7 @@ func (c *BootstrapData) Validate() error {
|
||||||
if c.CommitteeRoot != c.Committee.Root() {
|
if c.CommitteeRoot != c.Committee.Root() {
|
||||||
return errors.New("wrong committee root")
|
return errors.New("wrong committee root")
|
||||||
}
|
}
|
||||||
return merkle.VerifyProof(c.Header.StateRoot, params.StateIndexSyncCommittee, c.CommitteeBranch, merkle.Value(c.CommitteeRoot))
|
return merkle.VerifyProof(c.Header.StateRoot, params.StateIndexSyncCommittee(c.Version), c.CommitteeBranch, merkle.Value(c.CommitteeRoot))
|
||||||
}
|
}
|
||||||
|
|
||||||
// LightClientUpdate is a proof of the next sync committee root based on a header
|
// LightClientUpdate is a proof of the next sync committee root based on a header
|
||||||
|
|
@ -59,6 +60,7 @@ func (c *BootstrapData) Validate() error {
|
||||||
// See data structure definition here:
|
// See data structure definition here:
|
||||||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientupdate
|
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientupdate
|
||||||
type LightClientUpdate struct {
|
type LightClientUpdate struct {
|
||||||
|
Version string
|
||||||
AttestedHeader SignedHeader // Arbitrary header out of the period signed by the sync committee
|
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
|
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
|
NextSyncCommitteeBranch merkle.Values // Proof for the next period's sync committee
|
||||||
|
|
@ -79,11 +81,11 @@ func (update *LightClientUpdate) Validate() error {
|
||||||
if update.FinalizedHeader.SyncPeriod() != period {
|
if update.FinalizedHeader.SyncPeriod() != period {
|
||||||
return errors.New("finalized header is from different 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 {
|
if err := merkle.VerifyProof(update.AttestedHeader.Header.StateRoot, params.StateIndexFinalBlock(update.Version), update.FinalityBranch, merkle.Value(update.FinalizedHeader.Hash())); err != nil {
|
||||||
return fmt.Errorf("invalid finalized header proof: %w", err)
|
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 {
|
if err := merkle.VerifyProof(update.AttestedHeader.Header.StateRoot, params.StateIndexNextSyncCommittee(update.Version), update.NextSyncCommitteeBranch, merkle.Value(update.NextSyncCommitteeRoot)); err != nil {
|
||||||
return fmt.Errorf("invalid next sync committee proof: %w", err)
|
return fmt.Errorf("invalid next sync committee proof: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -194,6 +196,7 @@ func (u *OptimisticUpdate) Validate() error {
|
||||||
// See data structure definition here:
|
// See data structure definition here:
|
||||||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientfinalityupdate
|
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientfinalityupdate
|
||||||
type FinalityUpdate struct {
|
type FinalityUpdate struct {
|
||||||
|
Version string
|
||||||
Attested, Finalized HeaderWithExecProof
|
Attested, Finalized HeaderWithExecProof
|
||||||
FinalityBranch merkle.Values
|
FinalityBranch merkle.Values
|
||||||
// Sync committee BLS signature aggregate
|
// Sync committee BLS signature aggregate
|
||||||
|
|
@ -223,7 +226,7 @@ func (u *FinalityUpdate) Validate() error {
|
||||||
if err := u.Finalized.Validate(); err != nil {
|
if err := u.Finalized.Validate(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return merkle.VerifyProof(u.Attested.StateRoot, params.StateIndexFinalBlock, u.FinalityBranch, merkle.Value(u.Finalized.Hash()))
|
return merkle.VerifyProof(u.Attested.StateRoot, params.StateIndexFinalBlock(u.Version), u.FinalityBranch, merkle.Value(u.Finalized.Hash()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChainHeadEvent returns an authenticated execution payload associated with the
|
// ChainHeadEvent returns an authenticated execution payload associated with the
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue