Browse Source

ethereum: Init foundry project and add installer for native solc

Csongor Kiss 3 years ago
parent
commit
3e051e97b6

+ 2 - 0
.gitignore

@@ -26,3 +26,5 @@ bigtable-writer.json
 /solana/artifacts-testnet/
 /solana/artifacts-testnet/
 /solana/artifacts-devnet/
 /solana/artifacts-devnet/
 /solana/artifacts-mainnet/
 /solana/artifacts-mainnet/
+/ethereum/out/
+/ethereum/cache/

+ 2 - 0
ethereum/.gitignore

@@ -1 +1,3 @@
 ganache.log
 ganache.log
+lib/*
+!lib/README.md

+ 24 - 3
ethereum/Makefile

@@ -8,7 +8,21 @@ node_modules: package-lock.json
 	touch -m node_modules
 	touch -m node_modules
 	npm ci
 	npm ci
 
 
-dependencies: node_modules
+# Note: Forge really wants to manage dependencies via submodules, but that
+# workflow is a little awkward. There's currently no support for a more
+# traditional package manager workflow (with a package manifest file and
+# installation into a subdirectory that can be gitignored).
+# Instead, we just specify the dependencies here. make will then take care of
+# installing them if they are not yet present.
+# When adding a new dependency, make sure to specify the exact commit hash, and
+# the --no-git and --no-commit flags (see lib/forge-std below)
+.PHONY: forge_dependencies
+forge_dependencies: lib/forge-std
+
+lib/forge-std:
+	forge install foundry-rs/forge-std@2c7cbfc6fbede6d7c9e6b17afe997e3fdfe22fef --no-git --no-commit
+
+dependencies: node_modules forge_dependencies
 
 
 build: node_modules ${SOURCE_FILES}
 build: node_modules ${SOURCE_FILES}
 	mkdir -p build
 	mkdir -p build
@@ -18,7 +32,10 @@ build: node_modules ${SOURCE_FILES}
 .env: .env.test
 .env: .env.test
 	cp $< $@
 	cp $< $@
 
 
-test: build .env dependencies
+test: test-forge test-ganache
+
+.PHONY: test-ganache
+test-ganache: build .env dependencies
 	@if pgrep ganache-cli; then echo "Error: ganache-cli already running. Stop it before running tests"; exit 1; fi
 	@if pgrep ganache-cli; then echo "Error: ganache-cli already running. Stop it before running tests"; exit 1; fi
 	npx ganache-cli -e 10000 --deterministic --time="1970-01-01T00:00:00+00:00" > ganache.log &
 	npx ganache-cli -e 10000 --deterministic --time="1970-01-01T00:00:00+00:00" > ganache.log &
 	sleep 5
 	sleep 5
@@ -26,8 +43,12 @@ test: build .env dependencies
 	pkill ganache-cli || true
 	pkill ganache-cli || true
 
 
 .PHONY: test-upgrade
 .PHONY: test-upgrade
-test-upgrade: build .env dependencies
+test-upgrade: build .env node_modules
 	./simulate_upgrades
 	./simulate_upgrades
 
 
+.PHONY:
+test-forge: dependencies
+	forge test
+
 clean:
 clean:
 	rm -rf ganache.log .env node_modules build
 	rm -rf ganache.log .env node_modules build

+ 11 - 0
ethereum/README.md

@@ -46,3 +46,14 @@ chain address of the recipient, `target_chain` is the id of the chain to transfe
 
 
 `lockETH(bytes32 recipient, uint8 target_chain)` is a convenience function to wrap the Ether sent with the function call
 `lockETH(bytes32 recipient, uint8 target_chain)` is a convenience function to wrap the Ether sent with the function call
 and transfer it as described in `lockAssets`.
 and transfer it as described in `lockAssets`.
+
+
+### Forge
+
+Some tests and scripts use [Foundry](https://getfoundry.sh/). It can be installed via the official installer, or by running
+
+``` sh
+wormhole/ethereum $ ../scripts/install-foundry
+```
+
+The installer script installs foundry and the appropriate solc version to build the contracts.

+ 27 - 0
ethereum/forge-test/Messages.t.sol

@@ -0,0 +1,27 @@
+// test/Messages.sol
+// SPDX-License-Identifier: Apache 2
+
+pragma solidity ^0.8.0;
+
+import "../contracts/Messages.sol";
+import "forge-std/Test.sol";
+
+contract TestMessages is Messages, Test {
+  function testQuorum() public {
+    assertEq(quorum(0), 1);
+    assertEq(quorum(1), 1);
+    assertEq(quorum(2), 2);
+    assertEq(quorum(3), 3);
+    assertEq(quorum(4), 3);
+    assertEq(quorum(5), 4);
+    assertEq(quorum(6), 5);
+    assertEq(quorum(7), 5);
+    assertEq(quorum(8), 6);
+    assertEq(quorum(9), 7);
+    assertEq(quorum(10), 7);
+    assertEq(quorum(11), 8);
+    assertEq(quorum(12), 9);
+    assertEq(quorum(19), 13);
+    assertEq(quorum(20), 14);
+  }
+}

+ 23 - 0
ethereum/foundry.toml

@@ -0,0 +1,23 @@
+[default]
+solc_version = "0.8.4"
+optimizer = true
+optimizer_runs = 200
+src="contracts"
+# We put the tests into the forge-test directory (instead of test) so that
+# truffle doesn't try to build them
+test="forge-test"
+
+out = 'out'
+libs = [
+    'lib',
+    'node_modules',
+]
+remappings = [
+    '@openzeppelin/=node_modules/@openzeppelin/',
+    '@solidity-parser/=node_modules/@solidity-parser/',
+    'ds-test/=lib/forge-std/lib/ds-test/src/',
+    'forge-std/=lib/forge-std/src/',
+    'truffle/=node_modules/truffle/',
+]
+
+# See more config options https://github.com/foundry-rs/foundry/tree/master/config

+ 1 - 0
ethereum/lib/README.md

@@ -0,0 +1 @@
+Forge installs the dependencies in this folder. They are .gitignored

+ 0 - 27
ethereum/test/wormhole.sol

@@ -1,27 +0,0 @@
-// contracts/Messages.sol
-// SPDX-License-Identifier: Apache 2
-
-pragma solidity ^0.8.0;
-
-import "truffle/Assert.sol";
-import "../contracts/Messages.sol";
-
-contract TestMessages is Messages {
-  function testQuorum() public { 
-    Assert.equal(quorum(0), 1, "it should return quorum");
-    Assert.equal(quorum(1), 1, "it should return quorum");
-    Assert.equal(quorum(2), 2, "it should return quorum");
-    Assert.equal(quorum(3), 3, "it should return quorum");
-    Assert.equal(quorum(4), 3, "it should return quorum");
-    Assert.equal(quorum(5), 4, "it should return quorum");
-    Assert.equal(quorum(6), 5, "it should return quorum");
-    Assert.equal(quorum(7), 5, "it should return quorum");
-    Assert.equal(quorum(8), 6, "it should return quorum");
-    Assert.equal(quorum(9), 7, "it should return quorum");
-    Assert.equal(quorum(10), 7, "it should return quorum");
-    Assert.equal(quorum(11), 8, "it should return quorum");
-    Assert.equal(quorum(12), 9, "it should return quorum");
-    Assert.equal(quorum(19), 13, "it should return quorum");
-    Assert.equal(quorum(20), 14, "it should return quorum");
-  }  
-}

+ 92 - 0
scripts/install-foundry

@@ -0,0 +1,92 @@
+#!/bin/bash
+
+# This script install foundry and the solidity compiler required to build the
+# ethereum contracts. Foundry itself provides a mechanism to install solc, but
+# it doesn't work with certain firewall configurations.
+
+set -euo pipefail
+
+# check if foundry.toml exists
+if [ ! -f foundry.toml ]; then
+  echo "foundry.toml not found. Please call from the ethereum directory." >& 2
+  exit 1
+fi
+
+# Read compiler version from foundry.toml
+SOLC_VERSION=$(grep solc_version foundry.toml | cut -d'=' -f2 | tr -d '" ') || true
+
+if [ -z "$SOLC_VERSION" ]; then
+  echo "solc_version not found in foundry.toml." >& 2
+  exit 1
+fi
+
+main() {
+  OS=$(uname -s)
+  case "$OS" in
+    Darwin)
+      install_mac
+      ;;
+    Linux)
+      install_linux
+      ;;
+    *)
+      echo "Unsupported OS: $OS"
+      exit 1
+      ;;
+  esac
+}
+
+function install_mac() {
+  if ! command -v brew > /dev/null; then
+    echo "brew is unavailable. Please install: https://brew.sh"
+  fi
+
+  if ! brew list libusb > /dev/null 2>&1; then
+    echo "Installing libusb"
+    brew install libusb
+  fi
+
+  if ! command -v foundryup > /dev/null; then
+    curl -L https://foundry.paradigm.xyz --silent | bash
+    "$HOME/.foundry/bin/foundryup"
+  fi
+
+  INSTALL_DIR="$HOME/.svm/$SOLC_VERSION"
+
+  mkdir -p "$INSTALL_DIR"
+
+  SOLC_PATH="$INSTALL_DIR/solc-$SOLC_VERSION"
+
+  if [ ! -f "$SOLC_PATH" ]; then
+    echo "Installing solc-$SOLC_VERSION"
+    curl -L --silent "https://github.com/ethereum/solidity/releases/download/v$SOLC_VERSION/solc-macos" > "$SOLC_PATH"
+    chmod +x "$SOLC_PATH"
+    echo "Installed $SOLC_PATH"
+  else
+    echo "Solidity compiler found: $SOLC_PATH"
+  fi
+}
+
+function install_linux() {
+  if ! command -v foundryup > /dev/null; then
+    curl -L https://foundry.paradigm.xyz --silent | bash
+    "$HOME/.foundry/bin/foundryup"
+  fi
+
+  INSTALL_DIR="$HOME/.svm/$SOLC_VERSION"
+
+  mkdir -p "$INSTALL_DIR"
+
+  SOLC_PATH="$INSTALL_DIR/solc-$SOLC_VERSION"
+
+  if [ ! -f "$SOLC_PATH" ]; then
+    echo "Installing solc-$SOLC_VERSION"
+    curl -L --silent "https://github.com/ethereum/solidity/releases/download/v$SOLC_VERSION/solc-static-linux" > "$SOLC_PATH"
+    chmod +x "$SOLC_PATH"
+    echo "Installed $SOLC_PATH"
+  else
+    echo "Solidity compiler found: $SOLC_PATH"
+  fi
+}
+
+main "$@"; exit