Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add CI for integration test suite for contract upgrades #377

Closed
wants to merge 36 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d4c266d
chore: add workspace in package.json
viraj124 Dec 27, 2024
61e3417
feat: add docker setup in contracts package
viraj124 Dec 27, 2024
a51dc48
chore: add test placeholder contract
viraj124 Dec 27, 2024
a32de3f
feat: add upgrade scripts
viraj124 Dec 27, 2024
fab154b
chore: enable forking in hardhat config
viraj124 Dec 27, 2024
8647dbc
chore: add shell scripts
viraj124 Dec 27, 2024
e684961
chore: add additional committer signer in test setup
viraj124 Dec 27, 2024
c21c645
feat: add fork integration tests
viraj124 Dec 27, 2024
f36aef9
feat: add github action for fork integration tests
viraj124 Dec 27, 2024
7b932fb
chore: add build command in workflow
viraj124 Dec 27, 2024
2ebc8b7
chore: add docker and rust setup in ci
viraj124 Dec 30, 2024
22dafb8
chore: debug ci failure
viraj124 Dec 30, 2024
092e1db
chore: fast forward finalization time before relay
viraj124 Dec 30, 2024
8768fbb
chore: debug ci failure
viraj124 Dec 31, 2024
4a8ac6e
chore: debug ci failure
viraj124 Dec 31, 2024
3f56a0d
chore: update portal upgrade script
viraj124 Dec 31, 2024
b0e7f05
chore: uncomment code
viraj124 Dec 31, 2024
98afdf2
chore: add changeset
viraj124 Dec 31, 2024
666ccc6
chore: formatting
viraj124 Jan 1, 2025
51f7a9f
chore: update forc version
viraj124 Jan 2, 2025
1d53792
chore: debug format check in ci
viraj124 Jan 2, 2025
a134435
chore: ts lint fixes
viraj124 Jan 2, 2025
417733c
chore: update check shell script
viraj124 Jan 2, 2025
2ada6f5
chore: update order of commands in check script
viraj124 Jan 2, 2025
430bce2
chore: debug forc formatting
viraj124 Jan 2, 2025
da63952
chore: remove --check
viraj124 Jan 2, 2025
e933a2e
chore: update forc command
viraj124 Jan 2, 2025
08917b8
chore: add build command
viraj124 Jan 2, 2025
6348e38
chore: remove forc lock files in ci
viraj124 Jan 2, 2025
c4d176b
chore: update installation for forc-fmt
viraj124 Jan 3, 2025
8ff85d2
chore: test ci
viraj124 Jan 3, 2025
e31d697
chore: test ci
viraj124 Jan 3, 2025
396622d
chore: minor update
viraj124 Jan 3, 2025
537f38a
chore: small touchup in action.yml
viraj124 Jan 3, 2025
861d437
chore: revert workflow changes
viraj124 Jan 3, 2025
38ba169
chore: update fmt command
viraj124 Jan 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/thin-ways-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@fuel-bridge/solidity-contracts': minor
'@fuel-bridge/test-utils': minor
---

ci for contract upgrade test suite
2 changes: 1 addition & 1 deletion .github/actions/setup-rust/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ runs:
uses: FuelLabs/[email protected]
with:
name: fuel-bridge
components: ${{ inputs.forc-components }}
components: ${{ inputs.forc-components }}
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ jobs:
# TODO issue 115: https://github.com/FuelLabs/fuel-bridge/issues/115
# Run test again to ensure it works with node that already has transactions/messages
# - name: Test projects Again
# run: pnpm --filter @fuel-bridge/integration-tests test
# run: pnpm --filter @fuel-bridge/integration-tests test
43 changes: 43 additions & 0 deletions .github/workflows/upgrade-test-suite.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Upgrade Test Suite

on:
push:
branches:
- main
pull_request:
branches:
- main # Target branch for the PR
release:
types: [published]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
upgrade-test-suite:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v3
- uses: FuelLabs/github-actions/setups/node@master
with:
node-version: 20.16.0
pnpm-version: 9.0.6
- uses: FuelLabs/github-actions/setups/docker@master
with:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: ./.github/actions/setup-rust
- name: Build project
run: pnpm build
- name: Sets the tenderly rpc endpoint in the L1 docker container env
run: |
cat << EOF > l1_chain.env
TENDERLY_RPC_URL=${{ secrets.TENDERLY_RPC_URL }}
EOF
working-directory: ./packages/solidity-contracts/docker/envs
- name: Run integration tests on a L1 fork after upgrading contracts
run: |
pnpm upgrade:test:integration
working-directory: ./packages/solidity-contracts
2 changes: 1 addition & 1 deletion docker/l1-chain/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ RUN apk --no-cache add git curl
RUN npm i -g pnpm

# clone the contracts repo
ADD ./packages/solidity-contracts/package.json /l1chain/fuel-v2-contracts/
ADD docker/l1-chain/package.json /l1chain/fuel-v2-contracts/
# copy over the fuel chain and replace consts values
WORKDIR /l1chain/fuel-v2-contracts

Expand Down
85 changes: 85 additions & 0 deletions docker/l1-chain/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"name": "@fuel-bridge/solidity-contracts",
"version": "1.0.0",
"description": "The Fuel v2 Solidity smart contracts.",
"license": "APACHE-2.0",
"files": [
"typechain",
"contracts",
"artifacts",
"dist"
],
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"typings": "dist/index.d.ts",
"main": "dist/index.js",
"scripts": {
"build": "run-s clean compile build:exports",
"build:exports": "tsup",
"clean": "pnpm hardhat clean",
"compile": "pnpm hardhat compile --show-stack-traces",
"coverage": "pnpm run build && pnpm hardhat coverage --temp artifacts --network hardhat",
"check": "pnpm solhint \"contracts/**/*.sol\"",
"node": "pnpm hardhat node --network hardhat --hostname 0.0.0.0",
"start-mining": "pnpm hardhat run --no-compile --network localhost scripts/startAutoMining.ts",
"serve-deployments": "pnpm ts-node scripts/serveDeployments.ts",
"test": "pnpm hardhat test",
"integration-test": "pnpm mocha -b -r ts-node/register 'integration-tests/**/*.ts'",
"node:up": "sh ./scripts/node:up.sh",
"hardhat:test:integration": "DISABLE_GAS_REPORTER=true pnpm hardhat --network mainnetFork test fork-integration-tests/**/*.ts --bail",
"test-no-compile": "pnpm hardhat test --no-compile",
"test-parallel": "pnpx mocha 'test/**/*.ts' --recursive --parallel --require hardhat/register",
"prettier": "prettier --write --plugin=prettier-plugin-solidity 'contracts/**/*.sol'",
"lint": "prettier --list-different --plugin=prettier-plugin-solidity 'contracts/**/*.sol'"
},
"devDependencies": {
"@fuel-ts/merkle": "^0.21.2",
"@inquirer/prompts": "^5.3.8",
"@nomicfoundation/hardhat-chai-matchers": "^2.0.4",
"@nomicfoundation/hardhat-ethers": "^3.0.5",
"@nomicfoundation/hardhat-network-helpers": "^1.0.10",
"@nomicfoundation/hardhat-verify": "1.1.1",
"@openzeppelin/contracts": "^4.8.3",
"@openzeppelin/contracts-upgradeable": "^4.8.3",
"@openzeppelin/hardhat-upgrades": "^3.0.4",
"@safe-global/api-kit": "^2.4.6",
"@safe-global/protocol-kit": "^4.1.1",
"@safe-global/safe-core-sdk-types": "^5.1.0",
"@typechain/ethers-v6": "^0.5.1",
"@typechain/hardhat": "^9.1.0",
"@types/chai": "^4.3.4",
"@types/cors": "2.8.17",
"mocha": "^10.0.0",
"@types/express": "^4.17.14",
"@types/lodash": "^4.14.202",
"@types/mocha": "^10.0.0",
"@types/node": "^18.11.9",
"@typescript-eslint/eslint-plugin": "^5.43.0",
"@typescript-eslint/parser": "^5.43.0",
"axios": "^1.7.7",
"chai": "^4.3.7",
"cors": "2.8.5",
"dotenv": "^16.0.3",
"ethers": "6.13.1",
"express": "^4.18.2",
"fuels": "0.96.1",
"hardhat": "^2.20.1",
"hardhat-deploy": "^0.12.4",
"inquirer": "^10.1.8",
"lodash": "^4.17.21",
"markdownlint": "^0.26.2",
"markdownlint-cli": "^0.32.2",
"node-fetch": "^2.6.6",
"npm-run-all": "^4.1.5",
"prettier-plugin-solidity": "^1.1.3",
"solc": "^0.8.17",
"solhint": "3.3.7",
"solidity-coverage": "^0.8.5",
"ts-generator": "^0.1.1",
"ts-node": "^10.9.1",
"tsup": "^7.2.0",
"typechain": "^8.3.2",
"typescript": "^4.9.3"
}
}

5 changes: 5 additions & 0 deletions packages/solidity-contracts/contracts/test/PlaceHolder.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
/// @dev The only purpose of this contract is to be copied during the Dockerfile build
/// so that hardhat downloads the compiler and it gets cached
contract PlaceHolder {}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
upgrades: { deployProxy, erc1967 },
deployments: { save },
} = hre;

const isForking = hre.config.networks[hre.network.name]?.forking?.enabled;
if (isForking) return;

const [deployer] = await ethers.getSigners();

const contract = await deployProxy(new FuelChainState(deployer), [], {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
upgrades: { deployProxy, erc1967 },
deployments: { get, save },
} = hre;

const isForking = hre.config.networks[hre.network.name]?.forking?.enabled;
if (isForking) return;

const [deployer] = await ethers.getSigners();

const { address: fuelChainState } = await get('FuelChainState');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
upgrades: { deployProxy, erc1967 },
deployments: { get, save },
} = hre;

const isForking = hre.config.networks[hre.network.name]?.forking?.enabled;
if (isForking) return;

const [deployer] = await ethers.getSigners();

const fuelMessagePortal = await get('FuelMessagePortal');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,21 @@ const COMMITTER_ADDRESS = '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { ethers, deployments } = hre;

const isForking = hre.config.networks[hre.network.name]?.forking?.enabled;

const [deployer] = await ethers.getSigners();

const { address } = await deployments.get('FuelChainState');
if (!isForking) {
const { address } = await deployments.get('FuelChainState');

const fuelChainState = FuelChainState__factory.connect(address, deployer);
const COMMITTER_ROLE = await fuelChainState.COMMITTER_ROLE();
const fuelChainState = FuelChainState__factory.connect(address, deployer);
const COMMITTER_ROLE = await fuelChainState.COMMITTER_ROLE();

await fuelChainState
.grantRole(COMMITTER_ROLE, COMMITTER_ADDRESS)
.then((tx) => tx.wait());
await fuelChainState
.grantRole(COMMITTER_ROLE, COMMITTER_ADDRESS)
.then((tx) => tx.wait());
}

console.log('Granted role COMMITTER_ROLE to', COMMITTER_ADDRESS);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import fs from 'fs';
import type { HardhatRuntimeEnvironment } from 'hardhat/types';
import type { DeployFunction } from 'hardhat-deploy/dist/types';
import path from 'path';

import { FuelERC721GatewayV2__factory as FuelERC721GatewayV2 } from '../../typechain';

Expand All @@ -9,13 +11,33 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
upgrades: { deployProxy, erc1967 },
deployments: { get, save },
} = hre;

const isForking = hre.config.networks[hre.network.name]?.forking?.enabled;

const [deployer] = await ethers.getSigners();

const fuelMessagePortal = await get('FuelMessagePortal');
let portlAddress;
if (isForking) {
const deploymentPath = path.join(
__dirname,
'..',
'..',
'/',
'deployments',
'mainnet',
'FuelMessagePortal.json'
);

const deployment = JSON.parse(fs.readFileSync(deploymentPath, 'utf8'));
portlAddress = deployment.address;
} else {
const fuelMessagePortal = await get('FuelMessagePortal');
portlAddress = fuelMessagePortal.address;
}

const contract = await deployProxy(
new FuelERC721GatewayV2(deployer),
[fuelMessagePortal.address],
[portlAddress],
{
initializer: 'initialize',
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ const ASSET_ISSUER_ID =

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { ethers, deployments } = hre;

const isForking = hre.config.networks[hre.network.name]?.forking?.enabled;
if (isForking) return;

const [deployer] = await ethers.getSigners();

await deployments.execute(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import fs from 'fs';
import type { HardhatRuntimeEnvironment } from 'hardhat/types';
import type { DeployFunction } from 'hardhat-deploy/dist/types';
import path from 'path';

import { FuelChainState__factory } from '../../typechain';

const BLOCKS_PER_COMMIT_INTERVAL = 30;
const TIME_TO_FINALIZE = 5;
const COMMIT_COOLDOWN = TIME_TO_FINALIZE;

const ADMIN = '0x32da601374b38154f05904B16F44A1911Aa6f314';
let COMMITTER_ADDRESS = '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const {
ethers,
upgrades: { erc1967 },
} = hre;

const [deployer] = await ethers.getSigners();

const isForking = hre.config.networks[hre.network.name]?.forking?.enabled;
let address;

if (isForking) {
const deploymentPath = path.join(
__dirname,
'..',
'..',
'/',
'deployments',
'mainnet',
'FuelChainState.json'
);

const deployment = JSON.parse(fs.readFileSync(deploymentPath, 'utf8'));
address = deployment.address;

const chainState = FuelChainState__factory.connect(address, deployer);

const factory = await hre.ethers.getContractFactory('FuelChainState');

const newImplementation = await factory.deploy(
TIME_TO_FINALIZE,
BLOCKS_PER_COMMIT_INTERVAL,
COMMIT_COOLDOWN
);

const newImplementationAddress = await newImplementation.getAddress();

let txData = chainState.interface.encodeFunctionData('upgradeTo', [
newImplementationAddress,
]);

await deployer.sendTransaction({
to: ADMIN,
value: ethers.parseEther('100'),
});

const impersonatedSigner = await ethers.getImpersonatedSigner(ADMIN);
await impersonatedSigner.sendTransaction({
to: address,
data: txData,
});

const COMMITTER_ROLE = await chainState.COMMITTER_ROLE();

txData = await chainState.interface.encodeFunctionData('grantRole', [
COMMITTER_ROLE,
COMMITTER_ADDRESS,
]);

await impersonatedSigner.sendTransaction({
to: address,
data: txData,
});

COMMITTER_ADDRESS = '0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65';

txData = await chainState.interface.encodeFunctionData('grantRole', [
COMMITTER_ROLE,
COMMITTER_ADDRESS,
]);

await impersonatedSigner.sendTransaction({
to: address,
data: txData,
});

const implementation = await erc1967.getImplementationAddress(address);

console.log('Upgraded FuelChainState to', implementation);

return true;
}
};

func.tags = ['upgrade_chain_state'];
func.id = 'upgrade_chain_state';
export default func;
Loading
Loading