mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-08 20:11:21 +00:00
203 lines
6.2 KiB
Go
203 lines
6.2 KiB
Go
package rpc
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel"
|
|
"github.com/ledgerwatch/erigon/cl/cltypes"
|
|
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication"
|
|
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication/ssz_snappy"
|
|
"github.com/ledgerwatch/erigon/common"
|
|
"github.com/ledgerwatch/log/v3"
|
|
"go.uber.org/zap/buffer"
|
|
)
|
|
|
|
func SendLightClientFinaltyUpdateReqV1(ctx context.Context, client sentinel.SentinelClient) (*cltypes.LightClientFinalityUpdate, error) {
|
|
responsePacket := &cltypes.LightClientFinalityUpdate{}
|
|
|
|
message, err := client.SendRequest(ctx, &sentinel.RequestData{
|
|
Topic: communication.LightClientFinalityUpdateV1,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if message.Error {
|
|
log.Warn("received error", "err", string(message.Data))
|
|
return nil, nil
|
|
}
|
|
|
|
if err := ssz_snappy.DecodeAndRead(bytes.NewReader(message.Data), responsePacket); err != nil {
|
|
return nil, fmt.Errorf("unable to decode packet: %v", err)
|
|
}
|
|
return responsePacket, nil
|
|
}
|
|
|
|
func SendLightClientOptimisticUpdateReqV1(ctx context.Context, client sentinel.SentinelClient) (*cltypes.LightClientOptimisticUpdate, error) {
|
|
responsePacket := &cltypes.LightClientOptimisticUpdate{}
|
|
|
|
message, err := client.SendRequest(ctx, &sentinel.RequestData{
|
|
Topic: communication.LightClientOptimisticUpdateV1,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if message.Error {
|
|
log.Warn("received error", "err", string(message.Data))
|
|
return nil, nil
|
|
}
|
|
|
|
if err := ssz_snappy.DecodeAndRead(bytes.NewReader(message.Data), responsePacket); err != nil {
|
|
return nil, fmt.Errorf("unable to decode packet: %v", err)
|
|
}
|
|
return responsePacket, nil
|
|
}
|
|
|
|
func SendLightClientBootstrapReqV1(ctx context.Context, req *cltypes.SingleRoot, client sentinel.SentinelClient) (*cltypes.LightClientBootstrap, error) {
|
|
var buffer buffer.Buffer
|
|
if err := ssz_snappy.EncodeAndWrite(&buffer, req); err != nil {
|
|
return nil, err
|
|
}
|
|
responsePacket := &cltypes.LightClientBootstrap{}
|
|
data := common.CopyBytes(buffer.Bytes())
|
|
message, err := client.SendRequest(ctx, &sentinel.RequestData{
|
|
Data: data,
|
|
Topic: communication.LightClientBootstrapV1,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if message.Error {
|
|
log.Warn("received error", "err", string(message.Data))
|
|
return nil, nil
|
|
}
|
|
if err := ssz_snappy.DecodeAndRead(bytes.NewReader(message.Data), responsePacket); err != nil {
|
|
return nil, fmt.Errorf("unable to decode packet: %v", err)
|
|
}
|
|
return responsePacket, nil
|
|
}
|
|
|
|
func SendLightClientUpdatesReqV1(ctx context.Context, period uint64, client sentinel.SentinelClient) (*cltypes.LightClientUpdate, error) {
|
|
// This is approximately one day worth of data, we dont need to receive more than 1.
|
|
req := &cltypes.LightClientUpdatesByRangeRequest{
|
|
Period: period,
|
|
Count: 1,
|
|
}
|
|
var buffer buffer.Buffer
|
|
if err := ssz_snappy.EncodeAndWrite(&buffer, req); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
responsePacket := []cltypes.ObjectSSZ{&cltypes.LightClientUpdate{}}
|
|
|
|
data := common.CopyBytes(buffer.Bytes())
|
|
message, err := client.SendRequest(ctx, &sentinel.RequestData{
|
|
Data: data,
|
|
Topic: communication.LightClientUpdatesByRangeV1,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if message.Error {
|
|
log.Warn("received error", "err", string(message.Data))
|
|
return nil, nil
|
|
}
|
|
if err := ssz_snappy.DecodeListSSZ(message.Data, 1, responsePacket); err != nil {
|
|
return nil, fmt.Errorf("unable to decode packet: %v", err)
|
|
}
|
|
return responsePacket[0].(*cltypes.LightClientUpdate), nil
|
|
}
|
|
|
|
type blocksRequestOpts struct {
|
|
topic string
|
|
count int
|
|
client sentinel.SentinelClient
|
|
reqData []byte
|
|
}
|
|
|
|
func sendBlocksRequest(ctx context.Context, opts blocksRequestOpts) ([]cltypes.ObjectSSZ, error) {
|
|
// Prepare output slice.
|
|
responsePacket := []cltypes.ObjectSSZ{}
|
|
for i := 0; i < opts.count; i++ {
|
|
responsePacket = append(responsePacket, &cltypes.SignedBeaconBlockBellatrix{})
|
|
}
|
|
|
|
message, err := opts.client.SendRequest(ctx, &sentinel.RequestData{
|
|
Data: opts.reqData,
|
|
Topic: opts.topic,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if message.Error {
|
|
log.Trace("received error", "err", string(message.Data))
|
|
return nil, nil
|
|
}
|
|
if err := ssz_snappy.DecodeListSSZBeaconBlock(message.Data, uint64(opts.count), responsePacket); err != nil {
|
|
return nil, fmt.Errorf("unable to decode packet: %v", err)
|
|
}
|
|
return responsePacket, nil
|
|
}
|
|
|
|
func SendBeaconBlocksByRangeReq(ctx context.Context, start, count uint64, client sentinel.SentinelClient) ([]cltypes.ObjectSSZ, error) {
|
|
req := &cltypes.BeaconBlocksByRangeRequest{
|
|
StartSlot: start,
|
|
Count: count,
|
|
Step: 1, // deprecated, and must be set to 1.
|
|
}
|
|
var buffer buffer.Buffer
|
|
if err := ssz_snappy.EncodeAndWrite(&buffer, req); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
data := common.CopyBytes(buffer.Bytes())
|
|
return sendBlocksRequest(ctx, blocksRequestOpts{
|
|
topic: communication.BeaconBlocksByRangeProtocolV2,
|
|
count: int(count),
|
|
client: client,
|
|
reqData: data,
|
|
})
|
|
}
|
|
|
|
func SendBeaconBlocksByRootReq(ctx context.Context, roots [][32]byte, client sentinel.SentinelClient) ([]cltypes.ObjectSSZ, error) {
|
|
var req cltypes.BeaconBlocksByRootRequest = roots
|
|
var buffer buffer.Buffer
|
|
if err := ssz_snappy.EncodeAndWrite(&buffer, &req); err != nil {
|
|
return nil, err
|
|
}
|
|
data := common.CopyBytes(buffer.Bytes())
|
|
return sendBlocksRequest(ctx, blocksRequestOpts{
|
|
topic: communication.BeaconBlocksByRootProtocolV2,
|
|
count: len(roots),
|
|
client: client,
|
|
reqData: data,
|
|
})
|
|
}
|
|
|
|
func SendStatusReq(ctx context.Context, ourStatus *cltypes.Status, client sentinel.SentinelClient) (*cltypes.Status, error) {
|
|
var buffer buffer.Buffer
|
|
if err := ssz_snappy.EncodeAndWrite(&buffer, ourStatus); err != nil {
|
|
return nil, err
|
|
}
|
|
responsePacket := &cltypes.Status{}
|
|
|
|
data := common.CopyBytes(buffer.Bytes())
|
|
|
|
message, err := client.SendRequest(ctx, &sentinel.RequestData{
|
|
Data: data,
|
|
Topic: communication.StatusProtocolV1,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if message.Error {
|
|
log.Warn("received error", "err", string(message.Data))
|
|
return nil, nil
|
|
}
|
|
if err := ssz_snappy.DecodeAndReadNoForkDigest(bytes.NewReader(message.Data), responsePacket); err != nil {
|
|
return nil, fmt.Errorf("unable to decode packet: %v", err)
|
|
}
|
|
return responsePacket, nil
|
|
}
|