Skip to content

Commit

Permalink
Update dapp tests to be compatible with test chains (#1820)
Browse files Browse the repository at this point in the history
* test

* test

* add more setup

* add to path

* githubpath

* seid path

* dapp tests

* try artifacts

* ditch setup step

* deps

* test workflow

* set keyring

* without

* keys add

* add to sh

* nobackend

* no script

* test

* keyring

* no sh

* test

* fix flakiness

* cleanup

* move seid config command

* only if docker

* test without

* if isdocker

* printf mnemonic

* try escape path

* try single quotes

* try modifying execute

* no path

* backend

* try without keyring

* move keyring

* path

* basedir

* try pwd

* config reset

* seid config

* redeclare

* print

* docker path

* dynamic path

* config for all

* full

* lint issue

* backend

* cleanup
  • Loading branch information
mj850 authored Aug 16, 2024
1 parent 556baab commit 95c4767
Show file tree
Hide file tree
Showing 13 changed files with 581 additions and 485 deletions.
25 changes: 22 additions & 3 deletions .github/workflows/dapp_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,43 @@ jobs:
runs-on: ubuntu-latest
environment:
name: devnet
needs: run-tests-testnet
env:
DAPP_TESTS_MNEMONIC: ${{ secrets.DAPP_TESTS_MNEMONIC }}
steps:
- uses: actions/checkout@v3

- name: Install seid
run: |
# Install seid using go install
make install
# Add the Go bin directory to the PATH
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
echo "$HOME/go/bin" >> $GITHUB_PATH
- name: Run Dapp Tests Script on Devnet
run: |
chmod +x ./integration_test/dapp_tests/dapp_tests.sh
./integration_test/dapp_tests/dapp_tests.sh devnet
run-tests-testnet:
name: Run Tests on Testnet
runs-on: ubuntu-latest
environment:
name: testnet
env:
DAPP_TESTS_MNEMONIC: ${{ secrets.DAPP_TESTS_MNEMONIC }}
steps:
- uses: actions/checkout@v3

- name: Install seid
run: |
# Install seid using go install
make install
# Add the Go bin directory to the PATH
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
echo "$HOME/go/bin" >> $GITHUB_PATH
- name: Run Dapp Tests Script on Testnet
run: |
chmod +x ./integration_test/dapp_tests/dapp_tests.sh
./integration_test/dapp_tests/dapp_tests.sh testnet
1 change: 1 addition & 0 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
DAPP_TESTS_MNEMONIC: ${{ secrets.DAPP_TESTS_MNEMONIC }}
strategy:
# other jobs should run even if one integration test fails
fail-fast: false
Expand Down
35 changes: 21 additions & 14 deletions contracts/test/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ async function bankSend(toAddr, fromKey, amount="100000000000", denom="usei") {
return result
}

async function fundSeiAddress(seiAddr, amount="100000000000", denom="usei") {
return await execute(`seid tx bank send ${adminKeyName} ${seiAddr} ${amount}${denom} -b block --fees 20000usei -y`);
async function fundSeiAddress(seiAddr, amount="100000000000", denom="usei", funder=adminKeyName) {
return await execute(`seid tx bank send ${funder} ${seiAddr} ${amount}${denom} -b block --fees 20000usei -y`);
}

async function getSeiBalance(seiAddr, denom="usei") {
Expand Down Expand Up @@ -182,7 +182,7 @@ async function createTokenFactoryTokenAndMint(name, amount, recipient, from=admi
const mint_command = `seid tx tokenfactory mint ${amount}${token_denom} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode block -o json`
await execute(mint_command);

const send_command = `seid tx bank send ${adminKeyName} ${recipient} ${amount}${token_denom} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode block -o json`
const send_command = `seid tx bank send ${from} ${recipient} ${amount}${token_denom} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode block -o json`
await execute(send_command);
return token_denom
}
Expand All @@ -193,12 +193,13 @@ async function getPointerForNative(name) {
return JSON.parse(output);
}

async function storeWasm(path) {
const command = `seid tx wasm store ${path} --from ${adminKeyName} --gas=5000000 --fees=1000000usei -y --broadcast-mode block -o json`
async function storeWasm(path, from=adminKeyName) {
const command = `seid tx wasm store ${path} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode block -o json`
const output = await execute(command);
const response = JSON.parse(output)
return getEventAttribute(response, "store_code", "code_id")
}

async function getPointerForCw20(cw20Address) {
const command = `seid query evm pointer CW20 ${cw20Address} -o json`
const output = await execute(command);
Expand All @@ -211,8 +212,11 @@ async function getPointerForCw721(cw721Address) {
return JSON.parse(output);
}

async function deployErc20PointerForCw20(provider, cw20Address, attempts=10) {
const command = `seid tx evm register-evm-pointer CW20 ${cw20Address} --from=admin -b block`
async function deployErc20PointerForCw20(provider, cw20Address, attempts=10, from=adminKeyName, evmRpc="") {
let command = `seid tx evm register-evm-pointer CW20 ${cw20Address} --from=${from} -b block`
if (evmRpc) {
command = command + ` --evm-rpc=${evmRpc}`
}
const output = await execute(command);
const txHash = output.replace(/.*0x/, "0x").trim()
let attempt = 0;
Expand All @@ -229,8 +233,11 @@ async function deployErc20PointerForCw20(provider, cw20Address, attempts=10) {
throw new Error("contract deployment failed")
}

async function deployErc20PointerNative(provider, name) {
const command = `seid tx evm call-precompile pointer addNativePointer ${name} --from=admin -b block`
async function deployErc20PointerNative(provider, name, from=adminKeyName, evmRpc="") {
let command = `seid tx evm call-precompile pointer addNativePointer ${name} --from=${from} -b block`
if (evmRpc) {
command = command + ` --evm-rpc=${evmRpc}`
}
const output = await execute(command);
const txHash = output.replace(/.*0x/, "0x").trim()
let attempt = 0;
Expand Down Expand Up @@ -263,14 +270,14 @@ async function deployErc721PointerForCw721(provider, cw721Address) {
throw new Error("contract deployment failed")
}

async function deployWasm(path, adminAddr, label, args = {}) {
const codeId = await storeWasm(path)
return await instantiateWasm(codeId, adminAddr, label, args)
async function deployWasm(path, adminAddr, label, args = {}, from=adminKeyName) {
const codeId = await storeWasm(path, from)
return await instantiateWasm(codeId, adminAddr, label, args, from)
}

async function instantiateWasm(codeId, adminAddr, label, args = {}) {
async function instantiateWasm(codeId, adminAddr, label, args = {}, from=adminKeyName) {
const jsonString = JSON.stringify(args).replace(/"/g, '\\"');
const command = `seid tx wasm instantiate ${codeId} "${jsonString}" --label ${label} --admin ${adminAddr} --from ${adminKeyName} --gas=5000000 --fees=1000000usei -y --broadcast-mode block -o json`;
const command = `seid tx wasm instantiate ${codeId} "${jsonString}" --label ${label} --admin ${adminAddr} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode block -o json`;
const output = await execute(command);
const response = JSON.parse(output);
return getEventAttribute(response, "instantiate", "_contract_address");
Expand Down
20 changes: 20 additions & 0 deletions integration_test/dapp_tests/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const rpcUrls = {
"testnet": "https://rpc-testnet.sei-apis.com",
"devnet": "https://rpc-arctic-1.sei-apis.com"
}

const evmRpcUrls = {
"testnet": "https://evm-rpc-testnet.sei-apis.com",
"devnet": "https://evm-rpc-arctic-1.sei-apis.com"
}

const chainIds = {
"testnet": "atlantic-2",
"devnet": "arctic-1"
}

module.exports = {
rpcUrls,
evmRpcUrls,
chainIds
}
1 change: 1 addition & 0 deletions integration_test/dapp_tests/dapp_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ npx hardhat compile

# Set the CONFIG environment variable
export DAPP_TEST_ENV=$1

npx hardhat test --network $1 uniswap/uniswapTest.js
npx hardhat test --network $1 steak/SteakTests.js
25 changes: 21 additions & 4 deletions integration_test/dapp_tests/hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,30 @@ module.exports = {
networks: {
seilocal: {
url: "http://127.0.0.1:8545",
address: ["0xF87A299e6bC7bEba58dbBe5a5Aa21d49bCD16D52", "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"],
accounts: ["0x57acb95d82739866a5c29e40b0aa2590742ae50425b7dd5b5d279a986370189e", "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"],
accounts: {
mnemonic: process.env.DAPP_TESTS_MNEMONIC,
path: "m/44'/118'/0'/0/0",
initialIndex: 0,
count: 1
},
},
testnet: {
url: "https://evm-rpc-testnet.sei-apis.com",
address: ["0xF87A299e6bC7bEba58dbBe5a5Aa21d49bCD16D52", "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"],
accounts: ["0x57acb95d82739866a5c29e40b0aa2590742ae50425b7dd5b5d279a986370189e", "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"],
accounts: {
mnemonic: process.env.DAPP_TESTS_MNEMONIC,
path: "m/44'/118'/0'/0/0",
initialIndex: 0,
count: 1
},
},
devnet: {
url: "https://evm-rpc-arctic-1.sei-apis.com",
accounts: {
mnemonic: process.env.DAPP_TESTS_MNEMONIC,
path: "m/44'/118'/0'/0/0",
initialIndex: 0,
count: 1
},
},
},
};
67 changes: 54 additions & 13 deletions integration_test/dapp_tests/steak/SteakTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const {
getEvmAddress,
fundSeiAddress,
associateKey,
execute,
isDocker,
} = require("../../../contracts/test/lib.js");
const {
getValidators,
Expand All @@ -14,38 +16,45 @@ const {
queryTokenBalance,
unbond,
transferTokens,
} = require("./utils.js");
setupAccountWithMnemonic,
sendFunds
} = require("../utils.js");

const { expect } = require("chai");
const { v4: uuidv4 } = require("uuid");
const hre = require("hardhat");
const {chainIds, rpcUrls, evmRpcUrls} = require("../constants");
const path = require("path");

const STEAK_HUB_WASM =
"../integration_test/dapp_tests/steak/contracts/steak_hub.wasm";
const STEAK_TOKEN_WASM =
"../integration_test/dapp_tests/steak/contracts/steak_token.wasm";
const testChain = process.env.DAPP_TEST_ENV;

describe("Steak", async function () {
let owner;
let hubAddress;
let tokenAddress;
let tokenPointer;
let originalSeidConfig;

async function setupAccount(baseName, associate = true) {
async function setupAccount(baseName, associate = true, amount="100000000000", denom="usei", funder='admin') {
const uniqueName = `${baseName}-${uuidv4()}`;

const account = await addAccount(uniqueName);
await fundSeiAddress(account.address);
await fundSeiAddress(account.address, amount, denom, funder);
if (associate) {
await associateKey(account.address);
}

return account;
}

async function deployContracts(ownerAddress) {
// Store CW20 token wasm
const tokenCodeId = await storeWasm(STEAK_TOKEN_WASM);
const STEAK_TOKEN_WASM = (await isDocker()) ? '../integration_test/dapp_tests/steak/contracts/steak_token.wasm' : path.resolve(__dirname, '../steak/contracts/steak_token.wasm')
const tokenCodeId = await storeWasm(STEAK_TOKEN_WASM, ownerAddress);

// Store Hub contract
const hubCodeId = await storeWasm(STEAK_HUB_WASM);
const STEAK_HUB_WASM = (await isDocker()) ? '../integration_test/dapp_tests/steak/contracts/steak_hub.wasm' : path.resolve(__dirname, '../steak/contracts/steak_hub.wasm')
const hubCodeId = await storeWasm(STEAK_HUB_WASM, ownerAddress);

// Instantiate hub and token contracts
const validators = await getValidators();
Expand All @@ -69,8 +78,12 @@ describe("Steak", async function () {
// Deploy pointer for token contract
const pointerAddr = await deployErc20PointerForCw20(
hre.ethers.provider,
contractAddresses.tokenContract
contractAddresses.tokenContract,
10,
ownerAddress,
evmRpcUrls[testChain]
);

const tokenPointer = new hre.ethers.Contract(
pointerAddr,
ABI.ERC20,
Expand Down Expand Up @@ -104,8 +117,28 @@ describe("Steak", async function () {
}

before(async function () {

const seidConfig = await execute('seid config');
originalSeidConfig = JSON.parse(seidConfig);

// Set up the owner account
owner = await setupAccount("steak-owner");
if (testChain === 'seilocal') {
owner = await setupAccount("steak-owner");
} else {
// Set default seid config to the specified rpc url.
await execute(`seid config chain-id ${chainIds[testChain]}`)
await execute(`seid config node ${rpcUrls[testChain]}`)

const accounts = hre.config.networks[testChain].accounts
const deployerWallet = hre.ethers.Wallet.fromMnemonic(accounts.mnemonic, accounts.path);
const deployer = deployerWallet.connect(hre.ethers.provider)

await sendFunds('0.01', deployer.address, deployer)
// Set the config keyring to 'test' since we're using the key added to test from here.
owner = await setupAccountWithMnemonic("steak-owner", accounts.mnemonic, deployer)
}

await execute(`seid config keyring-backend test`);

// Store and deploy contracts
({ hubAddress, tokenAddress, tokenPointer } = await deployContracts(
Expand All @@ -130,7 +163,7 @@ describe("Steak", async function () {
});

it("Unassociated account should be able to bond", async function () {
const unassociatedAccount = await setupAccount("unassociated", false);
const unassociatedAccount = await setupAccount("unassociated", false, '2000000', 'usei', owner.address);
// Verify that account is not associated yet
const initialEvmAddress = await getEvmAddress(
unassociatedAccount.address
Expand All @@ -144,7 +177,7 @@ describe("Steak", async function () {
expect(evmAddress).to.not.be.empty;

// Send tokens to a new unassociated account
const newUnassociatedAccount = await setupAccount("unassociated", false);
const newUnassociatedAccount = await setupAccount("unassociated", false, '2000000', 'usei', owner.address);
const transferAmount = 500000;
await transferTokens(
tokenAddress,
Expand All @@ -162,4 +195,12 @@ describe("Steak", async function () {
await testUnbonding(newUnassociatedAccount.address, transferAmount / 2);
});
});

after(async function () {
// Set the chain back to regular state
console.log(`Resetting to ${originalSeidConfig}`)
await execute(`seid config chain-id ${originalSeidConfig["chain-id"]}`)
await execute(`seid config node ${originalSeidConfig["node"]}`)
await execute(`seid config keyring-backend ${originalSeidConfig["keyring-backend"]}`)
})
});
Loading

0 comments on commit 95c4767

Please sign in to comment.