diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 482620b02..debc9ff09 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,6 +45,15 @@ jobs: go-version: '1.17.5' - run: make node + ethereum: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: '16' + - run: cd ethereum && make test + # Run linters, Go tests and other outside-of-Tilt things. lint-and-tests: # The linter is slow enough that we want to run it on the self-hosted runner diff --git a/ethereum/.gitignore b/ethereum/.gitignore new file mode 100644 index 000000000..8657933f0 --- /dev/null +++ b/ethereum/.gitignore @@ -0,0 +1 @@ +ganache.log diff --git a/ethereum/Dockerfile b/ethereum/Dockerfile index c10d099f2..8f079eeba 100644 --- a/ethereum/Dockerfile +++ b/ethereum/Dockerfile @@ -10,6 +10,9 @@ RUN mkdir -p /home/node/app RUN mkdir -p /home/node/.npm WORKDIR /home/node/app +# Fix git ssh error +RUN git config --global url."https://".insteadOf ssh:// + # Support additional root CAs COPY README.md cert.pem* /certs/ # Node @@ -18,7 +21,7 @@ ENV NODE_OPTIONS=--use-openssl-ca # npm RUN if [ -e /certs/cert.pem ]; then npm config set cafile /certs/cert.pem; fi # git -RUN if [ -e /certs/cert.pem ]; then git config --global http.sslCAPath /certs; fi +RUN if [ -e /certs/cert.pem ]; then git config --global http.sslCAInfo /certs/cert.pem; fi # Only invalidate the npm install step if package.json changed ADD --chown=node:node package.json . @@ -28,7 +31,7 @@ ADD --chown=node:node .env.test .env # We want to cache node_modules *and* incorporate it into the final image. RUN --mount=type=cache,uid=1000,gid=1000,target=/home/node/.npm \ --mount=type=cache,uid=1000,gid=1000,target=node_modules \ - npm install && \ + npm ci && \ cp -r node_modules node_modules_cache # Amusingly, Debian's coreutils version has a bug where mv believes that diff --git a/ethereum/Makefile b/ethereum/Makefile new file mode 100644 index 000000000..e39aac905 --- /dev/null +++ b/ethereum/Makefile @@ -0,0 +1,29 @@ +SOURCE_FILES:=$(shell find contracts -name "*.sol") + +.PHONY: dependencies test clean all + +all: build + +node_modules: package-lock.json + touch -m node_modules + npm ci + +dependencies: node_modules + +build: node_modules ${SOURCE_FILES} + mkdir -p build + touch -m build + npm run build + +.env: .env.test + cp $< $@ + +test: build .env dependencies + @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 & + sleep 5 + npm test || (pkill ganache-cli && exit 1) + pkill ganache-cli || true + +clean: + rm -rf ganache.log .env node_modules build diff --git a/ethereum/migrations/6_deploy_bridge_implementation_only.js b/ethereum/migrations/6_deploy_bridge_implementation_only.js index edb2b6881..877d53148 100644 --- a/ethereum/migrations/6_deploy_bridge_implementation_only.js +++ b/ethereum/migrations/6_deploy_bridge_implementation_only.js @@ -7,6 +7,7 @@ // e.g. Polygon // MNEMONIC="" npm run deploy-bridge-implementation-only -- --network polygon const BridgeImplementation = artifacts.require("BridgeImplementation"); -module.exports = async function(deployer) { +module.exports = async function(deployer, network) { + if (network === "test") return; await deployer.deploy(BridgeImplementation); }; diff --git a/ethereum/package.json b/ethereum/package.json index b631718c9..5105d715b 100644 --- a/ethereum/package.json +++ b/ethereum/package.json @@ -19,7 +19,7 @@ }, "scripts": { "build": "truffle compile", - "test": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle test", + "test": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle test --network test", "migrate": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate --to 4", "flatten": "mkdir -p node_modules/@poanet/solidity-flattener/contracts && cp -r contracts/* node_modules/@poanet/solidity-flattener/contracts/ && poa-solidity-flattener", "deploy-bridge-implementation-only": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate --f 6 --to 6", diff --git a/ethereum/test/bridge.js b/ethereum/test/bridge.js index 6601995dc..da2303c0d 100644 --- a/ethereum/test/bridge.js +++ b/ethereum/test/bridge.js @@ -23,7 +23,7 @@ contract("Bridge", function () { const testChainId = "2"; const testGovernanceChainId = "1"; const testGovernanceContract = "0x0000000000000000000000000000000000000000000000000000000000000004"; - let WETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; + let WETH = process.env.BRIDGE_INIT_WETH;; const testForeignChainId = "1"; const testForeignBridgeContract = "0x000000000000000000000000000000000000000000000000000000000000ffff"; const testBridgedAssetChain = "0001"; diff --git a/ethereum/test/upgrades/01_tokenbridge_feetoken_support.js b/ethereum/test/upgrades/01_tokenbridge_feetoken_support.js index 2bce3e38a..e6f7558db 100644 --- a/ethereum/test/upgrades/01_tokenbridge_feetoken_support.js +++ b/ethereum/test/upgrades/01_tokenbridge_feetoken_support.js @@ -18,6 +18,7 @@ const BridgeImplementationFullABI = jsonfile.readFileSync("build/contracts/Bridg // needs to run on a mainnet fork contract("Update Bridge", function (accounts) { + if (config.network === "test") return; const testChainId = "2"; const testGovernanceChainId = "1"; const testGovernanceContract = "0x0000000000000000000000000000000000000000000000000000000000000004"; diff --git a/ethereum/truffle-config.js b/ethereum/truffle-config.js index 4e920b576..eff09839b 100644 --- a/ethereum/truffle-config.js +++ b/ethereum/truffle-config.js @@ -8,6 +8,12 @@ module.exports = { port: 8545, network_id: "*", }, + // test network is the same as development but allows us to omit certain migrations + test: { + host: "127.0.0.1", + port: 8545, + network_id: "*", + }, mainnet: { provider: () => new HDWalletProvider( @@ -56,10 +62,11 @@ module.exports = { gasPrice: 8000000000, }, binance_testnet: { - provider: () => new HDWalletProvider( - process.env.MNEMONIC, - "https://data-seed-prebsc-1-s1.binance.org:8545/" - ), + provider: () => + new HDWalletProvider( + process.env.MNEMONIC, + "https://data-seed-prebsc-1-s1.binance.org:8545/" + ), network_id: "97", gas: 70000000, gasPrice: 8000000000, @@ -79,7 +86,8 @@ module.exports = { provider: () => { return new HDWalletProvider( process.env.MNEMONIC, - "https://polygon-mumbai.infura.io/v3/" + process.env.INFURA_KEY) + "https://polygon-mumbai.infura.io/v3/" + process.env.INFURA_KEY + ); }, network_id: "80001", }, @@ -95,10 +103,11 @@ module.exports = { gasPrice: 26000000000, }, fuji: { - provider: () => new HDWalletProvider( - process.env.MNEMONIC, - "https://api.avax-test.network/ext/bc/C/rpc" - ), + provider: () => + new HDWalletProvider( + process.env.MNEMONIC, + "https://api.avax-test.network/ext/bc/C/rpc" + ), network_id: "43113", }, oasis: { @@ -126,7 +135,7 @@ module.exports = { return new HDWalletProvider( process.env.MNEMONIC, "https://testnet.aurora.dev" - ) + ); }, network_id: 0x4e454153, gas: 10000000, @@ -137,7 +146,7 @@ module.exports = { return new HDWalletProvider( process.env.MNEMONIC, "https://rpc.ftm.tools/" - ) + ); }, network_id: 250, gas: 8000000, @@ -149,7 +158,7 @@ module.exports = { return new HDWalletProvider( process.env.MNEMONIC, "https://rpc.testnet.fantom.network/" - ) + ); }, network_id: 0xfa2, gas: 4465030,