Skip to content

Commit

Permalink
Merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranbt committed Jan 9, 2024
2 parents 0b1dbf0 + 0b37577 commit eb3c4b7
Show file tree
Hide file tree
Showing 17 changed files with 538 additions and 183 deletions.
4 changes: 4 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
# they will be requested for review when someone opens a pull request.
* @ferranbt @metachris @zeroXbrock
34 changes: 34 additions & 0 deletions .github/workflows/check-gen-code.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Check forge-gen
on:
push:
branches:
- main
pull_request:

env:
FOUNDRY_PROFILE: ci

jobs:
check-forge-gen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Install deps
run: forge install

- name: Generate forge-gen
run: go run ./tools/forge-gen/main.go --apply

- name: Compare the expected and actual src/forge/ directories
run: |
if [ "$(git diff --ignore-space-at-eol src/forge/ | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build. See status below:"
git diff
exit 1
fi
11 changes: 9 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI
on:
push:
branches:
- master
- main
pull_request:

env:
Expand All @@ -14,6 +14,13 @@ jobs:
steps:
- uses: actions/checkout@v2

- name: Install suave-geth
uses: flashbots/[email protected]

- name: Run suave
run: |
suave-geth --suave.dev &
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
Expand All @@ -23,4 +30,4 @@ jobs:
run: forge install

- name: Run tests
run: forge test
run: forge test --ffi
31 changes: 28 additions & 3 deletions .github/workflows/suave-lib-sync.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: SuaveLib sync

on: [repository_dispatch, workflow_dispatch]
on:
workflow_dispatch:
repository_dispatch:
types: [suavelib-sync]

permissions:
pull-requests: write
Expand All @@ -12,12 +15,25 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Log Dispatch Information
if: ${{ github.event_name == 'repository_dispatch' }}
run: |
echo "this run was triggered by dispatch from repo: flashbots/suave-geth"
echo "ref: ${{ github.event.client_payload.ref }}"
echo "sha: ${{ github.event.client_payload.sha }}"
echo "run: ${{ github.event.client_payload.run }}"
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ^1.21

- name: Checkout tools repo
uses: actions/checkout@v4
with:
Expand All @@ -36,11 +52,20 @@ jobs:
- name: Mirror
run: |
cp suave-geth/suave/sol/libraries/Suave.sol ./src/suavelib/Suave.sol
cp suave-geth/suave/sol/libraries/SuaveForge.sol ./src/suavelib/SuaveForge.sol
git add ./src/suavelib/Suave.sol
git add ./src/suavelib/SuaveForge.sol
rm -rf suave-geth
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Regenerate Forge registry
run: |
forge build
go run ./tools/forge-gen/main.go --apply
git add ./src/forge/Registry.sol
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,38 @@ contract Example {
}
}
```

## Forge integration

In order to use `forge`, you need to have a running `Suave` node and the `suave` binary in your path.

To run `Suave` in development mode, use the following command:

```bash
$ suave --suave.dev
```

Then, your `forge` scripts/test must import the `SuaveEnabled` contract from the `suave-std/Test.sol` file.

```solidity
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.13;
import "forge-std/Test.sol";
import "suave-std/Test.sol";
import "suave-std/Suave.sol";
contract TestForge is Test, SuaveEnabled {
address[] public addressList = [0xC8df3686b4Afb2BB53e60EAe97EF043FE03Fb829];
function testConfidentialStore() public {
Suave.DataRecord memory record = Suave.newDataRecord(0, addressList, addressList, "namespace");
bytes memory value = abi.encode("suave works with forge!");
Suave.confidentialStore(record.id, "key1", value);
bytes memory found = Suave.confidentialRetrieve(record.id, "key1");
assertEq(keccak256(found), keccak256(value));
}
}
```
67 changes: 67 additions & 0 deletions src/Test.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.8;

import "./forge/Registry.sol";
import "forge-std/Test.sol";

contract SuaveEnabled is Test {
function setUp() public {
string[] memory inputs = new string[](3);
inputs[0] = "suave-geth";
inputs[1] = "forge";
inputs[2] = "status";

try vm.ffi(inputs) returns (bytes memory response) {
// the status call of the `suave-geth forge` command fails with the 'not-ok' prefix
// which is '6e6f742d6f6b' in hex
if (isPrefix(hex"6e6f742d6f6b", response)) {
revert("Local Suave node not detected running");
}
} catch (bytes memory reason) {
revert(detectErrorMessage(reason));
}

Registry.enable();
}

function detectErrorMessage(bytes memory reason) internal pure returns (string memory) {
// Errors from cheatcodes are reported as 'CheatcodeError(string)' events
// 'eeaa9e6f' is the signature of the event
if (!isPrefix(hex"eeaa9e6f", reason)) {
return string(reason);
}

// retrieve the body of the event by removing the signature
bytes memory eventBody = new bytes(reason.length - 4);
for (uint256 i = 4; i < reason.length; i++) {
eventBody[i - 4] = reason[i];
}

// decode event as 'tuple(bytes message)' since it is equivalent to tuple(string)
(bytes memory message) = abi.decode(eventBody, (bytes));

// the prefix is 'FFI is disabled' in hex
if (isPrefix(hex"4646492069732064697361626c6564", message)) {
return "Suave <> Forge integration requires the --ffi flag to be enabled";
}

// the prefix is 'failed to execute command' in hex
if (isPrefix(hex"6661696c656420746f206578656375746520636f6d6d616e64", message)) {
return "Forge cannot locate the 'suave' binary. Is it installed in $PATH?";
}

return string(message);
}

function isPrefix(bytes memory prefix, bytes memory data) internal pure returns (bool) {
if (prefix.length > data.length) {
return false;
}
for (uint256 i = 0; i < prefix.length; i++) {
if (prefix[i] != data[i]) {
return false;
}
}
return true;
}
}
15 changes: 13 additions & 2 deletions src/Transactions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ library Transactions {
items[0] = RLPWriter.writeUint(txStruct.nonce);
items[1] = RLPWriter.writeUint(txStruct.gasPrice);
items[2] = RLPWriter.writeUint(txStruct.gas);
items[3] = RLPWriter.writeAddress(txStruct.to);

if (txStruct.to == address(0)) {
items[3] = RLPWriter.writeBytes(bytes(""));
} else {
items[3] = RLPWriter.writeAddress(txStruct.to);
}
items[4] = RLPWriter.writeUint(txStruct.value);
items[5] = RLPWriter.writeBytes(txStruct.data);
items[6] = RLPWriter.writeBytes(txStruct.v);
Expand All @@ -47,7 +52,13 @@ library Transactions {
txStruct.nonce = uint64(ls[0].toUint());
txStruct.gasPrice = uint64(ls[1].toUint());
txStruct.gas = uint64(ls[2].toUint());
txStruct.to = ls[3].toAddress();

if (ls[3].toRlpBytes().length == 1) {
txStruct.to = address(0);
} else {
txStruct.to = ls[3].toAddress();
}

txStruct.value = uint64(ls[4].toUint());
txStruct.data = ls[5].toBytes();
txStruct.v = ls[6].toBytes();
Expand Down
47 changes: 47 additions & 0 deletions src/forge/Connector.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.8;

interface connectorVM {
function ffi(string[] calldata commandInput) external view returns (bytes memory result);
}

contract Connector {
connectorVM constant vm = connectorVM(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);

function forgeIt(bytes memory addr, bytes memory data) internal view returns (bytes memory) {
string memory addrHex = iToHex(addr);
string memory dataHex = iToHex(data);

string[] memory inputs = new string[](4);
inputs[0] = "suave-geth";
inputs[1] = "forge";
inputs[2] = addrHex;
inputs[3] = dataHex;

bytes memory res = vm.ffi(inputs);
return res;
}

function iToHex(bytes memory buffer) public pure returns (string memory) {
bytes memory converted = new bytes(buffer.length * 2);

bytes memory _base = "0123456789abcdef";

for (uint256 i = 0; i < buffer.length; i++) {
converted[i * 2] = _base[uint8(buffer[i]) / _base.length];
converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];
}

return string(abi.encodePacked("0x", converted));
}

fallback() external {
bytes memory msgdata = forgeIt(abi.encodePacked(address(this)), msg.data);

assembly {
let location := msgdata
let length := mload(msgdata)
return(add(location, 0x20), length)
}
}
}
41 changes: 41 additions & 0 deletions src/forge/Registry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: UNLICENSED
// DO NOT edit this file. Code generated by forge-gen.
pragma solidity ^0.8.8;

import "../suavelib/Suave.sol";

interface registryVM {
function etch(address, bytes calldata) external;
}

library Registry {
registryVM constant vm = registryVM(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);

function enableLib(address addr) public {
// code for Wrapper
bytes memory code =
hex"608060405234801561001057600080fd5b506004361061002b5760003560e01c8063671ff786146100a1575b6040516bffffffffffffffffffffffff193060601b1660208201526000906100959060340160408051808303601f19018152602036601f8101829004820285018201909352828452909291600091819084018382808284376000920191909152506100ca92505050565b90508081518060208301f35b6100b46100af366004610487565b61025e565b6040516100c19190610557565b60405180910390f35b606060006100d78461025e565b905060006100e48461025e565b60408051600480825260a0820190925291925060009190816020015b60608152602001906001900390816101005790505090506040518060400160405280600a8152602001690e6eac2ecca5acecae8d60b31b8152508160008151811061014d5761014d610571565b602002602001018190525060405180604001604052806005815260200164666f72676560d81b8152508160018151811061018957610189610571565b602002602001018190525082816002815181106101a8576101a8610571565b602002602001018190525081816003815181106101c7576101c7610571565b6020908102919091010152604051638916046760e01b8152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063891604679061020c908590600401610587565b600060405180830381865afa158015610229573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261025191908101906105eb565b9450505050505b92915050565b60606000825160026102709190610678565b67ffffffffffffffff81111561028857610288610418565b6040519080825280601f01601f1916602001820160405280156102b2576020820181803683370190505b5060408051808201909152601081526f181899199a1a9b1b9c1cb0b131b232b360811b602082015290915060005b84518110156103ee578182518683815181106102fe576102fe610571565b0160200151610310919060f81c6106a5565b8151811061032057610320610571565b01602001516001600160f81b0319168361033b836002610678565b8151811061034b5761034b610571565b60200101906001600160f81b031916908160001a90535081825186838151811061037757610377610571565b0160200151610389919060f81c6106b9565b8151811061039957610399610571565b01602001516001600160f81b031916836103b4836002610678565b6103bf9060016106cd565b815181106103cf576103cf610571565b60200101906001600160f81b031916908160001a9053506001016102e0565b508160405160200161040091906106e0565b60405160208183030381529060405292505050919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561045757610457610418565b604052919050565b600067ffffffffffffffff82111561047957610479610418565b50601f01601f191660200190565b60006020828403121561049957600080fd5b813567ffffffffffffffff8111156104b057600080fd5b8201601f810184136104c157600080fd5b80356104d46104cf8261045f565b61042e565b8181528560208385010111156104e957600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b8381101561052257818101518382015260200161050a565b50506000910152565b60008151808452610543816020860160208601610507565b601f01601f19169290920160200192915050565b60208152600061056a602083018461052b565b9392505050565b634e487b7160e01b600052603260045260246000fd5b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156105de57603f198886030184526105cc85835161052b565b945092850192908501906001016105b0565b5092979650505050505050565b6000602082840312156105fd57600080fd5b815167ffffffffffffffff81111561061457600080fd5b8201601f8101841361062557600080fd5b80516106336104cf8261045f565b81815285602083850101111561064857600080fd5b610659826020830160208601610507565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761025857610258610662565b634e487b7160e01b600052601260045260246000fd5b6000826106b4576106b461068f565b500490565b6000826106c8576106c861068f565b500690565b8082018082111561025857610258610662565b61060f60f31b8152600082516106fd816002850160208701610507565b919091016002019291505056fea164736f6c6343000817000a";
vm.etch(addr, code);
}

function enable() public {
enableLib(Suave.IS_CONFIDENTIAL_ADDR);
enableLib(Suave.BUILD_ETH_BLOCK);
enableLib(Suave.CONFIDENTIAL_INPUTS);
enableLib(Suave.CONFIDENTIAL_RETRIEVE);
enableLib(Suave.CONFIDENTIAL_STORE);
enableLib(Suave.DO_HTTPREQUEST);
enableLib(Suave.ETHCALL);
enableLib(Suave.EXTRACT_HINT);
enableLib(Suave.FETCH_DATA_RECORDS);
enableLib(Suave.FILL_MEV_SHARE_BUNDLE);
enableLib(Suave.NEW_BUILDER);
enableLib(Suave.NEW_DATA_RECORD);
enableLib(Suave.SIGN_ETH_TRANSACTION);
enableLib(Suave.SIGN_MESSAGE);
enableLib(Suave.SIMULATE_BUNDLE);
enableLib(Suave.SIMULATE_TRANSACTION);
enableLib(Suave.SUBMIT_BUNDLE_JSON_RPC);
enableLib(Suave.SUBMIT_ETH_BLOCK_TO_RELAY);
}
}
9 changes: 5 additions & 4 deletions src/suavelib/Suave.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ library Suave {
string method;
string[] headers;
bytes body;
bool withFlashbotsSignature;
}

struct SimulateTransactionResult {
Expand Down Expand Up @@ -138,8 +139,8 @@ library Suave {
return data;
}

function confidentialStore(DataId dataId, string memory key, bytes memory data1) internal view {
(bool success, bytes memory data) = CONFIDENTIAL_STORE.staticcall(abi.encode(dataId, key, data1));
function confidentialStore(DataId dataId, string memory key, bytes memory value) internal view {
(bool success, bytes memory data) = CONFIDENTIAL_STORE.staticcall(abi.encode(dataId, key, value));
if (!success) {
revert PeekerReverted(CONFIDENTIAL_STORE, data);
}
Expand Down Expand Up @@ -248,12 +249,12 @@ library Suave {
return abi.decode(data, (uint64));
}

function simulateTransaction(string memory session, bytes memory txn)
function simulateTransaction(string memory sessionid, bytes memory txn)
internal
view
returns (SimulateTransactionResult memory)
{
(bool success, bytes memory data) = SIMULATE_TRANSACTION.staticcall(abi.encode(session, txn));
(bool success, bytes memory data) = SIMULATE_TRANSACTION.staticcall(abi.encode(sessionid, txn));
if (!success) {
revert PeekerReverted(SIMULATE_TRANSACTION, data);
}
Expand Down
Loading

0 comments on commit eb3c4b7

Please sign in to comment.