This repository has been archived by the owner on Nov 30, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 161
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: add solidity test suites (#487)
* tests: add solidity test suite * tests: remove require strings * Update tests-solidity/init-test-node.sh * Update tests-solidity/init-test-node.sh Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
- Loading branch information
Showing
104 changed files
with
16,013 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.sol linguist-language=Solidity |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# dependencies | ||
node_modules/ | ||
|
||
# ignore package-lock files (only use yarn.lock) | ||
package-lock.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# Solidity tests | ||
|
||
Increasingly difficult tests are provided: | ||
|
||
- [Basic](./suites/basic): simple Counter example, for basic calls, transactions, and events | ||
- [Initialize](./suites/initialize): initialization contract and tests from [aragonOS](https://github.com/aragon/aragonOS) | ||
- [Initialize (Buidler)](./suites/initialize-buidler): initialization contract and tests from [aragonOS](https://github.com/aragon/aragonOS), using [buidler](https://buidler.dev/) | ||
- [Proxy](./suites/proxy): depositable delegate proxy contract and tests from [aragonOS](https://github.com/aragon/aragonOS) | ||
- [Staking](./suites/staking): Staking contracts and full test suite from [aragon/staking](http://github.com/aragon/staking) | ||
|
||
### Quick start | ||
|
||
**Prerequisite**: in the repo's root, run `make install` to install the `ethermintd` and `ethermintcli` binaries. When done, come back to this directory. | ||
|
||
**Prerequisite**: install the individual solidity packages. They're set up as individual reops in a yarn monorepo workspace. Install them all via `yarn install`. | ||
|
||
To run the tests, start three terminals (or two, if you run `ethermintd` with `&`). | ||
|
||
In the first, run `ethermintd`: | ||
|
||
```sh | ||
./init-test-node.sh | ||
``` | ||
|
||
In the second, run `ethermintcli` as mentioned in the script's output: | ||
|
||
```sh | ||
ethermintcli rest-server --laddr "tcp://localhost:8545" --unlock-key localkey,user1,user2 --chain-id 1337 --trace --wsport 8546 | ||
``` | ||
|
||
You will now have three ethereum accounts unlocked in the test node: | ||
|
||
- `0x3b7252d007059ffc82d16d022da3cbf9992d2f70` (Validator) | ||
- `0xddd64b4712f7c8f1ace3c145c950339eddaf221d` (User 1) | ||
- `0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0` (user 2) | ||
|
||
From here, in your other available terminal, go into any of the tests and run `yarn test-ethermint`. You should see `ethermintd` accepting transactions and producing blocks. You should be able to query for any transaction via: | ||
|
||
- `ethermintcli query tx <cosmos-sdk tx>` | ||
- `curl localhost:8545 -H "Content-Type:application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["<ethereum tx>"],"id":1}'` | ||
|
||
And obviously more, via the Ethereum JSON-RPC API). | ||
|
||
When in doubt, you can also run the tests against a Ganache instance via `yarn test-ganache`, to make sure they are behaving correctly. | ||
|
||
### Test node | ||
|
||
The [`init-test-node.sh`](./init-test-node.sh) script sets up ethermint with the following accounts: | ||
|
||
- `eth18de995q8qk0leqk3d5pzmg7tlxvj6tmsku084d` (Validator) | ||
- `0x3b7252d007059ffc82d16d022da3cbf9992d2f70` | ||
- `eth1mhtyk3cj7ly0rt8rc9zuj5pnnmw67gsapygwyq` (User 1) | ||
- `0xddd64b4712f7c8f1ace3c145c950339eddaf221d` | ||
- `eth1pa20g7lehr330vs5ent20slr3wyne4lsy8qae3` (user 2) | ||
- `0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0` | ||
|
||
Each with roughly 100 ETH available (1e18 photon). | ||
|
||
Running `ethermintcli list keys` should output: | ||
|
||
```json | ||
[ | ||
{ | ||
"name": "localkey", | ||
"type": "local", | ||
"address": "eth18de995q8qk0leqk3d5pzmg7tlxvj6tmsku084d", | ||
"pubkey": "ethpub1pfqnmk6pq3ycjs34vv4n6rkty89f6m02qcsal3ecdzn7a3uunx0e5ly0846pzg903hxf2zp5gq4grh8jcatcemfrscdfl797zhg5crkcsx43gujzppge3n" | ||
}, | ||
{ | ||
"name": "user1", | ||
"type": "local", | ||
"address": "eth1mhtyk3cj7ly0rt8rc9zuj5pnnmw67gsapygwyq", | ||
"pubkey": "ethpub1pfqnmk6pq3wrkx6lh7uug8ss0thggact3n49m5gkmpca4vylldpur5qrept57e0rrxfmeq5mp5xt3cyf4kys53qcv66qxttv970das69hlpkf8cnyd2a2x" | ||
}, | ||
{ | ||
"name": "user2", | ||
"type": "local", | ||
"address": "eth1pa20g7lehr330vs5ent20slr3wyne4lsy8qae3", | ||
"pubkey": "ethpub1pfqnmk6pq3art9y45zw5ntyktt2qrt0skmsl0ux9qwk8458ed3d8sgnrs99zlgvj3rt2vggvkh0x56hffugwsyddwqla48npx46pglgs6xhcqpall58tgn" | ||
} | ||
] | ||
``` | ||
|
||
And running: | ||
|
||
``` | ||
curl localhost:8545 -H "Content-Type:application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' | ||
``` | ||
|
||
Should output: | ||
|
||
```json | ||
{ | ||
"jsonrpc": "2.0", | ||
"id": 1, | ||
"result": [ | ||
"0x3b7252d007059ffc82d16d022da3cbf9992d2f70", | ||
"0xddd64b4712f7c8f1ace3c145c950339eddaf221d", | ||
"0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0" | ||
] | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#!/bin/bash | ||
|
||
CHAINID=1337 | ||
MONIKER="localtestnet" | ||
|
||
VAL_KEY="localkey" | ||
VAL_MNEMONIC="gesture inject test cycle original hollow east ridge hen combine junk child bacon zero hope comfort vacuum milk pitch cage oppose unhappy lunar seat" | ||
|
||
USER1_KEY="user1" | ||
USER1_MNEMONIC="copper push brief egg scan entry inform record adjust fossil boss egg comic alien upon aspect dry avoid interest fury window hint race symptom" | ||
|
||
USER2_KEY="user2" | ||
USER2_MNEMONIC="maximum display century economy unlock van census kite error heart snow filter midnight usage egg venture cash kick motor survey drastic edge muffin visual" | ||
|
||
# remove existing daemon and client | ||
rm -rf ~/.ethermint* | ||
|
||
ethermintcli config keyring-backend test | ||
|
||
# Set up config for CLI | ||
ethermintcli config chain-id $CHAINID | ||
ethermintcli config output json | ||
ethermintcli config indent true | ||
ethermintcli config trust-node true | ||
|
||
# Import keys from mnemonics | ||
echo $VAL_MNEMONIC | ethermintcli keys add $VAL_KEY --recover | ||
echo $USER1_MNEMONIC | ethermintcli keys add $USER1_KEY --recover | ||
echo $USER2_MNEMONIC | ethermintcli keys add $USER2_KEY --recover | ||
|
||
# Set moniker and chain-id for Ethermint (Moniker can be anything, chain-id must be an integer) | ||
ethermintd init $MONIKER --chain-id $CHAINID | ||
|
||
# Allocate genesis accounts (cosmos formatted addresses) | ||
ethermintd add-genesis-account $(ethermintcli keys show $VAL_KEY -a) 1000000000000000000000aphoton,10000000000000000stake | ||
ethermintd add-genesis-account $(ethermintcli keys show $USER1_KEY -a) 1000000000000000000000aphoton,10000000000000000stake | ||
ethermintd add-genesis-account $(ethermintcli keys show $USER2_KEY -a) 1000000000000000000000aphoton,10000000000000000stake | ||
|
||
# Sign genesis transaction | ||
ethermintd gentx --name $VAL_KEY --keyring-backend test | ||
|
||
# Collect genesis tx | ||
ethermintd collect-gentxs | ||
|
||
# Enable faucet | ||
cat $HOME/.ethermintd/config/genesis.json | jq '.app_state["faucet"]["enable_faucet"]=true' > $HOME/.ethermintd/config/tmp_genesis.json && mv $HOME/.ethermintd/config/tmp_genesis.json $HOME/.ethermintd/config/genesis.json | ||
|
||
echo -e '\n\ntestnet faucet enabled' | ||
echo -e 'to transfer tokens to your account address use:' | ||
echo -e "ethermintcli tx faucet request 100aphoton --from $VAL_KEY\n" | ||
|
||
|
||
# Run this to ensure everything worked and that the genesis file is setup correctly | ||
ethermintd validate-genesis | ||
|
||
# Command to run the rest server in a different terminal/window | ||
echo -e '\nrun the following command in a different terminal/window to run the REST server and JSON-RPC:' | ||
echo -e "ethermintcli rest-server --laddr \"tcp://localhost:8545\" --wsport 8546 --unlock-key $VAL_KEY,$USER1_KEY,$USER2_KEY --chain-id $CHAINID --trace\n" | ||
|
||
# Start the node (remove the --pruning=nothing flag if historical queries are not needed) | ||
ethermintd start --pruning=nothing --rpc.unsafe --log_level "main:info,state:info,mempool:info" --trace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"name": "tests-solidity", | ||
"private": true, | ||
"version": "1.0.0", | ||
"author": "Aragon Association <contact@aragon.org>", | ||
"license": "GPL-3.0-or-later", | ||
"workspaces": { | ||
"packages": [ | ||
"suites/*" | ||
], | ||
"nohoist": [ | ||
"**/@aragon/contract-helpers-test" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
pragma solidity ^0.5.11; | ||
|
||
contract Counter { | ||
uint256 counter = 0; | ||
string internal constant ERROR_TOO_LOW = "COUNTER_TOO_LOW"; | ||
event Changed(uint256 counter); | ||
event Added(uint256 counter); | ||
|
||
function add() public { | ||
counter++; | ||
emit Added(counter); | ||
emit Changed(counter); | ||
} | ||
|
||
function subtract() public { | ||
require(counter > 0, ERROR_TOO_LOW); | ||
counter--; | ||
emit Changed(counter); | ||
} | ||
|
||
function getCounter() public view returns (uint256) { | ||
return counter; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity >=0.4.22 <0.8.0; | ||
|
||
contract Migrations { | ||
address public owner = msg.sender; | ||
uint public last_completed_migration; | ||
|
||
modifier restricted() { | ||
require( | ||
msg.sender == owner, | ||
"This function is restricted to the contract's owner" | ||
); | ||
_; | ||
} | ||
|
||
function setCompleted(uint completed) public restricted { | ||
last_completed_migration = completed; | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
tests-solidity/suites/basic/migrations/1_initial_migration.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
const Migrations = artifacts.require("Migrations"); | ||
|
||
module.exports = function (deployer) { | ||
deployer.deploy(Migrations); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "basic", | ||
"version": "1.0.0", | ||
"author": "Aragon Association <contact@aragon.org>", | ||
"license": "GPL-3.0-or-later", | ||
"scripts": { | ||
"test-ganache": "yarn truffle test", | ||
"test-ethermint": "yarn truffle test --network ethermint" | ||
}, | ||
"devDependencies": { | ||
"truffle": "^5.1.42", | ||
"web3": "^1.2.11" | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
const Counter = artifacts.require("Counter") | ||
|
||
contract('Counter', ([one, two, three]) => { | ||
console.log(one, two, three) | ||
let counter | ||
|
||
beforeEach(async() => { | ||
counter = await Counter.new() | ||
console.log('Counter:', counter.address) | ||
|
||
console.log('Current eth:') | ||
console.log(' - ', await web3.eth.getBalance(one)) | ||
console.log(' - ', await web3.eth.getBalance(two)) | ||
console.log(' - ', await web3.eth.getBalance(three)) | ||
console.log('') | ||
}) | ||
|
||
it('should add', async() => { | ||
const balanceOne = await web3.eth.getBalance(one) | ||
const balanceTwo = await web3.eth.getBalance(two) | ||
const balanceThree = await web3.eth.getBalance(three) | ||
|
||
let count | ||
|
||
await counter.add({ from: one }) | ||
count = await counter.getCounter() | ||
console.log(count.toString()) | ||
assert.equal(count, '1', 'Counter should be 1') | ||
assert.notEqual(balanceOne, await web3.eth.getBalance(one), `${one}'s balance should be different`) | ||
|
||
await counter.add({ from: two }) | ||
count = await counter.getCounter() | ||
console.log(count.toString()) | ||
assert.equal(count, '2', 'Counter should be 2') | ||
assert.notEqual(balanceTwo, await web3.eth.getBalance(two), `${two}'s balance should be different`) | ||
|
||
await counter.add({ from: three }) | ||
count = await counter.getCounter() | ||
console.log(count.toString()) | ||
assert.equal(count, '3', 'Counter should be 3') | ||
assert.notEqual(balanceThree, await web3.eth.getBalance(three), `${three}'s balance should be different`) | ||
}) | ||
|
||
it('should subtract', async() => { | ||
let count | ||
|
||
await counter.add() | ||
count = await counter.getCounter() | ||
console.log(count.toString()) | ||
assert.equal(count, '1', 'Counter should be 1') | ||
|
||
// Use receipt to ensure logs are emitted | ||
const receipt = await counter.subtract() | ||
count = await counter.getCounter() | ||
console.log(count.toString()) | ||
console.log() | ||
console.log('Subtract tx receipt:', receipt) | ||
assert.equal(count, '0', 'Counter should be 0') | ||
assert.equal(receipt.logs[0].event, 'Changed', "Should have emitted 'Changed' event") | ||
assert.equal(receipt.logs[0].args.counter, '0', "Should have emitted 'Changed' event with counter being 0") | ||
|
||
// Check lifecycle of events | ||
const contract = new web3.eth.Contract(counter.abi, counter.address) | ||
const allEvents = await contract.getPastEvents("allEvents", { fromBlock: 0, toBlock: 'latest' }) | ||
const changedEvents = await contract.getPastEvents("Changed", { fromBlock: 0, toBlock: 'latest' }) | ||
console.log('allEvents', allEvents) | ||
console.log('changedEvents', changedEvents) | ||
assert.equal(allEvents.length, 3) | ||
assert.equal(changedEvents.length, 2) | ||
|
||
try { | ||
await counter.subtract() | ||
assert.fail('Subtracting past 0 should have reverted') | ||
} catch (err) { | ||
console.log() | ||
console.log('Passed -- was expecting error') | ||
console.log('Error:', err) | ||
} | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module.exports = { | ||
networks: { | ||
// Development network is just left as truffle's default settings | ||
ethermint: { | ||
host: "127.0.0.1", // Localhost (default: none) | ||
port: 8545, // Standard Ethereum port (default: none) | ||
network_id: "*", // Any network (default: none) | ||
gas: 5000000, // Gas sent with each transaction | ||
gasPrice: 1000000000, // 1 gwei (in wei) | ||
}, | ||
}, | ||
compilers: { | ||
solc: { | ||
version: "0.5.17", | ||
}, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Buidler | ||
artifacts | ||
cache |
28 changes: 28 additions & 0 deletions
28
tests-solidity/suites/initializable-buidler/buidler.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
const { usePlugin } = require('@nomiclabs/buidler/config') | ||
|
||
usePlugin("@nomiclabs/buidler-ganache") | ||
usePlugin('@nomiclabs/buidler-truffle5') | ||
|
||
module.exports = { | ||
networks: { | ||
// Development network is just left as truffle's default settings | ||
ganache: { | ||
url: 'http://localhost:8545', | ||
gasLimit: 5000000, | ||
gasPrice: 1000000000, // 1 gwei (in wei) | ||
defaultBalanceEther: 100 | ||
}, | ||
ethermint: { | ||
url: 'http://localhost:8545', | ||
gasLimit: 5000000, // Gas sent with each transaction | ||
gasPrice: 1000000000, // 1 gwei (in wei) | ||
}, | ||
}, | ||
solc: { | ||
version: '0.4.24', | ||
optimizer: { | ||
enabled: true, | ||
runs: 10000, | ||
}, | ||
}, | ||
} |
Oops, something went wrong.