From 78511aef4754b4a64faaf4056566ee1035b7e56f Mon Sep 17 00:00:00 2001 From: Giulio Rebuffo Date: Sun, 7 Nov 2021 00:53:01 +0100 Subject: [PATCH 1/3] added engine_ namespace in rpcdaemon --- cmd/rpcdaemon/commands/daemon.go | 8 +++ cmd/rpcdaemon/commands/engine_api.go | 104 +++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 cmd/rpcdaemon/commands/engine_api.go diff --git a/cmd/rpcdaemon/commands/daemon.go b/cmd/rpcdaemon/commands/daemon.go index 67ae90a4c34..a32f54c4664 100644 --- a/cmd/rpcdaemon/commands/daemon.go +++ b/cmd/rpcdaemon/commands/daemon.go @@ -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", + }) } } diff --git a/cmd/rpcdaemon/commands/engine_api.go b/cmd/rpcdaemon/commands/engine_api.go new file mode 100644 index 00000000000..7588f553ef1 --- /dev/null +++ b/cmd/rpcdaemon/commands/engine_api.go @@ -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, + } +} From 0cd8c363b23d18bdd446011758ebee01e8a85a72 Mon Sep 17 00:00:00 2001 From: Giulio Rebuffo Date: Sun, 7 Nov 2021 01:11:22 +0100 Subject: [PATCH 2/3] commented out unused (for now) status code --- cmd/rpcdaemon/commands/engine_api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/engine_api.go b/cmd/rpcdaemon/commands/engine_api.go index 7588f553ef1..c46cac51b65 100644 --- a/cmd/rpcdaemon/commands/engine_api.go +++ b/cmd/rpcdaemon/commands/engine_api.go @@ -17,7 +17,7 @@ import ( // - "SYNCING": Execution layer is still syncing and trying to catch up to the block head. const ( engineSuccessCode = "SUCCESS" - engineInvalidCode = "INVALID" +// engineInvalidCode = "INVALID" engineSyncingCode = "SYNCING" ) From 03e848e3a250beca874e7b2c8284a97877d6e70a Mon Sep 17 00:00:00 2001 From: Giulio Rebuffo Date: Sun, 7 Nov 2021 01:11:43 +0100 Subject: [PATCH 3/3] lint --- cmd/rpcdaemon/commands/engine_api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/engine_api.go b/cmd/rpcdaemon/commands/engine_api.go index c46cac51b65..919504d3933 100644 --- a/cmd/rpcdaemon/commands/engine_api.go +++ b/cmd/rpcdaemon/commands/engine_api.go @@ -17,7 +17,7 @@ import ( // - "SYNCING": Execution layer is still syncing and trying to catch up to the block head. const ( engineSuccessCode = "SUCCESS" -// engineInvalidCode = "INVALID" + // engineInvalidCode = "INVALID" engineSyncingCode = "SYNCING" )