Skip to content

Commit

Permalink
Merge pull request #6 from andytudhope/democratic-money
Browse files Browse the repository at this point in the history
Democratic Money + Understand section work
  • Loading branch information
andytudhope authored Sep 23, 2023
2 parents ab305d2 + 3181b6c commit 37ac566
Show file tree
Hide file tree
Showing 12 changed files with 353 additions and 97 deletions.
4 changes: 2 additions & 2 deletions docs/how-to/index.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Introduction
title: How To Guides
description: Start building with SUAVE
keywords:
- build
Expand Down Expand Up @@ -33,4 +33,4 @@ In this section, you'll find all of our recipes.

The tutorials are intended to get you from 0 to 1. These "how to guides" will help you get from 1 to wherever else you want to go. They do not provide history and background explanation: they show you how to do interesting and delicious things.

1. [How to setup SUAVE](/how-to/setup-suave), test your node, and participate in the network.
1. [How to run SUAVE](/how-to/run-suave), test your node, and participate in the network.
10 changes: 6 additions & 4 deletions docs/how-to/setup-suave.mdx → docs/how-to/run-suave.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Setup SUAVE
title: Run a node
description: Start running SUAVE and participating in the chain itself
keywords:
- build
Expand All @@ -8,11 +8,11 @@ keywords:
- practice
---

# Setup SUAVE
# Run a node

## Our goal

A SUAVE node is really two nodes in a trenchcoat, both participating in the same p2p network. We're going to start them both in this guide.
A SUAVE node is two nodes in a trenchcoat, both participating in the same p2p network. We're going to start both in this guide.

1. The "MEVM instance" is a full node that can run confidential computation and broadcast the results. You need to run it in order to _act on information_ you receive (i.e. run confidential computation). You need to run one MEVM instance per domain. Right now, we support Ethereum L1, but more domains will become available as we add the necessary precompiles, like `simulatePolygonBundle` or `buildOptimismBlock` etc. This will mean running many MEVM instances: one for each domain.

Expand Down Expand Up @@ -72,7 +72,7 @@ Both the MEVM instance and the Chain instance are now running in separate contai
2. Read more about [confidential computation](/reference/confidential-computation/index) and the [APIs we've built to enable it](/reference/confidential-computation/apis).
3. Dig deeper in the [architecture of the MEVM](/reference/MEVM#architecture).
4. Browse a full list of the [precompiles](/reference/precompiles) this gives you access to in [builder solidity](/reference/builder-solidity/index).
5. If you'd like to examine the Go code responsible for deploying contracts and sending transactions, you can do so [here].
5. If you'd like to examine the Go code responsible for deploying contracts and sending transactions, you can do so [here](https://github.com/flashbots/suave-geth/blob/main/suave/devenv/cmd/main.go).

### Common problems

Expand Down Expand Up @@ -130,6 +130,8 @@ You can now run any SUAVE command you like. Start by generating a new account (i
./build/bin/suave --suave account new
```

If the `--datadir` flag is not set, a geth client stores data in the `$HOME/.ethereum` directory. Depending on the chain you use, it creates a subdirectory. For example, if you run Sepolia, geth creates `$HOME/.ethereum/sepolia/`. So, if you use the `--suave` flag, your data ends up in `$HOME/.ethereum/suave/...`.

Consult the help page for anything else you need to do:
```bash
./build/bin/suave --suave help
Expand Down
8 changes: 5 additions & 3 deletions docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import GridBlock from "@site/src/components/GridBlock/GridBlock.tsx";

If MEV remains centralized, we cannot realise the promises that crypto offers.

SUAVE is our way to _decentralize the block building_ role by creating an open marketplace for mechanisms that innovate on both block building algorithms and order flow auctions. Such "MEV applications" can sustainably eliminate the centralizing forces in block building by creating a shared sequencing layer for anything effected by MEV.
SUAVE unifies coordination in a decentralized way. SUAVE does not compete with other blockchains: it is intended to aggregate bundles of transactions and coordinate the building of blocks that ultimately change the state of other chains.

_Sharing the same sequencing layer_ reduces the economic centralization pressure on all of us, enabling:
SUAVE is a permissionless and open marketplace for mechanisms. SUAVE enables anyone to innovate on auctions and other mechanisms for managing orderflow or filling blockspace, which enables us to (among other things) _decentralize block building_ for all blockchains. Such "MEV applications" can provide a sustainable [defender's advantage](https://vitalik.ca/general/2016/12/29/pos_design.html) against centralizing economic forces both within and beyond crypto.

Reducing the economic centralization pressure on other networks enables:

<Grid>
<GridBlock symbol="I." title="Blockchains">
Expand All @@ -27,7 +29,7 @@ _Sharing the same sequencing layer_ reduces the economic centralization pressure
to benefit from cross-domain MEV
</GridBlock>
<GridBlock symbol="III." title="Validators">
to maximize their revenue
to maximize revenue
</GridBlock>
<GridBlock symbol="IV." title="Humans">
to transact fairly, with the best execution.
Expand Down
8 changes: 5 additions & 3 deletions docs/reference/MEVM.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The MEVM seeks to offer every primitive of the MEV supply chain as a precompile,

For a high level description of the goals of the MEVM, we encourage you to read [this post](https://writings.flashbots.net/mevm-suave-centauri-and-beyond). On this page, we'll be diving deep into the technical implementation.

If you'd prefer to learn by running it yourself, please follow [this guide](/how-to/setup-suave).
If you'd prefer to learn by running it yourself, please follow [this guide](/how-to/run-suave).

## Architecture

Expand Down Expand Up @@ -75,9 +75,11 @@ graph TB
classDef lightgreen fill:#b3c69f,stroke:#444,stroke-width:2px, color:#333;
```

In words: the EVM is made up of a whole bunch of different parts. THose numbered `1` through `7` exist in the vanilla EVM we all know and love. Parts `8` through `13` are what we have added (or adapted in the case of the `interpreter`) in order to enable confidential computation.
In words: the EVM is made up of a whole bunch of different parts. Those numbered `1` through `7` exist in the vanilla EVM we all know and love. Parts `8` through `13` are what we have added (or adapted in the case of the `interpreter`) in order to enable confidential computation.

What do you get from the [SuaveExecutionBackend](https://github.com/flashbots/suave-geth/blob/main/core/vm/suave.go) that we've married to the EVM through the new runtime? In a nutshell: [3 new API endpoints](/reference/confidential-computation/apis):
What do you get from the [SuaveExecutionBackend](https://github.com/flashbots/suave-geth/blob/main/core/vm/suave.go) that we've married to the EVM through the new runtime?

In a nutshell: [3 new API endpoints](/reference/confidential-computation/apis):

```go
func NewRuntimeSuaveExecutionBackend(evm *EVM, caller common.Address) *SuaveExecutionBackend {
Expand Down
55 changes: 26 additions & 29 deletions docs/reference/builder-solidity/worked-examples/mev-share.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,24 @@ I want to swap on an decentralized exchange. However, I've heard that I can be e

What do I need to do, and what happens next? We'll describe the steps first in natural language. If you want to [jump straight to code, please do so](#the-code).

1. I take my signed ETH L1 Uniswap tx, and put it inside a `confidentialComputeRequest`.
1. I take my signed ETH L1 Uniswap tx, and encrypt it using the public key of a specific SUAVE node.
1. I decide whether I want all my transaction information in there, or just - for instance - the address of the pool contract I am trading on, but not the direction of the trade.
1. We call this Ethereum L1 transaction a "hint", because it need not reveal _everything_ an ordinary L1 transaction would.
2. I specify the SUAVE node for whom the hint is encrypted.
3. I craft a `creationTx` and point it at MEVShare.sol on SUAVE. Specifcally, I call the `newBid` function in that contract.
2. I send this `confidentialComputeRequest` (both the Uniswap tx and the `creationTx`) to a SUAVE node via `eth_sendRawTransaction`.
3. I wrap my L1 transaction in another transaction to the MEVShare.sol on SUAVE.
2. I send the transaction in (1.ii) to the SUAVE node I encrypted it for.
3. The SUAVE node sees this transaction, sees that it contains additional data (the encrypted L1 transaction), and passes it to the MEVM running in that node to process confidentially.

### 1. The trade

1. The MEVM enters into the `newBid` function in MEVShare.sol.
1. This _does not_ permute state: the call is to the `fetchConfidentialData` view function, which returns a result to the thread executing the EVM call.
2. `fetchConfidentialData` uses the `confidentalInputs` precompile, which enables the MEVM to fetch the data you encrypted for it.
3. Once it has the data, it calls two more precompiles:
1. Simulate whether this is a valid transaction with `simulateBundle`
2. Extracts the "hint" with `extractHint`.
4. The hint and simulation are stored in the `confidentialDataStore`, under the "mevshare" keyspace.
1. The MEVM enters into the function being called in the MEVShare.sol contract on SUAVE.
1. This _does not_ permute state: we use view functions to fetch confidential data, and then have the MEVM compute over that data off-chain.
3. Once the MEVM has the data, it will use any other combination of precompiles to extract relevant parts of it and simulate the results of any computation done ofer that data.
4. These "hint" and "simulations" are stored in the Confidential Data Store of that particular SUAVE node, under a specific "keyspace". The Confidential Data Store, and this notion of "keyspace", enables us to have public mechanisms specified in verifiable contracts which nevertheless collect and compute over private data. For instane:
2. When MEVShare.sol tells the MEVM to combine transactions from users looking for protection with transactions from searchers doing backruns, the MEVM can do so without storing any of this data in MEVShare.sol's onchain storage.
3. When EthBlockBid.sol tells the MEVM to access matched bids, it can also do, searching in its specific `confidentialDataStore`, in the same "mevshare" keyspace.
3. When EthBlockBid.sol tells the MEVM to access matched bids, it can also do, searching in its specific Confidential Data Store, in the same "mevshare" keyspace.
5. It's subtle but important: the view function being called here will return a _callback to another function_ which is intended to permute the state. If it returned the result - rather than this callback - it would expose all the confidential data when it is sent in the next step.
3. This `confidentialComputeResult` (which is a callback to a function which permutes states) is placed alongside the original `confidentialComputeRequest`.
1. We call this combination a "SUAVE transaction".
2. The callback to a function which does permute states is placed alongside the original transaction sent in (2) above.
1. We call this triple combination - the encrypted L1 transaction, the transaction I sent which wraps it, and the result from the MEVM - a "SUAVE transaction".
4. The SUAVE transaction is propagated to the public mempool via an internal p2p method in the MEVM.
5. Whoever is a proposer picks it up and includes it in the next block.

Expand All @@ -47,15 +44,15 @@ What do I need to do, and what happens next? We'll describe the steps first in n
Now, say some searcher is monitoring the chain, looking for hints about domains they're interested in. What do they do with all the above?

1. They see a new block, with a transaction to MEVShare.sol.
2. They check its logs, see a `Hint` event, and can extract the information they need to guess profitable backruns on a given domain.
3. They craft their backrun, and place _that transaction_ into another `confidentialComputeRequest` to the same SUAVE node.
4. What happens above is repeated, except that the searcher would call the `newMatch` function in MEVShare.sol.
1. This function looks aproximately similar to the `newBid` function above, except that it expects an additional param, which is the id of my original transaction that the searcher wants to backrun.
2. It uses the same `confidentalInputs`, `simulateBundle`, and `extractHint` precompiles, giving it acess to the searcher's backrun tx, which it simulates and stores as another "hint".
2. They check its logs, see a Hint event, and can extract the information they need to guess profitable backruns on a given domain.
3. They craft their backrun on ETH L1, and wrap that backrun transaction into another transaction to the same SUAVE node.
4. What happens above is repeated, except that the searcher would call a different function in MEVShare.sol.
1. This function operates similarly to what was described above, except that it expects an additional parameter, which is the id of my original transaction that the searcher wants to backrun.
2. It uses the same precompiles, giving it acess to the searcher's backrun transaction, which it simulates and stores as another "hint".
3. Using the additional input param, it then merges my original transaction with the searcher's backrun transaction and stores those in the "mevshare keyspace".
5. As above, the `newMatch` function then returns a _callback to another function_ which is intended to permute the state. This is the `confidentialComputeResult` that is propagated as a SUAVE transaction to the public mempool, so that we also don't reveal the searcher's successful backrun.
5. As above, the MEVM returns a _callback to another function_ which is intended to permute the state, all of which is propagated as a SUAVE transaction to the public mempool, so that we also don't reveal the searcher's successful backrun.

Of course, we still need to find out how the block which contains these matched transactions will be built and propagated, but let's put that to the side for one moment to look at the builder solidity code necessary to perform the above steps.
We still need to find out how the block which contains these matched transactions will be built and propagated, but let's put that to the side for one moment to look at the builder solidity code necessary to perform the above steps.

### The code

Expand All @@ -79,7 +76,7 @@ contract FetchAndEmit {
);
function fetchConfidentialData() public view returns (bytes memory) {
require(Suave.isOffchain());
require(Suave.isConfidential());
bytes memory confidentialInputs = Suave.confidentialInputs();
return abi.decode(confidentialInputs, (bytes));
Expand Down Expand Up @@ -113,8 +110,8 @@ contract MevShare is FetchAndEmit {
uint64 decryptionCondition,
address[] memory bidAllowedPeekers
) external payable returns (bytes memory) {
// 0. check offchain execution
require(Suave.isOffchain());
// 0. check confidential execution
require(Suave.isConfidential());
// 1. fetch bundle data
bytes memory bundleData = this.fetchBidConfidentialBundleData();
Expand Down Expand Up @@ -167,7 +164,7 @@ contract MevShare is FetchAndEmit {
// WARNING : this function will copy the original mev share bid
// into a new key with potentially different permsissions
require(Suave.isOffchain());
require(Suave.isConfidential());
// 1. fetch confidential data
bytes memory matchBundleData = this.fetchBidConfidentialBundleData();
Expand Down Expand Up @@ -263,7 +260,7 @@ contract EthBlockBid is FetchAndEmit {
Suave.BuildBlockArgs memory blockArgs,
uint64 blockHeight
) public returns (bytes memory) {
require(Suave.isOffchain());
require(Suave.isConfidential());
Suave.Bid[] memory allShareMatchBids = Suave.fetchBids(
blockHeight,
Expand Down Expand Up @@ -335,7 +332,7 @@ contract EthBlockBid is FetchAndEmit {
Suave.BidId[] memory bids,
string memory namespace
) public virtual returns (bytes memory) {
require(Suave.isOffchain());
require(Suave.isConfidential());
(Suave.Bid memory blockBid, bytes memory builderBid) = this.doBuild(blockArgs, blockHeight, bids, namespace);
Expand Down Expand Up @@ -383,7 +380,7 @@ contract EthBlockBid is FetchAndEmit {
Suave.BidId bidId,
bytes memory signedBlindedHeader
) public view returns (bytes memory) {
require(Suave.isOffchain());
require(Suave.isConfidential());
// TODO: verify the header is correct
// TODO: incorporate protocol name
Expand All @@ -409,7 +406,7 @@ contract EthBlockBidSender is EthBlockBid {
Suave.BidId[] memory bids,
string memory namespace
) public virtual override returns (bytes memory) {
require(Suave.isOffchain());
require(Suave.isConfidential());
(Suave.Bid memory blockBid, bytes memory builderBid) = this.doBuild(blockArgs, blockHeight, bids, namespace);
(bool ok, bytes memory err) = Suave.submitEthBlockBidToRelay(boostRelayUrl, builderBid);
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/index.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Introduction
title: Technical Details
description: All the up-to-date treasure maps to help you navigate SUAVE like the pirate you were born to be
keywords:
- references
Expand Down
File renamed without changes.
Loading

0 comments on commit 37ac566

Please sign in to comment.