From e52af66e7def3a401c331d88fb9ee85af874d999 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Sat, 6 Jan 2024 11:15:50 +0100 Subject: [PATCH 01/11] Add validation for --ffi enabled + suave binary in forge --- src/Test.sol | 59 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/src/Test.sol b/src/Test.sol index 9a78e0f..d2e3f1f 100644 --- a/src/Test.sol +++ b/src/Test.sol @@ -2,14 +2,61 @@ pragma solidity ^0.8.8; import "./forge/Registry.sol"; +import "forge-std/Test.sol"; -contract SuaveEnabled { +contract SuaveEnabled is Test { function setUp() public { - // TODO: Add checks to validate that: - // - User is running the test with ffi. Since vm.ffi is deployed as a contract, the error if ffi is not active - // is reported as a Suave.PeekerReverted error and it is not clear what the problem is. - // - Suave binary is on $PATH and Suave is running. This could be done with ffi calls to the suave binary. - // Put this logic inside `enable` itself. + string[] memory inputs = new string[](2); + inputs[0] = "suave1"; + inputs[1] = "forge"; + + try vm.ffi(inputs) returns (bytes memory result) { + console.logBytes(result); + } catch (bytes memory reason) { + revert(detectFFIErrorMessage(reason)); + } + Registry.enable(); } + + function detectFFIErrorMessage(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; + } } From 312bc9ebb535377a7f715d2f0d56daa9c51e4d8e Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Sat, 6 Jan 2024 11:18:01 +0100 Subject: [PATCH 02/11] Use correct command --- src/Test.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Test.sol b/src/Test.sol index d2e3f1f..b59b2c8 100644 --- a/src/Test.sol +++ b/src/Test.sol @@ -7,7 +7,7 @@ import "forge-std/Test.sol"; contract SuaveEnabled is Test { function setUp() public { string[] memory inputs = new string[](2); - inputs[0] = "suave1"; + inputs[0] = "suave"; inputs[1] = "forge"; try vm.ffi(inputs) returns (bytes memory result) { From dfcedc2d8174ffe93fa2e16305944b8bdf4be418 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Sat, 6 Jan 2024 11:24:04 +0100 Subject: [PATCH 03/11] Remove extra variable --- src/Test.sol | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Test.sol b/src/Test.sol index b59b2c8..954a387 100644 --- a/src/Test.sol +++ b/src/Test.sol @@ -10,9 +10,8 @@ contract SuaveEnabled is Test { inputs[0] = "suave"; inputs[1] = "forge"; - try vm.ffi(inputs) returns (bytes memory result) { - console.logBytes(result); - } catch (bytes memory reason) { + try vm.ffi(inputs) returns (bytes memory) {} + catch (bytes memory reason) { revert(detectFFIErrorMessage(reason)); } From 4a04f0aed9f9c178549d9bfb922d8ab08f9667c4 Mon Sep 17 00:00:00 2001 From: sukoneck <19413126+sukoneck@users.noreply.github.com> Date: Sat, 6 Jan 2024 03:39:12 -0700 Subject: [PATCH 04/11] specify dispatch trigger type and add logs to suavelib-sync (#16) --- .github/workflows/suave-lib-sync.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/suave-lib-sync.yml b/.github/workflows/suave-lib-sync.yml index cc581d5..b290a4d 100644 --- a/.github/workflows/suave-lib-sync.yml +++ b/.github/workflows/suave-lib-sync.yml @@ -1,6 +1,9 @@ name: SuaveLib sync -on: [repository_dispatch, workflow_dispatch] +on: + workflow_dispatch: + repository_dispatch: + types: [suavelib-sync] permissions: pull-requests: write @@ -12,6 +15,14 @@ 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: From 138ee0fe47d759c8262d33d8f0308c1e9c5bd8fd Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Sat, 6 Jan 2024 11:45:03 +0100 Subject: [PATCH 05/11] Regenerate forge registry on suave lib sync (#19) --- .github/workflows/suave-lib-sync.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/suave-lib-sync.yml b/.github/workflows/suave-lib-sync.yml index b290a4d..9a3d1e6 100644 --- a/.github/workflows/suave-lib-sync.yml +++ b/.github/workflows/suave-lib-sync.yml @@ -29,6 +29,11 @@ jobs: 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: @@ -50,6 +55,17 @@ jobs: git add ./src/suavelib/Suave.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: From 11e5d72238e1daf2b6465c55aa386ee8054180a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 6 Jan 2024 11:51:15 +0100 Subject: [PATCH 06/11] Update Suave.sol library to https://github.com/flashbots/suave-geth/commit/77f5e8a6cb882ccbe98e9b0287bc45ca54b55c9a (#20) Co-authored-by: sukoneck --- src/forge/Registry.sol | 3 ++- src/suavelib/Suave.sol | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/forge/Registry.sol b/src/forge/Registry.sol index 526181d..8d6bad3 100644 --- a/src/forge/Registry.sol +++ b/src/forge/Registry.sol @@ -1,4 +1,5 @@ // SPDX-License-Identifier: UNLICENSED +// DO NOT edit this file. Code generated by forge-gen. pragma solidity ^0.8.8; import "../suavelib/Suave.sol"; @@ -13,7 +14,7 @@ library Registry { function enableLib(address addr) public { // code for Wrapper bytes memory code = - hex"608060405234801561001057600080fd5b506004361061002b5760003560e01c8063671ff786146100a1575b6040516bffffffffffffffffffffffff193060601b1660208201526000906100959060340160408051808303601f19018152602036601f8101829004820285018201909352828452909291600091819084018382808284376000920191909152506100ca92505050565b90508081518060208301f35b6100b46100af36600461048c565b610259565b6040516100c1919061055c565b60405180910390f35b606060006100d784610259565b905060006100e484610259565b60408051600480825260a0820190925291925060009190816020015b606081526020019060019003908161010057905050905060405180604001604052806005815260200164737561766560d81b8152508160008151811061014857610148610576565b602002602001018190525060405180604001604052806005815260200164666f72676560d81b8152508160018151811061018457610184610576565b602002602001018190525082816002815181106101a3576101a3610576565b602002602001018190525081816003815181106101c2576101c2610576565b6020908102919091010152604051638916046760e01b8152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063891604679061020790859060040161058c565b600060405180830381865afa158015610224573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261024c91908101906105ee565b9450505050505b92915050565b606060008251600261026b919061067b565b67ffffffffffffffff8111156102835761028361041d565b6040519080825280601f01601f1916602001820160405280156102ad576020820181803683370190505b5060408051808201909152601081526f181899199a1a9b1b9c1cb0b131b232b360811b602082015290915060005b84518110156103f3578182518683815181106102f9576102f9610576565b016020015161030b919060f81c6106a8565b8151811061031b5761031b610576565b01602001516001600160f81b0319168361033683600261067b565b8151811061034657610346610576565b60200101906001600160f81b031916908160001a90535081825186838151811061037257610372610576565b0160200151610384919060f81c6106bc565b8151811061039457610394610576565b01602001516001600160f81b031916836103af83600261067b565b6103ba9060016106d0565b815181106103ca576103ca610576565b60200101906001600160f81b031916908160001a905350806103eb816106e3565b9150506102db565b508160405160200161040591906106fc565b60405160208183030381529060405292505050919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561045c5761045c61041d565b604052919050565b600067ffffffffffffffff82111561047e5761047e61041d565b50601f01601f191660200190565b60006020828403121561049e57600080fd5b813567ffffffffffffffff8111156104b557600080fd5b8201601f810184136104c657600080fd5b80356104d96104d482610464565b610433565b8181528560208385010111156104ee57600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b8381101561052757818101518382015260200161050f565b50506000910152565b6000815180845261054881602086016020860161050c565b601f01601f19169290920160200192915050565b60208152600061056f6020830184610530565b9392505050565b634e487b7160e01b600052603260045260246000fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156105e157603f198886030184526105cf858351610530565b945092850192908501906001016105b3565b5092979650505050505050565b60006020828403121561060057600080fd5b815167ffffffffffffffff81111561061757600080fd5b8201601f8101841361062857600080fd5b80516106366104d482610464565b81815285602083850101111561064b57600080fd5b61065c82602083016020860161050c565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761025357610253610665565b634e487b7160e01b600052601260045260246000fd5b6000826106b7576106b7610692565b500490565b6000826106cb576106cb610692565b500690565b8082018082111561025357610253610665565b6000600182016106f5576106f5610665565b5060010190565b61060f60f31b81526000825161071981600285016020870161050c565b919091016002019291505056fea2646970667358221220e66d500bc9a9ca9c0748086adfc51de57c85b7c9f66cc760e823099f0439820b64736f6c63430008130033"; + hex"608060405234801561001057600080fd5b506004361061002b5760003560e01c8063671ff786146100a1575b6040516bffffffffffffffffffffffff193060601b1660208201526000906100959060340160408051808303601f19018152602036601f8101829004820285018201909352828452909291600091819084018382808284376000920191909152506100ca92505050565b90508081518060208301f35b6100b46100af366004610482565b610259565b6040516100c19190610552565b60405180910390f35b606060006100d784610259565b905060006100e484610259565b60408051600480825260a0820190925291925060009190816020015b606081526020019060019003908161010057905050905060405180604001604052806005815260200164737561766560d81b815250816000815181106101485761014861056c565b602002602001018190525060405180604001604052806005815260200164666f72676560d81b815250816001815181106101845761018461056c565b602002602001018190525082816002815181106101a3576101a361056c565b602002602001018190525081816003815181106101c2576101c261056c565b6020908102919091010152604051638916046760e01b8152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d90638916046790610207908590600401610582565b600060405180830381865afa158015610224573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261024c91908101906105e6565b9450505050505b92915050565b606060008251600261026b9190610673565b67ffffffffffffffff81111561028357610283610413565b6040519080825280601f01601f1916602001820160405280156102ad576020820181803683370190505b5060408051808201909152601081526f181899199a1a9b1b9c1cb0b131b232b360811b602082015290915060005b84518110156103e9578182518683815181106102f9576102f961056c565b016020015161030b919060f81c6106a0565b8151811061031b5761031b61056c565b01602001516001600160f81b03191683610336836002610673565b815181106103465761034661056c565b60200101906001600160f81b031916908160001a9053508182518683815181106103725761037261056c565b0160200151610384919060f81c6106b4565b815181106103945761039461056c565b01602001516001600160f81b031916836103af836002610673565b6103ba9060016106c8565b815181106103ca576103ca61056c565b60200101906001600160f81b031916908160001a9053506001016102db565b50816040516020016103fb91906106db565b60405160208183030381529060405292505050919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561045257610452610413565b604052919050565b600067ffffffffffffffff82111561047457610474610413565b50601f01601f191660200190565b60006020828403121561049457600080fd5b813567ffffffffffffffff8111156104ab57600080fd5b8201601f810184136104bc57600080fd5b80356104cf6104ca8261045a565b610429565b8181528560208385010111156104e457600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b8381101561051d578181015183820152602001610505565b50506000910152565b6000815180845261053e816020860160208601610502565b601f01601f19169290920160200192915050565b6020815260006105656020830184610526565b9392505050565b634e487b7160e01b600052603260045260246000fd5b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156105d957603f198886030184526105c7858351610526565b945092850192908501906001016105ab565b5092979650505050505050565b6000602082840312156105f857600080fd5b815167ffffffffffffffff81111561060f57600080fd5b8201601f8101841361062057600080fd5b805161062e6104ca8261045a565b81815285602083850101111561064357600080fd5b610654826020830160208601610502565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176102535761025361065d565b634e487b7160e01b600052601260045260246000fd5b6000826106af576106af61068a565b500490565b6000826106c3576106c361068a565b500690565b808201808211156102535761025361065d565b61060f60f31b8152600082516106f8816002850160208701610502565b919091016002019291505056fea264697066735822122059ae496bcbd2ced9fbec0a08e12c546547a6f5be88964669c6db37d39d43d57e64736f6c63430008170033"; vm.etch(addr, code); } diff --git a/src/suavelib/Suave.sol b/src/suavelib/Suave.sol index 217b0e6..bcaf758 100644 --- a/src/suavelib/Suave.sol +++ b/src/suavelib/Suave.sol @@ -33,6 +33,7 @@ library Suave { string method; string[] headers; bytes body; + bool withFlashbotsSignature; } struct SimulateTransactionResult { @@ -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); } @@ -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); } From 414a6bd48c03cb420d683d13a6bc9e4829c1e17e Mon Sep 17 00:00:00 2001 From: sukoneck <19413126+sukoneck@users.noreply.github.com> Date: Mon, 8 Jan 2024 00:39:36 -0700 Subject: [PATCH 07/11] add codeowners (#17) * add codeowners * fix * fix * Update .github/CODEOWNERS Co-authored-by: Ferran Borreguero --------- Co-authored-by: Ferran Borreguero --- .github/CODEOWNERS | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..3d724cb --- /dev/null +++ b/.github/CODEOWNERS @@ -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 From cb8175fd15fe03f8906a5af11cc582e3069d53d2 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 8 Jan 2024 08:40:54 +0100 Subject: [PATCH 08/11] Add check to validate that a Suave node is running (#22) --- src/Test.sol | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Test.sol b/src/Test.sol index 954a387..f665643 100644 --- a/src/Test.sol +++ b/src/Test.sol @@ -6,12 +6,17 @@ import "forge-std/Test.sol"; contract SuaveEnabled is Test { function setUp() public { - string[] memory inputs = new string[](2); + string[] memory inputs = new string[](3); inputs[0] = "suave"; inputs[1] = "forge"; + inputs[2] = "status"; - try vm.ffi(inputs) returns (bytes memory) {} - catch (bytes memory reason) { + try vm.ffi(inputs) returns (bytes memory response) { + // the prefix is 'not-ok' + if (isPrefix(hex"6e6f742d6f6b", response)) { + revert("Local Suave node not detected running"); + } + } catch (bytes memory reason) { revert(detectFFIErrorMessage(reason)); } From fd8574d61377c66eef30ae2f754e3beffe4334de Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 9 Jan 2024 11:33:02 +0100 Subject: [PATCH 09/11] Use suave-toolchain action (#24) * Use suave-toolchain action * Do not checkout suave-geth * Use the PATH binary * Modify binary name * test * Try again * Update registry * Remove ci step --- .github/workflows/ci.yml | 20 +++----------------- src/forge/Connector.sol | 2 +- src/forge/Registry.sol | 2 +- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88886fb..c6934b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,26 +14,12 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Checkout suave-geth repo - uses: actions/checkout@v4 - with: - repository: flashbots/suave-geth - path: suave-geth - persist-credentials: false - fetch-depth: 0 - - - name: Build suave - run: | - cd suave-geth - make suave - - - name: Include the binary on $PATH - run: | - echo "$(pwd)/suave-geth/build/bin" >> $GITHUB_PATH + - name: Install suave-geth + uses: flashbots/suave-toolchain@v0.1 - name: Run suave run: | - ./suave-geth/build/bin/suave --suave.dev & + suave-geth --suave.dev & - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 diff --git a/src/forge/Connector.sol b/src/forge/Connector.sol index 2e2f4fd..b2be8d5 100644 --- a/src/forge/Connector.sol +++ b/src/forge/Connector.sol @@ -13,7 +13,7 @@ contract Connector { string memory dataHex = iToHex(data); string[] memory inputs = new string[](4); - inputs[0] = "suave"; + inputs[0] = "suave-geth"; inputs[1] = "forge"; inputs[2] = addrHex; inputs[3] = dataHex; diff --git a/src/forge/Registry.sol b/src/forge/Registry.sol index 8d6bad3..7758c49 100644 --- a/src/forge/Registry.sol +++ b/src/forge/Registry.sol @@ -14,7 +14,7 @@ library Registry { function enableLib(address addr) public { // code for Wrapper bytes memory code = - hex"608060405234801561001057600080fd5b506004361061002b5760003560e01c8063671ff786146100a1575b6040516bffffffffffffffffffffffff193060601b1660208201526000906100959060340160408051808303601f19018152602036601f8101829004820285018201909352828452909291600091819084018382808284376000920191909152506100ca92505050565b90508081518060208301f35b6100b46100af366004610482565b610259565b6040516100c19190610552565b60405180910390f35b606060006100d784610259565b905060006100e484610259565b60408051600480825260a0820190925291925060009190816020015b606081526020019060019003908161010057905050905060405180604001604052806005815260200164737561766560d81b815250816000815181106101485761014861056c565b602002602001018190525060405180604001604052806005815260200164666f72676560d81b815250816001815181106101845761018461056c565b602002602001018190525082816002815181106101a3576101a361056c565b602002602001018190525081816003815181106101c2576101c261056c565b6020908102919091010152604051638916046760e01b8152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d90638916046790610207908590600401610582565b600060405180830381865afa158015610224573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261024c91908101906105e6565b9450505050505b92915050565b606060008251600261026b9190610673565b67ffffffffffffffff81111561028357610283610413565b6040519080825280601f01601f1916602001820160405280156102ad576020820181803683370190505b5060408051808201909152601081526f181899199a1a9b1b9c1cb0b131b232b360811b602082015290915060005b84518110156103e9578182518683815181106102f9576102f961056c565b016020015161030b919060f81c6106a0565b8151811061031b5761031b61056c565b01602001516001600160f81b03191683610336836002610673565b815181106103465761034661056c565b60200101906001600160f81b031916908160001a9053508182518683815181106103725761037261056c565b0160200151610384919060f81c6106b4565b815181106103945761039461056c565b01602001516001600160f81b031916836103af836002610673565b6103ba9060016106c8565b815181106103ca576103ca61056c565b60200101906001600160f81b031916908160001a9053506001016102db565b50816040516020016103fb91906106db565b60405160208183030381529060405292505050919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561045257610452610413565b604052919050565b600067ffffffffffffffff82111561047457610474610413565b50601f01601f191660200190565b60006020828403121561049457600080fd5b813567ffffffffffffffff8111156104ab57600080fd5b8201601f810184136104bc57600080fd5b80356104cf6104ca8261045a565b610429565b8181528560208385010111156104e457600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b8381101561051d578181015183820152602001610505565b50506000910152565b6000815180845261053e816020860160208601610502565b601f01601f19169290920160200192915050565b6020815260006105656020830184610526565b9392505050565b634e487b7160e01b600052603260045260246000fd5b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156105d957603f198886030184526105c7858351610526565b945092850192908501906001016105ab565b5092979650505050505050565b6000602082840312156105f857600080fd5b815167ffffffffffffffff81111561060f57600080fd5b8201601f8101841361062057600080fd5b805161062e6104ca8261045a565b81815285602083850101111561064357600080fd5b610654826020830160208601610502565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176102535761025361065d565b634e487b7160e01b600052601260045260246000fd5b6000826106af576106af61068a565b500490565b6000826106c3576106c361068a565b500690565b808201808211156102535761025361065d565b61060f60f31b8152600082516106f8816002850160208701610502565b919091016002019291505056fea264697066735822122059ae496bcbd2ced9fbec0a08e12c546547a6f5be88964669c6db37d39d43d57e64736f6c63430008170033"; + hex"608060405234801561001057600080fd5b506004361061002b5760003560e01c8063671ff786146100a1575b6040516bffffffffffffffffffffffff193060601b1660208201526000906100959060340160408051808303601f19018152602036601f8101829004820285018201909352828452909291600091819084018382808284376000920191909152506100ca92505050565b90508081518060208301f35b6100b46100af366004610491565b61025e565b6040516100c19190610561565b60405180910390f35b606060006100d78461025e565b905060006100e48461025e565b60408051600480825260a0820190925291925060009190816020015b60608152602001906001900390816101005790505090506040518060400160405280600a8152602001690e6eac2ecca5acecae8d60b31b8152508160008151811061014d5761014d61057b565b602002602001018190525060405180604001604052806005815260200164666f72676560d81b815250816001815181106101895761018961057b565b602002602001018190525082816002815181106101a8576101a861057b565b602002602001018190525081816003815181106101c7576101c761057b565b6020908102919091010152604051638916046760e01b8152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063891604679061020c908590600401610591565b600060405180830381865afa158015610229573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261025191908101906105f3565b9450505050505b92915050565b60606000825160026102709190610680565b67ffffffffffffffff81111561028857610288610422565b6040519080825280601f01601f1916602001820160405280156102b2576020820181803683370190505b5060408051808201909152601081526f181899199a1a9b1b9c1cb0b131b232b360811b602082015290915060005b84518110156103f8578182518683815181106102fe576102fe61057b565b0160200151610310919060f81c6106ad565b815181106103205761032061057b565b01602001516001600160f81b0319168361033b836002610680565b8151811061034b5761034b61057b565b60200101906001600160f81b031916908160001a9053508182518683815181106103775761037761057b565b0160200151610389919060f81c6106c1565b815181106103995761039961057b565b01602001516001600160f81b031916836103b4836002610680565b6103bf9060016106d5565b815181106103cf576103cf61057b565b60200101906001600160f81b031916908160001a905350806103f0816106e8565b9150506102e0565b508160405160200161040a9190610701565b60405160208183030381529060405292505050919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561046157610461610422565b604052919050565b600067ffffffffffffffff82111561048357610483610422565b50601f01601f191660200190565b6000602082840312156104a357600080fd5b813567ffffffffffffffff8111156104ba57600080fd5b8201601f810184136104cb57600080fd5b80356104de6104d982610469565b610438565b8181528560208385010111156104f357600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b8381101561052c578181015183820152602001610514565b50506000910152565b6000815180845261054d816020860160208601610511565b601f01601f19169290920160200192915050565b6020815260006105746020830184610535565b9392505050565b634e487b7160e01b600052603260045260246000fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156105e657603f198886030184526105d4858351610535565b945092850192908501906001016105b8565b5092979650505050505050565b60006020828403121561060557600080fd5b815167ffffffffffffffff81111561061c57600080fd5b8201601f8101841361062d57600080fd5b805161063b6104d982610469565b81815285602083850101111561065057600080fd5b610661826020830160208601610511565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176102585761025861066a565b634e487b7160e01b600052601260045260246000fd5b6000826106bc576106bc610697565b500490565b6000826106d0576106d0610697565b500690565b808201808211156102585761025861066a565b6000600182016106fa576106fa61066a565b5060010190565b61060f60f31b81526000825161071e816002850160208701610511565b919091016002019291505056fea2646970667358221220918efca7b62d20c0fa19067dd7a091ef7cf76b94f70985c100a506284cf9d54664736f6c63430008130033"; vm.etch(addr, code); } From d82abfe439b27a9bfcd2366a92b3ce616197a63b Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 9 Jan 2024 15:44:32 +0100 Subject: [PATCH 10/11] Create deterministic builds with `forge-gen` (#25) --- .github/workflows/check-gen-code.yml | 34 +++++++++++++++++++++++ .github/workflows/ci.yml | 2 +- src/forge/Registry.sol | 2 +- tools/forge-gen/foundry.toml | 6 ++++ tools/forge-gen/main.go | 41 ++++++++++++++++++++-------- 5 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/check-gen-code.yml create mode 100644 tools/forge-gen/foundry.toml diff --git a/.github/workflows/check-gen-code.yml b/.github/workflows/check-gen-code.yml new file mode 100644 index 0000000..2cf66b9 --- /dev/null +++ b/.github/workflows/check-gen-code.yml @@ -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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6934b6..19efddc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: branches: - - master + - main pull_request: env: diff --git a/src/forge/Registry.sol b/src/forge/Registry.sol index 7758c49..995e42d 100644 --- a/src/forge/Registry.sol +++ b/src/forge/Registry.sol @@ -14,7 +14,7 @@ library Registry { function enableLib(address addr) public { // code for Wrapper bytes memory code = - hex"608060405234801561001057600080fd5b506004361061002b5760003560e01c8063671ff786146100a1575b6040516bffffffffffffffffffffffff193060601b1660208201526000906100959060340160408051808303601f19018152602036601f8101829004820285018201909352828452909291600091819084018382808284376000920191909152506100ca92505050565b90508081518060208301f35b6100b46100af366004610491565b61025e565b6040516100c19190610561565b60405180910390f35b606060006100d78461025e565b905060006100e48461025e565b60408051600480825260a0820190925291925060009190816020015b60608152602001906001900390816101005790505090506040518060400160405280600a8152602001690e6eac2ecca5acecae8d60b31b8152508160008151811061014d5761014d61057b565b602002602001018190525060405180604001604052806005815260200164666f72676560d81b815250816001815181106101895761018961057b565b602002602001018190525082816002815181106101a8576101a861057b565b602002602001018190525081816003815181106101c7576101c761057b565b6020908102919091010152604051638916046760e01b8152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063891604679061020c908590600401610591565b600060405180830381865afa158015610229573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261025191908101906105f3565b9450505050505b92915050565b60606000825160026102709190610680565b67ffffffffffffffff81111561028857610288610422565b6040519080825280601f01601f1916602001820160405280156102b2576020820181803683370190505b5060408051808201909152601081526f181899199a1a9b1b9c1cb0b131b232b360811b602082015290915060005b84518110156103f8578182518683815181106102fe576102fe61057b565b0160200151610310919060f81c6106ad565b815181106103205761032061057b565b01602001516001600160f81b0319168361033b836002610680565b8151811061034b5761034b61057b565b60200101906001600160f81b031916908160001a9053508182518683815181106103775761037761057b565b0160200151610389919060f81c6106c1565b815181106103995761039961057b565b01602001516001600160f81b031916836103b4836002610680565b6103bf9060016106d5565b815181106103cf576103cf61057b565b60200101906001600160f81b031916908160001a905350806103f0816106e8565b9150506102e0565b508160405160200161040a9190610701565b60405160208183030381529060405292505050919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561046157610461610422565b604052919050565b600067ffffffffffffffff82111561048357610483610422565b50601f01601f191660200190565b6000602082840312156104a357600080fd5b813567ffffffffffffffff8111156104ba57600080fd5b8201601f810184136104cb57600080fd5b80356104de6104d982610469565b610438565b8181528560208385010111156104f357600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b8381101561052c578181015183820152602001610514565b50506000910152565b6000815180845261054d816020860160208601610511565b601f01601f19169290920160200192915050565b6020815260006105746020830184610535565b9392505050565b634e487b7160e01b600052603260045260246000fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156105e657603f198886030184526105d4858351610535565b945092850192908501906001016105b8565b5092979650505050505050565b60006020828403121561060557600080fd5b815167ffffffffffffffff81111561061c57600080fd5b8201601f8101841361062d57600080fd5b805161063b6104d982610469565b81815285602083850101111561065057600080fd5b610661826020830160208601610511565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176102585761025861066a565b634e487b7160e01b600052601260045260246000fd5b6000826106bc576106bc610697565b500490565b6000826106d0576106d0610697565b500690565b808201808211156102585761025861066a565b6000600182016106fa576106fa61066a565b5060010190565b61060f60f31b81526000825161071e816002850160208701610511565b919091016002019291505056fea2646970667358221220918efca7b62d20c0fa19067dd7a091ef7cf76b94f70985c100a506284cf9d54664736f6c63430008130033"; + hex"608060405234801561001057600080fd5b506004361061002b5760003560e01c8063671ff786146100a1575b6040516bffffffffffffffffffffffff193060601b1660208201526000906100959060340160408051808303601f19018152602036601f8101829004820285018201909352828452909291600091819084018382808284376000920191909152506100ca92505050565b90508081518060208301f35b6100b46100af366004610487565b61025e565b6040516100c19190610557565b60405180910390f35b606060006100d78461025e565b905060006100e48461025e565b60408051600480825260a0820190925291925060009190816020015b60608152602001906001900390816101005790505090506040518060400160405280600a8152602001690e6eac2ecca5acecae8d60b31b8152508160008151811061014d5761014d610571565b602002602001018190525060405180604001604052806005815260200164666f72676560d81b8152508160018151811061018957610189610571565b602002602001018190525082816002815181106101a8576101a8610571565b602002602001018190525081816003815181106101c7576101c7610571565b6020908102919091010152604051638916046760e01b8152600090737109709ecfa91a80626ff3989d68f67f5b1dd12d9063891604679061020c908590600401610587565b600060405180830381865afa158015610229573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261025191908101906105eb565b9450505050505b92915050565b60606000825160026102709190610678565b67ffffffffffffffff81111561028857610288610418565b6040519080825280601f01601f1916602001820160405280156102b2576020820181803683370190505b5060408051808201909152601081526f181899199a1a9b1b9c1cb0b131b232b360811b602082015290915060005b84518110156103ee578182518683815181106102fe576102fe610571565b0160200151610310919060f81c6106a5565b8151811061032057610320610571565b01602001516001600160f81b0319168361033b836002610678565b8151811061034b5761034b610571565b60200101906001600160f81b031916908160001a90535081825186838151811061037757610377610571565b0160200151610389919060f81c6106b9565b8151811061039957610399610571565b01602001516001600160f81b031916836103b4836002610678565b6103bf9060016106cd565b815181106103cf576103cf610571565b60200101906001600160f81b031916908160001a9053506001016102e0565b508160405160200161040091906106e0565b60405160208183030381529060405292505050919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561045757610457610418565b604052919050565b600067ffffffffffffffff82111561047957610479610418565b50601f01601f191660200190565b60006020828403121561049957600080fd5b813567ffffffffffffffff8111156104b057600080fd5b8201601f810184136104c157600080fd5b80356104d46104cf8261045f565b61042e565b8181528560208385010111156104e957600080fd5b81602084016020830137600091810160200191909152949350505050565b60005b8381101561052257818101518382015260200161050a565b50506000910152565b60008151808452610543816020860160208601610507565b601f01601f19169290920160200192915050565b60208152600061056a602083018461052b565b9392505050565b634e487b7160e01b600052603260045260246000fd5b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156105de57603f198886030184526105cc85835161052b565b945092850192908501906001016105b0565b5092979650505050505050565b6000602082840312156105fd57600080fd5b815167ffffffffffffffff81111561061457600080fd5b8201601f8101841361062557600080fd5b80516106336104cf8261045f565b81815285602083850101111561064857600080fd5b610659826020830160208601610507565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761025857610258610662565b634e487b7160e01b600052601260045260246000fd5b6000826106b4576106b461068f565b500490565b6000826106c8576106c861068f565b500690565b8082018082111561025857610258610662565b61060f60f31b8152600082516106fd816002850160208701610507565b919091016002019291505056fea164736f6c6343000817000a"; vm.etch(addr, code); } diff --git a/tools/forge-gen/foundry.toml b/tools/forge-gen/foundry.toml new file mode 100644 index 0000000..3967eda --- /dev/null +++ b/tools/forge-gen/foundry.toml @@ -0,0 +1,6 @@ +[profile.default] +solc_version = "0.8.23" +src = "../../src" +out = "./out" +libs = ["../../lib"] +bytecode_hash = "none" \ No newline at end of file diff --git a/tools/forge-gen/main.go b/tools/forge-gen/main.go index 80fefff..92bba9a 100644 --- a/tools/forge-gen/main.go +++ b/tools/forge-gen/main.go @@ -8,7 +8,9 @@ import ( "html/template" "os" "os/exec" + "path/filepath" "regexp" + "runtime" "strings" ) @@ -85,7 +87,7 @@ func applyTemplate(bytecode string, precompileNames []string) error { } if applyFlag { - if err := os.WriteFile("./src/forge/Registry.sol", []byte(str), 0644); err != nil { + if err := os.WriteFile(resolvePath("../../src/forge/Registry.sol"), []byte(str), 0644); err != nil { return err } } else { @@ -95,7 +97,12 @@ func applyTemplate(bytecode string, precompileNames []string) error { } func getForgeConnectorBytecode() (string, error) { - abiContent, err := os.ReadFile("./out/Connector.sol/Connector.json") + // compile the Connector contract with forge and the local configuration + if _, err := execForgeCommand([]string{"build", "--config-path", resolvePath("./foundry.toml")}, ""); err != nil { + return "", err + } + + abiContent, err := os.ReadFile(resolvePath("./out/Connector.sol/Connector.json")) if err != nil { return "", err } @@ -138,21 +145,22 @@ func getPrecompileNames() ([]string, error) { } func formatSolidity(code string) (string, error) { - // Check if "forge" command is available in PATH + return execForgeCommand([]string{"fmt", "--raw", "-"}, code) +} + +func execForgeCommand(args []string, stdin string) (string, error) { _, err := exec.LookPath("forge") if err != nil { return "", fmt.Errorf("forge command not found in PATH: %v", err) } - // Command and arguments for forge fmt - command := "forge" - args := []string{"fmt", "--raw", "-"} - - // Create a command to run the forge fmt command - cmd := exec.Command(command, args...) + // Create a command to run the forge command + cmd := exec.Command("forge", args...) // Set up input from stdin - cmd.Stdin = bytes.NewBufferString(code) + if stdin != "" { + cmd.Stdin = bytes.NewBufferString(stdin) + } // Set up output buffer var outBuf, errBuf bytes.Buffer @@ -160,9 +168,20 @@ func formatSolidity(code string) (string, error) { cmd.Stderr = &errBuf // Run the command - if err = cmd.Run(); err != nil { + if err := cmd.Run(); err != nil { return "", fmt.Errorf("error running command: %v", err) } return outBuf.String(), nil } + +func resolvePath(path string) string { + // Get the caller's file path. + _, filename, _, _ := runtime.Caller(1) + + // Resolve the directory of the caller's file. + callerDir := filepath.Dir(filename) + + // Construct the absolute path to the target file. + return filepath.Join(callerDir, path) +} From a83c36390180a69350add9a53cf365aa0da46087 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 9 Jan 2024 15:55:44 +0100 Subject: [PATCH 11/11] Finish integration --- src/Test.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Test.sol b/src/Test.sol index f665643..a065146 100644 --- a/src/Test.sol +++ b/src/Test.sol @@ -7,23 +7,24 @@ import "forge-std/Test.sol"; contract SuaveEnabled is Test { function setUp() public { string[] memory inputs = new string[](3); - inputs[0] = "suave"; + inputs[0] = "suave-geth"; inputs[1] = "forge"; inputs[2] = "status"; try vm.ffi(inputs) returns (bytes memory response) { - // the prefix is 'not-ok' + // 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(detectFFIErrorMessage(reason)); + revert(detectErrorMessage(reason)); } Registry.enable(); } - function detectFFIErrorMessage(bytes memory reason) internal pure returns (string memory) { + 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)) {