mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Electra payload body engine methods (#14000)
* Combined v1/v2 payload body handling * prevent overflows when dealing with electra fixture --------- Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
This commit is contained in:
@@ -12,6 +12,7 @@ go_library(
|
||||
"log_processing.go",
|
||||
"metrics.go",
|
||||
"options.go",
|
||||
"payload_body.go",
|
||||
"prometheus.go",
|
||||
"rpc_connection.go",
|
||||
"service.go",
|
||||
@@ -86,6 +87,8 @@ go_test(
|
||||
"execution_chain_test.go",
|
||||
"init_test.go",
|
||||
"log_processing_test.go",
|
||||
"mock_test.go",
|
||||
"payload_body_test.go",
|
||||
"prometheus_test.go",
|
||||
"service_test.go",
|
||||
],
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package execution
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
@@ -34,12 +33,19 @@ var (
|
||||
supportedEngineEndpoints = []string{
|
||||
NewPayloadMethod,
|
||||
NewPayloadMethodV2,
|
||||
NewPayloadMethodV3,
|
||||
NewPayloadMethodV4,
|
||||
ForkchoiceUpdatedMethod,
|
||||
ForkchoiceUpdatedMethodV2,
|
||||
ForkchoiceUpdatedMethodV3,
|
||||
GetPayloadMethod,
|
||||
GetPayloadMethodV2,
|
||||
GetPayloadMethodV3,
|
||||
GetPayloadMethodV4,
|
||||
GetPayloadBodiesByHashV1,
|
||||
GetPayloadBodiesByRangeV1,
|
||||
GetPayloadBodiesByHashV2,
|
||||
GetPayloadBodiesByRangeV2,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -69,16 +75,22 @@ const (
|
||||
BlockByHashMethod = "eth_getBlockByHash"
|
||||
// BlockByNumberMethod request string for JSON-RPC.
|
||||
BlockByNumberMethod = "eth_getBlockByNumber"
|
||||
// GetPayloadBodiesByHashV1 v1 request string for JSON-RPC.
|
||||
// GetPayloadBodiesByHashV1 is the engine_getPayloadBodiesByHashX JSON-RPC method for pre-Electra payloads.
|
||||
GetPayloadBodiesByHashV1 = "engine_getPayloadBodiesByHashV1"
|
||||
// GetPayloadBodiesByRangeV1 v1 request string for JSON-RPC.
|
||||
// GetPayloadBodiesByHashV2 is the engine_getPayloadBodiesByHashX JSON-RPC method introduced by Electra.
|
||||
GetPayloadBodiesByHashV2 = "engine_getPayloadBodiesByHashV2"
|
||||
// GetPayloadBodiesByRangeV1 is the engine_getPayloadBodiesByRangeX JSON-RPC method for pre-Electra payloads.
|
||||
GetPayloadBodiesByRangeV1 = "engine_getPayloadBodiesByRangeV1"
|
||||
// GetPayloadBodiesByRangeV2 is the engine_getPayloadBodiesByRangeX JSON-RPC method introduced by Electra.
|
||||
GetPayloadBodiesByRangeV2 = "engine_getPayloadBodiesByRangeV2"
|
||||
// ExchangeCapabilities request string for JSON-RPC.
|
||||
ExchangeCapabilities = "engine_exchangeCapabilities"
|
||||
// Defines the seconds before timing out engine endpoints with non-block execution semantics.
|
||||
defaultEngineTimeout = time.Second
|
||||
)
|
||||
|
||||
var errInvalidPayloadBodyResponse = errors.New("engine api payload body response is invalid")
|
||||
|
||||
// ForkchoiceUpdatedResponse is the response kind received by the
|
||||
// engine_forkchoiceUpdatedV1 endpoint.
|
||||
type ForkchoiceUpdatedResponse struct {
|
||||
@@ -509,93 +521,19 @@ func (s *Service) HeaderByNumber(ctx context.Context, number *big.Int) (*types.H
|
||||
return hdr, err
|
||||
}
|
||||
|
||||
// GetPayloadBodiesByHash returns the relevant payload bodies for the provided block hash.
|
||||
func (s *Service) GetPayloadBodiesByHash(ctx context.Context, executionBlockHashes []common.Hash) ([]*pb.ExecutionPayloadBodyV1, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.GetPayloadBodiesByHashV1")
|
||||
defer span.End()
|
||||
|
||||
result := make([]*pb.ExecutionPayloadBodyV1, 0)
|
||||
// Exit early if there are no execution hashes.
|
||||
if len(executionBlockHashes) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
err := s.rpcClient.CallContext(ctx, &result, GetPayloadBodiesByHashV1, executionBlockHashes)
|
||||
if err != nil {
|
||||
return nil, handleRPCError(err)
|
||||
}
|
||||
if len(result) != len(executionBlockHashes) {
|
||||
return nil, fmt.Errorf("mismatch of payloads retrieved from the execution client: %d vs %d", len(result), len(executionBlockHashes))
|
||||
}
|
||||
for i, item := range result {
|
||||
if item == nil {
|
||||
result[i] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: make([][]byte, 0),
|
||||
Withdrawals: make([]*pb.Withdrawal, 0),
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetPayloadBodiesByRange returns the relevant payload bodies for the provided range.
|
||||
func (s *Service) GetPayloadBodiesByRange(ctx context.Context, start, count uint64) ([]*pb.ExecutionPayloadBodyV1, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.GetPayloadBodiesByRangeV1")
|
||||
defer span.End()
|
||||
|
||||
result := make([]*pb.ExecutionPayloadBodyV1, 0)
|
||||
err := s.rpcClient.CallContext(ctx, &result, GetPayloadBodiesByRangeV1, start, count)
|
||||
|
||||
for i, item := range result {
|
||||
if item == nil {
|
||||
result[i] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: make([][]byte, 0),
|
||||
Withdrawals: make([]*pb.Withdrawal, 0),
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, handleRPCError(err)
|
||||
}
|
||||
|
||||
// ReconstructFullBlock takes in a blinded beacon block and reconstructs
|
||||
// a beacon block with a full execution payload via the engine API.
|
||||
func (s *Service) ReconstructFullBlock(
|
||||
ctx context.Context, blindedBlock interfaces.ReadOnlySignedBeaconBlock,
|
||||
) (interfaces.SignedBeaconBlock, error) {
|
||||
if err := blocks.BeaconBlockIsNil(blindedBlock); err != nil {
|
||||
return nil, errors.Wrap(err, "cannot reconstruct bellatrix block from nil data")
|
||||
}
|
||||
if !blindedBlock.Block().IsBlinded() {
|
||||
return nil, errors.New("can only reconstruct block from blinded block format")
|
||||
}
|
||||
header, err := blindedBlock.Block().Body().Execution()
|
||||
reconstructed, err := s.ReconstructFullBellatrixBlockBatch(ctx, []interfaces.ReadOnlySignedBeaconBlock{blindedBlock})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if header.IsNil() {
|
||||
return nil, errors.New("execution payload header in blinded block was nil")
|
||||
if len(reconstructed) != 1 {
|
||||
return nil, errors.Errorf("could not retrieve the correct number of payload bodies: wanted 1 but got %d", len(reconstructed))
|
||||
}
|
||||
|
||||
// If the payload header has a block hash of 0x0, it means we are pre-merge and should
|
||||
// simply return the block with an empty execution payload.
|
||||
if bytes.Equal(header.BlockHash(), params.BeaconConfig().ZeroHash[:]) {
|
||||
payload, err := buildEmptyExecutionPayload(blindedBlock.Version())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return blocks.BuildSignedBeaconBlockFromExecutionPayload(blindedBlock, payload)
|
||||
}
|
||||
|
||||
executionBlockHash := common.BytesToHash(header.BlockHash())
|
||||
payload, err := s.retrievePayloadFromExecutionHash(ctx, executionBlockHash, header, blindedBlock.Version())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fullBlock, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(blindedBlock, payload.Proto())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reconstructedExecutionPayloadCount.Add(1)
|
||||
return fullBlock, nil
|
||||
return reconstructed[0], nil
|
||||
}
|
||||
|
||||
// ReconstructFullBellatrixBlockBatch takes in a batch of blinded beacon blocks and reconstructs
|
||||
@@ -603,114 +541,16 @@ func (s *Service) ReconstructFullBlock(
|
||||
func (s *Service) ReconstructFullBellatrixBlockBatch(
|
||||
ctx context.Context, blindedBlocks []interfaces.ReadOnlySignedBeaconBlock,
|
||||
) ([]interfaces.SignedBeaconBlock, error) {
|
||||
if len(blindedBlocks) == 0 {
|
||||
return []interfaces.SignedBeaconBlock{}, nil
|
||||
}
|
||||
var executionHashes []common.Hash
|
||||
var validExecPayloads []int
|
||||
var zeroExecPayloads []int
|
||||
for i, b := range blindedBlocks {
|
||||
if err := blocks.BeaconBlockIsNil(b); err != nil {
|
||||
return nil, errors.Wrap(err, "cannot reconstruct bellatrix block from nil data")
|
||||
}
|
||||
if !b.Block().IsBlinded() {
|
||||
return nil, errors.New("can only reconstruct block from blinded block format")
|
||||
}
|
||||
header, err := b.Block().Body().Execution()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if header.IsNil() {
|
||||
return nil, errors.New("execution payload header in blinded block was nil")
|
||||
}
|
||||
// Determine if the block is pre-merge or post-merge. Depending on the result,
|
||||
// we will ask the execution engine for the full payload.
|
||||
if bytes.Equal(header.BlockHash(), params.BeaconConfig().ZeroHash[:]) {
|
||||
zeroExecPayloads = append(zeroExecPayloads, i)
|
||||
} else {
|
||||
executionBlockHash := common.BytesToHash(header.BlockHash())
|
||||
validExecPayloads = append(validExecPayloads, i)
|
||||
executionHashes = append(executionHashes, executionBlockHash)
|
||||
}
|
||||
}
|
||||
fullBlocks, err := s.retrievePayloadsFromExecutionHashes(ctx, executionHashes, validExecPayloads, blindedBlocks)
|
||||
unb, err := reconstructBlindedBlockBatch(ctx, s.rpcClient, blindedBlocks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// For blocks that are pre-merge we simply reconstruct them via an empty
|
||||
// execution payload.
|
||||
for _, realIdx := range zeroExecPayloads {
|
||||
bblock := blindedBlocks[realIdx]
|
||||
payload, err := buildEmptyExecutionPayload(bblock.Version())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fullBlock, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(blindedBlocks[realIdx], payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fullBlocks[realIdx] = fullBlock
|
||||
}
|
||||
reconstructedExecutionPayloadCount.Add(float64(len(blindedBlocks)))
|
||||
return fullBlocks, nil
|
||||
}
|
||||
|
||||
func (s *Service) retrievePayloadFromExecutionHash(ctx context.Context, executionBlockHash common.Hash, header interfaces.ExecutionData, version int) (interfaces.ExecutionData, error) {
|
||||
pBodies, err := s.GetPayloadBodiesByHash(ctx, []common.Hash{executionBlockHash})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get payload body by hash %#x: %v", executionBlockHash, err)
|
||||
}
|
||||
if len(pBodies) != 1 {
|
||||
return nil, errors.Errorf("could not retrieve the correct number of payload bodies: wanted 1 but got %d", len(pBodies))
|
||||
}
|
||||
bdy := pBodies[0]
|
||||
return fullPayloadFromPayloadBody(header, bdy, version)
|
||||
}
|
||||
|
||||
// This method assumes that the provided execution hashes are all valid and part of the
|
||||
// canonical chain.
|
||||
func (s *Service) retrievePayloadsFromExecutionHashes(
|
||||
ctx context.Context,
|
||||
executionHashes []common.Hash,
|
||||
validExecPayloads []int,
|
||||
blindedBlocks []interfaces.ReadOnlySignedBeaconBlock) ([]interfaces.SignedBeaconBlock, error) {
|
||||
fullBlocks := make([]interfaces.SignedBeaconBlock, len(blindedBlocks))
|
||||
var payloadBodies []*pb.ExecutionPayloadBodyV1
|
||||
var err error
|
||||
|
||||
payloadBodies, err = s.GetPayloadBodiesByHash(ctx, executionHashes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not fetch payload bodies by hash %#x: %v", executionHashes, err)
|
||||
}
|
||||
|
||||
// For each valid payload, we reconstruct the full block from it with the
|
||||
// blinded block.
|
||||
for sliceIdx, realIdx := range validExecPayloads {
|
||||
var payload interfaces.ExecutionData
|
||||
bblock := blindedBlocks[realIdx]
|
||||
b := payloadBodies[sliceIdx]
|
||||
if b == nil {
|
||||
return nil, fmt.Errorf("received nil payload body for request by hash %#x", executionHashes[sliceIdx])
|
||||
}
|
||||
header, err := bblock.Block().Body().Execution()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
payload, err = fullPayloadFromPayloadBody(header, b, bblock.Version())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fullBlock, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(bblock, payload.Proto())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fullBlocks[realIdx] = fullBlock
|
||||
}
|
||||
return fullBlocks, nil
|
||||
reconstructedExecutionPayloadCount.Add(float64(len(unb)))
|
||||
return unb, nil
|
||||
}
|
||||
|
||||
func fullPayloadFromPayloadBody(
|
||||
header interfaces.ExecutionData, body *pb.ExecutionPayloadBodyV1, bVersion int,
|
||||
header interfaces.ExecutionData, body *pb.ExecutionPayloadBody, bVersion int,
|
||||
) (interfaces.ExecutionData, error) {
|
||||
if header.IsNil() || body == nil {
|
||||
return nil, errors.New("execution block and header cannot be nil")
|
||||
@@ -732,7 +572,7 @@ func fullPayloadFromPayloadBody(
|
||||
ExtraData: header.ExtraData(),
|
||||
BaseFeePerGas: header.BaseFeePerGas(),
|
||||
BlockHash: header.BlockHash(),
|
||||
Transactions: body.Transactions,
|
||||
Transactions: pb.RecastHexutilByteSlice(body.Transactions),
|
||||
})
|
||||
case version.Capella:
|
||||
return blocks.WrappedExecutionPayloadCapella(&pb.ExecutionPayloadCapella{
|
||||
@@ -749,7 +589,7 @@ func fullPayloadFromPayloadBody(
|
||||
ExtraData: header.ExtraData(),
|
||||
BaseFeePerGas: header.BaseFeePerGas(),
|
||||
BlockHash: header.BlockHash(),
|
||||
Transactions: body.Transactions,
|
||||
Transactions: pb.RecastHexutilByteSlice(body.Transactions),
|
||||
Withdrawals: body.Withdrawals,
|
||||
}, big.NewInt(0)) // We can't get the block value and don't care about the block value for this instance
|
||||
case version.Deneb:
|
||||
@@ -776,7 +616,7 @@ func fullPayloadFromPayloadBody(
|
||||
ExtraData: header.ExtraData(),
|
||||
BaseFeePerGas: header.BaseFeePerGas(),
|
||||
BlockHash: header.BlockHash(),
|
||||
Transactions: body.Transactions,
|
||||
Transactions: pb.RecastHexutilByteSlice(body.Transactions),
|
||||
Withdrawals: body.Withdrawals,
|
||||
ExcessBlobGas: ebg,
|
||||
BlobGasUsed: bgu,
|
||||
@@ -790,25 +630,35 @@ func fullPayloadFromPayloadBody(
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to extract BlobGasUsed attribute from execution payload header")
|
||||
}
|
||||
wr, err := pb.JsonWithdrawalRequestsToProto(body.WithdrawalRequests)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dr, err := pb.JsonDepositRequestsToProto(body.DepositRequests)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return blocks.WrappedExecutionPayloadElectra(
|
||||
&pb.ExecutionPayloadElectra{
|
||||
ParentHash: header.ParentHash(),
|
||||
FeeRecipient: header.FeeRecipient(),
|
||||
StateRoot: header.StateRoot(),
|
||||
ReceiptsRoot: header.ReceiptsRoot(),
|
||||
LogsBloom: header.LogsBloom(),
|
||||
PrevRandao: header.PrevRandao(),
|
||||
BlockNumber: header.BlockNumber(),
|
||||
GasLimit: header.GasLimit(),
|
||||
GasUsed: header.GasUsed(),
|
||||
Timestamp: header.Timestamp(),
|
||||
ExtraData: header.ExtraData(),
|
||||
BaseFeePerGas: header.BaseFeePerGas(),
|
||||
BlockHash: header.BlockHash(),
|
||||
Transactions: body.Transactions,
|
||||
Withdrawals: body.Withdrawals,
|
||||
ExcessBlobGas: ebg,
|
||||
BlobGasUsed: bgu,
|
||||
ParentHash: header.ParentHash(),
|
||||
FeeRecipient: header.FeeRecipient(),
|
||||
StateRoot: header.StateRoot(),
|
||||
ReceiptsRoot: header.ReceiptsRoot(),
|
||||
LogsBloom: header.LogsBloom(),
|
||||
PrevRandao: header.PrevRandao(),
|
||||
BlockNumber: header.BlockNumber(),
|
||||
GasLimit: header.GasLimit(),
|
||||
GasUsed: header.GasUsed(),
|
||||
Timestamp: header.Timestamp(),
|
||||
ExtraData: header.ExtraData(),
|
||||
BaseFeePerGas: header.BaseFeePerGas(),
|
||||
BlockHash: header.BlockHash(),
|
||||
Transactions: pb.RecastHexutilByteSlice(body.Transactions),
|
||||
Withdrawals: body.Withdrawals,
|
||||
ExcessBlobGas: ebg,
|
||||
BlobGasUsed: bgu,
|
||||
DepositReceipts: dr,
|
||||
WithdrawalRequests: wr,
|
||||
}, big.NewInt(0)) // We can't get the block value and don't care about the block value for this instance
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown execution block version for payload %d", bVersion)
|
||||
@@ -943,6 +793,22 @@ func buildEmptyExecutionPayload(v int) (proto.Message, error) {
|
||||
Transactions: make([][]byte, 0),
|
||||
Withdrawals: make([]*pb.Withdrawal, 0),
|
||||
}, nil
|
||||
case version.Electra:
|
||||
return &pb.ExecutionPayloadElectra{
|
||||
ParentHash: make([]byte, fieldparams.RootLength),
|
||||
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||
StateRoot: make([]byte, fieldparams.RootLength),
|
||||
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
|
||||
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||
ExtraData: make([]byte, 0),
|
||||
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
Transactions: make([][]byte, 0),
|
||||
Withdrawals: make([]*pb.Withdrawal, 0),
|
||||
WithdrawalRequests: make([]*pb.ExecutionLayerWithdrawalRequest, 0),
|
||||
DepositReceipts: make([]*pb.DepositReceipt, 0),
|
||||
}, nil
|
||||
default:
|
||||
return nil, errors.Wrapf(ErrUnsupportedVersion, "version=%s", version.String(v))
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/util"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
@@ -993,7 +994,7 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) {
|
||||
respJSON := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": []map[string]interface{}{jsonPayload, jsonPayload},
|
||||
"result": []map[string]interface{}{jsonPayload},
|
||||
}
|
||||
require.NoError(t, json.NewEncoder(w).Encode(respJSON))
|
||||
|
||||
@@ -1011,10 +1012,8 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) {
|
||||
blindedBlock.Block.Body.ExecutionPayloadHeader = header
|
||||
wrapped, err := blocks.NewSignedBeaconBlock(blindedBlock)
|
||||
require.NoError(t, err)
|
||||
copiedWrapped, err := wrapped.Copy()
|
||||
require.NoError(t, err)
|
||||
|
||||
reconstructed, err := service.ReconstructFullBellatrixBlockBatch(ctx, []interfaces.ReadOnlySignedBeaconBlock{wrappedEmpty, wrapped, copiedWrapped})
|
||||
reconstructed, err := service.ReconstructFullBellatrixBlockBatch(ctx, []interfaces.ReadOnlySignedBeaconBlock{wrappedEmpty, wrapped})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Make sure empty blocks are handled correctly
|
||||
@@ -1024,10 +1023,6 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) {
|
||||
got, err := reconstructed[1].Block().Body().Execution()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, payload, got.Proto())
|
||||
|
||||
got, err = reconstructed[2].Block().Body().Execution()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, payload, got.Proto())
|
||||
})
|
||||
t.Run("handles invalid response from EL", func(t *testing.T) {
|
||||
fix := fixtures()
|
||||
@@ -1094,7 +1089,7 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = service.ReconstructFullBellatrixBlockBatch(ctx, []interfaces.ReadOnlySignedBeaconBlock{wrappedEmpty, wrapped, copiedWrapped})
|
||||
require.ErrorContains(t, "mismatch of payloads retrieved from the execution client", err)
|
||||
require.ErrorIs(t, err, errInvalidPayloadBodyResponse)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1405,6 +1400,31 @@ func newTestIPCServer(t *testing.T) *rpc.Server {
|
||||
}
|
||||
|
||||
func fixtures() map[string]interface{} {
|
||||
s := fixturesStruct()
|
||||
return map[string]interface{}{
|
||||
"ExecutionBlock": s.ExecutionBlock,
|
||||
"ExecutionPayloadBody": s.ExecutionPayloadBody,
|
||||
"ExecutionPayload": s.ExecutionPayload,
|
||||
"ExecutionPayloadCapella": s.ExecutionPayloadCapella,
|
||||
"ExecutionPayloadDeneb": s.ExecutionPayloadDeneb,
|
||||
"ExecutionPayloadElectra": s.ExecutionPayloadElectra,
|
||||
"ExecutionPayloadCapellaWithValue": s.ExecutionPayloadWithValueCapella,
|
||||
"ExecutionPayloadDenebWithValue": s.ExecutionPayloadWithValueDeneb,
|
||||
"ExecutionPayloadElectraWithValue": s.ExecutionPayloadWithValueElectra,
|
||||
"ValidPayloadStatus": s.ValidPayloadStatus,
|
||||
"InvalidBlockHashStatus": s.InvalidBlockHashStatus,
|
||||
"AcceptedStatus": s.AcceptedStatus,
|
||||
"SyncingStatus": s.SyncingStatus,
|
||||
"InvalidStatus": s.InvalidStatus,
|
||||
"UnknownStatus": s.UnknownStatus,
|
||||
"ForkchoiceUpdatedResponse": s.ForkchoiceUpdatedResponse,
|
||||
"ForkchoiceUpdatedSyncingResponse": s.ForkchoiceUpdatedSyncingResponse,
|
||||
"ForkchoiceUpdatedAcceptedResponse": s.ForkchoiceUpdatedAcceptedResponse,
|
||||
"ForkchoiceUpdatedInvalidResponse": s.ForkchoiceUpdatedInvalidResponse,
|
||||
}
|
||||
}
|
||||
|
||||
func fixturesStruct() *payloadFixtures {
|
||||
foo := bytesutil.ToBytes32([]byte("foo"))
|
||||
bar := bytesutil.PadTo([]byte("bar"), 20)
|
||||
baz := bytesutil.PadTo([]byte("baz"), 256)
|
||||
@@ -1425,8 +1445,8 @@ func fixtures() map[string]interface{} {
|
||||
BlockHash: foo[:],
|
||||
Transactions: [][]byte{foo[:]},
|
||||
}
|
||||
executionPayloadBodyFixture := &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{foo[:]},
|
||||
executionPayloadBodyFixture := &pb.ExecutionPayloadBody{
|
||||
Transactions: []hexutil.Bytes{foo[:]},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
}
|
||||
executionPayloadFixtureCapella := &pb.ExecutionPayloadCapella{
|
||||
@@ -1446,7 +1466,7 @@ func fixtures() map[string]interface{} {
|
||||
Transactions: [][]byte{foo[:]},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
}
|
||||
executionPayloadFixtureDeneb := &pb.ExecutionPayloadDeneb{
|
||||
emptyExecutionPayloadDeneb := &pb.ExecutionPayloadDeneb{
|
||||
ParentHash: foo[:],
|
||||
FeeRecipient: bar,
|
||||
StateRoot: foo[:],
|
||||
@@ -1460,11 +1480,29 @@ func fixtures() map[string]interface{} {
|
||||
ExtraData: foo[:],
|
||||
BaseFeePerGas: bytesutil.PadTo(baseFeePerGas.Bytes(), fieldparams.RootLength),
|
||||
BlockHash: foo[:],
|
||||
Transactions: [][]byte{foo[:]},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
BlobGasUsed: 2,
|
||||
ExcessBlobGas: 3,
|
||||
}
|
||||
executionPayloadFixtureDeneb := &pb.ExecutionPayloadDeneb{
|
||||
ParentHash: emptyExecutionPayloadDeneb.ParentHash,
|
||||
FeeRecipient: emptyExecutionPayloadDeneb.FeeRecipient,
|
||||
StateRoot: emptyExecutionPayloadDeneb.StateRoot,
|
||||
ReceiptsRoot: emptyExecutionPayloadDeneb.ReceiptsRoot,
|
||||
LogsBloom: emptyExecutionPayloadDeneb.LogsBloom,
|
||||
PrevRandao: emptyExecutionPayloadDeneb.PrevRandao,
|
||||
BlockNumber: emptyExecutionPayloadDeneb.BlockNumber,
|
||||
GasLimit: emptyExecutionPayloadDeneb.GasLimit,
|
||||
GasUsed: emptyExecutionPayloadDeneb.GasUsed,
|
||||
Timestamp: emptyExecutionPayloadDeneb.Timestamp,
|
||||
ExtraData: emptyExecutionPayloadDeneb.ExtraData,
|
||||
BaseFeePerGas: emptyExecutionPayloadDeneb.BaseFeePerGas,
|
||||
BlockHash: emptyExecutionPayloadDeneb.BlockHash,
|
||||
BlobGasUsed: emptyExecutionPayloadDeneb.BlobGasUsed,
|
||||
ExcessBlobGas: emptyExecutionPayloadDeneb.ExcessBlobGas,
|
||||
// added on top of the empty payload
|
||||
Transactions: [][]byte{foo[:]},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
}
|
||||
withdrawalRequests := make([]pb.WithdrawalRequestV1, 3)
|
||||
for i := range withdrawalRequests {
|
||||
amount := hexutil.Uint64(i)
|
||||
@@ -1496,9 +1534,13 @@ func fixtures() map[string]interface{} {
|
||||
Index: &idx,
|
||||
}
|
||||
}
|
||||
outer := &pb.ExecutionPayloadElectraJSON{
|
||||
WithdrawalRequests: withdrawalRequests,
|
||||
DepositRequests: depositRequests,
|
||||
dr, err := pb.JsonDepositRequestsToProto(depositRequests)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
wr, err := pb.JsonWithdrawalRequestsToProto(withdrawalRequests)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
executionPayloadFixtureElectra := &pb.ExecutionPayloadElectra{
|
||||
ParentHash: foo[:],
|
||||
@@ -1518,8 +1560,8 @@ func fixtures() map[string]interface{} {
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
BlobGasUsed: 2,
|
||||
ExcessBlobGas: 3,
|
||||
DepositReceipts: outer.ElectraDepositReceipts(),
|
||||
WithdrawalRequests: outer.ElectraExecutionLayerWithdrawalRequests(),
|
||||
DepositReceipts: dr,
|
||||
WithdrawalRequests: wr,
|
||||
}
|
||||
hexUint := hexutil.Uint64(1)
|
||||
executionPayloadWithValueFixtureCapella := &pb.GetPayloadV2ResponseJson{
|
||||
@@ -1573,22 +1615,24 @@ func fixtures() map[string]interface{} {
|
||||
executionPayloadWithValueFixtureElectra := &pb.GetPayloadV4ResponseJson{
|
||||
ShouldOverrideBuilder: true,
|
||||
ExecutionPayload: &pb.ExecutionPayloadElectraJSON{
|
||||
ParentHash: &common.Hash{'a'},
|
||||
FeeRecipient: &common.Address{'b'},
|
||||
StateRoot: &common.Hash{'c'},
|
||||
ReceiptsRoot: &common.Hash{'d'},
|
||||
LogsBloom: &hexutil.Bytes{'e'},
|
||||
PrevRandao: &common.Hash{'f'},
|
||||
BaseFeePerGas: "0x123",
|
||||
BlockHash: &common.Hash{'g'},
|
||||
Transactions: []hexutil.Bytes{{'h'}},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
BlockNumber: &hexUint,
|
||||
GasLimit: &hexUint,
|
||||
GasUsed: &hexUint,
|
||||
Timestamp: &hexUint,
|
||||
BlobGasUsed: &bgu,
|
||||
ExcessBlobGas: &ebg,
|
||||
ParentHash: &common.Hash{'a'},
|
||||
FeeRecipient: &common.Address{'b'},
|
||||
StateRoot: &common.Hash{'c'},
|
||||
ReceiptsRoot: &common.Hash{'d'},
|
||||
LogsBloom: &hexutil.Bytes{'e'},
|
||||
PrevRandao: &common.Hash{'f'},
|
||||
BaseFeePerGas: "0x123",
|
||||
BlockHash: &common.Hash{'g'},
|
||||
Transactions: []hexutil.Bytes{{'h'}},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
BlockNumber: &hexUint,
|
||||
GasLimit: &hexUint,
|
||||
GasUsed: &hexUint,
|
||||
Timestamp: &hexUint,
|
||||
BlobGasUsed: &bgu,
|
||||
ExcessBlobGas: &ebg,
|
||||
DepositRequests: depositRequests,
|
||||
WithdrawalRequests: withdrawalRequests,
|
||||
},
|
||||
BlockValue: "0x11fffffffff",
|
||||
BlobsBundle: &pb.BlobBundleJSON{
|
||||
@@ -1681,27 +1725,52 @@ func fixtures() map[string]interface{} {
|
||||
Status: pb.PayloadStatus_UNKNOWN,
|
||||
LatestValidHash: foo[:],
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"ExecutionBlock": executionBlock,
|
||||
"ExecutionPayloadBody": executionPayloadBodyFixture,
|
||||
"ExecutionPayload": executionPayloadFixture,
|
||||
"ExecutionPayloadCapella": executionPayloadFixtureCapella,
|
||||
"ExecutionPayloadDeneb": executionPayloadFixtureDeneb,
|
||||
"ExecutionPayloadElectra": executionPayloadFixtureElectra,
|
||||
"ExecutionPayloadCapellaWithValue": executionPayloadWithValueFixtureCapella,
|
||||
"ExecutionPayloadDenebWithValue": executionPayloadWithValueFixtureDeneb,
|
||||
"ExecutionPayloadElectraWithValue": executionPayloadWithValueFixtureElectra,
|
||||
"ValidPayloadStatus": validStatus,
|
||||
"InvalidBlockHashStatus": inValidBlockHashStatus,
|
||||
"AcceptedStatus": acceptedStatus,
|
||||
"SyncingStatus": syncingStatus,
|
||||
"InvalidStatus": invalidStatus,
|
||||
"UnknownStatus": unknownStatus,
|
||||
"ForkchoiceUpdatedResponse": forkChoiceResp,
|
||||
"ForkchoiceUpdatedSyncingResponse": forkChoiceSyncingResp,
|
||||
"ForkchoiceUpdatedAcceptedResponse": forkChoiceAcceptedResp,
|
||||
"ForkchoiceUpdatedInvalidResponse": forkChoiceInvalidResp,
|
||||
return &payloadFixtures{
|
||||
ExecutionBlock: executionBlock,
|
||||
ExecutionPayloadBody: executionPayloadBodyFixture,
|
||||
ExecutionPayload: executionPayloadFixture,
|
||||
ExecutionPayloadCapella: executionPayloadFixtureCapella,
|
||||
ExecutionPayloadDeneb: executionPayloadFixtureDeneb,
|
||||
EmptyExecutionPayloadDeneb: emptyExecutionPayloadDeneb,
|
||||
ExecutionPayloadElectra: executionPayloadFixtureElectra,
|
||||
ExecutionPayloadWithValueCapella: executionPayloadWithValueFixtureCapella,
|
||||
ExecutionPayloadWithValueDeneb: executionPayloadWithValueFixtureDeneb,
|
||||
ExecutionPayloadWithValueElectra: executionPayloadWithValueFixtureElectra,
|
||||
ValidPayloadStatus: validStatus,
|
||||
InvalidBlockHashStatus: inValidBlockHashStatus,
|
||||
AcceptedStatus: acceptedStatus,
|
||||
SyncingStatus: syncingStatus,
|
||||
InvalidStatus: invalidStatus,
|
||||
UnknownStatus: unknownStatus,
|
||||
ForkchoiceUpdatedResponse: forkChoiceResp,
|
||||
ForkchoiceUpdatedSyncingResponse: forkChoiceSyncingResp,
|
||||
ForkchoiceUpdatedAcceptedResponse: forkChoiceAcceptedResp,
|
||||
ForkchoiceUpdatedInvalidResponse: forkChoiceInvalidResp,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type payloadFixtures struct {
|
||||
ExecutionBlock *pb.ExecutionBlock
|
||||
ExecutionPayloadBody *pb.ExecutionPayloadBody
|
||||
ExecutionPayload *pb.ExecutionPayload
|
||||
ExecutionPayloadCapella *pb.ExecutionPayloadCapella
|
||||
EmptyExecutionPayloadDeneb *pb.ExecutionPayloadDeneb
|
||||
ExecutionPayloadDeneb *pb.ExecutionPayloadDeneb
|
||||
ExecutionPayloadElectra *pb.ExecutionPayloadElectra
|
||||
ExecutionPayloadWithValueCapella *pb.GetPayloadV2ResponseJson
|
||||
ExecutionPayloadWithValueDeneb *pb.GetPayloadV3ResponseJson
|
||||
ExecutionPayloadWithValueElectra *pb.GetPayloadV4ResponseJson
|
||||
ValidPayloadStatus *pb.PayloadStatus
|
||||
InvalidBlockHashStatus *pb.PayloadStatus
|
||||
AcceptedStatus *pb.PayloadStatus
|
||||
SyncingStatus *pb.PayloadStatus
|
||||
InvalidStatus *pb.PayloadStatus
|
||||
UnknownStatus *pb.PayloadStatus
|
||||
ForkchoiceUpdatedResponse *ForkchoiceUpdatedResponse
|
||||
ForkchoiceUpdatedSyncingResponse *ForkchoiceUpdatedResponse
|
||||
ForkchoiceUpdatedAcceptedResponse *ForkchoiceUpdatedResponse
|
||||
ForkchoiceUpdatedInvalidResponse *ForkchoiceUpdatedResponse
|
||||
}
|
||||
|
||||
func TestHeaderByHash_NotFound(t *testing.T) {
|
||||
@@ -2084,507 +2153,35 @@ func newPayloadV4Setup(t *testing.T, status *pb.PayloadStatus, payload *pb.Execu
|
||||
return service
|
||||
}
|
||||
|
||||
func TestCapella_PayloadBodiesByHash(t *testing.T) {
|
||||
func TestReconstructBlindedBlockBatch(t *testing.T) {
|
||||
t.Run("empty response works", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 0)
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
cli, srv := newMockEngine(t)
|
||||
srv.registerDefault(func(*jsonrpcMessage, http.ResponseWriter, *http.Request) {
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{})
|
||||
t.Fatal("http request should not be made")
|
||||
})
|
||||
results, err := reconstructBlindedBlockBatch(ctx, cli, []interfaces.ReadOnlySignedBeaconBlock{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
t.Run("single element response null works", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 1)
|
||||
executionPayloadBodies[0] = nil
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
t.Run("expected error for nil response", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
slot, err := slots.EpochStart(params.BeaconConfig().DenebForkEpoch)
|
||||
require.NoError(t, err)
|
||||
blk, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, slot, 0)
|
||||
cli, srv := newMockEngine(t)
|
||||
srv.registerDefault(func(msg *jsonrpcMessage, w http.ResponseWriter, req *http.Request) {
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{nil}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
|
||||
blinded, err := blk.ToBlinded()
|
||||
require.NoError(t, err)
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
bRoot := [32]byte{}
|
||||
copy(bRoot[:], "hash")
|
||||
results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
t.Run("empty, null, full works", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 3)
|
||||
executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
}
|
||||
executionPayloadBodies[1] = nil
|
||||
executionPayloadBodies[2] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")},
|
||||
Withdrawals: []*pb.Withdrawal{{
|
||||
Index: 1,
|
||||
ValidatorIndex: 1,
|
||||
Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"),
|
||||
Amount: 1,
|
||||
}},
|
||||
}
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
bRoot := [32]byte{}
|
||||
copy(bRoot[:], "hash")
|
||||
results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot, bRoot, bRoot})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
t.Run("full works, single item", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 1)
|
||||
executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")},
|
||||
Withdrawals: []*pb.Withdrawal{{
|
||||
Index: 1,
|
||||
ValidatorIndex: 1,
|
||||
Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"),
|
||||
Amount: 1,
|
||||
}},
|
||||
}
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
bRoot := [32]byte{}
|
||||
copy(bRoot[:], "hash")
|
||||
results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
t.Run("full works, multiple items", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 2)
|
||||
executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")},
|
||||
Withdrawals: []*pb.Withdrawal{{
|
||||
Index: 1,
|
||||
ValidatorIndex: 1,
|
||||
Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"),
|
||||
Amount: 1,
|
||||
}},
|
||||
}
|
||||
executionPayloadBodies[1] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")},
|
||||
Withdrawals: []*pb.Withdrawal{{
|
||||
Index: 2,
|
||||
ValidatorIndex: 1,
|
||||
Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"),
|
||||
Amount: 1,
|
||||
}},
|
||||
}
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
bRoot := [32]byte{}
|
||||
copy(bRoot[:], "hash")
|
||||
results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot, bRoot})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
t.Run("returning empty, null, empty should work properly", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
// [A, B, C] but no B in the server means
|
||||
// we get [Abody, null, Cbody].
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 3)
|
||||
executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
}
|
||||
executionPayloadBodies[1] = nil
|
||||
executionPayloadBodies[2] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
}
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
bRoot := [32]byte{}
|
||||
copy(bRoot[:], "hash")
|
||||
results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot, bRoot, bRoot})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestCapella_PayloadBodiesByRange(t *testing.T) {
|
||||
t.Run("empty response works", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 0)
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
t.Run("single element response null works", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 1)
|
||||
executionPayloadBodies[0] = nil
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
t.Run("empty, null, full works", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 3)
|
||||
executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
}
|
||||
executionPayloadBodies[1] = nil
|
||||
executionPayloadBodies[2] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")},
|
||||
Withdrawals: []*pb.Withdrawal{{
|
||||
Index: 1,
|
||||
ValidatorIndex: 1,
|
||||
Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"),
|
||||
Amount: 1,
|
||||
}},
|
||||
}
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
t.Run("full works, single item", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 1)
|
||||
executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")},
|
||||
Withdrawals: []*pb.Withdrawal{{
|
||||
Index: 1,
|
||||
ValidatorIndex: 1,
|
||||
Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"),
|
||||
Amount: 1,
|
||||
}},
|
||||
}
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
t.Run("full works, multiple items", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 2)
|
||||
executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")},
|
||||
Withdrawals: []*pb.Withdrawal{{
|
||||
Index: 1,
|
||||
ValidatorIndex: 1,
|
||||
Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"),
|
||||
Amount: 1,
|
||||
}},
|
||||
}
|
||||
executionPayloadBodies[1] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")},
|
||||
Withdrawals: []*pb.Withdrawal{{
|
||||
Index: 2,
|
||||
ValidatorIndex: 1,
|
||||
Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"),
|
||||
Amount: 1,
|
||||
}},
|
||||
}
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
})
|
||||
t.Run("returning empty, null, empty should work properly", func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
// [A, B, C] but no B in the server means
|
||||
// we get [Abody, null, Cbody].
|
||||
executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 3)
|
||||
executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
}
|
||||
executionPayloadBodies[1] = nil
|
||||
executionPayloadBodies[2] = &pb.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{},
|
||||
Withdrawals: []*pb.Withdrawal{},
|
||||
}
|
||||
|
||||
resp := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": executionPayloadBodies,
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(resp)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
ctx := context.Background()
|
||||
|
||||
rpcClient, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &Service{}
|
||||
service.rpcClient = rpcClient
|
||||
|
||||
results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(results))
|
||||
|
||||
for _, item := range results {
|
||||
require.NotNil(t, item)
|
||||
}
|
||||
service.rpcClient = cli
|
||||
_, err = service.ReconstructFullBlock(ctx, blinded)
|
||||
require.ErrorIs(t, err, errNilPayloadBody)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
221
beacon-chain/execution/mock_test.go
Normal file
221
beacon-chain/execution/mock_test.go
Normal file
@@ -0,0 +1,221 @@
|
||||
package execution
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
pb "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
)
|
||||
|
||||
var mockHandlerDefaultName = "__default__"
|
||||
|
||||
type jsonError struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
type jsonrpcMessage struct {
|
||||
Version string `json:"jsonrpc,omitempty"`
|
||||
ID json.RawMessage `json:"id,omitempty"`
|
||||
Method string `json:"method,omitempty"`
|
||||
Params json.RawMessage `json:"params,omitempty"`
|
||||
Error *jsonError `json:"error,omitempty"`
|
||||
Result json.RawMessage `json:"result,omitempty"`
|
||||
}
|
||||
|
||||
type mockHandler func(*jsonrpcMessage, http.ResponseWriter, *http.Request)
|
||||
|
||||
type mockEngine struct {
|
||||
t *testing.T
|
||||
handlers map[string]mockHandler
|
||||
calls map[string][]*jsonrpcMessage
|
||||
}
|
||||
|
||||
func newMockEngine(t *testing.T) (*rpc.Client, *mockEngine) {
|
||||
s := &mockEngine{t: t, handlers: make(map[string]mockHandler), calls: make(map[string][]*jsonrpcMessage)}
|
||||
srv := httptest.NewServer(s)
|
||||
c, err := rpc.DialHTTP(srv.URL)
|
||||
require.NoError(t, err)
|
||||
return c, s
|
||||
}
|
||||
|
||||
func (s *mockEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
msg := &jsonrpcMessage{}
|
||||
defer func() {
|
||||
s.calls[msg.Method] = append(s.calls[msg.Method], msg)
|
||||
}()
|
||||
if err := json.NewDecoder(r.Body).Decode(msg); err != nil {
|
||||
http.Error(w, "failed to decode request: "+err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
defer func() {
|
||||
require.NoError(s.t, r.Body.Close())
|
||||
}()
|
||||
handler, ok := s.handlers[msg.Method]
|
||||
if !ok {
|
||||
// Fallback to default handler if it is registered.
|
||||
handler, ok = s.handlers[mockHandlerDefaultName]
|
||||
if !ok {
|
||||
s.t.Fatalf("mockEngine called with unexpected method %s", msg.Method)
|
||||
}
|
||||
}
|
||||
handler(msg, w, r)
|
||||
}
|
||||
|
||||
func (s *mockEngine) register(method string, handler mockHandler) {
|
||||
s.handlers[method] = handler
|
||||
}
|
||||
|
||||
func (s *mockEngine) registerDefault(handler mockHandler) {
|
||||
s.handlers[mockHandlerDefaultName] = handler
|
||||
}
|
||||
|
||||
func (s *mockEngine) callCount(method string) int {
|
||||
return len(s.calls[method])
|
||||
}
|
||||
|
||||
func mockParseUintList(t *testing.T, data json.RawMessage) []uint64 {
|
||||
var list []uint64
|
||||
if err := json.Unmarshal(data, &list); err != nil {
|
||||
t.Fatalf("failed to parse uint list: %v", err)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func mockParseHexByteList(t *testing.T, data json.RawMessage) []hexutil.Bytes {
|
||||
var list [][]hexutil.Bytes
|
||||
if err := json.Unmarshal(data, &list); err != nil {
|
||||
t.Fatalf("failed to parse hex byte list: %v", err)
|
||||
}
|
||||
require.Equal(t, 1, len(list))
|
||||
return list[0]
|
||||
}
|
||||
|
||||
func strToHexBytes(t *testing.T, s string) hexutil.Bytes {
|
||||
b := hexutil.Bytes{}
|
||||
require.NoError(t, b.UnmarshalText([]byte(s)))
|
||||
return b
|
||||
}
|
||||
|
||||
func mockWriteResult(t *testing.T, w http.ResponseWriter, req *jsonrpcMessage, result any) {
|
||||
marshaled, err := json.Marshal(result)
|
||||
require.NoError(t, err)
|
||||
req.Result = marshaled
|
||||
require.NoError(t, json.NewEncoder(w).Encode(req))
|
||||
}
|
||||
|
||||
func TestParseRequest(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cases := []struct {
|
||||
method string
|
||||
uintArgs []uint64
|
||||
byteArgs []hexutil.Bytes
|
||||
}{
|
||||
{
|
||||
method: GetPayloadBodiesByHashV1,
|
||||
byteArgs: []hexutil.Bytes{
|
||||
strToHexBytes(t, "0x656d707479000000000000000000000000000000000000000000000000000000"),
|
||||
strToHexBytes(t, "0x66756c6c00000000000000000000000000000000000000000000000000000000"),
|
||||
},
|
||||
},
|
||||
{
|
||||
method: GetPayloadBodiesByHashV2,
|
||||
byteArgs: []hexutil.Bytes{
|
||||
strToHexBytes(t, "0x656d707479000000000000000000000000000000000000000000000000000000"),
|
||||
strToHexBytes(t, "0x66756c6c00000000000000000000000000000000000000000000000000000000"),
|
||||
},
|
||||
},
|
||||
{
|
||||
method: GetPayloadBodiesByRangeV1,
|
||||
uintArgs: []uint64{0, 1},
|
||||
},
|
||||
{
|
||||
method: GetPayloadBodiesByRangeV2,
|
||||
uintArgs: []uint64{math.MaxUint64, 1},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.method, func(t *testing.T) {
|
||||
cli, srv := newMockEngine(t)
|
||||
srv.register(c.method, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, c.method, msg.Method)
|
||||
nr := uint64(len(c.byteArgs))
|
||||
if len(c.byteArgs) > 0 {
|
||||
require.DeepEqual(t, c.byteArgs, mockParseHexByteList(t, msg.Params))
|
||||
}
|
||||
if len(c.uintArgs) > 0 {
|
||||
rang := mockParseUintList(t, msg.Params)
|
||||
require.DeepEqual(t, c.uintArgs, rang)
|
||||
nr = rang[1]
|
||||
}
|
||||
mockWriteResult(t, w, msg, make([]*pb.ExecutionPayloadBody, nr))
|
||||
})
|
||||
|
||||
result := make([]*pb.ExecutionPayloadBody, 0)
|
||||
var args []interface{}
|
||||
if len(c.byteArgs) > 0 {
|
||||
args = []interface{}{c.byteArgs}
|
||||
}
|
||||
if len(c.uintArgs) > 0 {
|
||||
args = make([]interface{}, len(c.uintArgs))
|
||||
for i := range c.uintArgs {
|
||||
args[i] = c.uintArgs[i]
|
||||
}
|
||||
}
|
||||
require.NoError(t, cli.CallContext(ctx, &result, c.method, args...))
|
||||
if len(c.byteArgs) > 0 {
|
||||
require.Equal(t, len(c.byteArgs), len(result))
|
||||
}
|
||||
if len(c.uintArgs) > 0 {
|
||||
require.Equal(t, int(c.uintArgs[1]), len(result))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallCount(t *testing.T) {
|
||||
methods := []string{
|
||||
GetPayloadBodiesByHashV1,
|
||||
GetPayloadBodiesByHashV2,
|
||||
GetPayloadBodiesByRangeV1,
|
||||
GetPayloadBodiesByRangeV2,
|
||||
}
|
||||
cases := []struct {
|
||||
method string
|
||||
count int
|
||||
}{
|
||||
{method: GetPayloadBodiesByHashV1, count: 1},
|
||||
{method: GetPayloadBodiesByHashV1, count: 2},
|
||||
{method: GetPayloadBodiesByHashV2, count: 1},
|
||||
{method: GetPayloadBodiesByRangeV1, count: 1},
|
||||
{method: GetPayloadBodiesByRangeV1, count: 2},
|
||||
{method: GetPayloadBodiesByRangeV2, count: 1},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.method, func(t *testing.T) {
|
||||
cli, srv := newMockEngine(t)
|
||||
srv.register(c.method, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
mockWriteResult(t, w, msg, nil)
|
||||
})
|
||||
for i := 0; i < c.count; i++ {
|
||||
require.NoError(t, cli.CallContext(context.Background(), nil, c.method))
|
||||
}
|
||||
for _, m := range methods {
|
||||
if m == c.method {
|
||||
require.Equal(t, c.count, srv.callCount(m))
|
||||
} else {
|
||||
require.Equal(t, 0, srv.callCount(m))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
250
beacon-chain/execution/payload_body.go
Normal file
250
beacon-chain/execution/payload_body.go
Normal file
@@ -0,0 +1,250 @@
|
||||
package execution
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
pb "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
var errNilPayloadBody = errors.New("nil payload body for block")
|
||||
|
||||
type blockWithHeader struct {
|
||||
block interfaces.ReadOnlySignedBeaconBlock
|
||||
header interfaces.ExecutionData
|
||||
}
|
||||
|
||||
// reconstructionBatch is a map of block hashes to block numbers.
|
||||
type reconstructionBatch map[[32]byte]uint64
|
||||
|
||||
type blindedBlockReconstructor struct {
|
||||
orderedBlocks []*blockWithHeader
|
||||
bodies map[[32]byte]*pb.ExecutionPayloadBody
|
||||
batches map[string]reconstructionBatch
|
||||
}
|
||||
|
||||
func reconstructBlindedBlockBatch(ctx context.Context, client RPCClient, sbb []interfaces.ReadOnlySignedBeaconBlock) ([]interfaces.SignedBeaconBlock, error) {
|
||||
r, err := newBlindedBlockReconstructor(sbb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.requestBodies(ctx, client); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.unblinded()
|
||||
}
|
||||
|
||||
func newBlindedBlockReconstructor(sbb []interfaces.ReadOnlySignedBeaconBlock) (*blindedBlockReconstructor, error) {
|
||||
r := &blindedBlockReconstructor{
|
||||
orderedBlocks: make([]*blockWithHeader, 0, len(sbb)),
|
||||
bodies: make(map[[32]byte]*pb.ExecutionPayloadBody),
|
||||
}
|
||||
for i := range sbb {
|
||||
if err := r.addToBatch(sbb[i]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (r *blindedBlockReconstructor) addToBatch(b interfaces.ReadOnlySignedBeaconBlock) error {
|
||||
if err := blocks.BeaconBlockIsNil(b); err != nil {
|
||||
return errors.Wrap(err, "cannot reconstruct bellatrix block from nil data")
|
||||
}
|
||||
if !b.Block().IsBlinded() {
|
||||
return errors.New("can only reconstruct block from blinded block format")
|
||||
}
|
||||
header, err := b.Block().Body().Execution()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if header.IsNil() {
|
||||
return errors.New("execution payload header in blinded block was nil")
|
||||
}
|
||||
r.orderedBlocks = append(r.orderedBlocks, &blockWithHeader{block: b, header: header})
|
||||
blockHash := bytesutil.ToBytes32(header.BlockHash())
|
||||
if blockHash == params.BeaconConfig().ZeroHash {
|
||||
return nil
|
||||
}
|
||||
|
||||
method := payloadBodyMethodForBlock(b)
|
||||
if r.batches == nil {
|
||||
r.batches = make(map[string]reconstructionBatch)
|
||||
}
|
||||
if _, ok := r.batches[method]; !ok {
|
||||
r.batches[method] = make(reconstructionBatch)
|
||||
}
|
||||
r.batches[method][bytesutil.ToBytes32(header.BlockHash())] = header.BlockNumber()
|
||||
return nil
|
||||
}
|
||||
|
||||
func payloadBodyMethodForBlock(b interface{ Version() int }) string {
|
||||
if b.Version() > version.Deneb {
|
||||
return GetPayloadBodiesByHashV2
|
||||
}
|
||||
return GetPayloadBodiesByHashV1
|
||||
}
|
||||
|
||||
func (r *blindedBlockReconstructor) requestBodies(ctx context.Context, client RPCClient) error {
|
||||
for method := range r.batches {
|
||||
nilResults, err := r.requestBodiesByHash(ctx, client, method)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := r.handleNilResults(ctx, client, method, nilResults); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type hashBlockNumber struct {
|
||||
h [32]byte
|
||||
n uint64
|
||||
}
|
||||
|
||||
func (r *blindedBlockReconstructor) handleNilResults(ctx context.Context, client RPCClient, method string, nilResults [][32]byte) error {
|
||||
if len(nilResults) == 0 {
|
||||
return nil
|
||||
}
|
||||
hbns := make([]hashBlockNumber, len(nilResults))
|
||||
for i := range nilResults {
|
||||
h := nilResults[i]
|
||||
hbns[i] = hashBlockNumber{h: h, n: r.batches[method][h]}
|
||||
}
|
||||
reqs := computeRanges(hbns)
|
||||
for i := range reqs {
|
||||
if err := r.requestBodiesByRange(ctx, client, rangeMethodForHashMethod(method), reqs[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type byRangeReq struct {
|
||||
start uint64
|
||||
count uint64
|
||||
hbns []hashBlockNumber
|
||||
}
|
||||
|
||||
func computeRanges(hbns []hashBlockNumber) []byRangeReq {
|
||||
if len(hbns) == 0 {
|
||||
return nil
|
||||
}
|
||||
sort.Slice(hbns, func(i, j int) bool {
|
||||
return hbns[i].n < hbns[j].n
|
||||
})
|
||||
ranges := make([]byRangeReq, 0)
|
||||
start := hbns[0].n
|
||||
count := uint64(0)
|
||||
for i := 0; i < len(hbns); i++ {
|
||||
if hbns[i].n == start+count {
|
||||
count++
|
||||
continue
|
||||
}
|
||||
ranges = append(ranges, byRangeReq{start: start, count: count, hbns: hbns[uint64(i)-count : i]})
|
||||
start = hbns[i].n
|
||||
count = 1
|
||||
}
|
||||
ranges = append(ranges, byRangeReq{start: start, count: count, hbns: hbns[uint64(len(hbns))-count:]})
|
||||
return ranges
|
||||
}
|
||||
|
||||
func (r *blindedBlockReconstructor) requestBodiesByRange(ctx context.Context, client RPCClient, method string, req byRangeReq) error {
|
||||
result := make([]*pb.ExecutionPayloadBody, 0)
|
||||
if err := client.CallContext(ctx, &result, method, req.start, req.count); err != nil {
|
||||
return err
|
||||
}
|
||||
if uint64(len(result)) != req.count {
|
||||
return errors.Wrapf(errInvalidPayloadBodyResponse, "received %d payload bodies from %s with count=%d (start=%d)", len(result), method, req.count, req.start)
|
||||
}
|
||||
for i := range result {
|
||||
if result[i] == nil {
|
||||
return errors.Wrapf(errNilPayloadBody, "from %s, hash=%#x", method, req.hbns[i].h)
|
||||
}
|
||||
r.bodies[req.hbns[i].h] = result[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *blindedBlockReconstructor) requestBodiesByHash(ctx context.Context, client RPCClient, method string) ([][32]byte, error) {
|
||||
batch := r.batches[method]
|
||||
if len(batch) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
hashes := make([]common.Hash, 0, len(batch))
|
||||
for h := range batch {
|
||||
if h == params.BeaconConfig().ZeroHash {
|
||||
continue
|
||||
}
|
||||
hashes = append(hashes, h)
|
||||
}
|
||||
result := make([]*pb.ExecutionPayloadBody, 0)
|
||||
if err := client.CallContext(ctx, &result, method, hashes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(hashes) != len(result) {
|
||||
return nil, errors.Wrapf(errInvalidPayloadBodyResponse, "received %d payload bodies for %d requested hashes", len(result), len(hashes))
|
||||
}
|
||||
nilBodies := make([][32]byte, 0)
|
||||
for i := range result {
|
||||
if result[i] == nil {
|
||||
nilBodies = append(nilBodies, hashes[i])
|
||||
continue
|
||||
}
|
||||
r.bodies[hashes[i]] = result[i]
|
||||
}
|
||||
return nilBodies, nil
|
||||
}
|
||||
|
||||
func (r *blindedBlockReconstructor) payloadForHeader(header interfaces.ExecutionData, v int) (proto.Message, error) {
|
||||
bodyKey := bytesutil.ToBytes32(header.BlockHash())
|
||||
if bodyKey == params.BeaconConfig().ZeroHash {
|
||||
payload, err := buildEmptyExecutionPayload(v)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to reconstruct payload for body hash %#x", bodyKey)
|
||||
}
|
||||
return payload, nil
|
||||
}
|
||||
body, ok := r.bodies[bodyKey]
|
||||
if !ok {
|
||||
return nil, errors.Wrapf(errNilPayloadBody, "hash %#x", bodyKey)
|
||||
}
|
||||
ed, err := fullPayloadFromPayloadBody(header, body, v)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to reconstruct payload for body hash %#x", bodyKey)
|
||||
}
|
||||
return ed.Proto(), nil
|
||||
}
|
||||
|
||||
func (r *blindedBlockReconstructor) unblinded() ([]interfaces.SignedBeaconBlock, error) {
|
||||
unblinded := make([]interfaces.SignedBeaconBlock, len(r.orderedBlocks))
|
||||
for i := range r.orderedBlocks {
|
||||
blk, header := r.orderedBlocks[i].block, r.orderedBlocks[i].header
|
||||
payload, err := r.payloadForHeader(header, blk.Version())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
full, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(blk, payload)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to build full block from execution payload for block hash %#x", header.BlockHash())
|
||||
}
|
||||
unblinded[i] = full
|
||||
}
|
||||
return unblinded, nil
|
||||
}
|
||||
|
||||
func rangeMethodForHashMethod(method string) string {
|
||||
if method == GetPayloadBodiesByHashV2 {
|
||||
return GetPayloadBodiesByRangeV2
|
||||
}
|
||||
return GetPayloadBodiesByRangeV1
|
||||
}
|
||||
408
beacon-chain/execution/payload_body_test.go
Normal file
408
beacon-chain/execution/payload_body_test.go
Normal file
@@ -0,0 +1,408 @@
|
||||
package execution
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
pb "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/util"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
)
|
||||
|
||||
type versioner struct {
|
||||
version int
|
||||
}
|
||||
|
||||
func (v versioner) Version() int {
|
||||
return v.version
|
||||
}
|
||||
|
||||
func TestPayloadBodyMethodForBlock(t *testing.T) {
|
||||
cases := []struct {
|
||||
versions []int
|
||||
want string
|
||||
}{
|
||||
{
|
||||
versions: []int{version.Phase0, version.Altair, version.Bellatrix, version.Capella, version.Deneb},
|
||||
want: GetPayloadBodiesByHashV1,
|
||||
},
|
||||
{
|
||||
versions: []int{version.Electra},
|
||||
want: GetPayloadBodiesByHashV2,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
for _, v := range c.versions {
|
||||
t.Run(version.String(v), func(t *testing.T) {
|
||||
v := versioner{version: v}
|
||||
require.Equal(t, c.want, payloadBodyMethodForBlock(v))
|
||||
})
|
||||
}
|
||||
}
|
||||
t.Run("post-electra", func(t *testing.T) {
|
||||
require.Equal(t, GetPayloadBodiesByHashV2, payloadBodyMethodForBlock(versioner{version: version.Electra + 1}))
|
||||
})
|
||||
}
|
||||
|
||||
func payloadToBody(t *testing.T, ed interfaces.ExecutionData) *pb.ExecutionPayloadBody {
|
||||
body := &pb.ExecutionPayloadBody{}
|
||||
txs, err := ed.Transactions()
|
||||
require.NoError(t, err)
|
||||
wd, err := ed.Withdrawals()
|
||||
// Bellatrix does not have withdrawals and will return an error.
|
||||
if err == nil {
|
||||
body.Withdrawals = wd
|
||||
}
|
||||
for i := range txs {
|
||||
body.Transactions = append(body.Transactions, txs[i])
|
||||
}
|
||||
eed, isElectra := ed.(interfaces.ExecutionDataElectra)
|
||||
if isElectra {
|
||||
body.DepositRequests = pb.ProtoDepositRequestsToJson(eed.DepositReceipts())
|
||||
body.WithdrawalRequests = pb.ProtoWithdrawalRequestsToJson(eed.WithdrawalRequests())
|
||||
}
|
||||
return body
|
||||
}
|
||||
|
||||
type blindedBlockFixtures struct {
|
||||
denebBlock *fullAndBlinded
|
||||
emptyDenebBlock *fullAndBlinded
|
||||
afterSkipDeneb *fullAndBlinded
|
||||
electra *fullAndBlinded
|
||||
}
|
||||
|
||||
type fullAndBlinded struct {
|
||||
full interfaces.ReadOnlySignedBeaconBlock
|
||||
blinded *blockWithHeader
|
||||
}
|
||||
|
||||
func blindedBlockWithHeader(t *testing.T, b interfaces.ReadOnlySignedBeaconBlock) *fullAndBlinded {
|
||||
header, err := b.Block().Body().Execution()
|
||||
require.NoError(t, err)
|
||||
blinded, err := b.ToBlinded()
|
||||
require.NoError(t, err)
|
||||
return &fullAndBlinded{
|
||||
full: b,
|
||||
blinded: &blockWithHeader{
|
||||
block: blinded,
|
||||
header: header,
|
||||
}}
|
||||
}
|
||||
|
||||
func denebSlot(t *testing.T) primitives.Slot {
|
||||
s, err := slots.EpochStart(params.BeaconConfig().DenebForkEpoch)
|
||||
require.NoError(t, err)
|
||||
return s
|
||||
}
|
||||
|
||||
func electraSlot(t *testing.T) primitives.Slot {
|
||||
s, err := slots.EpochStart(params.BeaconConfig().ElectraForkEpoch)
|
||||
require.NoError(t, err)
|
||||
return s
|
||||
}
|
||||
|
||||
func testBlindedBlockFixtures(t *testing.T) *blindedBlockFixtures {
|
||||
pfx := fixturesStruct()
|
||||
fx := &blindedBlockFixtures{}
|
||||
full := pfx.ExecutionPayloadDeneb
|
||||
// this func overrides fixture blockhashes to ensure they are unique
|
||||
full.BlockHash = bytesutil.PadTo([]byte("full"), 32)
|
||||
denebBlock, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, denebSlot(t), 0, util.WithPayloadSetter(full))
|
||||
fx.denebBlock = blindedBlockWithHeader(t, denebBlock)
|
||||
|
||||
empty := pfx.EmptyExecutionPayloadDeneb
|
||||
empty.BlockHash = bytesutil.PadTo([]byte("empty"), 32)
|
||||
empty.BlockNumber = 2
|
||||
emptyDenebBlock, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, denebSlot(t)+1, 0, util.WithPayloadSetter(empty))
|
||||
fx.emptyDenebBlock = blindedBlockWithHeader(t, emptyDenebBlock)
|
||||
|
||||
afterSkip := fixturesStruct().ExecutionPayloadDeneb
|
||||
// this func overrides fixture blockhashes to ensure they are unique
|
||||
afterSkip.BlockHash = bytesutil.PadTo([]byte("afterSkip"), 32)
|
||||
afterSkip.BlockNumber = 4
|
||||
afterSkipBlock, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, denebSlot(t)+3, 0, util.WithPayloadSetter(afterSkip))
|
||||
fx.afterSkipDeneb = blindedBlockWithHeader(t, afterSkipBlock)
|
||||
|
||||
electra := fixturesStruct().ExecutionPayloadElectra
|
||||
electra.BlockHash = bytesutil.PadTo([]byte("electra"), 32)
|
||||
electra.BlockNumber = 5
|
||||
electraBlock, _ := util.GenerateTestElectraBlockWithSidecar(t, [32]byte{}, electraSlot(t), 0, util.WithElectraPayload(electra))
|
||||
fx.electra = blindedBlockWithHeader(t, electraBlock)
|
||||
return fx
|
||||
}
|
||||
|
||||
func TestPayloadBodiesViaUnblinder(t *testing.T) {
|
||||
defer util.HackElectraMaxuint(t)()
|
||||
fx := testBlindedBlockFixtures(t)
|
||||
t.Run("mix of non-empty and empty", func(t *testing.T) {
|
||||
cli, srv := newMockEngine(t)
|
||||
srv.register(GetPayloadBodiesByHashV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{
|
||||
payloadToBody(t, fx.denebBlock.blinded.header),
|
||||
payloadToBody(t, fx.emptyDenebBlock.blinded.header),
|
||||
}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
ctx := context.Background()
|
||||
|
||||
toUnblind := []interfaces.ReadOnlySignedBeaconBlock{
|
||||
fx.denebBlock.blinded.block,
|
||||
fx.emptyDenebBlock.blinded.block,
|
||||
}
|
||||
bbr, err := newBlindedBlockReconstructor(toUnblind)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, bbr.requestBodies(ctx, cli))
|
||||
|
||||
payload, err := bbr.payloadForHeader(fx.denebBlock.blinded.header, fx.denebBlock.blinded.block.Version())
|
||||
require.NoError(t, err)
|
||||
unblindFull, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(fx.denebBlock.blinded.block, payload)
|
||||
require.NoError(t, err)
|
||||
testAssertReconstructedEquivalent(t, fx.denebBlock.full, unblindFull)
|
||||
|
||||
emptyPayload, err := bbr.payloadForHeader(fx.emptyDenebBlock.blinded.header, fx.emptyDenebBlock.blinded.block.Version())
|
||||
require.NoError(t, err)
|
||||
unblindEmpty, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(fx.emptyDenebBlock.blinded.block, emptyPayload)
|
||||
require.NoError(t, err)
|
||||
testAssertReconstructedEquivalent(t, fx.emptyDenebBlock.full, unblindEmpty)
|
||||
})
|
||||
}
|
||||
|
||||
func TestFixtureEquivalence(t *testing.T) {
|
||||
defer util.HackElectraMaxuint(t)()
|
||||
fx := testBlindedBlockFixtures(t)
|
||||
t.Run("full and blinded block equivalence", func(t *testing.T) {
|
||||
testAssertReconstructedEquivalent(t, fx.denebBlock.blinded.block, fx.denebBlock.full)
|
||||
testAssertReconstructedEquivalent(t, fx.emptyDenebBlock.blinded.block, fx.emptyDenebBlock.full)
|
||||
})
|
||||
}
|
||||
|
||||
func testAssertReconstructedEquivalent(t *testing.T, b, ogb interfaces.ReadOnlySignedBeaconBlock) {
|
||||
bHtr, err := b.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
ogbHtr, err := ogb.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, bHtr, ogbHtr)
|
||||
}
|
||||
|
||||
func TestComputeRanges(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
hbns []hashBlockNumber
|
||||
want []byRangeReq
|
||||
}{
|
||||
{
|
||||
name: "3 contiguous, 1 not",
|
||||
hbns: []hashBlockNumber{
|
||||
{h: [32]byte{5}, n: 5},
|
||||
{h: [32]byte{3}, n: 3},
|
||||
{h: [32]byte{2}, n: 2},
|
||||
{h: [32]byte{1}, n: 1},
|
||||
},
|
||||
want: []byRangeReq{
|
||||
{start: 1, count: 3, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}, {h: [32]byte{2}, n: 2}, {h: [32]byte{3}, n: 3}}},
|
||||
{start: 5, count: 1, hbns: []hashBlockNumber{{h: [32]byte{5}, n: 5}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "1 element",
|
||||
hbns: []hashBlockNumber{
|
||||
{h: [32]byte{1}, n: 1},
|
||||
},
|
||||
want: []byRangeReq{
|
||||
{start: 1, count: 1, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "2 contiguous",
|
||||
hbns: []hashBlockNumber{
|
||||
{h: [32]byte{2}, n: 2},
|
||||
{h: [32]byte{1}, n: 1},
|
||||
},
|
||||
want: []byRangeReq{
|
||||
{start: 1, count: 2, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}, {h: [32]byte{2}, n: 2}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "2 non-contiguous",
|
||||
hbns: []hashBlockNumber{
|
||||
{h: [32]byte{3}, n: 3},
|
||||
{h: [32]byte{1}, n: 1},
|
||||
},
|
||||
want: []byRangeReq{
|
||||
{start: 1, count: 1, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}}},
|
||||
{start: 3, count: 1, hbns: []hashBlockNumber{{h: [32]byte{3}, n: 3}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "3 contiguous",
|
||||
hbns: []hashBlockNumber{
|
||||
{h: [32]byte{2}, n: 2},
|
||||
{h: [32]byte{1}, n: 1},
|
||||
{h: [32]byte{3}, n: 3},
|
||||
},
|
||||
want: []byRangeReq{
|
||||
{start: 1, count: 3, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}, {h: [32]byte{2}, n: 2}, {h: [32]byte{3}, n: 3}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "3 non-contiguous",
|
||||
hbns: []hashBlockNumber{
|
||||
{h: [32]byte{5}, n: 5},
|
||||
{h: [32]byte{3}, n: 3},
|
||||
{h: [32]byte{1}, n: 1},
|
||||
},
|
||||
want: []byRangeReq{
|
||||
{start: 1, count: 1, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}}},
|
||||
{start: 3, count: 1, hbns: []hashBlockNumber{{h: [32]byte{3}, n: 3}}},
|
||||
{start: 5, count: 1, hbns: []hashBlockNumber{{h: [32]byte{5}, n: 5}}},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
got := computeRanges(c.hbns)
|
||||
for i := range got {
|
||||
require.Equal(t, c.want[i].start, got[i].start)
|
||||
require.Equal(t, c.want[i].count, got[i].count)
|
||||
require.DeepEqual(t, c.want[i].hbns, got[i].hbns)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReconstructBlindedBlockBatchFallbackToRange(t *testing.T) {
|
||||
defer util.HackElectraMaxuint(t)()
|
||||
ctx := context.Background()
|
||||
t.Run("fallback fails", func(t *testing.T) {
|
||||
cli, srv := newMockEngine(t)
|
||||
fx := testBlindedBlockFixtures(t)
|
||||
srv.register(GetPayloadBodiesByHashV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{nil, nil}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
srv.register(GetPayloadBodiesByRangeV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{nil, nil}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
toUnblind := []interfaces.ReadOnlySignedBeaconBlock{
|
||||
fx.denebBlock.blinded.block,
|
||||
fx.emptyDenebBlock.blinded.block,
|
||||
}
|
||||
_, err := reconstructBlindedBlockBatch(ctx, cli, toUnblind)
|
||||
require.ErrorIs(t, err, errNilPayloadBody)
|
||||
require.Equal(t, 1, srv.callCount(GetPayloadBodiesByHashV1))
|
||||
require.Equal(t, 1, srv.callCount(GetPayloadBodiesByRangeV1))
|
||||
})
|
||||
t.Run("fallback succeeds", func(t *testing.T) {
|
||||
cli, srv := newMockEngine(t)
|
||||
fx := testBlindedBlockFixtures(t)
|
||||
srv.register(GetPayloadBodiesByHashV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{nil, nil}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
srv.register(GetPayloadBodiesByRangeV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{
|
||||
payloadToBody(t, fx.denebBlock.blinded.header),
|
||||
payloadToBody(t, fx.emptyDenebBlock.blinded.header),
|
||||
}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
unblind := []interfaces.ReadOnlySignedBeaconBlock{
|
||||
fx.denebBlock.blinded.block,
|
||||
fx.emptyDenebBlock.blinded.block,
|
||||
}
|
||||
_, err := reconstructBlindedBlockBatch(ctx, cli, unblind)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("separated by block number gap", func(t *testing.T) {
|
||||
cli, srv := newMockEngine(t)
|
||||
fx := testBlindedBlockFixtures(t)
|
||||
srv.register(GetPayloadBodiesByHashV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{nil, nil, nil}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
srv.register(GetPayloadBodiesByRangeV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
p := mockParseUintList(t, msg.Params)
|
||||
require.Equal(t, 2, len(p))
|
||||
start, count := p[0], p[1]
|
||||
// Return first 2 blocks by number, which are contiguous.
|
||||
if start == fx.denebBlock.blinded.header.BlockNumber() {
|
||||
require.Equal(t, uint64(2), count)
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{
|
||||
payloadToBody(t, fx.denebBlock.blinded.header),
|
||||
payloadToBody(t, fx.emptyDenebBlock.blinded.header),
|
||||
}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
return
|
||||
}
|
||||
// Assume it's the second request
|
||||
require.Equal(t, fx.afterSkipDeneb.blinded.header.BlockNumber(), start)
|
||||
require.Equal(t, uint64(1), count)
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{
|
||||
payloadToBody(t, fx.afterSkipDeneb.blinded.header),
|
||||
}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
// separate methods for the electra block
|
||||
srv.register(GetPayloadBodiesByHashV2, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{nil}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
srv.register(GetPayloadBodiesByRangeV2, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
p := mockParseUintList(t, msg.Params)
|
||||
require.Equal(t, 2, len(p))
|
||||
start, count := p[0], p[1]
|
||||
require.Equal(t, fx.electra.blinded.header.BlockNumber(), start)
|
||||
require.Equal(t, uint64(1), count)
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{
|
||||
payloadToBody(t, fx.electra.blinded.header),
|
||||
}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
blind := []interfaces.ReadOnlySignedBeaconBlock{
|
||||
fx.denebBlock.blinded.block,
|
||||
fx.emptyDenebBlock.blinded.block,
|
||||
fx.afterSkipDeneb.blinded.block,
|
||||
}
|
||||
unblind, err := reconstructBlindedBlockBatch(ctx, cli, blind)
|
||||
require.NoError(t, err)
|
||||
for i := range unblind {
|
||||
testAssertReconstructedEquivalent(t, blind[i], unblind[i])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestReconstructBlindedBlockBatchDenebAndElectra(t *testing.T) {
|
||||
defer util.HackElectraMaxuint(t)()
|
||||
t.Run("deneb and electra", func(t *testing.T) {
|
||||
cli, srv := newMockEngine(t)
|
||||
fx := testBlindedBlockFixtures(t)
|
||||
// The reconstructed should make separate calls for the deneb (v1) and electra (v2) blocks.
|
||||
srv.register(GetPayloadBodiesByHashV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{payloadToBody(t, fx.denebBlock.blinded.header)}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
srv.register(GetPayloadBodiesByHashV2, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) {
|
||||
executionPayloadBodies := []*pb.ExecutionPayloadBody{payloadToBody(t, fx.electra.blinded.header)}
|
||||
mockWriteResult(t, w, msg, executionPayloadBodies)
|
||||
})
|
||||
blinded := []interfaces.ReadOnlySignedBeaconBlock{
|
||||
fx.denebBlock.blinded.block,
|
||||
fx.electra.blinded.block,
|
||||
}
|
||||
unblinded, err := reconstructBlindedBlockBatch(context.Background(), cli, blinded)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(blinded), len(unblinded))
|
||||
for i := range unblinded {
|
||||
testAssertReconstructedEquivalent(t, blinded[i], unblinded[i])
|
||||
}
|
||||
})
|
||||
}
|
||||
329
proto/engine/v1/execution_engine.pb.go
generated
329
proto/engine/v1/execution_engine.pb.go
generated
@@ -78,7 +78,7 @@ func (x PayloadStatus_Status) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use PayloadStatus_Status.Descriptor instead.
|
||||
func (PayloadStatus_Status) EnumDescriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{15, 0}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{14, 0}
|
||||
}
|
||||
|
||||
type ExecutionPayload struct {
|
||||
@@ -232,61 +232,6 @@ func (x *ExecutionPayload) GetTransactions() [][]byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExecutionPayloadBodyV1 struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Transactions [][]byte `protobuf:"bytes,1,rep,name=transactions,proto3" json:"transactions,omitempty"`
|
||||
Withdrawals []*Withdrawal `protobuf:"bytes,2,rep,name=withdrawals,proto3" json:"withdrawals,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadBodyV1) Reset() {
|
||||
*x = ExecutionPayloadBodyV1{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadBodyV1) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExecutionPayloadBodyV1) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadBodyV1) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExecutionPayloadBodyV1.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadBodyV1) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadBodyV1) GetTransactions() [][]byte {
|
||||
if x != nil {
|
||||
return x.Transactions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadBodyV1) GetWithdrawals() []*Withdrawal {
|
||||
if x != nil {
|
||||
return x.Withdrawals
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExecutionPayloadCapella struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -312,7 +257,7 @@ type ExecutionPayloadCapella struct {
|
||||
func (x *ExecutionPayloadCapella) Reset() {
|
||||
*x = ExecutionPayloadCapella{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[2]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -325,7 +270,7 @@ func (x *ExecutionPayloadCapella) String() string {
|
||||
func (*ExecutionPayloadCapella) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadCapella) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[2]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -338,7 +283,7 @@ func (x *ExecutionPayloadCapella) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecutionPayloadCapella.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadCapella) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{2}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadCapella) GetParentHash() []byte {
|
||||
@@ -473,7 +418,7 @@ type ExecutionPayloadDeneb struct {
|
||||
func (x *ExecutionPayloadDeneb) Reset() {
|
||||
*x = ExecutionPayloadDeneb{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[3]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -486,7 +431,7 @@ func (x *ExecutionPayloadDeneb) String() string {
|
||||
func (*ExecutionPayloadDeneb) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadDeneb) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[3]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -499,7 +444,7 @@ func (x *ExecutionPayloadDeneb) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecutionPayloadDeneb.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadDeneb) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{3}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadDeneb) GetParentHash() []byte {
|
||||
@@ -650,7 +595,7 @@ type ExecutionPayloadElectra struct {
|
||||
func (x *ExecutionPayloadElectra) Reset() {
|
||||
*x = ExecutionPayloadElectra{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[4]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -663,7 +608,7 @@ func (x *ExecutionPayloadElectra) String() string {
|
||||
func (*ExecutionPayloadElectra) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadElectra) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[4]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -676,7 +621,7 @@ func (x *ExecutionPayloadElectra) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecutionPayloadElectra.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadElectra) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{4}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadElectra) GetParentHash() []byte {
|
||||
@@ -826,7 +771,7 @@ type ExecutionPayloadElectraWithValueAndBlobsBundle struct {
|
||||
func (x *ExecutionPayloadElectraWithValueAndBlobsBundle) Reset() {
|
||||
*x = ExecutionPayloadElectraWithValueAndBlobsBundle{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[5]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -839,7 +784,7 @@ func (x *ExecutionPayloadElectraWithValueAndBlobsBundle) String() string {
|
||||
func (*ExecutionPayloadElectraWithValueAndBlobsBundle) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadElectraWithValueAndBlobsBundle) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[5]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -852,7 +797,7 @@ func (x *ExecutionPayloadElectraWithValueAndBlobsBundle) ProtoReflect() protoref
|
||||
|
||||
// Deprecated: Use ExecutionPayloadElectraWithValueAndBlobsBundle.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadElectraWithValueAndBlobsBundle) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{5}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadElectraWithValueAndBlobsBundle) GetPayload() *ExecutionPayloadElectra {
|
||||
@@ -895,7 +840,7 @@ type ExecutionPayloadCapellaWithValue struct {
|
||||
func (x *ExecutionPayloadCapellaWithValue) Reset() {
|
||||
*x = ExecutionPayloadCapellaWithValue{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[6]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -908,7 +853,7 @@ func (x *ExecutionPayloadCapellaWithValue) String() string {
|
||||
func (*ExecutionPayloadCapellaWithValue) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadCapellaWithValue) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[6]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -921,7 +866,7 @@ func (x *ExecutionPayloadCapellaWithValue) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecutionPayloadCapellaWithValue.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadCapellaWithValue) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{6}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadCapellaWithValue) GetPayload() *ExecutionPayloadCapella {
|
||||
@@ -952,7 +897,7 @@ type ExecutionPayloadDenebWithValueAndBlobsBundle struct {
|
||||
func (x *ExecutionPayloadDenebWithValueAndBlobsBundle) Reset() {
|
||||
*x = ExecutionPayloadDenebWithValueAndBlobsBundle{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[7]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -965,7 +910,7 @@ func (x *ExecutionPayloadDenebWithValueAndBlobsBundle) String() string {
|
||||
func (*ExecutionPayloadDenebWithValueAndBlobsBundle) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadDenebWithValueAndBlobsBundle) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[7]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -978,7 +923,7 @@ func (x *ExecutionPayloadDenebWithValueAndBlobsBundle) ProtoReflect() protorefle
|
||||
|
||||
// Deprecated: Use ExecutionPayloadDenebWithValueAndBlobsBundle.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadDenebWithValueAndBlobsBundle) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{7}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadDenebWithValueAndBlobsBundle) GetPayload() *ExecutionPayloadDeneb {
|
||||
@@ -1033,7 +978,7 @@ type ExecutionPayloadHeader struct {
|
||||
func (x *ExecutionPayloadHeader) Reset() {
|
||||
*x = ExecutionPayloadHeader{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[8]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1046,7 +991,7 @@ func (x *ExecutionPayloadHeader) String() string {
|
||||
func (*ExecutionPayloadHeader) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadHeader) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[8]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1059,7 +1004,7 @@ func (x *ExecutionPayloadHeader) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecutionPayloadHeader.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadHeader) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{8}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadHeader) GetParentHash() []byte {
|
||||
@@ -1185,7 +1130,7 @@ type ExecutionPayloadHeaderCapella struct {
|
||||
func (x *ExecutionPayloadHeaderCapella) Reset() {
|
||||
*x = ExecutionPayloadHeaderCapella{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[9]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1198,7 +1143,7 @@ func (x *ExecutionPayloadHeaderCapella) String() string {
|
||||
func (*ExecutionPayloadHeaderCapella) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadHeaderCapella) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[9]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1211,7 +1156,7 @@ func (x *ExecutionPayloadHeaderCapella) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecutionPayloadHeaderCapella.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadHeaderCapella) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{9}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadHeaderCapella) GetParentHash() []byte {
|
||||
@@ -1346,7 +1291,7 @@ type ExecutionPayloadHeaderDeneb struct {
|
||||
func (x *ExecutionPayloadHeaderDeneb) Reset() {
|
||||
*x = ExecutionPayloadHeaderDeneb{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[10]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1359,7 +1304,7 @@ func (x *ExecutionPayloadHeaderDeneb) String() string {
|
||||
func (*ExecutionPayloadHeaderDeneb) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadHeaderDeneb) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[10]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1372,7 +1317,7 @@ func (x *ExecutionPayloadHeaderDeneb) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecutionPayloadHeaderDeneb.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadHeaderDeneb) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{10}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadHeaderDeneb) GetParentHash() []byte {
|
||||
@@ -1523,7 +1468,7 @@ type ExecutionPayloadHeaderElectra struct {
|
||||
func (x *ExecutionPayloadHeaderElectra) Reset() {
|
||||
*x = ExecutionPayloadHeaderElectra{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[11]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1536,7 +1481,7 @@ func (x *ExecutionPayloadHeaderElectra) String() string {
|
||||
func (*ExecutionPayloadHeaderElectra) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionPayloadHeaderElectra) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[11]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1549,7 +1494,7 @@ func (x *ExecutionPayloadHeaderElectra) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecutionPayloadHeaderElectra.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionPayloadHeaderElectra) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{11}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *ExecutionPayloadHeaderElectra) GetParentHash() []byte {
|
||||
@@ -1698,7 +1643,7 @@ type PayloadAttributes struct {
|
||||
func (x *PayloadAttributes) Reset() {
|
||||
*x = PayloadAttributes{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[12]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1711,7 +1656,7 @@ func (x *PayloadAttributes) String() string {
|
||||
func (*PayloadAttributes) ProtoMessage() {}
|
||||
|
||||
func (x *PayloadAttributes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[12]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[11]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1724,7 +1669,7 @@ func (x *PayloadAttributes) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use PayloadAttributes.ProtoReflect.Descriptor instead.
|
||||
func (*PayloadAttributes) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{12}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
func (x *PayloadAttributes) GetTimestamp() uint64 {
|
||||
@@ -1762,7 +1707,7 @@ type PayloadAttributesV2 struct {
|
||||
func (x *PayloadAttributesV2) Reset() {
|
||||
*x = PayloadAttributesV2{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[13]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1775,7 +1720,7 @@ func (x *PayloadAttributesV2) String() string {
|
||||
func (*PayloadAttributesV2) ProtoMessage() {}
|
||||
|
||||
func (x *PayloadAttributesV2) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[13]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[12]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1788,7 +1733,7 @@ func (x *PayloadAttributesV2) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use PayloadAttributesV2.ProtoReflect.Descriptor instead.
|
||||
func (*PayloadAttributesV2) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{13}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{12}
|
||||
}
|
||||
|
||||
func (x *PayloadAttributesV2) GetTimestamp() uint64 {
|
||||
@@ -1834,7 +1779,7 @@ type PayloadAttributesV3 struct {
|
||||
func (x *PayloadAttributesV3) Reset() {
|
||||
*x = PayloadAttributesV3{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[14]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[13]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1847,7 +1792,7 @@ func (x *PayloadAttributesV3) String() string {
|
||||
func (*PayloadAttributesV3) ProtoMessage() {}
|
||||
|
||||
func (x *PayloadAttributesV3) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[14]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[13]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1860,7 +1805,7 @@ func (x *PayloadAttributesV3) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use PayloadAttributesV3.ProtoReflect.Descriptor instead.
|
||||
func (*PayloadAttributesV3) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{14}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{13}
|
||||
}
|
||||
|
||||
func (x *PayloadAttributesV3) GetTimestamp() uint64 {
|
||||
@@ -1911,7 +1856,7 @@ type PayloadStatus struct {
|
||||
func (x *PayloadStatus) Reset() {
|
||||
*x = PayloadStatus{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[14]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1924,7 +1869,7 @@ func (x *PayloadStatus) String() string {
|
||||
func (*PayloadStatus) ProtoMessage() {}
|
||||
|
||||
func (x *PayloadStatus) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[14]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -1937,7 +1882,7 @@ func (x *PayloadStatus) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use PayloadStatus.ProtoReflect.Descriptor instead.
|
||||
func (*PayloadStatus) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{15}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{14}
|
||||
}
|
||||
|
||||
func (x *PayloadStatus) GetStatus() PayloadStatus_Status {
|
||||
@@ -1974,7 +1919,7 @@ type ForkchoiceState struct {
|
||||
func (x *ForkchoiceState) Reset() {
|
||||
*x = ForkchoiceState{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -1987,7 +1932,7 @@ func (x *ForkchoiceState) String() string {
|
||||
func (*ForkchoiceState) ProtoMessage() {}
|
||||
|
||||
func (x *ForkchoiceState) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2000,7 +1945,7 @@ func (x *ForkchoiceState) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ForkchoiceState.ProtoReflect.Descriptor instead.
|
||||
func (*ForkchoiceState) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{16}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{15}
|
||||
}
|
||||
|
||||
func (x *ForkchoiceState) GetHeadBlockHash() []byte {
|
||||
@@ -2038,7 +1983,7 @@ type Withdrawal struct {
|
||||
func (x *Withdrawal) Reset() {
|
||||
*x = Withdrawal{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2051,7 +1996,7 @@ func (x *Withdrawal) String() string {
|
||||
func (*Withdrawal) ProtoMessage() {}
|
||||
|
||||
func (x *Withdrawal) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2064,7 +2009,7 @@ func (x *Withdrawal) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Withdrawal.ProtoReflect.Descriptor instead.
|
||||
func (*Withdrawal) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{17}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{16}
|
||||
}
|
||||
|
||||
func (x *Withdrawal) GetIndex() uint64 {
|
||||
@@ -2108,7 +2053,7 @@ type BlobsBundle struct {
|
||||
func (x *BlobsBundle) Reset() {
|
||||
*x = BlobsBundle{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2121,7 +2066,7 @@ func (x *BlobsBundle) String() string {
|
||||
func (*BlobsBundle) ProtoMessage() {}
|
||||
|
||||
func (x *BlobsBundle) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2134,7 +2079,7 @@ func (x *BlobsBundle) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use BlobsBundle.ProtoReflect.Descriptor instead.
|
||||
func (*BlobsBundle) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{18}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{17}
|
||||
}
|
||||
|
||||
func (x *BlobsBundle) GetKzgCommitments() [][]byte {
|
||||
@@ -2169,7 +2114,7 @@ type Blob struct {
|
||||
func (x *Blob) Reset() {
|
||||
*x = Blob{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[19]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2182,7 +2127,7 @@ func (x *Blob) String() string {
|
||||
func (*Blob) ProtoMessage() {}
|
||||
|
||||
func (x *Blob) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[19]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2195,7 +2140,7 @@ func (x *Blob) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Blob.ProtoReflect.Descriptor instead.
|
||||
func (*Blob) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{19}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{18}
|
||||
}
|
||||
|
||||
func (x *Blob) GetData() []byte {
|
||||
@@ -2216,7 +2161,7 @@ type ExchangeCapabilities struct {
|
||||
func (x *ExchangeCapabilities) Reset() {
|
||||
*x = ExchangeCapabilities{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[20]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[19]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2229,7 +2174,7 @@ func (x *ExchangeCapabilities) String() string {
|
||||
func (*ExchangeCapabilities) ProtoMessage() {}
|
||||
|
||||
func (x *ExchangeCapabilities) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[20]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[19]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2242,7 +2187,7 @@ func (x *ExchangeCapabilities) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExchangeCapabilities.ProtoReflect.Descriptor instead.
|
||||
func (*ExchangeCapabilities) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{20}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{19}
|
||||
}
|
||||
|
||||
func (x *ExchangeCapabilities) GetSupportedMethods() []string {
|
||||
@@ -2265,7 +2210,7 @@ type ExecutionLayerWithdrawalRequest struct {
|
||||
func (x *ExecutionLayerWithdrawalRequest) Reset() {
|
||||
*x = ExecutionLayerWithdrawalRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[21]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[20]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2278,7 +2223,7 @@ func (x *ExecutionLayerWithdrawalRequest) String() string {
|
||||
func (*ExecutionLayerWithdrawalRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionLayerWithdrawalRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[21]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[20]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2291,7 +2236,7 @@ func (x *ExecutionLayerWithdrawalRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecutionLayerWithdrawalRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionLayerWithdrawalRequest) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{21}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{20}
|
||||
}
|
||||
|
||||
func (x *ExecutionLayerWithdrawalRequest) GetSourceAddress() []byte {
|
||||
@@ -2330,7 +2275,7 @@ type DepositReceipt struct {
|
||||
func (x *DepositReceipt) Reset() {
|
||||
*x = DepositReceipt{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[22]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[21]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -2343,7 +2288,7 @@ func (x *DepositReceipt) String() string {
|
||||
func (*DepositReceipt) ProtoMessage() {}
|
||||
|
||||
func (x *DepositReceipt) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[22]
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[21]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -2356,7 +2301,7 @@ func (x *DepositReceipt) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use DepositReceipt.ProtoReflect.Descriptor instead.
|
||||
func (*DepositReceipt) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{22}
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{21}
|
||||
}
|
||||
|
||||
func (x *DepositReceipt) GetPubkey() []byte {
|
||||
@@ -2439,15 +2384,7 @@ var file_proto_engine_v1_execution_engine_proto_rawDesc = []byte{
|
||||
0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x1d, 0x8a, 0xb5, 0x18, 0x03, 0x3f, 0x2c, 0x3f,
|
||||
0x92, 0xb5, 0x18, 0x12, 0x31, 0x30, 0x34, 0x38, 0x35, 0x37, 0x36, 0x2c, 0x31, 0x30, 0x37, 0x33,
|
||||
0x37, 0x34, 0x31, 0x38, 0x32, 0x34, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7e, 0x0a, 0x16, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x64, 0x79, 0x56, 0x31, 0x12, 0x22,
|
||||
0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x12, 0x40, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c,
|
||||
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||
0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x74,
|
||||
0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61,
|
||||
0x77, 0x61, 0x6c, 0x73, 0x22, 0x99, 0x05, 0x0a, 0x17, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x22, 0x99, 0x05, 0x0a, 0x17, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61,
|
||||
0x12, 0x27, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0a, 0x70,
|
||||
@@ -2958,53 +2895,51 @@ func file_proto_engine_v1_execution_engine_proto_rawDescGZIP() []byte {
|
||||
}
|
||||
|
||||
var file_proto_engine_v1_execution_engine_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_proto_engine_v1_execution_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
|
||||
var file_proto_engine_v1_execution_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 22)
|
||||
var file_proto_engine_v1_execution_engine_proto_goTypes = []interface{}{
|
||||
(PayloadStatus_Status)(0), // 0: ethereum.engine.v1.PayloadStatus.Status
|
||||
(*ExecutionPayload)(nil), // 1: ethereum.engine.v1.ExecutionPayload
|
||||
(*ExecutionPayloadBodyV1)(nil), // 2: ethereum.engine.v1.ExecutionPayloadBodyV1
|
||||
(*ExecutionPayloadCapella)(nil), // 3: ethereum.engine.v1.ExecutionPayloadCapella
|
||||
(*ExecutionPayloadDeneb)(nil), // 4: ethereum.engine.v1.ExecutionPayloadDeneb
|
||||
(*ExecutionPayloadElectra)(nil), // 5: ethereum.engine.v1.ExecutionPayloadElectra
|
||||
(*ExecutionPayloadElectraWithValueAndBlobsBundle)(nil), // 6: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle
|
||||
(*ExecutionPayloadCapellaWithValue)(nil), // 7: ethereum.engine.v1.ExecutionPayloadCapellaWithValue
|
||||
(*ExecutionPayloadDenebWithValueAndBlobsBundle)(nil), // 8: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle
|
||||
(*ExecutionPayloadHeader)(nil), // 9: ethereum.engine.v1.ExecutionPayloadHeader
|
||||
(*ExecutionPayloadHeaderCapella)(nil), // 10: ethereum.engine.v1.ExecutionPayloadHeaderCapella
|
||||
(*ExecutionPayloadHeaderDeneb)(nil), // 11: ethereum.engine.v1.ExecutionPayloadHeaderDeneb
|
||||
(*ExecutionPayloadHeaderElectra)(nil), // 12: ethereum.engine.v1.ExecutionPayloadHeaderElectra
|
||||
(*PayloadAttributes)(nil), // 13: ethereum.engine.v1.PayloadAttributes
|
||||
(*PayloadAttributesV2)(nil), // 14: ethereum.engine.v1.PayloadAttributesV2
|
||||
(*PayloadAttributesV3)(nil), // 15: ethereum.engine.v1.PayloadAttributesV3
|
||||
(*PayloadStatus)(nil), // 16: ethereum.engine.v1.PayloadStatus
|
||||
(*ForkchoiceState)(nil), // 17: ethereum.engine.v1.ForkchoiceState
|
||||
(*Withdrawal)(nil), // 18: ethereum.engine.v1.Withdrawal
|
||||
(*BlobsBundle)(nil), // 19: ethereum.engine.v1.BlobsBundle
|
||||
(*Blob)(nil), // 20: ethereum.engine.v1.Blob
|
||||
(*ExchangeCapabilities)(nil), // 21: ethereum.engine.v1.ExchangeCapabilities
|
||||
(*ExecutionLayerWithdrawalRequest)(nil), // 22: ethereum.engine.v1.ExecutionLayerWithdrawalRequest
|
||||
(*DepositReceipt)(nil), // 23: ethereum.engine.v1.DepositReceipt
|
||||
(*ExecutionPayloadCapella)(nil), // 2: ethereum.engine.v1.ExecutionPayloadCapella
|
||||
(*ExecutionPayloadDeneb)(nil), // 3: ethereum.engine.v1.ExecutionPayloadDeneb
|
||||
(*ExecutionPayloadElectra)(nil), // 4: ethereum.engine.v1.ExecutionPayloadElectra
|
||||
(*ExecutionPayloadElectraWithValueAndBlobsBundle)(nil), // 5: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle
|
||||
(*ExecutionPayloadCapellaWithValue)(nil), // 6: ethereum.engine.v1.ExecutionPayloadCapellaWithValue
|
||||
(*ExecutionPayloadDenebWithValueAndBlobsBundle)(nil), // 7: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle
|
||||
(*ExecutionPayloadHeader)(nil), // 8: ethereum.engine.v1.ExecutionPayloadHeader
|
||||
(*ExecutionPayloadHeaderCapella)(nil), // 9: ethereum.engine.v1.ExecutionPayloadHeaderCapella
|
||||
(*ExecutionPayloadHeaderDeneb)(nil), // 10: ethereum.engine.v1.ExecutionPayloadHeaderDeneb
|
||||
(*ExecutionPayloadHeaderElectra)(nil), // 11: ethereum.engine.v1.ExecutionPayloadHeaderElectra
|
||||
(*PayloadAttributes)(nil), // 12: ethereum.engine.v1.PayloadAttributes
|
||||
(*PayloadAttributesV2)(nil), // 13: ethereum.engine.v1.PayloadAttributesV2
|
||||
(*PayloadAttributesV3)(nil), // 14: ethereum.engine.v1.PayloadAttributesV3
|
||||
(*PayloadStatus)(nil), // 15: ethereum.engine.v1.PayloadStatus
|
||||
(*ForkchoiceState)(nil), // 16: ethereum.engine.v1.ForkchoiceState
|
||||
(*Withdrawal)(nil), // 17: ethereum.engine.v1.Withdrawal
|
||||
(*BlobsBundle)(nil), // 18: ethereum.engine.v1.BlobsBundle
|
||||
(*Blob)(nil), // 19: ethereum.engine.v1.Blob
|
||||
(*ExchangeCapabilities)(nil), // 20: ethereum.engine.v1.ExchangeCapabilities
|
||||
(*ExecutionLayerWithdrawalRequest)(nil), // 21: ethereum.engine.v1.ExecutionLayerWithdrawalRequest
|
||||
(*DepositReceipt)(nil), // 22: ethereum.engine.v1.DepositReceipt
|
||||
}
|
||||
var file_proto_engine_v1_execution_engine_proto_depIdxs = []int32{
|
||||
18, // 0: ethereum.engine.v1.ExecutionPayloadBodyV1.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
18, // 1: ethereum.engine.v1.ExecutionPayloadCapella.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
18, // 2: ethereum.engine.v1.ExecutionPayloadDeneb.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
18, // 3: ethereum.engine.v1.ExecutionPayloadElectra.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
23, // 4: ethereum.engine.v1.ExecutionPayloadElectra.deposit_receipts:type_name -> ethereum.engine.v1.DepositReceipt
|
||||
22, // 5: ethereum.engine.v1.ExecutionPayloadElectra.withdrawal_requests:type_name -> ethereum.engine.v1.ExecutionLayerWithdrawalRequest
|
||||
5, // 6: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle.payload:type_name -> ethereum.engine.v1.ExecutionPayloadElectra
|
||||
19, // 7: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle
|
||||
3, // 8: ethereum.engine.v1.ExecutionPayloadCapellaWithValue.payload:type_name -> ethereum.engine.v1.ExecutionPayloadCapella
|
||||
4, // 9: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb
|
||||
19, // 10: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle
|
||||
18, // 11: ethereum.engine.v1.PayloadAttributesV2.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
18, // 12: ethereum.engine.v1.PayloadAttributesV3.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
0, // 13: ethereum.engine.v1.PayloadStatus.status:type_name -> ethereum.engine.v1.PayloadStatus.Status
|
||||
14, // [14:14] is the sub-list for method output_type
|
||||
14, // [14:14] is the sub-list for method input_type
|
||||
14, // [14:14] is the sub-list for extension type_name
|
||||
14, // [14:14] is the sub-list for extension extendee
|
||||
0, // [0:14] is the sub-list for field type_name
|
||||
17, // 0: ethereum.engine.v1.ExecutionPayloadCapella.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
17, // 1: ethereum.engine.v1.ExecutionPayloadDeneb.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
17, // 2: ethereum.engine.v1.ExecutionPayloadElectra.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
22, // 3: ethereum.engine.v1.ExecutionPayloadElectra.deposit_receipts:type_name -> ethereum.engine.v1.DepositReceipt
|
||||
21, // 4: ethereum.engine.v1.ExecutionPayloadElectra.withdrawal_requests:type_name -> ethereum.engine.v1.ExecutionLayerWithdrawalRequest
|
||||
4, // 5: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle.payload:type_name -> ethereum.engine.v1.ExecutionPayloadElectra
|
||||
18, // 6: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle
|
||||
2, // 7: ethereum.engine.v1.ExecutionPayloadCapellaWithValue.payload:type_name -> ethereum.engine.v1.ExecutionPayloadCapella
|
||||
3, // 8: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb
|
||||
18, // 9: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle
|
||||
17, // 10: ethereum.engine.v1.PayloadAttributesV2.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
17, // 11: ethereum.engine.v1.PayloadAttributesV3.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
|
||||
0, // 12: ethereum.engine.v1.PayloadStatus.status:type_name -> ethereum.engine.v1.PayloadStatus.Status
|
||||
13, // [13:13] is the sub-list for method output_type
|
||||
13, // [13:13] is the sub-list for method input_type
|
||||
13, // [13:13] is the sub-list for extension type_name
|
||||
13, // [13:13] is the sub-list for extension extendee
|
||||
0, // [0:13] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_engine_v1_execution_engine_proto_init() }
|
||||
@@ -3026,18 +2961,6 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadBodyV1); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadCapella); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3049,7 +2972,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadDeneb); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3061,7 +2984,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadElectra); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3073,7 +2996,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadElectraWithValueAndBlobsBundle); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3085,7 +3008,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadCapellaWithValue); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3097,7 +3020,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadDenebWithValueAndBlobsBundle); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3109,7 +3032,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadHeader); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3121,7 +3044,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadHeaderCapella); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3133,7 +3056,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadHeaderDeneb); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3145,7 +3068,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadHeaderElectra); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3157,7 +3080,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PayloadAttributes); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3169,7 +3092,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PayloadAttributesV2); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3181,7 +3104,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PayloadAttributesV3); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3193,7 +3116,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PayloadStatus); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3205,7 +3128,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ForkchoiceState); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3217,7 +3140,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Withdrawal); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3229,7 +3152,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BlobsBundle); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3241,7 +3164,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Blob); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3253,7 +3176,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExchangeCapabilities); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3265,7 +3188,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionLayerWithdrawalRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3277,7 +3200,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DepositReceipt); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -3296,7 +3219,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_engine_v1_execution_engine_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 23,
|
||||
NumMessages: 22,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -41,11 +41,6 @@ message ExecutionPayload {
|
||||
repeated bytes transactions = 14 [(ethereum.eth.ext.ssz_size) = "?,?", (ethereum.eth.ext.ssz_max) = "1048576,1073741824"];
|
||||
}
|
||||
|
||||
message ExecutionPayloadBodyV1 {
|
||||
repeated bytes transactions = 1;
|
||||
repeated Withdrawal withdrawals = 2;
|
||||
}
|
||||
|
||||
message ExecutionPayloadCapella {
|
||||
bytes parent_hash = 1 [(ethereum.eth.ext.ssz_size) = "32"];
|
||||
bytes fee_recipient = 2 [(ethereum.eth.ext.ssz_size) = "20"];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: 88fdbdfda4571603e11174a57e65c25e06780ff2cbd795c8ae2a4709da24d9a9
|
||||
// Hash: 5e73dfd1d7df4fb984d773b9aa92658a1bc4db66b0e050f9b869a470e61416d3
|
||||
package enginev1
|
||||
|
||||
import (
|
||||
|
||||
@@ -21,6 +21,8 @@ const (
|
||||
BlsSignLen = 96
|
||||
)
|
||||
|
||||
var errJsonNilField = errors.New("nil field in JSON value")
|
||||
|
||||
// BlsPubkey represents a 48 byte BLS public key.
|
||||
type BlsPubkey [BlsPubKeyLen]byte
|
||||
|
||||
@@ -325,6 +327,14 @@ type ExecutionPayloadElectraJSON struct {
|
||||
DepositRequests []DepositRequestV1 `json:"depositRequests"`
|
||||
}
|
||||
|
||||
// ExecutionPayloadBody represents the engine API ExecutionPayloadV1 or ExecutionPayloadV2 type.
|
||||
type ExecutionPayloadBody struct {
|
||||
Transactions []hexutil.Bytes `json:"transactions"`
|
||||
Withdrawals []*Withdrawal `json:"withdrawals"`
|
||||
WithdrawalRequests []WithdrawalRequestV1 `json:"withdrawalRequests"`
|
||||
DepositRequests []DepositRequestV1 `json:"depositRequests"`
|
||||
}
|
||||
|
||||
// Validate returns an error if key fields in GetPayloadV4ResponseJson are nil or invalid.
|
||||
func (j *GetPayloadV4ResponseJson) Validate() error {
|
||||
if j.ExecutionPayload == nil {
|
||||
@@ -411,6 +421,19 @@ type WithdrawalRequestV1 struct {
|
||||
Amount *hexutil.Uint64 `json:"amount"`
|
||||
}
|
||||
|
||||
func (r WithdrawalRequestV1) Validate() error {
|
||||
if r.SourceAddress == nil {
|
||||
return errors.Wrap(errJsonNilField, "missing required field 'sourceAddress' for WithdrawalRequestV1")
|
||||
}
|
||||
if r.ValidatorPubkey == nil {
|
||||
return errors.Wrap(errJsonNilField, "missing required field 'validatorPublicKey' for WithdrawalRequestV1")
|
||||
}
|
||||
if r.Amount == nil {
|
||||
return errors.Wrap(errJsonNilField, "missing required field 'amount' for WithdrawalRequestV1")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DepositRequestV1 represents an execution engine DepositRequestV1 value
|
||||
// https://github.com/ethereum/execution-apis/blob/main/src/engine/prague.md#depositrequestv1
|
||||
type DepositRequestV1 struct {
|
||||
@@ -426,6 +449,25 @@ type DepositRequestV1 struct {
|
||||
Index *hexutil.Uint64 `json:"index"`
|
||||
}
|
||||
|
||||
func (r DepositRequestV1) Validate() error {
|
||||
if r.PubKey == nil {
|
||||
return errors.Wrap(errJsonNilField, "missing required field 'pubkey' for DepositRequestV1")
|
||||
}
|
||||
if r.WithdrawalCredentials == nil {
|
||||
return errors.Wrap(errJsonNilField, "missing required field 'withdrawalCredentials' for DepositRequestV1")
|
||||
}
|
||||
if r.Amount == nil {
|
||||
return errors.Wrap(errJsonNilField, "missing required field 'amount' for DepositRequestV1")
|
||||
}
|
||||
if r.Signature == nil {
|
||||
return errors.Wrap(errJsonNilField, "missing required field 'signature' for DepositRequestV1")
|
||||
}
|
||||
if r.Index == nil {
|
||||
return errors.Wrap(errJsonNilField, "missing required field 'index' for DepositRequestV1")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON --
|
||||
func (e *ExecutionPayload) MarshalJSON() ([]byte, error) {
|
||||
transactions := make([]hexutil.Bytes, len(e.Transactions))
|
||||
@@ -941,17 +983,20 @@ func (e *ExecutionPayloadElectra) MarshalJSON() ([]byte, error) {
|
||||
Withdrawals: withdrawals,
|
||||
BlobGasUsed: &blobGasUsed,
|
||||
ExcessBlobGas: &excessBlobGas,
|
||||
WithdrawalRequests: WithdrawalRequestProtoToJson(e.WithdrawalRequests),
|
||||
DepositRequests: DepositRequestProtoToJson(e.DepositReceipts),
|
||||
WithdrawalRequests: ProtoWithdrawalRequestsToJson(e.WithdrawalRequests),
|
||||
DepositRequests: ProtoDepositRequestsToJson(e.DepositReceipts),
|
||||
})
|
||||
}
|
||||
|
||||
func (j *ExecutionPayloadElectraJSON) ElectraDepositReceipts() []*DepositReceipt {
|
||||
rcpt := make([]*DepositReceipt, len(j.DepositRequests))
|
||||
func JsonDepositRequestsToProto(j []DepositRequestV1) ([]*DepositReceipt, error) {
|
||||
reqs := make([]*DepositReceipt, len(j))
|
||||
|
||||
for i := range j.DepositRequests {
|
||||
req := j.DepositRequests[i]
|
||||
rcpt[i] = &DepositReceipt{
|
||||
for i := range j {
|
||||
req := j[i]
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reqs[i] = &DepositReceipt{
|
||||
Pubkey: req.PubKey.Bytes(),
|
||||
WithdrawalCredentials: req.WithdrawalCredentials.Bytes(),
|
||||
Amount: uint64(*req.Amount),
|
||||
@@ -960,10 +1005,10 @@ func (j *ExecutionPayloadElectraJSON) ElectraDepositReceipts() []*DepositReceipt
|
||||
}
|
||||
}
|
||||
|
||||
return rcpt
|
||||
return reqs, nil
|
||||
}
|
||||
|
||||
func DepositRequestProtoToJson(reqs []*DepositReceipt) []DepositRequestV1 {
|
||||
func ProtoDepositRequestsToJson(reqs []*DepositReceipt) []DepositRequestV1 {
|
||||
j := make([]DepositRequestV1, len(reqs))
|
||||
for i := range reqs {
|
||||
r := reqs[i]
|
||||
@@ -985,11 +1030,14 @@ func DepositRequestProtoToJson(reqs []*DepositReceipt) []DepositRequestV1 {
|
||||
return j
|
||||
}
|
||||
|
||||
func (j *ExecutionPayloadElectraJSON) ElectraExecutionLayerWithdrawalRequests() []*ExecutionLayerWithdrawalRequest {
|
||||
reqs := make([]*ExecutionLayerWithdrawalRequest, len(j.WithdrawalRequests))
|
||||
func JsonWithdrawalRequestsToProto(j []WithdrawalRequestV1) ([]*ExecutionLayerWithdrawalRequest, error) {
|
||||
reqs := make([]*ExecutionLayerWithdrawalRequest, len(j))
|
||||
|
||||
for i := range j.WithdrawalRequests {
|
||||
req := j.WithdrawalRequests[i]
|
||||
for i := range j {
|
||||
req := j[i]
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reqs[i] = &ExecutionLayerWithdrawalRequest{
|
||||
SourceAddress: req.SourceAddress.Bytes(),
|
||||
ValidatorPubkey: req.ValidatorPubkey.Bytes(),
|
||||
@@ -997,10 +1045,10 @@ func (j *ExecutionPayloadElectraJSON) ElectraExecutionLayerWithdrawalRequests()
|
||||
}
|
||||
}
|
||||
|
||||
return reqs
|
||||
return reqs, nil
|
||||
}
|
||||
|
||||
func WithdrawalRequestProtoToJson(reqs []*ExecutionLayerWithdrawalRequest) []WithdrawalRequestV1 {
|
||||
func ProtoWithdrawalRequestsToJson(reqs []*ExecutionLayerWithdrawalRequest) []WithdrawalRequestV1 {
|
||||
j := make([]WithdrawalRequestV1, len(reqs))
|
||||
for i := range reqs {
|
||||
r := reqs[i]
|
||||
@@ -1031,6 +1079,14 @@ func (j *ExecutionPayloadElectraJSON) ElectraPayload() (*ExecutionPayloadElectra
|
||||
if j.Withdrawals == nil {
|
||||
j.Withdrawals = make([]*Withdrawal, 0)
|
||||
}
|
||||
dr, err := JsonDepositRequestsToProto(j.DepositRequests)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wr, err := JsonWithdrawalRequestsToProto(j.WithdrawalRequests)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ExecutionPayloadElectra{
|
||||
ParentHash: j.ParentHash.Bytes(),
|
||||
FeeRecipient: j.FeeRecipient.Bytes(),
|
||||
@@ -1049,8 +1105,8 @@ func (j *ExecutionPayloadElectraJSON) ElectraPayload() (*ExecutionPayloadElectra
|
||||
Withdrawals: j.Withdrawals,
|
||||
BlobGasUsed: uint64(*j.BlobGasUsed),
|
||||
ExcessBlobGas: uint64(*j.ExcessBlobGas),
|
||||
DepositReceipts: j.ElectraDepositReceipts(),
|
||||
WithdrawalRequests: j.ElectraExecutionLayerWithdrawalRequests(),
|
||||
DepositReceipts: dr,
|
||||
WithdrawalRequests: wr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1232,42 +1288,11 @@ func (e *ExecutionPayloadDenebWithValueAndBlobsBundle) UnmarshalJSON(enc []byte)
|
||||
return nil
|
||||
}
|
||||
|
||||
type executionPayloadBodyV1JSON struct {
|
||||
Transactions []hexutil.Bytes `json:"transactions"`
|
||||
Withdrawals []*Withdrawal `json:"withdrawals"`
|
||||
}
|
||||
|
||||
func (b *ExecutionPayloadBodyV1) MarshalJSON() ([]byte, error) {
|
||||
transactions := make([]hexutil.Bytes, len(b.Transactions))
|
||||
for i, tx := range b.Transactions {
|
||||
transactions[i] = tx
|
||||
}
|
||||
if len(b.Withdrawals) == 0 {
|
||||
b.Withdrawals = make([]*Withdrawal, 0)
|
||||
}
|
||||
return json.Marshal(executionPayloadBodyV1JSON{
|
||||
Transactions: transactions,
|
||||
Withdrawals: b.Withdrawals,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *ExecutionPayloadBodyV1) UnmarshalJSON(enc []byte) error {
|
||||
var decoded *executionPayloadBodyV1JSON
|
||||
err := json.Unmarshal(enc, &decoded)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(decoded.Transactions) == 0 {
|
||||
b.Transactions = make([][]byte, 0)
|
||||
}
|
||||
if len(decoded.Withdrawals) == 0 {
|
||||
b.Withdrawals = make([]*Withdrawal, 0)
|
||||
}
|
||||
transactions := make([][]byte, len(decoded.Transactions))
|
||||
for i, tx := range decoded.Transactions {
|
||||
transactions[i] = tx
|
||||
}
|
||||
b.Transactions = transactions
|
||||
b.Withdrawals = decoded.Withdrawals
|
||||
return nil
|
||||
// RecastHexutilByteSlice converts a []hexutil.Bytes to a [][]byte
|
||||
func RecastHexutilByteSlice(h []hexutil.Bytes) [][]byte {
|
||||
r := make([][]byte, len(h))
|
||||
for i := range h {
|
||||
r[i] = h[i]
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -360,8 +360,8 @@ func TestJsonMarshalUnmarshal(t *testing.T) {
|
||||
}},
|
||||
BlobGasUsed: &bgu,
|
||||
ExcessBlobGas: &ebg,
|
||||
WithdrawalRequests: enginev1.WithdrawalRequestProtoToJson(withdrawalReq),
|
||||
DepositRequests: enginev1.DepositRequestProtoToJson(depositReq),
|
||||
WithdrawalRequests: enginev1.ProtoWithdrawalRequestsToJson(withdrawalReq),
|
||||
DepositRequests: enginev1.ProtoDepositRequestsToJson(depositReq),
|
||||
},
|
||||
}
|
||||
enc, err := json.Marshal(resp)
|
||||
@@ -763,8 +763,8 @@ func TestPayloadIDBytes_MarshalUnmarshalJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExecutionPayloadBody_MarshalUnmarshalJSON(t *testing.T) {
|
||||
pBody := &enginev1.ExecutionPayloadBodyV1{
|
||||
Transactions: [][]byte{[]byte("random1"), []byte("random2"), []byte("random3")},
|
||||
pBody := &enginev1.ExecutionPayloadBody{
|
||||
Transactions: []hexutil.Bytes{[]byte("random1"), []byte("random2"), []byte("random3")},
|
||||
Withdrawals: []*enginev1.Withdrawal{
|
||||
{
|
||||
Index: 200,
|
||||
@@ -782,8 +782,8 @@ func TestExecutionPayloadBody_MarshalUnmarshalJSON(t *testing.T) {
|
||||
}
|
||||
enc, err := json.Marshal(pBody)
|
||||
require.NoError(t, err)
|
||||
res := &enginev1.ExecutionPayloadBodyV1{}
|
||||
err = res.UnmarshalJSON(enc)
|
||||
res := &enginev1.ExecutionPayloadBody{}
|
||||
err = json.Unmarshal(enc, res)
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, pBody, res)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: 6fed60156f1e57926b40b972ee25b48a82b18726a9c64fb0e974e4f638784049
|
||||
// Hash: a13be0354388a9ab681c78ee577580c9aebbd6d3d17024084c06c839c5db58ee
|
||||
package v1
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: 36d05ceafa355d5aa87123eb218143987a79f5095e2cafbad7760712ad0934a3
|
||||
// Hash: e1b3713d854395a4c86aa7a0bf0249d9f2764183a636fcc53badddeaf38990f2
|
||||
package eth
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: 4e7c07afe12b97ee034415333c33967cab8cf624f3fd43f37562cd6307760ec3
|
||||
// Hash: 5d2c5eb257aa9cd0f12fd74f707963c8e7f779fbef26d0031f6ae18e9b1ee124
|
||||
package eth
|
||||
|
||||
import (
|
||||
|
||||
@@ -31,6 +31,7 @@ type denebBlockGenerator struct {
|
||||
sk bls.SecretKey
|
||||
proposer primitives.ValidatorIndex
|
||||
valRoot []byte
|
||||
payload *enginev1.ExecutionPayloadDeneb
|
||||
}
|
||||
|
||||
func WithProposerSigning(idx primitives.ValidatorIndex, sk bls.SecretKey, valRoot []byte) DenebBlockGeneratorOption {
|
||||
@@ -42,6 +43,12 @@ func WithProposerSigning(idx primitives.ValidatorIndex, sk bls.SecretKey, valRoo
|
||||
}
|
||||
}
|
||||
|
||||
func WithPayloadSetter(p *enginev1.ExecutionPayloadDeneb) DenebBlockGeneratorOption {
|
||||
return func(g *denebBlockGenerator) {
|
||||
g.payload = p
|
||||
}
|
||||
}
|
||||
|
||||
func GenerateTestDenebBlockWithSidecar(t *testing.T, parent [32]byte, slot primitives.Slot, nblobs int, opts ...DenebBlockGeneratorOption) (blocks.ROBlock, []blocks.ROBlob) {
|
||||
g := &denebBlockGenerator{
|
||||
parent: parent,
|
||||
@@ -51,47 +58,51 @@ func GenerateTestDenebBlockWithSidecar(t *testing.T, parent [32]byte, slot primi
|
||||
for _, o := range opts {
|
||||
o(g)
|
||||
}
|
||||
stateRoot := bytesutil.PadTo([]byte("stateRoot"), fieldparams.RootLength)
|
||||
receiptsRoot := bytesutil.PadTo([]byte("receiptsRoot"), fieldparams.RootLength)
|
||||
logsBloom := bytesutil.PadTo([]byte("logs"), fieldparams.LogsBloomLength)
|
||||
parentHash := bytesutil.PadTo([]byte("parentHash"), fieldparams.RootLength)
|
||||
ads := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
|
||||
tx := gethTypes.NewTx(&gethTypes.LegacyTx{
|
||||
Nonce: 0,
|
||||
To: &ads,
|
||||
Value: big.NewInt(0),
|
||||
Gas: 0,
|
||||
GasPrice: big.NewInt(0),
|
||||
Data: nil,
|
||||
})
|
||||
|
||||
txs := []*gethTypes.Transaction{tx}
|
||||
encodedBinaryTxs := make([][]byte, 1)
|
||||
var err error
|
||||
encodedBinaryTxs[0], err = txs[0].MarshalBinary()
|
||||
require.NoError(t, err)
|
||||
blockHash := bytesutil.ToBytes32([]byte("foo"))
|
||||
payload := &enginev1.ExecutionPayloadDeneb{
|
||||
ParentHash: parentHash,
|
||||
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||
StateRoot: stateRoot,
|
||||
ReceiptsRoot: receiptsRoot,
|
||||
LogsBloom: logsBloom,
|
||||
PrevRandao: blockHash[:],
|
||||
BlockNumber: 0,
|
||||
GasLimit: 0,
|
||||
GasUsed: 0,
|
||||
Timestamp: 0,
|
||||
ExtraData: make([]byte, 0),
|
||||
BaseFeePerGas: bytesutil.PadTo([]byte("baseFeePerGas"), fieldparams.RootLength),
|
||||
BlockHash: blockHash[:],
|
||||
Transactions: encodedBinaryTxs,
|
||||
Withdrawals: make([]*enginev1.Withdrawal, 0),
|
||||
BlobGasUsed: 0,
|
||||
ExcessBlobGas: 0,
|
||||
if g.payload == nil {
|
||||
stateRoot := bytesutil.PadTo([]byte("stateRoot"), fieldparams.RootLength)
|
||||
ads := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
|
||||
tx := gethTypes.NewTx(&gethTypes.LegacyTx{
|
||||
Nonce: 0,
|
||||
To: &ads,
|
||||
Value: big.NewInt(0),
|
||||
Gas: 0,
|
||||
GasPrice: big.NewInt(0),
|
||||
Data: nil,
|
||||
})
|
||||
|
||||
txs := []*gethTypes.Transaction{tx}
|
||||
encodedBinaryTxs := make([][]byte, 1)
|
||||
var err error
|
||||
encodedBinaryTxs[0], err = txs[0].MarshalBinary()
|
||||
require.NoError(t, err)
|
||||
blockHash := bytesutil.ToBytes32([]byte("foo"))
|
||||
logsBloom := bytesutil.PadTo([]byte("logs"), fieldparams.LogsBloomLength)
|
||||
receiptsRoot := bytesutil.PadTo([]byte("receiptsRoot"), fieldparams.RootLength)
|
||||
parentHash := bytesutil.PadTo([]byte("parentHash"), fieldparams.RootLength)
|
||||
g.payload = &enginev1.ExecutionPayloadDeneb{
|
||||
ParentHash: parentHash,
|
||||
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||
StateRoot: stateRoot,
|
||||
ReceiptsRoot: receiptsRoot,
|
||||
LogsBloom: logsBloom,
|
||||
PrevRandao: blockHash[:],
|
||||
BlockNumber: 0,
|
||||
GasLimit: 0,
|
||||
GasUsed: 0,
|
||||
Timestamp: 0,
|
||||
ExtraData: make([]byte, 0),
|
||||
BaseFeePerGas: bytesutil.PadTo([]byte("baseFeePerGas"), fieldparams.RootLength),
|
||||
BlockHash: blockHash[:],
|
||||
Transactions: encodedBinaryTxs,
|
||||
Withdrawals: make([]*enginev1.Withdrawal, 0),
|
||||
BlobGasUsed: 0,
|
||||
ExcessBlobGas: 0,
|
||||
}
|
||||
}
|
||||
|
||||
block := NewBeaconBlockDeneb()
|
||||
block.Block.Body.ExecutionPayload = payload
|
||||
block.Block.Body.ExecutionPayload = g.payload
|
||||
block.Block.Slot = g.slot
|
||||
block.Block.ParentRoot = g.parent[:]
|
||||
block.Block.ProposerIndex = g.proposer
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/network/forks"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
)
|
||||
|
||||
// HackElectraMaxuint is helpful for tests that need to set up cases where the electra fork has passed.
|
||||
@@ -23,3 +36,165 @@ func HackElectraMaxuint(t *testing.T) func() {
|
||||
require.NoError(t, undo())
|
||||
}
|
||||
}
|
||||
|
||||
type ElectraBlockGeneratorOption func(*electraBlockGenerator)
|
||||
|
||||
type electraBlockGenerator struct {
|
||||
parent [32]byte
|
||||
slot primitives.Slot
|
||||
nblobs int
|
||||
sign bool
|
||||
sk bls.SecretKey
|
||||
proposer primitives.ValidatorIndex
|
||||
valRoot []byte
|
||||
payload *enginev1.ExecutionPayloadElectra
|
||||
}
|
||||
|
||||
func WithElectraProposerSigning(idx primitives.ValidatorIndex, sk bls.SecretKey, valRoot []byte) ElectraBlockGeneratorOption {
|
||||
return func(g *electraBlockGenerator) {
|
||||
g.sign = true
|
||||
g.proposer = idx
|
||||
g.sk = sk
|
||||
g.valRoot = valRoot
|
||||
}
|
||||
}
|
||||
|
||||
func WithElectraPayload(p *enginev1.ExecutionPayloadElectra) ElectraBlockGeneratorOption {
|
||||
return func(g *electraBlockGenerator) {
|
||||
g.payload = p
|
||||
}
|
||||
}
|
||||
|
||||
func GenerateTestElectraBlockWithSidecar(t *testing.T, parent [32]byte, slot primitives.Slot, nblobs int, opts ...ElectraBlockGeneratorOption) (blocks.ROBlock, []blocks.ROBlob) {
|
||||
g := &electraBlockGenerator{
|
||||
parent: parent,
|
||||
slot: slot,
|
||||
nblobs: nblobs,
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(g)
|
||||
}
|
||||
|
||||
if g.payload == nil {
|
||||
stateRoot := bytesutil.PadTo([]byte("stateRoot"), fieldparams.RootLength)
|
||||
ads := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
|
||||
tx := gethTypes.NewTx(&gethTypes.LegacyTx{
|
||||
Nonce: 0,
|
||||
To: &ads,
|
||||
Value: big.NewInt(0),
|
||||
Gas: 0,
|
||||
GasPrice: big.NewInt(0),
|
||||
Data: nil,
|
||||
})
|
||||
|
||||
txs := []*gethTypes.Transaction{tx}
|
||||
encodedBinaryTxs := make([][]byte, 1)
|
||||
var err error
|
||||
encodedBinaryTxs[0], err = txs[0].MarshalBinary()
|
||||
require.NoError(t, err)
|
||||
blockHash := bytesutil.ToBytes32([]byte("foo"))
|
||||
logsBloom := bytesutil.PadTo([]byte("logs"), fieldparams.LogsBloomLength)
|
||||
receiptsRoot := bytesutil.PadTo([]byte("receiptsRoot"), fieldparams.RootLength)
|
||||
parentHash := bytesutil.PadTo([]byte("parentHash"), fieldparams.RootLength)
|
||||
g.payload = &enginev1.ExecutionPayloadElectra{
|
||||
ParentHash: parentHash,
|
||||
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||
StateRoot: stateRoot,
|
||||
ReceiptsRoot: receiptsRoot,
|
||||
LogsBloom: logsBloom,
|
||||
PrevRandao: blockHash[:],
|
||||
BlockNumber: 0,
|
||||
GasLimit: 0,
|
||||
GasUsed: 0,
|
||||
Timestamp: 0,
|
||||
ExtraData: make([]byte, 0),
|
||||
BaseFeePerGas: bytesutil.PadTo([]byte("baseFeePerGas"), fieldparams.RootLength),
|
||||
BlockHash: blockHash[:],
|
||||
Transactions: encodedBinaryTxs,
|
||||
Withdrawals: make([]*enginev1.Withdrawal, 0),
|
||||
BlobGasUsed: 0,
|
||||
ExcessBlobGas: 0,
|
||||
DepositReceipts: generateTestDepositRequests(uint64(g.slot), 4),
|
||||
WithdrawalRequests: generateTestWithdrawalRequests(uint64(g.slot), 4),
|
||||
}
|
||||
}
|
||||
|
||||
block := NewBeaconBlockElectra()
|
||||
block.Block.Body.ExecutionPayload = g.payload
|
||||
block.Block.Slot = g.slot
|
||||
block.Block.ParentRoot = g.parent[:]
|
||||
block.Block.ProposerIndex = g.proposer
|
||||
commitments := make([][48]byte, g.nblobs)
|
||||
block.Block.Body.BlobKzgCommitments = make([][]byte, g.nblobs)
|
||||
for i := range commitments {
|
||||
binary.LittleEndian.PutUint16(commitments[i][0:16], uint16(i))
|
||||
binary.LittleEndian.PutUint16(commitments[i][16:32], uint16(g.slot))
|
||||
block.Block.Body.BlobKzgCommitments[i] = commitments[i][:]
|
||||
}
|
||||
|
||||
body, err := blocks.NewBeaconBlockBody(block.Block.Body)
|
||||
require.NoError(t, err)
|
||||
inclusion := make([][][]byte, len(commitments))
|
||||
for i := range commitments {
|
||||
proof, err := blocks.MerkleProofKZGCommitment(body, i)
|
||||
require.NoError(t, err)
|
||||
inclusion[i] = proof
|
||||
}
|
||||
if g.sign {
|
||||
epoch := slots.ToEpoch(block.Block.Slot)
|
||||
schedule := forks.NewOrderedSchedule(params.BeaconConfig())
|
||||
version, err := schedule.VersionForEpoch(epoch)
|
||||
require.NoError(t, err)
|
||||
fork, err := schedule.ForkFromVersion(version)
|
||||
require.NoError(t, err)
|
||||
domain := params.BeaconConfig().DomainBeaconProposer
|
||||
sig, err := signing.ComputeDomainAndSignWithoutState(fork, epoch, domain, g.valRoot, block.Block, g.sk)
|
||||
require.NoError(t, err)
|
||||
block.Signature = sig
|
||||
}
|
||||
|
||||
root, err := block.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
sidecars := make([]blocks.ROBlob, len(commitments))
|
||||
sbb, err := blocks.NewSignedBeaconBlock(block)
|
||||
require.NoError(t, err)
|
||||
|
||||
sh, err := sbb.Header()
|
||||
require.NoError(t, err)
|
||||
for i, c := range block.Block.Body.BlobKzgCommitments {
|
||||
sidecars[i] = GenerateTestDenebBlobSidecar(t, root, sh, i, c, inclusion[i])
|
||||
}
|
||||
|
||||
rob, err := blocks.NewROBlock(sbb)
|
||||
require.NoError(t, err)
|
||||
return rob, sidecars
|
||||
}
|
||||
|
||||
func generateTestDepositRequests(offset, n uint64) []*enginev1.DepositReceipt {
|
||||
r := make([]*enginev1.DepositReceipt, n)
|
||||
var i uint64
|
||||
for i = 0; i < n; i++ {
|
||||
r[i] = &enginev1.DepositReceipt{
|
||||
Pubkey: make([]byte, 48),
|
||||
WithdrawalCredentials: make([]byte, 32),
|
||||
Amount: offset + i,
|
||||
Signature: make([]byte, 96),
|
||||
Index: offset + i + 100,
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func generateTestWithdrawalRequests(offset, n uint64) []*enginev1.ExecutionLayerWithdrawalRequest {
|
||||
r := make([]*enginev1.ExecutionLayerWithdrawalRequest, n)
|
||||
var i uint64
|
||||
for i = 0; i < n; i++ {
|
||||
r[i] = &enginev1.ExecutionLayerWithdrawalRequest{
|
||||
SourceAddress: make([]byte, 20),
|
||||
ValidatorPubkey: make([]byte, 48),
|
||||
Amount: offset + i,
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user