added engine_ namespace in rpcdaemon (#2923)

This commit is contained in:
Giulio rebuffo 2021-11-07 02:38:36 +01:00 committed by GitHub
parent e14fb4756b
commit c1e7650106
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 112 additions and 0 deletions

View File

@ -31,6 +31,7 @@ func APIList(ctx context.Context, db kv.RoDB,
traceImpl := NewTraceAPI(base, db, &cfg)
web3Impl := NewWeb3APIImpl(eth)
dbImpl := NewDBAPIImpl() /* deprecated */
engineImpl := NewEngineAPI(base, db)
for _, enabledAPI := range cfg.API {
switch enabledAPI {
@ -90,6 +91,13 @@ func APIList(ctx context.Context, db kv.RoDB,
Service: ErigonAPI(erigonImpl),
Version: "1.0",
})
case "engine":
defaultAPIList = append(defaultAPIList, rpc.API{
Namespace: "engine",
Public: true,
Service: EngineAPI(engineImpl),
Version: "1.0",
})
}
}

View File

@ -0,0 +1,104 @@
package commands
import (
"context"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/common/hexutil"
"github.com/ledgerwatch/erigon/rpc"
)
// The following code follows the Proof-of-stake specifications: https://github.com/ethereum/execution-apis/blob/v1.0.0-alpha.2/src/engine/interop/specification.md
// Status codes returned by the engine_ API
// - "SUCCESS": Operation ended successfully
// - "INVALID": Block could not be execute properly (Bad block)
// - "SYNCING": Execution layer is still syncing and trying to catch up to the block head.
const (
engineSuccessCode = "SUCCESS"
// engineInvalidCode = "INVALID"
engineSyncingCode = "SYNCING"
)
// ExecutionPayload represents an execution payload (aka slot/block)
type ExecutionPayload struct {
ParentHash *rpc.BlockNumberOrHash `json:"parentHash"`
StateRoot *rpc.BlockNumberOrHash `json:"stateRoot"`
ReceiptRoot *rpc.BlockNumberOrHash `json:"receiptRoot"`
LogsBloom *hexutil.Bytes `json:"logsBloom"`
Random *rpc.BlockNumberOrHash `json:"random"`
BlockNumber *hexutil.Uint64 `json:"blockNumber"`
GasLimit *hexutil.Uint64 `json:"gasLimit"`
GasUsed *hexutil.Uint64 `json:"gasUsed"`
Extra *hexutil.Bytes `json:"extraData"`
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas"`
BlockHash *rpc.BlockNumberOrHash `json:"blockHash"`
Timestamp *hexutil.Uint64 `json:"timestamp"`
Coinbase *common.Address `json:"coinbase"`
Transactions *[]hexutil.Bytes `json:"transactions"`
}
// PreparePayloadArgs represents a request to assemble a payload from the beacon chain
type PreparePayloadArgs struct {
Random *common.Hash `json:"random"`
Timestamp *hexutil.Uint64 `json:"timestamp"`
FeeRecipient *common.Address `json:"feeRecipients"`
}
// PreparePayloadArgs represents a request to execute POS_FORKCHOICE_UPDATED.
// specs: https://github.com/ethereum/EIPs/blob/504954e3bba2b58712d84865966ebc17bd4875f5/EIPS/eip-3675.md
type ForkchoiceArgs struct {
HeadBlockHash *rpc.BlockNumberOrHash `json:"headBlockHash"`
SafeBlockHash *rpc.BlockNumberOrHash `json:"safeBlockHash"`
FinalizedBlockHash *rpc.BlockNumberOrHash `json:"finalizedBlockHash"`
}
// EngineAPI Beacon chain communication endpoint
type EngineAPI interface {
ForkchoiceUpdatedV1(context.Context, ForkchoiceArgs, PreparePayloadArgs) (map[string]interface{}, error)
ExecutePayloadV1(context.Context, ExecutionPayload) (map[string]interface{}, error)
GetPayloadV1(context.Context, hexutil.Uint64) (ExecutionPayload, error)
}
// EngineImpl is implementation of the EngineAPI interface
type EngineImpl struct {
*BaseAPI
db kv.RoDB
}
// PreparePayload is executed only if we running a beacon Validator so it
// has relatively low priority
func (e *EngineImpl) ForkchoiceUpdatedV1(_ context.Context, _ ForkchoiceArgs, buildPayloadArgs PreparePayloadArgs) (map[string]interface{}, error) {
if buildPayloadArgs.Timestamp == nil {
return map[string]interface{}{
"status": engineSyncingCode,
}, nil
} else {
return map[string]interface{}{
"status": engineSuccessCode,
"payloadId": 0,
}, nil
}
}
// ExecutePayloadV1 takes a block from the beacon chain and do either two of the following things
// - Stageloop the block just received if we have the payload's parent hash already
// - Start the reverse sync process otherwise, and return "Syncing"
func (e *EngineImpl) ExecutePayloadV1(context.Context, ExecutionPayload) (map[string]interface{}, error) {
return map[string]interface{}{
"status": engineSyncingCode,
}, nil
}
func (e *EngineImpl) GetPayloadV1(context.Context, hexutil.Uint64) (ExecutionPayload, error) {
return ExecutionPayload{}, nil
}
// NewEngineAPI returns EngineImpl instance
func NewEngineAPI(base *BaseAPI, db kv.RoDB) *EngineImpl {
return &EngineImpl{
BaseAPI: base,
db: db,
}
}