From 73612bf6611f8bdff022bf72ea30017c8c8cf6f3 Mon Sep 17 00:00:00 2001 From: fearlessfe <505380967@qq.com> Date: Sat, 20 Apr 2024 21:03:23 +0800 Subject: [PATCH] feat: change portal api --- cmd/shisui/main.go | 2 +- go.mod | 2 + portalnetwork/beacon/beacon_network.go | 63 +++---- portalnetwork/beacon/light_client.go | 219 +++++++++++++++++----- portalnetwork/beacon/light_client_test.go | 54 ++++-- portalnetwork/beacon/portal_api.go | 11 +- portalnetwork/beacon/types.go | 18 +- 7 files changed, 247 insertions(+), 122 deletions(-) diff --git a/cmd/shisui/main.go b/cmd/shisui/main.go index 73e416e53429..0a2bee13bdf7 100644 --- a/cmd/shisui/main.go +++ b/cmd/shisui/main.go @@ -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) diff --git a/go.mod b/go.mod index 2cc115ad013d..31f7c91fa179 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/portalnetwork/beacon/beacon_network.go b/portalnetwork/beacon/beacon_network.go index 0a2316400aeb..8dd8e23569be 100644 --- a/portalnetwork/beacon/beacon_network.go +++ b/portalnetwork/beacon/beacon_network.go @@ -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) { diff --git a/portalnetwork/beacon/light_client.go b/portalnetwork/beacon/light_client.go index 6d7fb9eb4188..ab5658abcc56 100644 --- a/portalnetwork/beacon/light_client.go +++ b/portalnetwork/beacon/light_client.go @@ -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 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 FromLightClientOptimisticUpdate(update *capella.LightClientOptimisticUpdate) *GenericUpdate { - return &GenericUpdate{ - AttestedHeader: &update.AttestedHeader.Beacon, - SyncAggregate: &update.SyncAggregate, - SignatureSlot: update.SignatureSlot, - } +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(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(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 { diff --git a/portalnetwork/beacon/light_client_test.go b/portalnetwork/beacon/light_client_test.go index 6e45eebb585e..a558e29f5f85 100644 --- a/portalnetwork/beacon/light_client_test.go +++ b/portalnetwork/beacon/light_client_test.go @@ -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) } diff --git a/portalnetwork/beacon/portal_api.go b/portalnetwork/beacon/portal_api.go index 38948d63e76f..34dbccc89668 100644 --- a/portalnetwork/beacon/portal_api.go +++ b/portalnetwork/beacon/portal_api.go @@ -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)) } diff --git a/portalnetwork/beacon/types.go b/portalnetwork/beacon/types.go index 5e4d92237dc6..b062683fd4ee 100644 --- a/portalnetwork/beacon/types.go +++ b/portalnetwork/beacon/types.go @@ -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 {