-
Notifications
You must be signed in to change notification settings - Fork 2
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
Integration tests against Mezo Portal #372
Conversation
This configuration is aimed to run MezoAllocator tests against mainnet fork and check the flow with the real Mezo Portal contract deployed on mainnet. This also sets up a ground for other tests that can also be moved and check against the real contracts on mainnet. The network is called "integration". A local hardhat node should be run to execute these tests.
Changed from "pnpm run deploy" to "pnpm run deployment". The original change was driven by the conflict between hardhat and pnpm "deploy" commands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please include instructions in README on how to run the tests.
solidity/package.json
Outdated
@@ -16,7 +16,7 @@ | |||
"scripts": { | |||
"clean": "hardhat clean && rm -rf cache/ export/ gen/ export.json", | |||
"build": "hardhat compile", | |||
"deploy": "hardhat deploy --export export.json", | |||
"deployment": "hardhat deploy --export export.json", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd keep deploy
as we're used to it across the projects. I know it may overlap with pnpm deploy
but we should execute the deployment script with pnpm run deploy
as we do in CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not me not liking the deploy
name, it is that it's conflicting with the pnpm
deploy build-in command and it's not working as is. See here. If you run pnpm deploy
you will get
ERR_PNPM_NOTHING_TO_DEPLOY No project was selected for deployment
Having said that, I figured I change it to deployment
(you can suggest some other name) so at least we have a working command. Otherwise it's not useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will work if you execute it with pnpm run deploy
. pnpm run <script> is the command we use to run the scripts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see, I didn't know that and assumed all the commands are triggered as pnpm <command>
b08c47f
solidity/.gitignore
Outdated
@@ -5,3 +5,4 @@ export.json | |||
export/ | |||
gen/ | |||
typechain/ | |||
deployments/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's ignore only the specific network artifacts (deployments/integration/
), as we don't want to ignore deployments/mainnet/
and deployments/sepolia/
directories.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After I ran the tests locally I noticed there was no output under the deployments/
directory. Maybe we don't need this entry added to .gitignore
at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, turns out it's not needed 2e88d5d. Must've been a leftover after some changes during implementation. Removed.
solidity/package.json
Outdated
@@ -26,7 +26,8 @@ | |||
"lint:sol:fix": "solhint 'contracts/**/*.sol' --fix && prettier --write 'contracts/**/*.sol'", | |||
"lint:config": "prettier --check '**/*.@(json)'", | |||
"lint:config:fix": "prettier --write '**/*.@(json)'", | |||
"test": "hardhat test" | |||
"test": "hardhat test ./test/*.test.ts", | |||
"test:integration": "INTEGRATION_TEST=true hardhat test ./test/integration/*.test.ts --network integration" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we add --deploy-fixture
flag the external deployment artifacts will be read from the ./external/mainnet/
directory and we won't need to deal with the alternative deployments.getArtifact
path in deployment scripts.
"test:integration": "INTEGRATION_TEST=true hardhat test ./test/integration/*.test.ts --network integration" | |
"test:integration": "hardhat test --deploy-fixture ./test/integration/*.test.ts --network integration" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's nice, way cleaner! 718a723
solidity/hardhat.config.ts
Outdated
@@ -29,6 +29,10 @@ const config: HardhatUserConfig = { | |||
hardhat: { | |||
tags: ["allowStubs"], | |||
}, | |||
integration: { | |||
url: "http://localhost:8545", | |||
tags: ["allowStubs"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we could remove this tag.
tags: ["allowStubs"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let mezoPortal = await deployments.getOrNull("MezoPortal") | ||
if (hre.network.name === "integration") { | ||
mezoPortal = await deployments.getArtifact("MezoPortal") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use --deploy-fixture
flag for tests running we could revert the getArtifact
change across the deployment scripts.
let mezoPortal = await deployments.getOrNull("MezoPortal") | |
if (hre.network.name === "integration") { | |
mezoPortal = await deployments.getArtifact("MezoPortal") | |
} | |
const mezoPortal = await deployments.getOrNull("MezoPortal") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(hre.network.config as HardhatNetworkConfig)?.forking?.enabled && | ||
hre.network.name !== "hardhat" | ||
) { | ||
} else if ((hre.network.config as HardhatNetworkConfig)?.forking?.enabled) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For integration tests we want the script to fail if the deployment artifact is not found, we need to make sure it doesn't deploy the stub.
} else if ((hre.network.config as HardhatNetworkConfig)?.forking?.enabled) { | |
} else if ( | |
hre.network.name === "integration" || | |
(hre.network.config as HardhatNetworkConfig)?.forking?.enabled | |
) { |
We should also introduce a similar change in other scripts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
solidity/hardhat.config.ts
Outdated
contracts: | ||
process.env.INTEGRATION_TEST === "true" | ||
? [ | ||
{ | ||
artifacts: "./external/mainnet", | ||
}, | ||
] | ||
: undefined, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could remove it if we add the --deploy-fixture
flag (see comment in package.json).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use the '--deploy-fixture' flag to fetch the mainnet artifacts for integration tests purposes. This can replace dealing with the 'integration' flag and using 'getArtifacts' function.
|
Name | Link |
---|---|
🔨 Latest commit | ce77495 |
Added 0a2a2d8 |
hre.network.name === "integration" || | ||
(hre.network.config as HardhatNetworkConfig)?.forking?.enabled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're not using hardhat forking network and we want the stubs to be deployed only for unit tests maybe we could modify this check in all deployment scripts and throw the error when hre.network.name !== "hardhat"
?
hre.network.name === "integration" || | |
(hre.network.config as HardhatNetworkConfig)?.forking?.enabled | |
hre.network.name !== "hardhat" |
This way the stub will be deployed only for hardhat
network (which we use for unit tests), and for any other case (integration, mainnet, sepolia) when the actual contract is not found it will throw an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We certainly can do that 962d173
hre.network.name === "integration" || | ||
!hre.network.tags.allowStubs || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could remove the allowStubs
tag from the network configuration and deployment scripts as it is used only for hardhat network (see other comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"setOwner", | ||
deployment.address, | ||
) | ||
if (hre.network.name === "hardhat") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're in the else
block, the stub is being deployed so maybe we don't need this network check here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} = await loadFixture(fixture)) | ||
|
||
await impersonateAccount(whaleAddress) | ||
// eslint-disable-next-line |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could fix the eslint problem if we import ethers from hardhat:
import { helpers, ethers } from "hardhat"
// eslint-disable-next-line |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
it("should increment the deposit id", async () => { | ||
const actualDepositId = await mezoAllocator.depositId() | ||
// As of writing this test, the deposit id was 2272 before the new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// As of writing this test, the deposit id was 2272 before the new | |
// As of forked block 19680873, the deposit id was 2272 before the new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of running 'pnpm deploy', you should run 'pnpm run deploy' to bypass the conflict between a custom hardhat command and a build-in pnpm command.
We use stubs only in hardhat network. For all other networks we'd use actual contracts. This way the deployment scripts can be simplified.
Verified that MezoPortal will throw an InsufficientDepositAmount error when a depositor wants to withdraw more than was initially deposited.
- Run the Hardhat Node locally forking Mainnet at block `19680873`: | ||
|
||
``` | ||
$ npx hardhat node --no-deploy --fork https://eth-mainnet.g.alchemy.com/v2/<key> --fork-block-number 19680873 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another idea to simplify setup is to include the node configuration in the hardhat config file and define a script, so to run the node for testing we will only need to run pnpm run test:node-forking
.
diff --git a/solidity/hardhat.config.ts b/solidity/hardhat.config.ts
index ac6a1492..e1e2fae2 100644
--- a/solidity/hardhat.config.ts
+++ b/solidity/hardhat.config.ts
@@ -26,6 +26,12 @@ const config: HardhatUserConfig = {
},
networks: {
+ hardhat: {
+ forking:
+ process.env.FORKING === "true"
+ ? { url: process.env.CHAIN_API_URL ?? "", blockNumber: 19680873 }
+ : undefined,
+ },
integration: {
url: "http://localhost:8545",
},
diff --git a/solidity/package.json b/solidity/package.json
index 8cb5969e..4e200da4 100644
--- a/solidity/package.json
+++ b/solidity/package.json
@@ -27,6 +27,7 @@
"lint:config": "prettier --check '**/*.@(json)'",
"lint:config:fix": "prettier --write '**/*.@(json)'",
"test": "hardhat test ./test/*.test.ts",
+ "test:node-forking": "FORKING=true hardhat node --no-deploy",
"test:integration": "hardhat test --deploy-fixture ./test/integration/*.test.ts --network integration"
},
"devDependencies": {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not blocking this PR. I'll create a follow-up PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, that might work. We'll need to provide a key for CHAIN_API_URL because we probably don't want to make it public. Or even assemble everything into one bash script to run the tests like ./scripts/run-integration-tests.sh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// It is reverted because deposit Id is 0 and there is no deposit | ||
// with id 0 in Mezo Portal for Acre. Mezo Portal reverts with the | ||
// "unrecognized custom error" that is why we verify only against | ||
// a generic revert. | ||
await expect(stbtc.withdraw(1n, depositor, depositor)).to.be.reverted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to verify the exact custom error now similar to the InsufficientDepositAmount check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done 90f1e64
Depends on #372 Adding CI config `solidity-integration-test` to run integration tests against forked mainnet by the local hardhat node.
Depends on #350
This configuration is aimed to run
MezoAllocator
tests againstmainnet
fork and check the flow with the real Mezo Portal contract deployed on mainnet. This also sets up a ground for other tests that can also be moved and checked against the real contracts on mainnet.The network is called "integration". A local hardhat node should be run to execute these tests.
E.g.
19680873
the current block number was used as of writing these tests.Once the local node is running, then the tests can be executed by running: