erigon-pulse/cl/phase1/execution_client/execution_client_direct.go

111 lines
3.6 KiB
Go

package execution_client
import (
"context"
"fmt"
"math/big"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon/cl/clparams"
"github.com/ledgerwatch/erigon/cl/cltypes"
"github.com/ledgerwatch/erigon/common/hexutil"
"github.com/ledgerwatch/erigon/turbo/engineapi"
"github.com/ledgerwatch/erigon/turbo/engineapi/engine_types"
"github.com/ledgerwatch/log/v3"
)
type ExecutionClientDirect struct {
api engineapi.EngineAPI
ctx context.Context
}
func NewExecutionClientDirect(ctx context.Context, api engineapi.EngineAPI) (*ExecutionClientDirect, error) {
return &ExecutionClientDirect{
api: api,
ctx: ctx,
}, nil
}
func (cc *ExecutionClientDirect) NewPayload(payload *cltypes.Eth1Block) (invalid bool, err error) {
if payload == nil {
return
}
reversedBaseFeePerGas := libcommon.Copy(payload.BaseFeePerGas[:])
for i, j := 0, len(reversedBaseFeePerGas)-1; i < j; i, j = i+1, j-1 {
reversedBaseFeePerGas[i], reversedBaseFeePerGas[j] = reversedBaseFeePerGas[j], reversedBaseFeePerGas[i]
}
baseFee := new(big.Int).SetBytes(reversedBaseFeePerGas)
request := engine_types.ExecutionPayload{
ParentHash: payload.ParentHash,
FeeRecipient: payload.FeeRecipient,
StateRoot: payload.StateRoot,
ReceiptsRoot: payload.ReceiptsRoot,
LogsBloom: payload.LogsBloom[:],
PrevRandao: payload.PrevRandao,
BlockNumber: hexutil.Uint64(payload.BlockNumber),
GasLimit: hexutil.Uint64(payload.GasLimit),
GasUsed: hexutil.Uint64(payload.GasUsed),
Timestamp: hexutil.Uint64(payload.Time),
ExtraData: payload.Extra.Bytes(),
BlockHash: payload.BlockHash,
}
request.BaseFeePerGas = new(hexutil.Big)
*request.BaseFeePerGas = hexutil.Big(*baseFee)
payloadBody := payload.Body()
// Setup transactionbody
request.Withdrawals = payloadBody.Withdrawals
for _, bytesTransaction := range payloadBody.Transactions {
request.Transactions = append(request.Transactions, bytesTransaction)
}
// Process Deneb
if payload.Version() >= clparams.DenebVersion {
request.BlobGasUsed = new(hexutil.Uint64)
request.ExcessBlobGas = new(hexutil.Uint64)
*request.BlobGasUsed = hexutil.Uint64(payload.BlobGasUsed)
*request.ExcessBlobGas = hexutil.Uint64(payload.ExcessBlobGas)
}
payloadStatus := &engine_types.PayloadStatus{} // As it is done in the rpcdaemon
// determine the engine method
switch payload.Version() {
case clparams.BellatrixVersion:
payloadStatus, err = cc.api.NewPayloadV1(cc.ctx, &request)
case clparams.CapellaVersion:
payloadStatus, err = cc.api.NewPayloadV2(cc.ctx, &request)
case clparams.DenebVersion:
payloadStatus, err = cc.api.NewPayloadV3(cc.ctx, &request)
default:
err = fmt.Errorf("invalid payload version")
}
if err != nil {
err = fmt.Errorf("execution Client RPC failed to retrieve the NewPayload status response, err: %w", err)
return
}
invalid = payloadStatus.Status == engine_types.InvalidStatus || payloadStatus.Status == engine_types.InvalidBlockHashStatus
err = checkPayloadStatus(payloadStatus)
if payloadStatus.Status == engine_types.AcceptedStatus {
log.Info("[ExecutionClientRpc] New block accepted")
}
return
}
func (cc *ExecutionClientDirect) ForkChoiceUpdate(finalized libcommon.Hash, head libcommon.Hash) error {
forkChoiceRequest := engine_types.ForkChoiceState{
HeadHash: head,
SafeBlockHash: head,
FinalizedBlockHash: finalized,
}
forkChoiceResp, err := cc.api.ForkchoiceUpdatedV2(cc.ctx, &forkChoiceRequest, nil)
if err != nil {
return fmt.Errorf("execution Client RPC failed to retrieve ForkChoiceUpdate response, err: %w", err)
}
return checkPayloadStatus(forkChoiceResp.PayloadStatus)
}