mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
engine payload bodies rpc endpoints (#6644)
Very basic implementation for get payload bodies rpc calls. Once we have Hive tests for these calls I can pick this back up and work through any issues. Implementation of https://github.com/ethereum/execution-apis/pull/352.
This commit is contained in:
parent
49f8d4c4ad
commit
4dcba50e99
@ -69,6 +69,11 @@ type TransitionConfiguration struct {
|
||||
TerminalBlockNumber *hexutil.Big `json:"terminalBlockNumber" gencodec:"required"`
|
||||
}
|
||||
|
||||
type ExecutionPayloadBodyV1 struct {
|
||||
Transactions [][]byte `json:"transactions" gencodec:"required"`
|
||||
Withdrawals []*types.Withdrawal `json:"withdrawals" gencodec:"required"`
|
||||
}
|
||||
|
||||
// EngineAPI Beacon chain communication endpoint
|
||||
type EngineAPI interface {
|
||||
NewPayloadV1(context.Context, *ExecutionPayload) (map[string]interface{}, error)
|
||||
@ -78,6 +83,8 @@ type EngineAPI interface {
|
||||
GetPayloadV1(ctx context.Context, payloadID hexutil.Bytes) (*ExecutionPayload, error)
|
||||
GetPayloadV2(ctx context.Context, payloadID hexutil.Bytes) (*GetPayloadV2Response, error)
|
||||
ExchangeTransitionConfigurationV1(ctx context.Context, transitionConfiguration *TransitionConfiguration) (*TransitionConfiguration, error)
|
||||
GetPayloadBodiesByHashV1(ctx context.Context, hashes []libcommon.Hash) ([]*ExecutionPayloadBodyV1, error)
|
||||
GetPayloadBodiesByRangeV1(ctx context.Context, start uint64, count uint64) ([]*ExecutionPayloadBodyV1, error)
|
||||
}
|
||||
|
||||
// EngineImpl is implementation of the EngineAPI interface
|
||||
@ -358,6 +365,46 @@ func (e *EngineImpl) ExchangeTransitionConfigurationV1(ctx context.Context, beac
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (e *EngineImpl) GetPayloadBodiesByHashV1(ctx context.Context, hashes []libcommon.Hash) ([]*ExecutionPayloadBodyV1, error) {
|
||||
h := make([]*types2.H256, len(hashes))
|
||||
for i, hash := range hashes {
|
||||
h[i] = gointerfaces.ConvertHashToH256(hash)
|
||||
}
|
||||
|
||||
apiRes, err := e.api.EngineGetPayloadBodiesByHashV1(ctx, &remote.EngineGetPayloadBodiesByHashV1Request{Hashes: h})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return convertExecutionPayloadV1(apiRes), nil
|
||||
}
|
||||
|
||||
func (e *EngineImpl) GetPayloadBodiesByRangeV1(ctx context.Context, start uint64, count uint64) ([]*ExecutionPayloadBodyV1, error) {
|
||||
apiRes, err := e.api.EngineGetPayloadBodiesByRangeV1(ctx, &remote.EngineGetPayloadBodiesByRangeV1Request{Start: start, Count: count})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return convertExecutionPayloadV1(apiRes), nil
|
||||
}
|
||||
|
||||
func convertExecutionPayloadV1(response *remote.EngineGetPayloadBodiesV1Response) []*ExecutionPayloadBodyV1 {
|
||||
result := make([]*ExecutionPayloadBodyV1, len(response.Bodies))
|
||||
for idx, body := range response.Bodies {
|
||||
if body == nil {
|
||||
result[idx] = nil
|
||||
} else {
|
||||
pl := &ExecutionPayloadBodyV1{
|
||||
Transactions: body.Transactions,
|
||||
Withdrawals: privateapi.ConvertWithdrawalsFromRpc(body.Withdrawals),
|
||||
}
|
||||
result[idx] = pl
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// NewEngineAPI returns EngineImpl instance
|
||||
func NewEngineAPI(base *BaseAPI, db kv.RoDB, api rpchelper.ApiBackend, internalCL bool) *EngineImpl {
|
||||
return &EngineImpl{
|
||||
|
@ -212,6 +212,14 @@ func (back *RemoteBackend) EngineGetPayload(ctx context.Context, payloadId uint6
|
||||
})
|
||||
}
|
||||
|
||||
func (back *RemoteBackend) EngineGetPayloadBodiesByHashV1(ctx context.Context, request *remote.EngineGetPayloadBodiesByHashV1Request) (*remote.EngineGetPayloadBodiesV1Response, error) {
|
||||
return back.remoteEthBackend.EngineGetPayloadBodiesByHashV1(ctx, request)
|
||||
}
|
||||
|
||||
func (back *RemoteBackend) EngineGetPayloadBodiesByRangeV1(ctx context.Context, request *remote.EngineGetPayloadBodiesByRangeV1Request) (*remote.EngineGetPayloadBodiesV1Response, error) {
|
||||
return back.remoteEthBackend.EngineGetPayloadBodiesByRangeV1(ctx, request)
|
||||
}
|
||||
|
||||
func (back *RemoteBackend) NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error) {
|
||||
nodes, err := back.remoteEthBackend.NodeInfo(ctx, &remote.NodesInfoRequest{Limit: limit})
|
||||
if err != nil {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package privateapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -679,6 +680,96 @@ func (s *EthBackendServer) EngineForkChoiceUpdated(ctx context.Context, req *rem
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *EthBackendServer) EngineGetPayloadBodiesByHashV1(ctx context.Context, request *remote.EngineGetPayloadBodiesByHashV1Request) (*remote.EngineGetPayloadBodiesV1Response, error) {
|
||||
tx, err := s.db.BeginRo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bodies := make([]*types2.ExecutionPayloadBodyV1, len(request.Hashes))
|
||||
|
||||
for hashIdx, hash := range request.Hashes {
|
||||
h := gointerfaces.ConvertH256ToHash(hash)
|
||||
block, err := rawdb.ReadBlockByHash(tx, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body, err := extractPayloadBodyFromBlock(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodies[hashIdx] = body
|
||||
}
|
||||
|
||||
return &remote.EngineGetPayloadBodiesV1Response{Bodies: bodies}, nil
|
||||
}
|
||||
|
||||
func (s *EthBackendServer) EngineGetPayloadBodiesByRangeV1(ctx context.Context, request *remote.EngineGetPayloadBodiesByRangeV1Request) (*remote.EngineGetPayloadBodiesV1Response, error) {
|
||||
tx, err := s.db.BeginRo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bodies := make([]*types2.ExecutionPayloadBodyV1, request.Count)
|
||||
|
||||
var i uint64
|
||||
for i = 0; i < request.Count; i++ {
|
||||
block, err := rawdb.ReadBlockByNumber(tx, request.Start+i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := extractPayloadBodyFromBlock(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if body == nil {
|
||||
// break early if the body is nil to trim the response. A missing body indicates we don't have the
|
||||
// canonical block so can just stop outputting from here
|
||||
break
|
||||
}
|
||||
bodies[i] = body
|
||||
}
|
||||
|
||||
return &remote.EngineGetPayloadBodiesV1Response{Bodies: bodies}, nil
|
||||
}
|
||||
|
||||
func extractPayloadBodyFromBlock(block *types.Block) (*types2.ExecutionPayloadBodyV1, error) {
|
||||
if block == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
txs := block.Transactions()
|
||||
bdTxs := make([][]byte, len(txs))
|
||||
for idx, tx := range txs {
|
||||
var buf bytes.Buffer
|
||||
if err := tx.MarshalBinary(&buf); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
bdTxs[idx] = buf.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
wds := block.Withdrawals()
|
||||
bdWds := make([]*types2.Withdrawal, len(wds))
|
||||
|
||||
if wds == nil {
|
||||
// pre shanghai blocks could have nil withdrawals so nil the slice as per spec
|
||||
bdWds = nil
|
||||
} else {
|
||||
for idx, wd := range wds {
|
||||
bdWds[idx] = &types2.Withdrawal{
|
||||
Index: wd.Index,
|
||||
ValidatorIndex: wd.Validator,
|
||||
Address: gointerfaces.ConvertAddressToH160(wd.Address),
|
||||
Amount: wd.Amount,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &types2.ExecutionPayloadBodyV1{Transactions: bdTxs, Withdrawals: bdWds}, nil
|
||||
}
|
||||
|
||||
func (s *EthBackendServer) evictOldBuilders() {
|
||||
ids := common.SortedKeys(s.builders)
|
||||
|
||||
|
@ -31,4 +31,6 @@ type ApiBackend interface {
|
||||
NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error)
|
||||
Peers(ctx context.Context) ([]*p2p.PeerInfo, error)
|
||||
PendingBlock(ctx context.Context) (*types.Block, error)
|
||||
EngineGetPayloadBodiesByHashV1(ctx context.Context, request *remote.EngineGetPayloadBodiesByHashV1Request) (*remote.EngineGetPayloadBodiesV1Response, error)
|
||||
EngineGetPayloadBodiesByRangeV1(ctx context.Context, request *remote.EngineGetPayloadBodiesByRangeV1Request) (*remote.EngineGetPayloadBodiesV1Response, error)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user