mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-08 02:31:19 +00:00
5a66807989
* First take at updating everything to v5 * Patch gRPC gateway to use prysm v5 Fix patch * Update go ssz --------- Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
192 lines
6.6 KiB
Go
192 lines
6.6 KiB
Go
package beacon_api
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
neturl "net/url"
|
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
"github.com/pkg/errors"
|
|
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
|
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
|
"github.com/prysmaticlabs/prysm/v5/network/httputil"
|
|
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
|
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
|
)
|
|
|
|
type abstractProduceBlockResponseJson struct {
|
|
Version string `json:"version"`
|
|
Data json.RawMessage `json:"data"`
|
|
}
|
|
|
|
func (c beaconApiValidatorClient) getBeaconBlock(ctx context.Context, slot primitives.Slot, randaoReveal []byte, graffiti []byte) (*ethpb.GenericBeaconBlock, error) {
|
|
queryParams := neturl.Values{}
|
|
queryParams.Add("randao_reveal", hexutil.Encode(randaoReveal))
|
|
if len(graffiti) > 0 {
|
|
queryParams.Add("graffiti", hexutil.Encode(graffiti))
|
|
}
|
|
|
|
var ver string
|
|
var blinded bool
|
|
var decoder *json.Decoder
|
|
|
|
// Try v3 endpoint first. If it's not supported, then we fall back to older endpoints.
|
|
// We try the blinded block endpoint first. If it fails, we assume that we got a full block and try the full block endpoint.
|
|
queryUrl := buildURL(fmt.Sprintf("/eth/v3/validator/blocks/%d", slot), queryParams)
|
|
produceBlockV3ResponseJson := structs.ProduceBlockV3Response{}
|
|
err := c.jsonRestHandler.Get(ctx, queryUrl, &produceBlockV3ResponseJson)
|
|
errJson := &httputil.DefaultJsonError{}
|
|
if err != nil {
|
|
if !errors.As(err, &errJson) {
|
|
return nil, err
|
|
}
|
|
if errJson.Code != http.StatusNotFound {
|
|
return nil, errJson
|
|
}
|
|
log.Debug("Endpoint /eth/v3/validator/blocks is not supported, falling back to older endpoints for block proposal.")
|
|
fallbackResp, err := c.fallBackToBlinded(ctx, slot, queryParams)
|
|
errJson = &httputil.DefaultJsonError{}
|
|
if err != nil {
|
|
if !errors.As(err, &errJson) {
|
|
return nil, err
|
|
}
|
|
log.Debug("Endpoint /eth/v1/validator/blinded_blocks failed to produce a blinded block, trying /eth/v2/validator/blocks.")
|
|
fallbackResp, err = c.fallBackToFull(ctx, slot, queryParams)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
blinded = false
|
|
} else {
|
|
blinded = true
|
|
}
|
|
ver = fallbackResp.Version
|
|
decoder = json.NewDecoder(bytes.NewReader(fallbackResp.Data))
|
|
} else {
|
|
ver = produceBlockV3ResponseJson.Version
|
|
blinded = produceBlockV3ResponseJson.ExecutionPayloadBlinded
|
|
decoder = json.NewDecoder(bytes.NewReader(produceBlockV3ResponseJson.Data))
|
|
}
|
|
|
|
var response *ethpb.GenericBeaconBlock
|
|
switch ver {
|
|
case version.String(version.Phase0):
|
|
jsonPhase0Block := structs.BeaconBlock{}
|
|
if err := decoder.Decode(&jsonPhase0Block); err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode phase0 block response json")
|
|
}
|
|
genericBlock, err := jsonPhase0Block.ToGeneric()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get phase0 block")
|
|
}
|
|
response = genericBlock
|
|
case version.String(version.Altair):
|
|
jsonAltairBlock := structs.BeaconBlockAltair{}
|
|
if err := decoder.Decode(&jsonAltairBlock); err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode altair block response json")
|
|
}
|
|
genericBlock, err := jsonAltairBlock.ToGeneric()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get altair block")
|
|
}
|
|
response = genericBlock
|
|
case version.String(version.Bellatrix):
|
|
if blinded {
|
|
jsonBellatrixBlock := structs.BlindedBeaconBlockBellatrix{}
|
|
if err := decoder.Decode(&jsonBellatrixBlock); err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode blinded bellatrix block response json")
|
|
}
|
|
genericBlock, err := jsonBellatrixBlock.ToGeneric()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get blinded bellatrix block")
|
|
}
|
|
response = genericBlock
|
|
} else {
|
|
jsonBellatrixBlock := structs.BeaconBlockBellatrix{}
|
|
if err := decoder.Decode(&jsonBellatrixBlock); err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode bellatrix block response json")
|
|
}
|
|
genericBlock, err := jsonBellatrixBlock.ToGeneric()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get bellatrix block")
|
|
}
|
|
response = genericBlock
|
|
}
|
|
case version.String(version.Capella):
|
|
if blinded {
|
|
jsonCapellaBlock := structs.BlindedBeaconBlockCapella{}
|
|
if err := decoder.Decode(&jsonCapellaBlock); err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode blinded capella block response json")
|
|
}
|
|
genericBlock, err := jsonCapellaBlock.ToGeneric()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get blinded capella block")
|
|
}
|
|
response = genericBlock
|
|
} else {
|
|
jsonCapellaBlock := structs.BeaconBlockCapella{}
|
|
if err := decoder.Decode(&jsonCapellaBlock); err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode capella block response json")
|
|
}
|
|
genericBlock, err := jsonCapellaBlock.ToGeneric()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get capella block")
|
|
}
|
|
response = genericBlock
|
|
}
|
|
case version.String(version.Deneb):
|
|
if blinded {
|
|
jsonDenebBlock := structs.BlindedBeaconBlockDeneb{}
|
|
if err := decoder.Decode(&jsonDenebBlock); err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode blinded deneb block response json")
|
|
}
|
|
genericBlock, err := jsonDenebBlock.ToGeneric()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get blinded deneb block")
|
|
}
|
|
response = genericBlock
|
|
} else {
|
|
jsonDenebBlockContents := structs.BeaconBlockContentsDeneb{}
|
|
if err := decoder.Decode(&jsonDenebBlockContents); err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode deneb block response json")
|
|
}
|
|
genericBlock, err := jsonDenebBlockContents.ToGeneric()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get deneb block")
|
|
}
|
|
response = genericBlock
|
|
}
|
|
default:
|
|
return nil, errors.Errorf("unsupported consensus version `%s`", ver)
|
|
}
|
|
return response, nil
|
|
}
|
|
|
|
func (c beaconApiValidatorClient) fallBackToBlinded(
|
|
ctx context.Context,
|
|
slot primitives.Slot,
|
|
queryParams neturl.Values,
|
|
) (*abstractProduceBlockResponseJson, error) {
|
|
resp := &abstractProduceBlockResponseJson{}
|
|
url := buildURL(fmt.Sprintf("/eth/v1/validator/blinded_blocks/%d", slot), queryParams)
|
|
if err := c.jsonRestHandler.Get(ctx, url, resp); err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (c beaconApiValidatorClient) fallBackToFull(
|
|
ctx context.Context,
|
|
slot primitives.Slot,
|
|
queryParams neturl.Values,
|
|
) (*abstractProduceBlockResponseJson, error) {
|
|
resp := &abstractProduceBlockResponseJson{}
|
|
url := buildURL(fmt.Sprintf("/eth/v2/validator/blocks/%d", slot), queryParams)
|
|
if err := c.jsonRestHandler.Get(ctx, url, resp); err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|