erigon-pulse/cmd/rpcdaemon/commands/engine_api.go

257 lines
11 KiB
Go
Raw Normal View History

package commands
import (
"context"
"encoding/binary"
2021-11-30 13:14:04 +00:00
"fmt"
2021-11-22 10:36:52 +00:00
"math/big"
2021-11-22 10:36:52 +00:00
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/gointerfaces"
"github.com/ledgerwatch/erigon-lib/gointerfaces/remote"
2021-11-22 15:12:34 +00:00
types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types"
"github.com/ledgerwatch/erigon-lib/kv"
2021-11-22 10:36:52 +00:00
"github.com/ledgerwatch/erigon/cmd/rpcdaemon/services"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/common/hexutil"
2021-11-22 15:12:34 +00:00
"github.com/ledgerwatch/erigon/core/types"
2021-11-22 10:36:52 +00:00
"github.com/ledgerwatch/log/v3"
)
// ExecutionPayload represents an execution payload (aka slot/block)
type ExecutionPayload struct {
2021-11-29 17:30:33 +00:00
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
2021-11-29 17:30:33 +00:00
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
2021-11-29 17:30:33 +00:00
LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"random" gencodec:"required"`
BlockNumber hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"`
ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"`
2021-11-29 17:30:33 +00:00
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
}
// PayloadAttributes represent the attributes required to start assembling a payload
type ForkChoiceState struct {
HeadHash common.Hash `json:"headBlockHash" gencodec:"required"`
SafeBlockHash common.Hash `json:"safeBlockHash" gencodec:"required"`
FinalizedBlockHash common.Hash `json:"finalizedBlockHash" gencodec:"required"`
}
// PayloadAttributes represent the attributes required to start assembling a payload
type PayloadAttributes struct {
Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"`
Random common.Hash `json:"random" gencodec:"required"`
SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
}
// TransitionConfiguration represents the correct configurations of the CL and the EL
type TransitionConfiguration struct {
TerminalTotalDifficulty *hexutil.Big `json:"terminalTotalDifficulty" gencodec:"required"`
TerminalBlockHash common.Hash `json:"terminalBlockHash" gencodec:"required"`
TerminalBlockNumber hexutil.Uint64 `json:"terminalBlockNumber" gencodec:"required"`
}
// EngineAPI Beacon chain communication endpoint
type EngineAPI interface {
ForkchoiceUpdatedV1(ctx context.Context, forkChoiceState *ForkChoiceState, payloadAttributes *PayloadAttributes) (map[string]interface{}, error)
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
NewPayloadV1(context.Context, *ExecutionPayload) (map[string]interface{}, error)
GetPayloadV1(ctx context.Context, payloadID hexutil.Bytes) (*ExecutionPayload, error)
ExchangeTransitionConfigurationV1(ctx context.Context, transitionConfiguration TransitionConfiguration) (TransitionConfiguration, error)
}
// EngineImpl is implementation of the EngineAPI interface
type EngineImpl struct {
*BaseAPI
2021-11-22 10:36:52 +00:00
db kv.RoDB
api services.ApiBackend
}
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
func convertPayloadStatus(x *remote.EnginePayloadStatus) map[string]interface{} {
json := map[string]interface{}{
"status": x.Status.String(),
}
if x.LatestValidHash != nil {
json["latestValidHash"] = common.Hash(gointerfaces.ConvertH256ToHash(x.LatestValidHash))
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
}
if x.ValidationError != "" {
json["validationError"] = x.ValidationError
}
return json
}
func (e *EngineImpl) ForkchoiceUpdatedV1(ctx context.Context, forkChoiceState *ForkChoiceState, payloadAttributes *PayloadAttributes) (map[string]interface{}, error) {
log.Info("Received ForkchoiceUpdated", "head", forkChoiceState.HeadHash, "safe", forkChoiceState.HeadHash, "finalized", forkChoiceState.FinalizedBlockHash,
"build", payloadAttributes != nil)
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
var prepareParameters *remote.EnginePayloadAttributes
if payloadAttributes != nil {
prepareParameters = &remote.EnginePayloadAttributes{
Timestamp: uint64(payloadAttributes.Timestamp),
Random: gointerfaces.ConvertHashToH256(payloadAttributes.Random),
SuggestedFeeRecipient: gointerfaces.ConvertAddressToH160(payloadAttributes.SuggestedFeeRecipient),
}
}
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
reply, err := e.api.EngineForkchoiceUpdatedV1(ctx, &remote.EngineForkChoiceUpdatedRequest{
ForkchoiceState: &remote.EngineForkChoiceState{
HeadBlockHash: gointerfaces.ConvertHashToH256(forkChoiceState.HeadHash),
SafeBlockHash: gointerfaces.ConvertHashToH256(forkChoiceState.SafeBlockHash),
FinalizedBlockHash: gointerfaces.ConvertHashToH256(forkChoiceState.FinalizedBlockHash),
},
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
PayloadAttributes: prepareParameters,
})
if err != nil {
return nil, err
}
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
json := map[string]interface{}{
"payloadStatus": convertPayloadStatus(reply.PayloadStatus),
}
if reply.PayloadId != 0 {
encodedPayloadId := make([]byte, 8)
binary.BigEndian.PutUint64(encodedPayloadId, reply.PayloadId)
json["payloadId"] = hexutil.Bytes(encodedPayloadId)
}
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
return json, nil
}
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
// NewPayloadV1 processes new payloads (blocks) from the beacon chain.
// See https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#engine_newpayloadv1
func (e *EngineImpl) NewPayloadV1(ctx context.Context, payload *ExecutionPayload) (map[string]interface{}, error) {
log.Info("Received NewPayload", "height", payload.BlockNumber, "hash", payload.BlockHash)
2021-11-22 10:36:52 +00:00
var baseFee *uint256.Int
if payload.BaseFeePerGas != nil {
2021-11-30 13:14:04 +00:00
var overflow bool
baseFee, overflow = uint256.FromBig((*big.Int)(payload.BaseFeePerGas))
if overflow {
return nil, fmt.Errorf("invalid request")
}
2021-11-22 10:36:52 +00:00
}
2021-11-22 15:12:34 +00:00
// Convert slice of hexutil.Bytes to a slice of slice of bytes
transactions := make([][]byte, len(payload.Transactions))
for i, transaction := range payload.Transactions {
transactions[i] = ([]byte)(transaction)
}
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
res, err := e.api.EngineNewPayloadV1(ctx, &types2.ExecutionPayload{
2021-11-25 18:44:02 +00:00
ParentHash: gointerfaces.ConvertHashToH256(payload.ParentHash),
Coinbase: gointerfaces.ConvertAddressToH160(payload.FeeRecipient),
2021-11-25 18:44:02 +00:00
StateRoot: gointerfaces.ConvertHashToH256(payload.StateRoot),
ReceiptRoot: gointerfaces.ConvertHashToH256(payload.ReceiptsRoot),
2021-11-25 18:44:02 +00:00
LogsBloom: gointerfaces.ConvertBytesToH2048(([]byte)(payload.LogsBloom)),
2021-11-22 10:36:52 +00:00
Random: gointerfaces.ConvertHashToH256(payload.Random),
2022-01-20 07:00:31 +00:00
BlockNumber: uint64(payload.BlockNumber),
GasLimit: uint64(payload.GasLimit),
GasUsed: uint64(payload.GasUsed),
Timestamp: uint64(payload.Timestamp),
ExtraData: payload.ExtraData,
2021-11-22 10:36:52 +00:00
BaseFeePerGas: gointerfaces.ConvertUint256IntToH256(baseFee),
BlockHash: gointerfaces.ConvertHashToH256(payload.BlockHash),
2021-11-22 15:12:34 +00:00
Transactions: transactions,
2021-11-22 10:36:52 +00:00
})
2021-11-21 22:11:50 +00:00
if err != nil {
return nil, err
}
2021-11-22 15:12:34 +00:00
New Engine API semantics (Kiln v1) (#3340) * Disable PoS sync temporarily * Resore PoS sync * Handle Ctrl^C in HeadersPOS * Consistent naming * Extract verifyAndSavePoSHeader & downloadMissingPoSHeaders * Preparation for EngineForkChoiceUpdated re-orgs * Extract ForkingPoint * Comments * New proto for Engine API * EngineExecutePayload -> EngineNewPayload * Return INVALID_BLOCK_HASH if block hash is invalid * Return EngineStatus_ACCEPTED for side chain blocks * Update erigon-lib (PR 268) * Fix payload2Hash * reverseDownloadCh -> beaconPayloadCh * Update erigon-lib * Engine API updated * ExecutionStatus -> PayloadStatus * Introduce forkChoiceCh * Mock ForkChoiceMessage/PayloadStatus * Add ValidationError to PayloadStatus * Small clean-ups * Add INVALID_TERMINAL_BLOCK to EngineStatus * Add a comment * Extract handleNewPayload & handleForkChoice * Partially implement handleForkChoice * Update erigon-lib * short vs long re-org * Move header insertion out of downloadMissingPoSHeaders * Update erigon-lib * Refactor ProcessSegmentPOS * Fix imports * Wire downloadMissingPoSHeaders into handleForkChoice * evictOldPendingPayloads * nolint:unused for assertSegment * Try nolint instead of nolint:unused * Small comment improvements * HeadHeaderHash/StageProgress in handleForkChoice * TODO: bodyDownloader.AddToPrefetch(block) * Review call suggestions * Don't use ReadHeaderNumber in ProcessSegmentPOS * Don't leave ethbackend waiting when server is stopping * Update erigon-lib * More explicit signature of downloadMissingPoSHeaders
2022-02-09 07:33:22 +00:00
return convertPayloadStatus(res), nil
}
func (e *EngineImpl) GetPayloadV1(ctx context.Context, payloadID hexutil.Bytes) (*ExecutionPayload, error) {
decodedPayloadId := binary.BigEndian.Uint64(payloadID)
log.Info("Received GetPayload", "payloadId", decodedPayloadId)
payload, err := e.api.EngineGetPayloadV1(ctx, decodedPayloadId)
2021-11-22 15:12:34 +00:00
if err != nil {
return nil, err
}
var bloom types.Bloom = gointerfaces.ConvertH2048ToBloom(payload.LogsBloom)
var baseFee *big.Int
if payload.BaseFeePerGas != nil {
baseFee = gointerfaces.ConvertH256ToUint256Int(payload.BaseFeePerGas).ToBig()
}
// Convert slice of hexutil.Bytes to a slice of slice of bytes
transactions := make([]hexutil.Bytes, len(payload.Transactions))
for i, transaction := range payload.Transactions {
transactions[i] = transaction
}
return &ExecutionPayload{
ParentHash: gointerfaces.ConvertH256ToHash(payload.ParentHash),
FeeRecipient: gointerfaces.ConvertH160toAddress(payload.Coinbase),
2021-11-22 15:12:34 +00:00
StateRoot: gointerfaces.ConvertH256ToHash(payload.StateRoot),
ReceiptsRoot: gointerfaces.ConvertH256ToHash(payload.ReceiptRoot),
2021-11-22 15:12:34 +00:00
LogsBloom: bloom[:],
Random: gointerfaces.ConvertH256ToHash(payload.Random),
2021-11-22 15:12:34 +00:00
BlockNumber: hexutil.Uint64(payload.BlockNumber),
GasLimit: hexutil.Uint64(payload.GasLimit),
GasUsed: hexutil.Uint64(payload.GasUsed),
Timestamp: hexutil.Uint64(payload.Timestamp),
ExtraData: payload.ExtraData,
BaseFeePerGas: (*hexutil.Big)(baseFee),
BlockHash: gointerfaces.ConvertH256ToHash(payload.BlockHash),
2021-11-22 15:12:34 +00:00
Transactions: transactions,
}, nil
}
// Receives consensus layer's transition configuration and checks if the execution layer has the correct configuration.
// Can also be used to ping the execution layer (heartbeats).
// See https://github.com/ethereum/execution-apis/blob/v1.0.0-alpha.7/src/engine/specification.md#engine_exchangetransitionconfigurationv1
func (e *EngineImpl) ExchangeTransitionConfigurationV1(ctx context.Context, beaconConfig TransitionConfiguration) (TransitionConfiguration, error) {
tx, err := e.db.BeginRo(ctx)
if err != nil {
return TransitionConfiguration{}, err
}
defer tx.Rollback()
// terminal block number must always be zero
if beaconConfig.TerminalBlockNumber != 0 {
return TransitionConfiguration{}, fmt.Errorf("received the wrong terminal block number. expected zero, but instead got: %d", beaconConfig.TerminalBlockNumber)
}
chainConfig, err := e.BaseAPI.chainConfig(tx)
if err != nil {
return TransitionConfiguration{}, err
}
terminalTotalDifficulty := chainConfig.TerminalTotalDifficulty
if terminalTotalDifficulty == nil {
return TransitionConfiguration{}, fmt.Errorf("the execution layer doesn't have the terminal total difficulty. expected: %v", beaconConfig.TerminalTotalDifficulty)
}
if terminalTotalDifficulty.Cmp((*big.Int)(beaconConfig.TerminalTotalDifficulty)) != 0 {
return TransitionConfiguration{}, fmt.Errorf("the execution layer has the wrong total terminal difficulty. expected %v, but instead got: %d", beaconConfig.TerminalTotalDifficulty, terminalTotalDifficulty)
}
if chainConfig.TerminalBlockHash != (common.Hash{}) && beaconConfig.TerminalBlockHash != (common.Hash{}) &&
chainConfig.TerminalBlockHash != beaconConfig.TerminalBlockHash {
return TransitionConfiguration{}, fmt.Errorf("the execution layer has the wrong block hash. expected %s, but instead got: %s", beaconConfig.TerminalBlockHash, chainConfig.TerminalBlockHash)
}
return TransitionConfiguration{
TerminalTotalDifficulty: (*hexutil.Big)(terminalTotalDifficulty),
TerminalBlockHash: chainConfig.TerminalBlockHash,
TerminalBlockNumber: hexutil.Uint64(chainConfig.TerminalBlockNumber),
}, nil
}
// NewEngineAPI returns EngineImpl instance
2021-11-22 10:36:52 +00:00
func NewEngineAPI(base *BaseAPI, db kv.RoDB, api services.ApiBackend) *EngineImpl {
return &EngineImpl{
BaseAPI: base,
db: db,
2021-11-22 10:36:52 +00:00
api: api,
}
}