mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-11 22:43:47 +00:00
refactor: portal api
This commit is contained in:
parent
4fec1b226a
commit
777d67cdc3
7 changed files with 148 additions and 247 deletions
|
|
@ -32,6 +32,7 @@ type BeaconNetwork struct {
|
||||||
log log.Logger
|
log log.Logger
|
||||||
closeCtx context.Context
|
closeCtx context.Context
|
||||||
closeFunc context.CancelFunc
|
closeFunc context.CancelFunc
|
||||||
|
// lightClient *ConsensusLightClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBeaconNetwork(portalProtocol *discover.PortalProtocol) *BeaconNetwork {
|
func NewBeaconNetwork(portalProtocol *discover.PortalProtocol) *BeaconNetwork {
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,10 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConsensusAPI interface {
|
type ConsensusAPI interface {
|
||||||
|
GetBootstrap(blockRoot common.Root) (common.SpecObj, error)
|
||||||
GetUpdates(firstPeriod, count uint64) ([]common.SpecObj, error)
|
GetUpdates(firstPeriod, count uint64) ([]common.SpecObj, error)
|
||||||
GetCheckpointData(checkpointHash common.Root) (common.SpecObj, error)
|
GetFinalityUpdate() (common.SpecObj, error)
|
||||||
GetFinalityData() (common.SpecObj, error)
|
GetOptimisticUpdate() (common.SpecObj, error)
|
||||||
GetOptimisticData() (common.SpecObj, error)
|
|
||||||
ChainID() uint64
|
ChainID() uint64
|
||||||
Name() string
|
Name() string
|
||||||
}
|
}
|
||||||
|
|
@ -174,7 +174,7 @@ func (c *ConsensusLightClient) Sync() error {
|
||||||
c.ApplyUpdate(update)
|
c.ApplyUpdate(update)
|
||||||
}
|
}
|
||||||
|
|
||||||
finalityUpdate, err := c.API.GetFinalityData()
|
finalityUpdate, err := c.API.GetFinalityUpdate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -184,7 +184,7 @@ func (c *ConsensusLightClient) Sync() error {
|
||||||
}
|
}
|
||||||
c.ApplyFinalityUpdate(finalityUpdate)
|
c.ApplyFinalityUpdate(finalityUpdate)
|
||||||
|
|
||||||
optimisticUpdate, err := c.API.GetOptimisticData()
|
optimisticUpdate, err := c.API.GetOptimisticUpdate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -199,7 +199,7 @@ func (c *ConsensusLightClient) Sync() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsensusLightClient) Advance() error {
|
func (c *ConsensusLightClient) Advance() error {
|
||||||
finalityUpdate, err := c.API.GetFinalityData()
|
finalityUpdate, err := c.API.GetFinalityUpdate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -209,7 +209,7 @@ func (c *ConsensusLightClient) Advance() error {
|
||||||
}
|
}
|
||||||
c.ApplyFinalityUpdate(finalityUpdate)
|
c.ApplyFinalityUpdate(finalityUpdate)
|
||||||
|
|
||||||
optimisticUpdate, err := c.API.GetOptimisticData()
|
optimisticUpdate, err := c.API.GetOptimisticUpdate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -240,7 +240,7 @@ func (c *ConsensusLightClient) Advance() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsensusLightClient) bootstrap() error {
|
func (c *ConsensusLightClient) bootstrap() error {
|
||||||
forkedBootstrap, err := c.API.GetCheckpointData(c.InitialCheckpoint)
|
forkedBootstrap, err := c.API.GetBootstrap(c.InitialCheckpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ func (m MockConsensusAPI) GetUpdates(_, _ uint64) ([]common.SpecObj, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MockConsensusAPI) GetCheckpointData(_ common.Root) (common.SpecObj, error) {
|
func (m MockConsensusAPI) GetBootstrap(_ common.Root) (common.SpecObj, error) {
|
||||||
jsonStr, _ := os.ReadFile(m.testdataDir + "/bootstrap.json")
|
jsonStr, _ := os.ReadFile(m.testdataDir + "/bootstrap.json")
|
||||||
|
|
||||||
bootstrap := &capella.LightClientBootstrap{}
|
bootstrap := &capella.LightClientBootstrap{}
|
||||||
|
|
@ -47,7 +47,7 @@ func (m MockConsensusAPI) GetCheckpointData(_ common.Root) (common.SpecObj, erro
|
||||||
return bootstrap, nil
|
return bootstrap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MockConsensusAPI) GetFinalityData() (common.SpecObj, error) {
|
func (m MockConsensusAPI) GetFinalityUpdate() (common.SpecObj, error) {
|
||||||
jsonStr, _ := os.ReadFile(m.testdataDir + "/finality.json")
|
jsonStr, _ := os.ReadFile(m.testdataDir + "/finality.json")
|
||||||
|
|
||||||
finality := &capella.LightClientFinalityUpdate{}
|
finality := &capella.LightClientFinalityUpdate{}
|
||||||
|
|
@ -56,7 +56,7 @@ func (m MockConsensusAPI) GetFinalityData() (common.SpecObj, error) {
|
||||||
return finality, nil
|
return finality, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MockConsensusAPI) GetOptimisticData() (common.SpecObj, error) {
|
func (m MockConsensusAPI) GetOptimisticUpdate() (common.SpecObj, error) {
|
||||||
jsonStr, _ := os.ReadFile(m.testdataDir + "/optimistic.json")
|
jsonStr, _ := os.ReadFile(m.testdataDir + "/optimistic.json")
|
||||||
|
|
||||||
optimistic := &capella.LightClientOptimisticUpdate{}
|
optimistic := &capella.LightClientOptimisticUpdate{}
|
||||||
|
|
@ -140,7 +140,7 @@ func TestVerifyFinalityUpdate(t *testing.T) {
|
||||||
client, err := getClient(false, t)
|
client, err := getClient(false, t)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
update, err := client.API.GetFinalityData()
|
update, err := client.API.GetFinalityUpdate()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// normal
|
// normal
|
||||||
|
|
@ -154,7 +154,7 @@ func TestVerifyFinalityUpdate(t *testing.T) {
|
||||||
err = client.VerifyGenericUpdate(genericUpdate)
|
err = client.VerifyGenericUpdate(genericUpdate)
|
||||||
require.Equal(t, ErrInvalidFinalityProof, err)
|
require.Equal(t, ErrInvalidFinalityProof, err)
|
||||||
// ErrInvalidSignature
|
// ErrInvalidSignature
|
||||||
update, err = client.API.GetFinalityData()
|
update, err = client.API.GetFinalityUpdate()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
genericUpdate, err = FromLightClientFinalityUpdate(update)
|
genericUpdate, err = FromLightClientFinalityUpdate(update)
|
||||||
|
|
@ -168,7 +168,7 @@ func TestVerifyOptimisticUpdate(t *testing.T) {
|
||||||
client, err := getClient(false, t)
|
client, err := getClient(false, t)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
update, err := client.API.GetOptimisticData()
|
update, err := client.API.GetOptimisticUpdate()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// normal
|
// normal
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package lightclient
|
|
||||||
|
|
||||||
import "github.com/protolambda/zrnt/eth2/beacon/common"
|
|
||||||
|
|
||||||
type ConsensusAPI interface {
|
|
||||||
GetBootstrap(blockRoot common.Root) (common.SpecObj, error)
|
|
||||||
GetUpdates(firstPeriod, count uint64) ([]common.SpecObj, error)
|
|
||||||
GetFinalityUpdate() (common.SpecObj, error)
|
|
||||||
GetOptimisticUpdate() (common.SpecObj, error)
|
|
||||||
ChainID() uint64
|
|
||||||
Name() string
|
|
||||||
}
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
package lightclient
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/protolambda/zrnt/eth2/beacon/common"
|
|
||||||
"github.com/protolambda/ztyp/tree"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ ConsensusAPI = (*MockRpc)(nil)
|
|
||||||
|
|
||||||
type MockRpc struct {
|
|
||||||
testdataDir string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChainID implements ConsensusAPI.
|
|
||||||
func (m *MockRpc) ChainID() uint64 {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBootstrap implements ConsensusAPI.
|
|
||||||
func (m *MockRpc) GetBootstrap(blockRoot tree.Root) (common.SpecObj, error) {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFinalityUpdate implements ConsensusAPI.
|
|
||||||
func (m *MockRpc) GetFinalityUpdate() (common.SpecObj, error) {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOptimisticUpdate implements ConsensusAPI.
|
|
||||||
func (m *MockRpc) GetOptimisticUpdate() (common.SpecObj, error) {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUpdates implements ConsensusAPI.
|
|
||||||
func (m *MockRpc) GetUpdates(firstPeriod uint64, count uint64) ([]common.SpecObj, error) {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements ConsensusAPI.
|
|
||||||
func (m *MockRpc) Name() string {
|
|
||||||
panic("unimplemented")
|
|
||||||
}
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
package lightclient
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
|
||||||
"github.com/ethereum/go-ethereum/portalnetwork/beacon"
|
|
||||||
"github.com/ethereum/go-ethereum/portalnetwork/storage"
|
|
||||||
"github.com/protolambda/zrnt/eth2/beacon/common"
|
|
||||||
"github.com/protolambda/ztyp/codec"
|
|
||||||
"github.com/protolambda/ztyp/tree"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ ConsensusAPI = &PortalRpc{}
|
|
||||||
|
|
||||||
type PortalRpc struct {
|
|
||||||
portalProtocol *discover.PortalProtocol
|
|
||||||
spec *common.Spec
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChainID implements ConsensusAPI.
|
|
||||||
func (p *PortalRpc) ChainID() uint64 {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCheckpointData implements ConsensusAPI.
|
|
||||||
func (p *PortalRpc) GetBootstrap(blockRoot tree.Root) (common.SpecObj, error) {
|
|
||||||
bootstrapKey := &beacon.LightClientBootstrapKey{
|
|
||||||
BlockHash: blockRoot[:],
|
|
||||||
}
|
|
||||||
contentKeyBytes, err := bootstrapKey.MarshalSSZ()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
contentKey := storage.NewContentKey(beacon.LightClientBootstrap, contentKeyBytes).Encode()
|
|
||||||
// Get from local
|
|
||||||
contentId := p.portalProtocol.ToContentId(contentKey)
|
|
||||||
res, err := p.getContent(contentKey, contentId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
forkedLightClientBootstrap := &beacon.ForkedLightClientBootstrap{}
|
|
||||||
err = forkedLightClientBootstrap.Deserialize(p.spec, codec.NewDecodingReader(bytes.NewReader(res), uint64(len(res))))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return forkedLightClientBootstrap.Bootstrap, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFinalityData implements ConsensusAPI.
|
|
||||||
func (p *PortalRpc) GetFinalityUpdate() (common.SpecObj, error) {
|
|
||||||
// Get the finality update for the most recent finalized epoch. We use 0 as the finalized
|
|
||||||
// slot because the finalized slot is not known at this point and the protocol is
|
|
||||||
// designed to return the most recent which is > 0
|
|
||||||
finUpdateKey := &beacon.LightClientFinalityUpdateKey{
|
|
||||||
FinalizedSlot: 0,
|
|
||||||
}
|
|
||||||
contentKeyBytes, err := finUpdateKey.MarshalSSZ()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
contentKey := storage.NewContentKey(beacon.LightClientFinalityUpdate, contentKeyBytes).Encode()
|
|
||||||
// Get from local
|
|
||||||
contentId := p.portalProtocol.ToContentId(contentKey)
|
|
||||||
res, err := p.getContent(contentKey, contentId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
finalityUpdate := &beacon.ForkedLightClientFinalityUpdate{}
|
|
||||||
err = finalityUpdate.Deserialize(p.spec, codec.NewDecodingReader(bytes.NewReader(res), uint64(len(res))))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return finalityUpdate.LightClientFinalityUpdate, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOptimisticData implements ConsensusAPI.
|
|
||||||
func (p *PortalRpc) GetOptimisticUpdate() (common.SpecObj, error) {
|
|
||||||
currentSlot := p.spec.TimeToSlot(common.Timestamp(time.Now().Unix()), common.Timestamp(beacon.BeaconGenesisTime))
|
|
||||||
optimisticUpdateKey := &beacon.LightClientOptimisticUpdateKey{
|
|
||||||
OptimisticSlot: uint64(currentSlot),
|
|
||||||
}
|
|
||||||
contentKeyBytes, err := optimisticUpdateKey.MarshalSSZ()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
contentKey := storage.NewContentKey(beacon.LightClientOptimisticUpdate, contentKeyBytes).Encode()
|
|
||||||
// Get from local
|
|
||||||
contentId := p.portalProtocol.ToContentId(contentKey)
|
|
||||||
res, err := p.getContent(contentKey, contentId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
optimisticUpdate := &beacon.ForkedLightClientOptimisticUpdate{}
|
|
||||||
err = optimisticUpdate.Deserialize(p.spec, codec.NewDecodingReader(bytes.NewReader(res), uint64(len(res))))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return optimisticUpdate.LightClientOptimisticUpdate, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUpdates implements ConsensusAPI.
|
|
||||||
func (p *PortalRpc) GetUpdates(firstPeriod uint64, count uint64) ([]common.SpecObj, error) {
|
|
||||||
lightClientUpdateKey := &beacon.LightClientUpdateKey{
|
|
||||||
StartPeriod: firstPeriod,
|
|
||||||
Count: count,
|
|
||||||
}
|
|
||||||
contentKeyBytes, err := lightClientUpdateKey.MarshalSSZ()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
contentKey := storage.NewContentKey(beacon.LightClientUpdate, contentKeyBytes).Encode()
|
|
||||||
// Get from local
|
|
||||||
contentId := p.portalProtocol.ToContentId(contentKey)
|
|
||||||
data, err := p.getContent(contentKey, contentId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var lightClientUpdateRange beacon.LightClientUpdateRange = make([]beacon.ForkedLightClientUpdate, 0)
|
|
||||||
err = lightClientUpdateRange.Deserialize(p.spec, codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data))))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
res := make([]common.SpecObj, len(lightClientUpdateRange))
|
|
||||||
|
|
||||||
for i, item := range lightClientUpdateRange {
|
|
||||||
res[i] = item.LightClientUpdate
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements ConsensusAPI.
|
|
||||||
func (p *PortalRpc) Name() string {
|
|
||||||
return "portal"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PortalRpc) getContent(contentKey, contentId []byte) ([]byte, error) {
|
|
||||||
res, err := p.portalProtocol.Get(contentKey, contentId)
|
|
||||||
// other error
|
|
||||||
if err != nil && !errors.Is(err, storage.ErrContentNotFound) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if res == nil {
|
|
||||||
// Get from remote
|
|
||||||
res, _, err = p.portalProtocol.ContentLookup(contentKey, contentId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
package beacon
|
package beacon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
zrntcommon "github.com/protolambda/zrnt/eth2/beacon/common"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/portalnetwork/storage"
|
||||||
|
"github.com/protolambda/zrnt/eth2/beacon/common"
|
||||||
|
"github.com/protolambda/ztyp/codec"
|
||||||
"github.com/protolambda/ztyp/tree"
|
"github.com/protolambda/ztyp/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -12,40 +17,142 @@ const BeaconGenesisTime uint64 = 1606824023
|
||||||
var _ ConsensusAPI = &PortalLightApi{}
|
var _ ConsensusAPI = &PortalLightApi{}
|
||||||
|
|
||||||
type PortalLightApi struct {
|
type PortalLightApi struct {
|
||||||
bn *BeaconNetwork
|
portalProtocol *discover.PortalProtocol
|
||||||
|
spec *common.Spec
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPortalLightApi() *PortalLightApi {
|
func NewPortalLightApi() *PortalLightApi {
|
||||||
return &PortalLightApi{}
|
return &PortalLightApi{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *PortalLightApi) GetUpdates(firstPeriod, count uint64) ([]zrntcommon.SpecObj, error) {
|
// ChainID implements ConsensusAPI.
|
||||||
return api.bn.GetUpdates(firstPeriod, count)
|
func (p *PortalLightApi) ChainID() uint64 {
|
||||||
}
|
|
||||||
|
|
||||||
func (api *PortalLightApi) GetCheckpointData(checkpointHash tree.Root) (zrntcommon.SpecObj, error) {
|
|
||||||
return api.bn.GetCheckpointData(checkpointHash)
|
|
||||||
}
|
|
||||||
|
|
||||||
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() (zrntcommon.SpecObj, error) {
|
|
||||||
expectedCurrentSlot := api.bn.spec.TimeToSlot(zrntcommon.Timestamp(time.Now().Unix()), zrntcommon.Timestamp(BeaconGenesisTime))
|
|
||||||
return api.bn.GetOptimisticUpdate(uint64(expectedCurrentSlot))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *PortalLightApi) ChainID() uint64 {
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *PortalLightApi) Name() string {
|
// GetCheckpointData implements ConsensusAPI.
|
||||||
|
func (p *PortalLightApi) GetBootstrap(blockRoot tree.Root) (common.SpecObj, error) {
|
||||||
|
bootstrapKey := &LightClientBootstrapKey{
|
||||||
|
BlockHash: blockRoot[:],
|
||||||
|
}
|
||||||
|
contentKeyBytes, err := bootstrapKey.MarshalSSZ()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
contentKey := storage.NewContentKey(LightClientBootstrap, contentKeyBytes).Encode()
|
||||||
|
// Get from local
|
||||||
|
contentId := p.portalProtocol.ToContentId(contentKey)
|
||||||
|
res, err := p.getContent(contentKey, contentId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
forkedLightClientBootstrap := &ForkedLightClientBootstrap{}
|
||||||
|
err = forkedLightClientBootstrap.Deserialize(p.spec, codec.NewDecodingReader(bytes.NewReader(res), uint64(len(res))))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return forkedLightClientBootstrap.Bootstrap, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFinalityData implements ConsensusAPI.
|
||||||
|
func (p *PortalLightApi) GetFinalityUpdate() (common.SpecObj, error) {
|
||||||
|
// Get the finality update for the most recent finalized epoch. We use 0 as the finalized
|
||||||
|
// slot because the finalized slot is not known at this point and the protocol is
|
||||||
|
// designed to return the most recent which is > 0
|
||||||
|
finUpdateKey := &LightClientFinalityUpdateKey{
|
||||||
|
FinalizedSlot: 0,
|
||||||
|
}
|
||||||
|
contentKeyBytes, err := finUpdateKey.MarshalSSZ()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
contentKey := storage.NewContentKey(LightClientFinalityUpdate, contentKeyBytes).Encode()
|
||||||
|
// Get from local
|
||||||
|
contentId := p.portalProtocol.ToContentId(contentKey)
|
||||||
|
res, err := p.getContent(contentKey, contentId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
finalityUpdate := &ForkedLightClientFinalityUpdate{}
|
||||||
|
err = finalityUpdate.Deserialize(p.spec, codec.NewDecodingReader(bytes.NewReader(res), uint64(len(res))))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return finalityUpdate.LightClientFinalityUpdate, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOptimisticData implements ConsensusAPI.
|
||||||
|
func (p *PortalLightApi) GetOptimisticUpdate() (common.SpecObj, error) {
|
||||||
|
currentSlot := p.spec.TimeToSlot(common.Timestamp(time.Now().Unix()), common.Timestamp(BeaconGenesisTime))
|
||||||
|
optimisticUpdateKey := &LightClientOptimisticUpdateKey{
|
||||||
|
OptimisticSlot: uint64(currentSlot),
|
||||||
|
}
|
||||||
|
contentKeyBytes, err := optimisticUpdateKey.MarshalSSZ()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
contentKey := storage.NewContentKey(LightClientOptimisticUpdate, contentKeyBytes).Encode()
|
||||||
|
// Get from local
|
||||||
|
contentId := p.portalProtocol.ToContentId(contentKey)
|
||||||
|
res, err := p.getContent(contentKey, contentId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
optimisticUpdate := &ForkedLightClientOptimisticUpdate{}
|
||||||
|
err = optimisticUpdate.Deserialize(p.spec, codec.NewDecodingReader(bytes.NewReader(res), uint64(len(res))))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return optimisticUpdate.LightClientOptimisticUpdate, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUpdates implements ConsensusAPI.
|
||||||
|
func (p *PortalLightApi) GetUpdates(firstPeriod uint64, count uint64) ([]common.SpecObj, error) {
|
||||||
|
lightClientUpdateKey := &LightClientUpdateKey{
|
||||||
|
StartPeriod: firstPeriod,
|
||||||
|
Count: count,
|
||||||
|
}
|
||||||
|
contentKeyBytes, err := lightClientUpdateKey.MarshalSSZ()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
contentKey := storage.NewContentKey(LightClientUpdate, contentKeyBytes).Encode()
|
||||||
|
// Get from local
|
||||||
|
contentId := p.portalProtocol.ToContentId(contentKey)
|
||||||
|
data, err := p.getContent(contentKey, contentId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var lightClientUpdateRange LightClientUpdateRange = make([]ForkedLightClientUpdate, 0)
|
||||||
|
err = lightClientUpdateRange.Deserialize(p.spec, codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data))))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res := make([]common.SpecObj, len(lightClientUpdateRange))
|
||||||
|
|
||||||
|
for i, item := range lightClientUpdateRange {
|
||||||
|
res[i] = item.LightClientUpdate
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements ConsensusAPI.
|
||||||
|
func (p *PortalLightApi) Name() string {
|
||||||
return "portal"
|
return "portal"
|
||||||
}
|
}
|
||||||
|
|
||||||
// func CurrentSlot() uint64 {
|
func (p *PortalLightApi) getContent(contentKey, contentId []byte) ([]byte, error) {
|
||||||
|
res, err := p.portalProtocol.Get(contentKey, contentId)
|
||||||
// }
|
// other error
|
||||||
|
if err != nil && !errors.Is(err, storage.ErrContentNotFound) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if res == nil {
|
||||||
|
// Get from remote
|
||||||
|
res, _, err = p.portalProtocol.ContentLookup(contentKey, contentId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue