From e2a66831fcc5984f478513ce298607e178c364e8 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:38:06 -0600 Subject: [PATCH] Update EIP-7685: General purpose execution layer requests Merged by EIP-Bot. --- EIPS/eip-7685.md | 102 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 13 deletions(-) diff --git a/EIPS/eip-7685.md b/EIPS/eip-7685.md index e97845468f614b..428e1902581ffc 100644 --- a/EIPS/eip-7685.md +++ b/EIPS/eip-7685.md @@ -12,11 +12,18 @@ created: 2024-04-14 ## Abstract -This proposal defines a general purpose framework for propagating contract-triggered requests from execution layer to the consensus layer. It extends the header and body with only a single field each to store the request information. +This proposal defines a general purpose framework for storing contract-triggered +requests. It extends the execution header and body with a single field each to +store the request information. This inherently exposes the requests to the +consensus layer, which can then process each one. ## Motivation -The proliferation of smart contract controlled validators has caused there to be a demand for additional EL triggered behaviors. By allowing these systems to delegate administrative operations to their governing smart contracts, they can avoid intermediaries needing to step in and ensure certain operations occur. This creates a safer system for end users. +The proliferation of smart contract controlled validators has caused there to be +a demand for additional EL triggered behaviors. By allowing these systems to +delegate administrative operations to their governing smart contracts, they can +avoid intermediaries needing to step in and ensure certain operations occur. +This creates a safer system for end users. ## Specification @@ -24,38 +31,107 @@ The proliferation of smart contract controlled validators has caused there to be #### Request -A `Request` consists of a `RequestType` prepended to an opaque byte array `RequestData`. +A `request` consists of a `request_type` prepended to an opaque byte array +`request_data`: ``` -Request = RequestType ++ RequestData +request = request_type ++ request_data ``` -Let `Requests` be the list of all `Request` objects in the block in ascending order by type. +Let `requests` be the list of all `request` objects in the block in ascending +order by type. For example: -#### Header +``` +[0x00_request_0, 0x01_request_0, 0x01_request_1, 0x02_request_0, ...] +``` + +The ordering of requests within a type is to be defined by each request type. + +#### Block structure + +The block body is appended with a list of requests. RLP encoding of the extended +block body structure is computed as follows: + +```python +block_body_rlp = rlp([ + field_0, + ..., + # Latest block body field before `requests` + field_n, + [request_0, ..., request_k], +]) +``` + +#### Block Header + +Extend the header with a new 32 byte value `requests_root`. -Extend the header with a new 32 byte value `RequestsRoot`. +Let `requests_root` be the root of a Merkle-Patricia trie keyed by the index in +the list of `requests`. This is equivalent to how the transaction trie root is +computed. -Let `RequestsRoot` be the root of a Merkle-Patricia trie keyed by the index in the list of `Requests`. This is equivalent to how the transaction trie root is computed. + The `requests_root` field value is therefore computed as follows: + +```python +def compute_trie_root_from_indexed_data(data): + trie = Trie.from([(i, obj) for i, obj in enumerate(data)]) + return trie.root + +block.header.requests_root = compute_trie_root_from_indexed_data(block.body.requests) +``` ### Consensus Layer -Each proposal may choose how to extend `ExecutionPayload` to include the new EL request and how and when the request is processed. +Each proposal may choose how to extend the beacon chain types to include the new +EL request. ## Rationale ### Opaque byte array rather than an RLP array -By having the second byte on be opaque bytes, rather than an RLP (or other encoding) list, we can support different encoding formats for the transaction payload in the future such as SSZ, LEB128, or a fixed width format. +By having the second byte on be opaque bytes, rather than an RLP (or other +encoding) list, we can support different encoding formats for the transaction +payload in the future such as SSZ, LEB128, or a fixed width format. ### Request source and validity -This EIP makes no strict requirement where a request may come from nor when/how a request must be validated. This is to provide future protocol designers maximum flexibility. +This EIP makes no strict requirement where a request may come from nor when/how +a request must be validated. This is to provide future protocol designers +maximum flexibility. The authors' recommendations on source and validity of requests are: -* The source of requests should be from the execution of transactions. More specifically, transactions which make calls to designated system contracts that store the request in account. The storage would later be retrieved by a post-block system call to the contract. Alternatively, if the system call does not need to be inherently concerned with rate limiting, it could rely simply on emitting an event which is later parsed post-block by the system and converted into a request. -* A request's validity can often not be fully verified at the execution layer. This is why they are referred to merely as "requests"; they do not carry the authority on their own unilaterally catalyze and action. We expect the system contracts to perform whatever validation is possible by the EL and then pass it on to the CL for further validation. +* The source of requests should be from the execution of transactions. More + specifically, transactions which make calls to designated system contracts + that store the request in account. The storage would later be retrieved by a + post-block system call to the contract. Alternatively, if the system call does + not need to be inherently concerned with rate limiting, it could rely simply + on emitting an event which is later parsed post-block by the system and + converted into a request. +* A request's validity can often not be fully verified at the execution layer. + This is why they are referred to merely as "requests"; they do not carry the + authority on their own unilaterally catalyze and action. We expect the system + contracts to perform whatever validation is possible by the EL and then pass + it on to the CL for further validation. + +### Ordering + +The ordering across types is ascending by type. This is to simplify the process +of verifying that all requests which were committed to in `requests_root` were +found in the block. + +An alternative could be to order by when the request was generated within the +block. Since it's expected that many requests will be accumulated at the end of +the block via system calls, this would be difficult to enforce. Therefore, +ordering by type is the most straightforward ordering which ensures integrity. + +#### Intra-type + +Within the same type, order is not defined. This is because the data of the +request is opaque as far as this EIP is concerned. The only valid ordering +scheme would be lexicographical ordering of the opaque byte data. + +For this reason, it is to be determined by each request type individually. ## Backwards Compatibility