Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
tkstanczak authored and jparyani committed May 18, 2021
1 parent cb4764f commit 36236d5
Show file tree
Hide file tree
Showing 5 changed files with 575 additions and 184 deletions.
130 changes: 130 additions & 0 deletions MEV_spec_RPC_v0_1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
tags: spec
---

# MEV-Geth RPC v0.1

# eth_sendBundle

### Description

Sends a bundle of transactions to the miner. The bundle has to be executed at the beginning of the block (before any other transactions), with bundle transactions executed exactly in the same order as provided in the bundle. During the Flashbots Alpha this is only called by the Flashbots relay.

| Name | Type | Description | Comment
--------|----------|-----------|-----------
transactions | `Array<Data>` | Array of signed transactions (`eth_sendRawTransaction` style, signed and RLP-encoded) | a no-op in the light mode
blockNumber |`Quantity` |Exact block number at which the bundle can be included. |bundle is evicted after the block
minTimestamp |`Quantity` |Minimum (inclusive) block timestamp at which the bundle can be included. If this value is 0 then any timestamp is acceptable.
maxTimestamp |`Quantity` |Maximum (inclusive) block timestamp at which the bundle can be included. If this value is 0 then any timestamp is acceptable.

### Returns

{`boolean`} - `true` if bundle has been accepted by the node, otherwise `false`

### Example

```bash
# Request
curl -X POST --data '{
"id": 1337,
"jsonrpc": "2.0",
"method": "eth_sendBundle",
"params": [
[
"f9014946843b9aca00830493e094a011e5f4ea471ee4341a135bb1a4af368155d7a280b8e40d5f2659000000000000000000000000fdd45a22dd1d606b3782f2119621e928e32743000000000000000000000000000000000000000000000000000000000077359400000000000000000000000000000000000000000000000",
"f86e8204d085012a05f200830c350094daf24c20717f428f00d8448d74d67a77f67ceb8287354a6ba7a18000802ea00e411bcb660dd8d47717df89078d2e8160c08e7f11cb7ad0ee935e7436eceb32a013ee00a21b7fa0a9f9c1224d11261648191875d4633aed6003543ea319f12b62"
],
"0x12ab34",
"0x0",
"0x0"
]
}' <url>

# Response
{
"id": 1337,
"jsonrpc": "2.0",
"result": "true"
}
```

# eth_callBundle

### Description

Simulate a bundle of transactions at the top of a block.

After retrieving the block specified in the `blockNrOrHash` it takes the same `blockhash`, `gasLimit`, `difficulty`, same `timestamp` unless the `blockTimestamp` property is specified, and increases the block number by `1`. `eth_callBundle` will timeout after `5` seconds.

| Name | Type | Description |
| ---- | ---- | ----------- |
| encodedTxs | `Array<Data>` | Array of signed transactions (`eth_sendRawTransaction` style, signed and RLP-encoded) |
| blockNrOrHash | `Quantity\|string\|Block Identifier` | Block number, or one of "latest", "earliest" or "pending", or a block identifier as described in {Block Identifier} |
| blockTimestamp |`Quantity` |Block timestamp to be used in replacement of the timestamp taken from the parent block. |

### Returns

Map<`Data`, "error|value" : `Data`> - a mapping from transaction hashes to execution results with error or output (value) for each of the transactions

### Example

```bash
# Request
curl -X POST --data '{
"id": 1337,
"jsonrpc": "2.0",
"method": "eth_callBundle",
"params": [
[
"f9014946843b9aca00830493e094a011e5f4ea471ee4341a135bb1a4af368155d7a280b8e40d5f2659000000000000000000000000fdd45a22dd1d606b3782f2119621e928e32743000000000000000000000000000000000000000000000000000000000077359400000000000000000000000000000000000000000000000",
"f86e8204d085012a05f200830c350094daf24c20717f428f00d8448d74d67a77f67ceb8287354a6ba7a18000802ea00e411bcb660dd8d47717df89078d2e8160c08e7f11cb7ad0ee935e7436eceb32a013ee00a21b7fa0a9f9c1224d11261648191875d4633aed6003543ea319f12b62"
],
"0x12ab34"
]
}' <url>

# Response
{
"id": 1337,
"jsonrpc": "2.0",
"result":
{
"0x22b3806fbef9532db4105475222983404783aacd4d865ea5dab76a84aa1a07eb" : {
"value" : "0x0012"
},
"0x489e3b5493af31d55059f8e296351b267720bc4ba7dc170871c1d789e5541027" : {
"value" : "0xabcd"
}
}
}
```

---

Below type description can also be found in [EIP-1474](https://eips.ethereum.org/EIPS/eip-1474)

### `Quantity`

- A `Quantity` value **MUST** be hex-encoded.
- A `Quantity` value **MUST** be "0x"-prefixed.
- A `Quantity` value **MUST** be expressed using the fewest possible hex digits per byte.
- A `Quantity` value **MUST** express zero as "0x0".

### `Data`

-`Data` value **MUST** be hex-encoded.
-`Data` value **MUST** be “0x”-prefixed.
-`Data` value **MUST** be expressed using two hex digits per byte.

### `Block Identifier`

Since there is no way to clearly distinguish between a `Data` parameter and a `Quantity` parameter, [EIP-1898](https://eips.ethereum.org/EIPS/eip-1898) provides a format to specify a block either using the block hash or block number. The block identifier is a JSON `object` with the following fields:

| Position | Name | Type | Description |
| -------- | ---- | ---- | ------------|
| 0A |blockNumber |`Quantity` |The block in the canonical chain with this number |
| 0B |blockHash |`Data` | The block uniquely identified by this hash. The blockNumber and blockHash properties are mutually exclusive; exactly one of them must be set. |
| 1B |requireCanonical |`boolean` | (optional) Whether or not to throw an error if the block is not in the canonical chain as described below. Only allowed in conjunction with the blockHash tag. Defaults to false. |


If the block is not found, the callee SHOULD raise a JSON-RPC error (the recommended error code is `-32001: Resource not found`. If the tag is `blockHash` and `requireCanonical` is `true`, the callee SHOULD additionally raise a JSON-RPC error if the block is not in the canonical chain (the recommended error code is `-32000: Invalid input` and in any case should be different than the error code for the block not found case so that the caller can distinguish the cases). The block-not-found check SHOULD take precedence over the block-is-canonical check, so that if the block is not found the callee raises block-not-found rather than block-not-canonical.
133 changes: 133 additions & 0 deletions MEV_spec_RPC_v0_2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
tags: spec
---

# MEV-Geth RPC v0.2

# eth_sendBundle

### Description

Sends a bundle of transactions to the miner. The bundle has to be executed at the beginning of the block (before any other transactions), with bundle transactions executed exactly in the same order as provided in the bundle. During the Flashbots Alpha this is only called by the Flashbots relay.

| Name | Type | Description | Comment
--------|----------|-----------|-----------
txs | `Array<Data>` | Array of signed transactions (`eth_sendRawTransaction` style, signed and RLP-encoded) | a no-op in the light mode
blockNumber |`Quantity` |Exact block number at which the bundle can be included. |bundle is evicted after the block
minTimestamp |`Quantity` |Minimum (inclusive) block timestamp at which the bundle can be included. If this value is 0 then any timestamp is acceptable.
maxTimestamp |`Quantity` |Maximum (inclusive) block timestamp at which the bundle can be included. If this value is 0 then any timestamp is acceptable.
revertingTxHashes |Array<`Data`> |Array of tx hashes within the bundle that are allowed to cause the EVM execution to revert without preventing the bundle inclusion in a block.

### Returns

{`boolean`} - `true` if bundle has been accepted by the node, otherwise `false`

### Example

```bash
# Request
curl -X POST --data '{
"id": 1337,
"jsonrpc": "2.0",
"method": "eth_sendBundle",
"params": [
{
"txs" : [
"f9014946843b9aca00830493e094a011e5f4ea471ee4341a135bb1a4af368155d7a280b8e40d5f2659000000000000000000000000fdd45a22dd1d606b3782f2119621e928e32743000000000000000000000000000000000000000000000000000000000077359400000000000000000000000000000000000000000000000",
"f86e8204d085012a05f200830c350094daf24c20717f428f00d8448d74d67a77f67ceb8287354a6ba7a18000802ea00e411bcb660dd8d47717df89078d2e8160c08e7f11cb7ad0ee935e7436eceb32a013ee00a21b7fa0a9f9c1224d11261648191875d4633aed6003543ea319f12b62"
],
"blockNumber" : "0x12ab34",
"minTimestamp" : "0x0",
"minTimestamp" :"0x0"
}
]
}' <url>

# Response
{
"id": 1337,
"jsonrpc": "2.0",
"result": "true"
}
```

# eth_callBundle

### Description

Simulate a bundle of transactions at the top of a block.

After retrieving the block specified in the `blockNrOrHash` it takes the same `blockhash`, `gasLimit`, `difficulty`, same `timestamp` unless the `blockTimestamp` property is specified, and increases the block number by `1`. `eth_callBundle` will timeout after `5` seconds.

| Name | Type | Description |
| ---- | ---- | ----------- |
| encodedTxs | `Array<Data>` | Array of signed transactions (`eth_sendRawTransaction` style, signed and RLP-encoded) |
| blockNrOrHash | `Quantity\|string\|Block Identifier` | Block number, or one of "latest", "earliest" or "pending", or a block identifier as described in {Block Identifier} |
| blockTimestamp |`Quantity` |Block timestamp to be used in replacement of the timestamp taken from the parent block. |

### Returns

Map<`Data`, "error|value" : `Data`> - a mapping from transaction hashes to execution results with error or output (value) for each of the transactions

### Example

```bash
# Request
curl -X POST --data '{
"id": 1337,
"jsonrpc": "2.0",
"method": "eth_callBundle",
"params": [
[
"f9014946843b9aca00830493e094a011e5f4ea471ee4341a135bb1a4af368155d7a280b8e40d5f2659000000000000000000000000fdd45a22dd1d606b3782f2119621e928e32743000000000000000000000000000000000000000000000000000000000077359400000000000000000000000000000000000000000000000",
"f86e8204d085012a05f200830c350094daf24c20717f428f00d8448d74d67a77f67ceb8287354a6ba7a18000802ea00e411bcb660dd8d47717df89078d2e8160c08e7f11cb7ad0ee935e7436eceb32a013ee00a21b7fa0a9f9c1224d11261648191875d4633aed6003543ea319f12b62"
],
"0x12ab34"
]
}' <url>

# Response
{
"id": 1337,
"jsonrpc": "2.0",
"result":
{
"0x22b3806fbef9532db4105475222983404783aacd4d865ea5dab76a84aa1a07eb" : {
"value" : "0x0012"
},
"0x489e3b5493af31d55059f8e296351b267720bc4ba7dc170871c1d789e5541027" : {
"value" : "0xabcd"
}
}
}
```

---

Below type description can also be found in [EIP-1474](https://eips.ethereum.org/EIPS/eip-1474)

### `Quantity`

- A `Quantity` value **MUST** be hex-encoded.
- A `Quantity` value **MUST** be "0x"-prefixed.
- A `Quantity` value **MUST** be expressed using the fewest possible hex digits per byte.
- A `Quantity` value **MUST** express zero as "0x0".

### `Data`

-`Data` value **MUST** be hex-encoded.
-`Data` value **MUST** be “0x”-prefixed.
-`Data` value **MUST** be expressed using two hex digits per byte.

### `Block Identifier`

Since there is no way to clearly distinguish between a `Data` parameter and a `Quantity` parameter, [EIP-1898](https://eips.ethereum.org/EIPS/eip-1898) provides a format to specify a block either using the block hash or block number. The block identifier is a JSON `object` with the following fields:

| Position | Name | Type | Description |
| -------- | ---- | ---- | ------------|
| 0A |blockNumber |`Quantity` |The block in the canonical chain with this number |
| 0B |blockHash |`Data` | The block uniquely identified by this hash. The blockNumber and blockHash properties are mutually exclusive; exactly one of them must be set. |
| 1B |requireCanonical |`boolean` | (optional) Whether or not to throw an error if the block is not in the canonical chain as described below. Only allowed in conjunction with the blockHash tag. Defaults to false. |


If the block is not found, the callee SHOULD raise a JSON-RPC error (the recommended error code is `-32001: Resource not found`. If the tag is `blockHash` and `requireCanonical` is `true`, the callee SHOULD additionally raise a JSON-RPC error if the block is not in the canonical chain (the recommended error code is `-32000: Invalid input` and in any case should be different than the error code for the block not found case so that the caller can distinguish the cases). The block-not-found check SHOULD take precedence over the block-is-canonical check, so that if the block is not found the callee raises block-not-found rather than block-not-canonical.
120 changes: 120 additions & 0 deletions MEV_spec_v0_1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
tags: spec
---

# MEV-Geth v0.1 specification

## Simple Summary

Defines the construction and usage of MEV bundles by the miners. Provides specification for custom implementation of required node changes so that MEV bundles can be used correctly.

## Abstract

`MevBundles` are stored by the node and the best bundle is added to the block in front of other transactions. `MevBundles` are sorted by their `adjusted gas price`.

## Motivation

We believe that without the adoption of neutral, public, open-source infrastructure for permissionless MEV extraction, MEV risks becoming an insiders' game. We commit as an organisation to releasing reference implementations for participation in fair, ethical, and politically neutral MEV extraction.

## Specification

The key words `MUST`, `MUST NOT`, `REQUIRED`, `SHALL`, `SHALL NOT`, `SHOULD`, `SHOULD NOT`, `RECOMMENDED`, `MAY`, and `OPTIONAL` in this document are to be interpreted as described in [RFC-2119](https://www.ietf.org/rfc/rfc2119.txt).

### Definitions

#### `Bundle`
A set of transactions that `MUST` be executed together and `MUST` be executed at the beginning of the block.

#### `Unit of work`
A `transaction`, a `bundle` or a `block`.

#### `Subunit`
A discernible `unit of work` that is a part of a bigger `unit of work`. A `transaction` is a `subunit` of a `bundle` or a `block`. A `bundle` is a `subunit` of a `block`.

#### `Total gas used`
A sum of gas units used by each transaction from the `unit of work`.

#### `Average gas price`
Sum of (`gas price` * `total gas used`) of all `subunits` divided by the `total gas used` of the unit.

#### `Direct coinbase payment`
A value of a transaction with a recipient set to be the same as the `coinbase` address.

#### `Contract coinbase payment`
A payment from a smart contract to the `coinbase` address.

#### `Profit`
A difference between the balance of the `coinbase` account at the end and at the beginning of the execution of a `unit of work`. We can measure a `transaction profit`, a `bundle profit`, and a `block profit`.

Balance of the `coinbase` account changes in the following way
|Unit of work|Balance Change|
|-|-|
|Transaction| `average gas price` * `total gas used` + `direct coinbase payment` + `contract coinbase payment` |
|Bundle | `average gas price` * `total gas used` + `direct coinbase payment` + `contract coinbase payment` |
|Block | `block reward` + `average gas price` * `total gas used` + `direct coinbase payment` + `contract coinbase payment` |

#### `Adjusted gas price`
`Unit of work` `profit` divided by the `total gas used` by the `unit of work`.

#### `MevBundle`
An object with four properties:

|Property| Type|Description|
|-|-|-|
|`transactions`|`Array<RLP(SignedTransaction)>`|A list of transactions in the bundle. Each transaction is signed and RLP-encoded.|
|`blockNumber`|`uint64`|The exact block number at which the bundle can be executed|
|`minTimestamp`|`uint64`|Minimum block timestamp (inclusive) at which the bundle can be executed|
|`maxTimestamp`|`uint64`|Maximum block timestamp (inclusive) at which the bundle can be executed|

### Bundle construction

Bundle `SHOULD` contain transactions with nonces that are following the current nonces of the signing addresses or other transactions preceding them in the same bundle.

A bundle `MUST` contain at least one transaction. There is no upper limit for the number of transactions in the bundle, however bundles that exceed the block gas limit will always be rejected.

A bundle `MAY` include a `direct coinbase payment` or a `contract coinbase payment`. Bundles that do not contain such payments may lose comparison when their `profit` is compared with other bundles.

The `maxTimestamp` value `MUST` be greater or equal the `minTimestamp` value.

### Accepting bundles from the network

Node `MUST` provide a way of exposing a JSON RPC endpoint accepting `eth_sendBundle` calls (specified [here](MEV_spec_RPC_v0_1.md)). Such endpoint `SHOULD` only be accepting calls from `MEV-relay` but there is no requirement to restrict it through the node source code as it can be done on the infrastructure level.

### Bundle eligibility

Any bundle that is correctly constructed `MUST` have a `blockNumber` field set which specifies in which block it can be included. If the node has already progressed to a later block number then such bundle `MAY` be removed from memory.

Any bundle that is correctly constructed `MAY` have a `minTimestamp` and/or a `maxTimestamp` field set. Default values for both of these fields are `0` and the meaning of `0` is that any block timestamp value is accepted. When these values are not `0`, then `block.timestamp` is compared with them. If the current `block.timestamp` is greater than the `maxTimestamp` then the bundle `MUST NOT` be included in the block and `MAY` be removed from memory. If the `block.timestamp` is less than `minTimestamp` then the bundle `MUST NOT` be included in the block and `SHOULD NOT` be removed from memory (it awaits future blocks).

### Block construction

A block `MUST` either contain one bundle or no bundles. When a bundle is included it `MUST` be the bundle with the highest `adjusted gas price` among eligible bundles. The node `SHOULD` be able to compare a `block profit` in cases when a bundle is included (MEV block) and when no bundles are included (regular block) and choose a block with the highest `profit`.

A block with a bundle `MUST` place the bundle at the beginning of the block and `MUST NOT` insert any transactions between the bundle transactions.

### Bundle eviction

Node `SHOULD` be able to limit the number of bundles kept in memory and apply an algorithm for selecting bundles to be evicted when too many eligible bundles have been received.

## Rationale

### At most one MevBundle gets included in the block

There are two reasons for which multiple bundles in a block may cause problems:

- two bundles may affect each other's `profit` and so the bundle creator may not be willing to accept a possibility of not being added in the front of the block
- simulating multiple bundle combinations may be very straining for the node infrastructure and introduce excessive latency into the block creation process

Both of these problems may be addressed in the future versions.

## Each bundle needs a blockNumber

This allows specifying bundles to be included in the future blocks (e.g. just after some smart contracts change their state). This cannot be used to ensure a specific parent block / hash.

## Backwards Compatibility

This change is not affecting consensus and is fully backwards compatible.

## Security Considerations

`MevBundles` that are awaiting future blocks must be stored by the miner's node and it is important to ensure that there is a mechanism to ensure that the storage is limits are not exceeded (whether they are store in memory or persisted).
Loading

0 comments on commit 36236d5

Please sign in to comment.