feat: change portal api

This commit is contained in:
fearlessfe 2024-04-20 21:03:23 +08:00
parent c6b57fdff7
commit 73612bf661
7 changed files with 240 additions and 115 deletions

View file

@ -140,7 +140,7 @@ func initDiscV5(config Config, conn discover.UDPConn) (*discover.UDPv5, *enode.L
PrivateKey: config.PrivateKey,
NetRestrict: config.Protocol.NetRestrict,
Bootnodes: config.Protocol.BootstrapNodes,
Log: log.New("discV5"),
Log: log.New("protocol", "discV5"),
}
nodeDB, err := enode.OpenDB(config.Protocol.NodeDBPath)

2
go.mod
View file

@ -153,4 +153,6 @@ require (
rsc.io/tmplfunc v0.0.3 // indirect
)
// replace github.com/protolambda/zrnt v0.32.2 => ../zrnt-fork
replace github.com/protolambda/zrnt v0.32.2 => github.com/optimism-java/zrnt v0.32.4-0.20240415084906-d9dbf06b32f7

View file

@ -11,7 +11,6 @@ import (
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/portalnetwork/storage"
ssz "github.com/ferranbt/fastssz"
"github.com/protolambda/zrnt/eth2/beacon/capella"
"github.com/protolambda/zrnt/eth2/beacon/common"
"github.com/protolambda/zrnt/eth2/configs"
"github.com/protolambda/ztyp/codec"
@ -62,100 +61,82 @@ func (bn *BeaconNetwork) Stop() {
bn.portalProtocol.Stop()
}
func (bn *BeaconNetwork) GetUpdates(firstPeriod, count uint64) ([]*capella.LightClientUpdate, error) {
func (bn *BeaconNetwork) GetUpdates(firstPeriod, count uint64) ([]common.SpecObj, error) {
lightClientUpdateKey := &LightClientUpdateKey{
StartPeriod: firstPeriod,
Count: count,
}
lightClientUpdateRangeContent, err := bn.getContent(LightClientUpdate, lightClientUpdateKey)
data, err := bn.getContent(LightClientUpdate, lightClientUpdateKey)
if err != nil {
return nil, err
}
var lightClientUpdateRange LightClientUpdateRange = make([]ForkedLightClientUpdate, 0)
err = lightClientUpdateRange.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(lightClientUpdateRangeContent), uint64(len(lightClientUpdateRangeContent))))
err = lightClientUpdateRange.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data))))
if err != nil {
return nil, err
}
res := make([]common.SpecObj, len(lightClientUpdateRange))
updates := make([]*capella.LightClientUpdate, len(lightClientUpdateRange))
for i, update := range lightClientUpdateRange {
if update.ForkDigest != Capella {
return nil, errors.New("unknown fork digest")
}
updates[i] = update.LightClientUpdate.(*capella.LightClientUpdate)
for i, item := range lightClientUpdateRange {
res[i] = item.LightClientUpdate
}
return updates, nil
return res, nil
}
func (bn *BeaconNetwork) GetCheckpointData(checkpointHash tree.Root) (*capella.LightClientBootstrap, error) {
func (bn *BeaconNetwork) GetCheckpointData(checkpointHash tree.Root) (common.SpecObj, error) {
bootstrapKey := &LightClientBootstrapKey{
BlockHash: checkpointHash[:],
}
bootstrapValue, err := bn.getContent(LightClientBootstrap, bootstrapKey)
data, err := bn.getContent(LightClientBootstrap, bootstrapKey)
if err != nil {
return nil, err
}
var forkedLightClientBootstrap ForkedLightClientBootstrap
err = forkedLightClientBootstrap.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(bootstrapValue), uint64(len(bootstrapValue))))
var forkedLightClientBootstrap *ForkedLightClientBootstrap
err = forkedLightClientBootstrap.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data))))
if err != nil {
return nil, err
}
if forkedLightClientBootstrap.ForkDigest != Capella {
return nil, errors.New("unknown fork digest")
}
return forkedLightClientBootstrap.Bootstrap.(*capella.LightClientBootstrap), nil
return forkedLightClientBootstrap.Bootstrap, nil
}
func (bn *BeaconNetwork) GetFinalityUpdate(finalizedSlot uint64) (*capella.LightClientFinalityUpdate, error) {
func (bn *BeaconNetwork) GetFinalityUpdate(finalizedSlot uint64) (common.SpecObj, error) {
finalityUpdateKey := &LightClientFinalityUpdateKey{
FinalizedSlot: finalizedSlot,
}
finalityUpdateValue, err := bn.getContent(LightClientFinalityUpdate, finalityUpdateKey)
data, err := bn.getContent(LightClientFinalityUpdate, finalityUpdateKey)
if err != nil {
return nil, err
}
var forkedLightClientFinalityUpdate ForkedLightClientFinalityUpdate
err = forkedLightClientFinalityUpdate.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(finalityUpdateValue), uint64(len(finalityUpdateValue))))
var forkedLightClientFinalityUpdate *ForkedLightClientFinalityUpdate
err = forkedLightClientFinalityUpdate.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data))))
if err != nil {
return nil, err
}
if forkedLightClientFinalityUpdate.ForkDigest != Capella {
return nil, errors.New("unknown fork digest")
}
return forkedLightClientFinalityUpdate.LightClientFinalityUpdate.(*capella.LightClientFinalityUpdate), nil
return forkedLightClientFinalityUpdate.LightClientFinalityUpdate, nil
}
func (bn *BeaconNetwork) GetOptimisticUpdate(optimisticSlot uint64) (*capella.LightClientOptimisticUpdate, error) {
func (bn *BeaconNetwork) GetOptimisticUpdate(optimisticSlot uint64) (common.SpecObj, error) {
optimisticUpdateKey := &LightClientOptimisticUpdateKey{
OptimisticSlot: optimisticSlot,
}
optimisticUpdateValue, err := bn.getContent(LightClientOptimisticUpdate, optimisticUpdateKey)
data, err := bn.getContent(LightClientOptimisticUpdate, optimisticUpdateKey)
if err != nil {
return nil, err
}
var forkedLightClientOptimisticUpdate ForkedLightClientOptimisticUpdate
err = forkedLightClientOptimisticUpdate.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(optimisticUpdateValue), uint64(len(optimisticUpdateValue))))
var forkedLightClientOptimisticUpdate *ForkedLightClientOptimisticUpdate
err = forkedLightClientOptimisticUpdate.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data))))
if err != nil {
return nil, err
}
if forkedLightClientOptimisticUpdate.ForkDigest != Capella {
return nil, errors.New("unknown fork digest")
}
return forkedLightClientOptimisticUpdate.LightClientOptimisticUpdate.(*capella.LightClientOptimisticUpdate), nil
return forkedLightClientOptimisticUpdate.LightClientOptimisticUpdate, nil
}
func (bn *BeaconNetwork) getContent(contentType storage.ContentType, beaconContentKey ssz.Marshaler) ([]byte, error) {

View file

@ -9,6 +9,7 @@ import (
"github.com/protolambda/zrnt/eth2/beacon/altair"
"github.com/protolambda/zrnt/eth2/beacon/capella"
"github.com/protolambda/zrnt/eth2/beacon/common"
"github.com/protolambda/zrnt/eth2/beacon/deneb"
"github.com/protolambda/zrnt/eth2/configs"
"github.com/protolambda/zrnt/eth2/util/merkle"
@ -29,10 +30,10 @@ var (
)
type ConsensusAPI interface {
GetUpdates(firstPeriod, count uint64) ([]*capella.LightClientUpdate, error)
GetCheckpointData(checkpointHash common.Root) (*capella.LightClientBootstrap, error)
GetFinalityData() (*capella.LightClientFinalityUpdate, error)
GetOptimisticData() (*capella.LightClientOptimisticUpdate, error)
GetUpdates(firstPeriod, count uint64) ([]common.SpecObj, error)
GetCheckpointData(checkpointHash common.Root) (common.SpecObj, error)
GetFinalityData() (common.SpecObj, error)
GetOptimisticData() (common.SpecObj, error)
ChainID() uint64
Name() string
}
@ -85,6 +86,36 @@ type GenericUpdate struct {
FinalityBranch *altair.FinalizedRootProofBranch
}
type GenericBootstrap struct {
Header *common.BeaconBlockHeader
CurrentSyncCommittee common.SyncCommittee
CurrentSyncCommitteeBranch altair.SyncCommitteeProofBranch
}
func FromBootstrap(commonBootstrap common.SpecObj) (*GenericBootstrap, error) {
switch bootstrap := commonBootstrap.(type) {
case *deneb.LightClientBootstrap:
return &GenericBootstrap{
Header: &bootstrap.Header.Beacon,
CurrentSyncCommittee: bootstrap.CurrentSyncCommittee,
CurrentSyncCommitteeBranch: bootstrap.CurrentSyncCommitteeBranch,
}, nil
case *capella.LightClientBootstrap:
return &GenericBootstrap{
Header: &bootstrap.Header.Beacon,
CurrentSyncCommittee: bootstrap.CurrentSyncCommittee,
CurrentSyncCommitteeBranch: bootstrap.CurrentSyncCommitteeBranch,
}, nil
case *altair.LightClientBootstrap:
return &GenericBootstrap{
Header: &bootstrap.Header.Beacon,
CurrentSyncCommittee: bootstrap.CurrentSyncCommittee,
CurrentSyncCommitteeBranch: bootstrap.CurrentSyncCommitteeBranch,
}, nil
}
return nil, errors.New("unknown bootstrap type")
}
func NewConsensusLightClient(api ConsensusAPI, config *Config, checkpointBlockRoot common.Root, logger log.Logger) (*ConsensusLightClient, error) {
client := &ConsensusLightClient{
API: api,
@ -117,7 +148,7 @@ func (c *ConsensusLightClient) Sync() error {
bootstrapPeriod := CalcSyncPeriod(uint64(c.Store.FinalizedHeader.Slot))
updates := make([]*capella.LightClientUpdate, 0)
updates := make([]common.SpecObj, 0)
if c.API.Name() == "portal" {
currentPeriod := CalcSyncPeriod(uint64(c.expectedCurrentSlot()))
@ -209,12 +240,15 @@ func (c *ConsensusLightClient) Advance() error {
}
func (c *ConsensusLightClient) bootstrap() error {
bootstrap, err := c.API.GetCheckpointData(c.InitialCheckpoint)
forkedBootstrap, err := c.API.GetCheckpointData(c.InitialCheckpoint)
if err != nil {
return err
}
isValid := c.isValidCheckpoint(bootstrap.Header.Beacon.Slot)
bootstrap, err := FromBootstrap(forkedBootstrap)
if err != nil {
return err
}
isValid := c.isValidCheckpoint(bootstrap.Header.Slot)
if !isValid {
if c.Config.StrictCheckpointAge {
return errors.New("checkpoint is too old")
@ -223,9 +257,9 @@ func (c *ConsensusLightClient) bootstrap() error {
}
}
committeeValid := c.isCurrentCommitteeProofValid(bootstrap.Header.Beacon, bootstrap.CurrentSyncCommittee, bootstrap.CurrentSyncCommitteeBranch)
committeeValid := c.isCurrentCommitteeProofValid(*bootstrap.Header, bootstrap.CurrentSyncCommittee, bootstrap.CurrentSyncCommitteeBranch)
headerHash := bootstrap.Header.Beacon.HashTreeRoot(tree.GetHashFn()).String()
headerHash := bootstrap.Header.HashTreeRoot(tree.GetHashFn()).String()
expectedHash := c.InitialCheckpoint.String()
headerValid := headerHash == expectedHash
@ -239,9 +273,9 @@ func (c *ConsensusLightClient) bootstrap() error {
}
c.Store = LightClientStore{
FinalizedHeader: &bootstrap.Header.Beacon,
FinalizedHeader: bootstrap.Header,
CurrentSyncCommittee: &bootstrap.CurrentSyncCommittee,
OptimisticHeader: &bootstrap.Header.Beacon,
OptimisticHeader: bootstrap.Header,
PreviousMaxActiveParticipants: view.Uint64View(0),
CurrentMaxActiveParticipants: view.Uint64View(0),
}
@ -329,18 +363,27 @@ func (c *ConsensusLightClient) VerifyGenericUpdate(update *GenericUpdate) error
return nil
}
func (c *ConsensusLightClient) VerifyUpdate(update *capella.LightClientUpdate) error {
genericUpdate := FromLightClientUpdate(update)
func (c *ConsensusLightClient) VerifyUpdate(update common.SpecObj) error {
genericUpdate, err := FromLightClientUpdate(update)
if err != nil {
return err
}
return c.VerifyGenericUpdate(genericUpdate)
}
func (c *ConsensusLightClient) VerifyFinalityUpdate(update *capella.LightClientFinalityUpdate) error {
genericUpdate := FromLightClientFinalityUpdate(update)
func (c *ConsensusLightClient) VerifyFinalityUpdate(update common.SpecObj) error {
genericUpdate, err := FromLightClientFinalityUpdate(update)
if err != nil {
return err
}
return c.VerifyGenericUpdate(genericUpdate)
}
func (c *ConsensusLightClient) VerifyOptimisticUpdate(update *capella.LightClientOptimisticUpdate) error {
genericUpdate := FromLightClientOptimisticUpdate(update)
func (c *ConsensusLightClient) VerifyOptimisticUpdate(update common.SpecObj) error {
genericUpdate, err := FromLightClientOptimisticUpdate(update)
if err != nil {
return err
}
return c.VerifyGenericUpdate(genericUpdate)
}
@ -407,19 +450,31 @@ func (c *ConsensusLightClient) ApplyGenericUpdate(update *GenericUpdate) {
}
}
func (c *ConsensusLightClient) ApplyUpdate(update *capella.LightClientUpdate) {
genericUpdate := FromLightClientUpdate(update)
func (c *ConsensusLightClient) ApplyUpdate(update common.SpecObj) error {
genericUpdate, err := FromLightClientUpdate(update)
if err != nil {
return err
}
c.ApplyGenericUpdate(genericUpdate)
return nil
}
func (c *ConsensusLightClient) ApplyFinalityUpdate(update *capella.LightClientFinalityUpdate) {
genericUpdate := FromLightClientFinalityUpdate(update)
func (c *ConsensusLightClient) ApplyFinalityUpdate(update common.SpecObj) error {
genericUpdate, err := FromLightClientFinalityUpdate(update)
if err != nil {
return err
}
c.ApplyGenericUpdate(genericUpdate)
return nil
}
func (c *ConsensusLightClient) ApplyOptimisticUpdate(update *capella.LightClientOptimisticUpdate) {
genericUpdate := FromLightClientOptimisticUpdate(update)
func (c *ConsensusLightClient) ApplyOptimisticUpdate(update common.SpecObj) error {
genericUpdate, err := FromLightClientOptimisticUpdate(update)
if err != nil {
return err
}
c.ApplyGenericUpdate(genericUpdate)
return nil
}
func (c *ConsensusLightClient) VerifySyncCommitteeSignature(pks []common.BLSPubkey, attestedHeader common.BeaconBlockHeader, signature common.BLSSignature, signatureSlot common.Slot) (bool, error) {
@ -532,34 +587,94 @@ func (c *ConsensusLightClient) getParticipatingKeys(committee common.SyncCommitt
return res
}
func FromLightClientUpdate(update *capella.LightClientUpdate) *GenericUpdate {
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
NextSyncCommittee: &update.NextSyncCommittee,
NextSyncCommitteeBranch: &update.NextSyncCommitteeBranch,
FinalizedHeader: &update.FinalizedHeader.Beacon,
FinalityBranch: &update.FinalityBranch,
func FromLightClientUpdate(commonUpdate common.SpecObj) (*GenericUpdate, error) {
switch update := commonUpdate.(type) {
case *deneb.LightClientUpdate:
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
NextSyncCommittee: &update.NextSyncCommittee,
NextSyncCommitteeBranch: &update.NextSyncCommitteeBranch,
FinalizedHeader: &update.FinalizedHeader.Beacon,
FinalityBranch: &update.FinalityBranch,
}, nil
case *capella.LightClientUpdate:
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
NextSyncCommittee: &update.NextSyncCommittee,
NextSyncCommitteeBranch: &update.NextSyncCommitteeBranch,
FinalizedHeader: &update.FinalizedHeader.Beacon,
FinalityBranch: &update.FinalityBranch,
}, nil
case *altair.LightClientUpdate:
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
NextSyncCommittee: &update.NextSyncCommittee,
NextSyncCommitteeBranch: &update.NextSyncCommitteeBranch,
FinalizedHeader: &update.FinalizedHeader.Beacon,
FinalityBranch: &update.FinalityBranch,
}, nil
}
return nil, errors.New("unknown update type")
}
func FromLightClientFinalityUpdate(update *capella.LightClientFinalityUpdate) *GenericUpdate {
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
FinalizedHeader: &update.FinalizedHeader.Beacon,
FinalityBranch: &update.FinalityBranch,
func FromLightClientFinalityUpdate(commonFinalityUpdate common.SpecObj) (*GenericUpdate, error) {
switch update := commonFinalityUpdate.(type) {
case *deneb.LightClientFinalityUpdate:
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
FinalizedHeader: &update.FinalizedHeader.Beacon,
FinalityBranch: &update.FinalityBranch,
}, nil
case *capella.LightClientFinalityUpdate:
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
FinalizedHeader: &update.FinalizedHeader.Beacon,
FinalityBranch: &update.FinalityBranch,
}, nil
case *altair.LightClientFinalityUpdate:
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
FinalizedHeader: &update.FinalizedHeader,
FinalityBranch: &update.FinalityBranch,
}, nil
}
return nil, errors.New("unknown finality update type")
}
func FromLightClientOptimisticUpdate(update *capella.LightClientOptimisticUpdate) *GenericUpdate {
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
func FromLightClientOptimisticUpdate(commonOptimisticUpdate common.SpecObj) (*GenericUpdate, error) {
switch update := commonOptimisticUpdate.(type) {
case *deneb.LightClientOptimisticUpdate:
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
}, nil
case *capella.LightClientOptimisticUpdate:
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
}, nil
case *altair.LightClientOptimisticUpdate:
return &GenericUpdate{
AttestedHeader: &update.AttestedHeader.Beacon,
SyncAggregate: &update.SyncAggregate,
SignatureSlot: update.SignatureSlot,
}, nil
}
return nil, errors.New("unknown optimistic update type")
}
func ComputeSigningRoot(root common.Root, domain common.BLSDomain) common.Root {

View file

@ -24,16 +24,21 @@ func NewMockConsensusAPI(path string) (ConsensusAPI, error) {
return &MockConsensusAPI{testdataDir: path}, nil
}
func (m MockConsensusAPI) GetUpdates(_, _ uint64) ([]*capella.LightClientUpdate, error) {
func (m MockConsensusAPI) GetUpdates(_, _ uint64) ([]common.SpecObj, error) {
jsonStr, _ := os.ReadFile(m.testdataDir + "/updates.json")
updates := make([]*capella.LightClientUpdate, 0)
_ = json.Unmarshal(jsonStr, &updates)
return updates, nil
res := make([]common.SpecObj, 0)
for _, item := range updates {
res = append(res, item)
}
return res, nil
}
func (m MockConsensusAPI) GetCheckpointData(_ common.Root) (*capella.LightClientBootstrap, error) {
func (m MockConsensusAPI) GetCheckpointData(_ common.Root) (common.SpecObj, error) {
jsonStr, _ := os.ReadFile(m.testdataDir + "/bootstrap.json")
bootstrap := &capella.LightClientBootstrap{}
@ -42,7 +47,7 @@ func (m MockConsensusAPI) GetCheckpointData(_ common.Root) (*capella.LightClient
return bootstrap, nil
}
func (m MockConsensusAPI) GetFinalityData() (*capella.LightClientFinalityUpdate, error) {
func (m MockConsensusAPI) GetFinalityData() (common.SpecObj, error) {
jsonStr, _ := os.ReadFile(m.testdataDir + "/finality.json")
finality := &capella.LightClientFinalityUpdate{}
@ -51,7 +56,7 @@ func (m MockConsensusAPI) GetFinalityData() (*capella.LightClientFinalityUpdate,
return finality, nil
}
func (m MockConsensusAPI) GetOptimisticData() (*capella.LightClientOptimisticUpdate, error) {
func (m MockConsensusAPI) GetOptimisticData() (common.SpecObj, error) {
jsonStr, _ := os.ReadFile(m.testdataDir + "/optimistic.json")
optimistic := &capella.LightClientOptimisticUpdate{}
@ -107,21 +112,27 @@ func TestVerifyUpdate(t *testing.T) {
err = client.VerifyUpdate(updates[0])
require.NoError(t, err)
// ErrInvalidNextSyncCommitteeProof
updates[0].NextSyncCommittee.Pubkeys[0] = common.BLSPubkey{}
err = client.VerifyUpdate(updates[0])
genericUpdate, err := FromLightClientUpdate(updates[0])
require.NoError(t, err)
genericUpdate.NextSyncCommittee.Pubkeys[0] = common.BLSPubkey{}
err = client.VerifyGenericUpdate(genericUpdate)
require.Equal(t, ErrInvalidNextSyncCommitteeProof, err)
// ErrInvalidFinalityProof
updates, err = client.API.GetUpdates(period, MaxRequestLightClientUpdates)
require.NoError(t, err)
updates[0].FinalizedHeader.Beacon = common.BeaconBlockHeader{}
err = client.VerifyUpdate(updates[0])
genericUpdate, err = FromLightClientUpdate(updates[0])
require.NoError(t, err)
genericUpdate.FinalizedHeader = &common.BeaconBlockHeader{}
err = client.VerifyGenericUpdate(genericUpdate)
require.Equal(t, ErrInvalidFinalityProof, err)
// ErrInvalidSignature
updates, err = client.API.GetUpdates(period, MaxRequestLightClientUpdates)
require.NoError(t, err)
updates[0].SyncAggregate.SyncCommitteeSignature[1] = 0xFE
err = client.VerifyUpdate(updates[0])
genericUpdate, err = FromLightClientUpdate(updates[0])
require.NoError(t, err)
genericUpdate.SyncAggregate.SyncCommitteeSignature[1] = 0xFE
err = client.VerifyGenericUpdate(genericUpdate)
require.Error(t, err)
}
@ -136,14 +147,20 @@ func TestVerifyFinalityUpdate(t *testing.T) {
err = client.VerifyFinalityUpdate(update)
require.NoError(t, err)
update.FinalizedHeader.Beacon = common.BeaconBlockHeader{}
err = client.VerifyFinalityUpdate(update)
genericUpdate, err := FromLightClientFinalityUpdate(update)
require.NoError(t, err)
genericUpdate.FinalizedHeader = &common.BeaconBlockHeader{}
err = client.VerifyGenericUpdate(genericUpdate)
require.Equal(t, ErrInvalidFinalityProof, err)
// ErrInvalidSignature
update, err = client.API.GetFinalityData()
require.NoError(t, err)
update.SyncAggregate.SyncCommitteeSignature[1] = 0xFE
err = client.VerifyFinalityUpdate(update)
genericUpdate, err = FromLightClientFinalityUpdate(update)
require.NoError(t, err)
genericUpdate.SyncAggregate.SyncCommitteeSignature[1] = 0xFE
err = client.VerifyGenericUpdate(genericUpdate)
require.Error(t, err)
}
@ -158,8 +175,11 @@ func TestVerifyOptimisticUpdate(t *testing.T) {
err = client.VerifyOptimisticUpdate(update)
require.NoError(t, err)
update.SyncAggregate.SyncCommitteeSignature = common.BLSSignature{}
err = client.VerifyOptimisticUpdate(update)
genericUpdate, err := FromLightClientOptimisticUpdate(update)
require.NoError(t, err)
genericUpdate.SyncAggregate.SyncCommitteeSignature = common.BLSSignature{}
err = client.VerifyGenericUpdate(genericUpdate)
require.Error(t, err)
}

View file

@ -3,7 +3,6 @@ package beacon
import (
"time"
"github.com/protolambda/zrnt/eth2/beacon/capella"
zrntcommon "github.com/protolambda/zrnt/eth2/beacon/common"
"github.com/protolambda/ztyp/tree"
)
@ -18,24 +17,22 @@ func NewPortalLightApi() *PortalLightApi {
return &PortalLightApi{}
}
func (api *PortalLightApi) GetUpdates(firstPeriod, count uint64) ([]*capella.LightClientUpdate, error) {
func (api *PortalLightApi) GetUpdates(firstPeriod, count uint64) ([]zrntcommon.SpecObj, error) {
return api.bn.GetUpdates(firstPeriod, count)
}
func (api *PortalLightApi) GetCheckpointData(checkpointHash tree.Root) (*capella.LightClientBootstrap, error) {
func (api *PortalLightApi) GetCheckpointData(checkpointHash tree.Root) (zrntcommon.SpecObj, error) {
return api.bn.GetCheckpointData(checkpointHash)
}
func (api *PortalLightApi) GetFinalityData() (*capella.LightClientFinalityUpdate, error) {
func (api *PortalLightApi) GetFinalityData() (zrntcommon.SpecObj, error) {
expectedCurrentSlot := api.bn.spec.TimeToSlot(zrntcommon.Timestamp(time.Now().Unix()), zrntcommon.Timestamp(BeaconGenesisTime))
recentEpochStart := expectedCurrentSlot - (expectedCurrentSlot % api.bn.spec.SLOTS_PER_EPOCH) + 1
return api.bn.GetFinalityUpdate(uint64(recentEpochStart))
}
func (api *PortalLightApi) GetOptimisticData() (*capella.LightClientOptimisticUpdate, error) {
func (api *PortalLightApi) GetOptimisticData() (zrntcommon.SpecObj, error) {
expectedCurrentSlot := api.bn.spec.TimeToSlot(zrntcommon.Timestamp(time.Now().Unix()), zrntcommon.Timestamp(BeaconGenesisTime))
return api.bn.GetOptimisticUpdate(uint64(expectedCurrentSlot))
}

View file

@ -6,6 +6,7 @@ import (
"github.com/protolambda/zrnt/eth2/beacon/altair"
"github.com/protolambda/zrnt/eth2/beacon/capella"
"github.com/protolambda/zrnt/eth2/beacon/common"
"github.com/protolambda/zrnt/eth2/beacon/deneb"
"github.com/protolambda/ztyp/codec"
"github.com/protolambda/ztyp/tree"
)
@ -15,6 +16,7 @@ const MaxRequestLightClientUpdates = 128
var (
Bellatrix common.ForkDigest = [4]byte{0x0, 0x0, 0x0, 0x0}
Capella common.ForkDigest = [4]byte{0xbb, 0xa4, 0xda, 0x96}
Deneb common.ForkDigest = [4]byte{0x6a, 0x95, 0xa1, 0xa9}
)
//go:generate sszgen --path types.go --exclude-objs ForkedLightClientBootstrap,ForkedLightClientUpdate,LightClientUpdateRange
@ -51,6 +53,8 @@ func (flcb *ForkedLightClientBootstrap) Deserialize(spec *common.Spec, dr *codec
flcb.Bootstrap = &altair.LightClientBootstrap{}
} else if flcb.ForkDigest == Capella {
flcb.Bootstrap = &capella.LightClientBootstrap{}
} else if flcb.ForkDigest == Deneb {
flcb.Bootstrap = &deneb.LightClientBootstrap{}
} else {
return errors.New("unknown fork digest")
}
@ -64,7 +68,7 @@ func (flcb *ForkedLightClientBootstrap) Deserialize(spec *common.Spec, dr *codec
}
func (flcb *ForkedLightClientBootstrap) Serialize(spec *common.Spec, w *codec.EncodingWriter) error {
return w.Container(flcb.ForkDigest, spec.Wrap(flcb.Bootstrap))
return w.FixedLenContainer(flcb.ForkDigest, spec.Wrap(flcb.Bootstrap))
}
func (flcb *ForkedLightClientBootstrap) FixedLength(_ *common.Spec) uint64 {
@ -94,6 +98,8 @@ func (flcu *ForkedLightClientUpdate) Deserialize(spec *common.Spec, dr *codec.De
flcu.LightClientUpdate = &altair.LightClientUpdate{}
} else if flcu.ForkDigest == Capella {
flcu.LightClientUpdate = &capella.LightClientUpdate{}
} else if flcu.ForkDigest == Deneb {
flcu.LightClientUpdate = &deneb.LightClientUpdate{}
} else {
return errors.New("unknown fork digest")
}
@ -107,7 +113,7 @@ func (flcu *ForkedLightClientUpdate) Deserialize(spec *common.Spec, dr *codec.De
}
func (flcu *ForkedLightClientUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error {
return w.Container(flcu.ForkDigest, spec.Wrap(flcu.LightClientUpdate))
return w.FixedLenContainer(flcu.ForkDigest, spec.Wrap(flcu.LightClientUpdate))
}
func (flcu *ForkedLightClientUpdate) FixedLength(_ *common.Spec) uint64 {
@ -174,6 +180,8 @@ func (flcou *ForkedLightClientOptimisticUpdate) Deserialize(spec *common.Spec, d
flcou.LightClientOptimisticUpdate = &altair.LightClientOptimisticUpdate{}
} else if flcou.ForkDigest == Capella {
flcou.LightClientOptimisticUpdate = &capella.LightClientOptimisticUpdate{}
} else if flcou.ForkDigest == Deneb {
flcou.LightClientOptimisticUpdate = &deneb.LightClientOptimisticUpdate{}
} else {
return errors.New("unknown fork digest")
}
@ -187,7 +195,7 @@ func (flcou *ForkedLightClientOptimisticUpdate) Deserialize(spec *common.Spec, d
}
func (flcou *ForkedLightClientOptimisticUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error {
return w.Container(flcou.ForkDigest, spec.Wrap(flcou.LightClientOptimisticUpdate))
return w.FixedLenContainer(flcou.ForkDigest, spec.Wrap(flcou.LightClientOptimisticUpdate))
}
func (flcou *ForkedLightClientOptimisticUpdate) FixedLength(_ *common.Spec) uint64 {
@ -217,6 +225,8 @@ func (flcfu *ForkedLightClientFinalityUpdate) Deserialize(spec *common.Spec, dr
flcfu.LightClientFinalityUpdate = &altair.LightClientFinalityUpdate{}
} else if flcfu.ForkDigest == Capella {
flcfu.LightClientFinalityUpdate = &capella.LightClientFinalityUpdate{}
} else if flcfu.ForkDigest == Deneb {
flcfu.LightClientFinalityUpdate = &deneb.LightClientFinalityUpdate{}
} else {
return errors.New("unknown fork digest")
}
@ -230,7 +240,7 @@ func (flcfu *ForkedLightClientFinalityUpdate) Deserialize(spec *common.Spec, dr
}
func (flcfu *ForkedLightClientFinalityUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error {
return w.Container(flcfu.ForkDigest, spec.Wrap(flcfu.LightClientFinalityUpdate))
return w.FixedLenContainer(flcfu.ForkDigest, spec.Wrap(flcfu.LightClientFinalityUpdate))
}
func (flcfu *ForkedLightClientFinalityUpdate) FixedLength(_ *common.Spec) uint64 {