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

Unit Tests - NomadBase, Replica, CI #247

Merged
merged 87 commits into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from 80 commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
95c2af5
forge install: forge-std
odyslam Apr 14, 2022
fc20dd5
chore: add manual remappings as /lib confuses foundry
odyslam Apr 14, 2022
460a38f
forge install: ds-test
odyslam Apr 14, 2022
328e373
chore: setup test skeleton
odyslam Apr 14, 2022
8f50270
chore: remove old tests, fix compiler issues
odyslam Apr 15, 2022
209c8a5
fix: signUpdater test pass
odyslam Apr 15, 2022
1e68bcf
chore: update forge-std, use Test import
odyslam Apr 20, 2022
7fe3230
feat: rejectNon, failDoubleUpdate
odyslam Apr 26, 2022
3782e4d
feat: test_notFailOnInvalidDoubleUpdateProof()
odyslam Apr 26, 2022
83a38a5
chore: remove ds-test, update forge-std
odyslam Apr 26, 2022
c10bac0
chore: add makefile
odyslam Apr 28, 2022
5adb402
last unit tests
odyslam Apr 28, 2022
ae7f5b6
add export statement to .env
odyslam Apr 28, 2022
e69c0db
chore: add space cause vim went crazy
odyslam Apr 28, 2022
598809c
feat: updaterManager fixture
odyslam Apr 28, 2022
29853fb
feat: homeDomain, onlyUpdaterManagersetUpdater
odyslam Apr 28, 2022
1378dc4
feat: replica::update unit tests, refactor base for remote/home
odyslam May 5, 2022
a7b9b76
chore: WIP merkleTeest
odyslam May 9, 2022
d5f4a90
chore: add replicaHarness
odyslam May 9, 2022
ad70eaa
feat: (WIP) testProveMessageInclusion
odyslam May 9, 2022
0f86645
chore: add comment/link to merkle fixture
odyslam May 9, 2022
709f507
chore: update libs
odyslam May 9, 2022
a37edad
feat: testProveMessageInclusion
odyslam May 9, 2022
0a915b3
feat: add tests for prove; process
odyslam May 10, 2022
dfdf18f
fix: testAcceptProve, check for event
odyslam May 10, 2022
035ce0f
feat: test onlyOwner setters
odyslam May 11, 2022
0a58b35
fix: test for event emission on setters
odyslam May 11, 2022
e0ad6d5
feat: test_rejectProcessUnderGas()
odyslam May 11, 2022
c1e04c3
feat: add tests for bad handlers
odyslam May 12, 2022
4302072
feat: gas snapshot
odyslam May 12, 2022
b1c856d
chore: gas snapshot
odyslam May 12, 2022
b546d6a
fix: remove top level gas snapshot
odyslam May 12, 2022
53113f1
feat: add forge test/snapshot to ci
odyslam May 12, 2022
6c2ff9d
chore: remove moot script
odyslam May 12, 2022
e26cc45
chore: update libs
odyslam May 18, 2022
63aa239
fix: James comments
odyslam May 18, 2022
57ec5f8
chore: fix compiler warnings
odyslam May 19, 2022
017a067
feat: build and use accumulator-cli in solidity via ffi
odyslam May 19, 2022
c66f51c
feat: proveAndProcess test
odyslam May 19, 2022
1f156e5
chore: remove debugging prints
odyslam May 19, 2022
b59ec00
fix: remove accumulator-cli binary, add to gitignore
odyslam May 19, 2022
3a68a5e
chore: add ffi to core profile
odyslam May 19, 2022
fea1f27
fix: build-acli remove old source dir if exists
odyslam May 19, 2022
b2a43c6
fix: almost working ignore test files in hh build
odyslam May 23, 2022
2c3794f
fix: hh compilation, thx james
odyslam May 23, 2022
13c638f
chore: remove unecessery diff cache
odyslam May 23, 2022
37e9f90
feat: slither script, GHA
odyslam May 23, 2022
be17365
fix: remove syntax mystake, add build:accumulator to GHA
odyslam May 23, 2022
09a4584
fix: syntax
odyslam May 23, 2022
450c247
chore: move acli to top-level scripts dir
odyslam May 24, 2022
81198c5
fix: build-acimulator script path
odyslam May 24, 2022
6b477ba
fix: gen-proof path
odyslam May 24, 2022
22fe583
fix: set home to updateManager
odyslam May 24, 2022
6821d1e
fix: forge install/udpate
odyslam May 24, 2022
b75d25e
fix: ignore accumulator binary
odyslam May 24, 2022
4cd817a
fix: yarn bootstrap, contracts build & forge dependencies
odyslam May 24, 2022
97019a7
fix: remove --check from snapshot; update .gas-snapshot
odyslam May 24, 2022
c064cd1
fix: skip acli build if already built
odyslam May 24, 2022
7227b4d
fix: newline
odyslam May 24, 2022
50a71f7
fix: james comments
odyslam May 24, 2022
7408c23
chore: update gas snapshot
odyslam May 24, 2022
baf3a97
fix: remove commented-out test
odyslam May 24, 2022
d4006b9
feat: test successUpdate
odyslam May 27, 2022
60018b2
chore: merge main
odyslam May 27, 2022
c1d8393
Merge pull request #1 from odyslam/main
odyslam May 27, 2022
8728478
fix: repair tests after merge and change on process()
odyslam May 28, 2022
677d2ea
fix: test dispatchAndUpdate
odyslam May 29, 2022
1d06ac7
fix: remove debug logs
odyslam May 29, 2022
20d4ec5
feat: updateProveAndProcess test on replica
odyslam May 29, 2022
524df45
fix: remove forge-verify from hardhat
odyslam May 29, 2022
bb884ea
fix: remove double entries in package.json
odyslam May 29, 2022
a52bb25
chore: update gas snapshot
odyslam May 29, 2022
2e98421
feat: update readme
odyslam May 29, 2022
8fd4792
fix: James comments
odyslam May 31, 2022
a0cae3c
chore: remove forge update, install; address james' comments
odyslam Jun 1, 2022
0a623fa
chore: add lib/ to gitignore
odyslam Jun 1, 2022
8144b58
chore: address james comments;lock forge-std commit
odyslam Jun 2, 2022
702a6d4
chore: address james comments
odyslam Jun 2, 2022
c771b0c
forge install: forge-std
odyslam Jun 2, 2022
b7866e1
fix: gha yaml syntax
odyslam Jun 2, 2022
4bcca34
fix: address Anna's comments
odyslam Jun 2, 2022
91e8ea4
fix: improve setUpdater based on Anna's cmments
odyslam Jun 2, 2022
8e5c1f6
chore: yarn prettier
odyslam Jun 2, 2022
8b9b317
fix: address Anna's comments (for real this time)
odyslam Jun 2, 2022
523e566
fix: improve gas-snapshot user story, add to CI
odyslam Jun 2, 2022
12a452d
chore: update .gas-snapshot
odyslam Jun 2, 2022
354f7cf
fix: add memview link
odyslam Jun 2, 2022
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
10 changes: 9 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@ jobs:
uses: onbjerg/foundry-toolchain@v1
with:
version: nightly

- run: |
yarn install
- run: |
yarn lint
- run: |
yarn build:accumulator-cli
- run: |
yarn build
- run: |
yarn test

- name: "Static Analysis: Core"
uses: crytic/[email protected]
id: slither
continue-on-error: true
with:
target: "packages/contracts-core"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ yarn-error.log
**/tsconfig.tsbuildinfo
dist/
cache/
scripts/accumulator-cli

.pnp.*
.yarn/*
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib/forge-std"]
odyslam marked this conversation as resolved.
Show resolved Hide resolved
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
27 changes: 23 additions & 4 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
[default]
solc_version = '0.7.6'
optimizer_runs = 999999
bytecodeHash = 'none'
solc_version = '0.7.6' # Version of solc that we use
remappings = [ # Libraries that we use from node_modules and are used by the smart contracts
"@openzeppelin/=node_modules/@openzeppelin/",
"@summa-tx/=node_modules/@summa-tx/",
"@nomad-xyz/=packages/"
]
offline = true # Disable downloading of missing solc version(s)
optimizer = true # Enable or disable the solc optimizer
optimizer_runs = 999999 # The number of optimizer runs
verbosity = 3 # The verbosity of tests
bytecode_hash = "none" # For deterministic code
block_timestamp = 1622400000 # Timestamp for tests (non-zero)

[core]
src = 'packages/contracts-core/contracts'
test = 'packages/contracts-core/contracts/foundry-tests'
out = 'packages/contracts-core/foundry_artifacts'
ffi = true

[core-ci]
src = 'packages/contracts-core/contracts'
test = 'packages/contracts-core/contracts/foundry-tests'
out = 'packages/contracts-core/foundry_artifacts'
fuzz-runs = 10_000

[router]
src = 'packages/contracts-router/contracts'
out = 'packages/contracts-router/foundry_artifacts'

[bridge]
src = 'packages/contracts-bridge/contracts'
out = 'packages/contracts-bridge/foundry_artifacts'
out = 'packages/contracts-bridge/foundry_artifacts'


1 change: 1 addition & 0 deletions lib/forge-std
Submodule forge-std added at 564510
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
"packages/indexer"
],
"scripts": {
"bootstrap": "yarn workspaces foreach -Apv --exclude @nomad-xyz/local-environment --exclude @nomad-xyz/monitor run bootstrap",
"build": "yarn workspaces foreach -Atv --exclude @nomad-xyz/local-environment --exclude @nomad-xyz/monitor run build",
"compile": "yarn workspaces foreach -Apv --exclude @nomad-xyz/local-environment --exclude @nomad-xyz/monitor run compile",
"compile": "yarn workspaces foreach -Apv --exclude @nomad-xyz/deploy --exclude @nomad-xyz/local-environment --exclude @nomad-xyz/monitor run compile",
"bootstrap": "yarn build:accumulator-cli && yarn workspaces foreach -Atv --exclude @nomad-xyz/deploy --exclude @nomad-xyz/local-environment --exclude @nomad-xyz/monitor run bootstrap",
"build": "yarn build:accumulator-cli && yarn workspaces foreach -Atv --exclude @nomad-xyz/deploy --exclude @nomad-xyz/local-environment --exclude @nomad-xyz/monitor run build",
"build:accumulator-cli": "cd scripts && ./build-acli.sh",
"contracts-bridge": "yarn workspace @nomad-xyz/contracts-bridge",
"contracts-core": "yarn workspace @nomad-xyz/contracts-core",
"contracts-router": "yarn workspace @nomad-xyz/contracts-router",
Expand All @@ -31,7 +32,8 @@
"sdk": "yarn workspace @nomad-xyz/sdk",
"sdk-bridge": "yarn workspace @nomad-xyz/sdk-bridge",
"sdk-govern": "yarn workspace @nomad-xyz/sdk-govern",
"test": "yarn workspaces foreach -Apv --exclude @nomad-xyz/local-environment run test"
"test": "yarn workspaces foreach -Apv --exclude @nomad-xyz/deploy --exclude @nomad-xyz/local-environment run test",
"gen-proof": "scripts/accumulator-cli"
},
"packageManager": "[email protected]"
}
3 changes: 2 additions & 1 deletion packages/contracts-core/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
ETHERSCAN_API_KEY=
INFURA_API_KEY=
FOUNDRY_PROFILE=core

34 changes: 34 additions & 0 deletions packages/contracts-core/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
HomeTest:test_committedRoot() (gas: 7928)
HomeTest:test_dispatchRejectBigMessage() (gas: 29181)
HomeTest:test_homeDomain() (gas: 8010)
anna-carroll marked this conversation as resolved.
Show resolved Hide resolved
HomeTest:test_improperUpdate() (gas: 46103)
HomeTest:test_nonUpdaterManagerCannotSetUpdater() (gas: 11839)
HomeTest:test_onlyUpdaterManagerSetUpdater() (gas: 19666)
HomeTest:test_succesfulDispatch() (gas: 216412)
HomeTest:test_successfulDispatchAndUpdate() (gas: 228379)
NomadBaseTest:test_acceptUpdaterSignature() (gas: 27469)
NomadBaseTest:test_failInitializeTwice() (gas: 13452)
NomadBaseTest:test_homeDomainHash() (gas: 10078)
NomadBaseTest:test_ownerIsContractCreator() (gas: 7631)
NomadBaseTest:test_rejectNonUpdaterSignature() (gas: 27434)
NomadBaseTest:test_stateIsActiveAfterInit() (gas: 7679)
ReplicaTest:test_acceptLeafCorrectProof() (gas: 141632)
ReplicaTest:test_acceptReplicaUpdate() (gas: 66587)
ReplicaTest:test_acceptableRoot() (gas: 10030)
ReplicaTest:test_notProcessLegacyProvenMessageEmptyAddress() (gas: 46689)
ReplicaTest:test_notProcessLegacyProvenMessageRevertingHandlers1() (gas: 49050)
ReplicaTest:test_notProcessLegacyProvenMessageRevertingHandlers2() (gas: 49200)
ReplicaTest:test_notProcessLegacyProvenMessageRevertingHandlers3() (gas: 49110)
ReplicaTest:test_notProcessLegacyProvenMessageRevertingHandlers4() (gas: 49072)
ReplicaTest:test_notProcessLegacyWrongDestination() (gas: 175511)
ReplicaTest:test_notProcessUnprovenMessage() (gas: 155331)
ReplicaTest:test_processLegacyProvenMessageReturnZeroHandler() (gas: 55611)
ReplicaTest:test_processProvenMessage() (gas: 127896)
ReplicaTest:test_proveAndProcess() (gas: 130253)
ReplicaTest:test_rejectLeafWrongProof() (gas: 126638)
ReplicaTest:test_rejectReplicaNonCurrentUpdate() (gas: 17030)
ReplicaTest:test_rejectReplicaUpdateInvalidSig() (gas: 27635)
ReplicaTest:test_setConfirmationOnlyOwner() (gas: 39771)
ReplicaTest:test_setOptimisticTimeoutOnlyOwner() (gas: 18585)
ReplicaTest:test_setUpdaterOnlyOwner() (gas: 19624)
ReplicaTest:test_updateProveAndProcessMessage() (gas: 150113)
6 changes: 4 additions & 2 deletions packages/contracts-core/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules/
/node_modules
!/node_modules/
cache/
artifacts/
coverage/
Expand All @@ -7,4 +8,5 @@ coverage.json
src.ts/
src/
dist/
foundry_artifacts/
foundry_artifacts/
scripts/accumulator-cli
26 changes: 22 additions & 4 deletions packages/contracts-core/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
## Nomad Core
## Nomad Core 𓀃
prestwich marked this conversation as resolved.
Show resolved Hide resolved

Solidity implementations of the core Nomad protocol.

### Setup

- See repo setup
- `brew install jq`   OR   `sudo apt-get install jq`
- `yarn bootstrap`: `yarn clean` and `yarn build`

### Build

- `yarn build`
- `yarn build`: compile smart contracts and create definitions for the SDK

### Test

For testing, we use [Foundry](https://getfoundry.sh/).

- Run `yarn build:accumulator-cli` from the root directory of the monorepo. It will build a rust-based cli tool that creates Sparse Merkle Tree proofs for arbitrary data. It's used in our testing suite via the `--ffi` flag for Forge. The binary is built in thre `/scripts` top-level directory of the monorepo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: thre

- `yarn test` will run all tests. Note that `--ffi` is enabled by default,
odyslam marked this conversation as resolved.
Show resolved Hide resolved
- `yarn snapshot --check` will run the test suite and verify that it doesn't produce a different gas snapshot from the existing (`.gas-snapshot`)
- `yarn snapshot` will create a new `.gas-snapshot`. You can inspect the different gas usage via `git diff`
- `yarn gen-proof` will execute the `accumulator-cli` binary

### Static Analysis

The monorepo is configured to run [slither](https://github.com/crytic/slither) with every PR. We suggest all contributors to use slither while developing, to avoid common mistakes.

- Install Slither
- Run `yarn test:static-analyze`

We use a `yarn command` because we need to link the top-level `node_modules` directory in the `core-contracts` package. It's a known [issue](https://github.com/crytic/slither/issues/852) for which the workaround is to link the directory.
124 changes: 124 additions & 0 deletions packages/contracts-core/contracts/test/Home.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.6.11;
odyslam marked this conversation as resolved.
Show resolved Hide resolved

import {Home} from "../Home.sol";
import {NomadTestWithUpdaterManager} from "./utils/NomadTest.sol";
import {IUpdaterManager} from "../interfaces/IUpdaterManager.sol";
import {Message} from "../libs/Message.sol";


contract HomeTest is NomadTestWithUpdaterManager {
Home home;

function setUp() public override {
super.setUp();
home = new Home(homeDomain);
home.initialize(IUpdaterManager(address(updaterManager)));
updaterManager.setHome(address(home));
vm.prank(address(updaterManager));

}

function test_homeDomain() public {
assertEq(
keccak256(abi.encodePacked(homeDomain, "NOMAD")),
home.homeDomainHash()
);
}

function test_onlyUpdaterManagerSetUpdater() public {
vm.prank(address(updaterManager));
home.setUpdater(vm.addr(420));
odyslam marked this conversation as resolved.
Show resolved Hide resolved
}

function test_nonUpdaterManagerCannotSetUpdater() public {
vm.prank(vm.addr(40123));
vm.expectRevert("!updaterManager");
home.setUpdater(vm.addr(420));
}

function test_committedRoot() public{
bytes32 emptyRoot;
assertEq(abi.encode(home.committedRoot()), abi.encode(emptyRoot));
odyslam marked this conversation as resolved.
Show resolved Hide resolved
}

event Dispatch(
bytes32 indexed messageHash,
uint256 indexed leafIndex,
uint64 indexed destinationAndNonce,
bytes32 committedRoot,
bytes message
);

function test_succesfulDispatch() public {
bytes32 recipient = bytes32(uint256(uint160(vm.addr(1505))));
odyslam marked this conversation as resolved.
Show resolved Hide resolved
address sender = vm.addr(1555);
bytes memory messageBody = bytes("hey buddy");
uint32 nonce = home.nonces(remoteDomain);
bytes memory message = Message.formatMessage(
homeDomain,
bytes32(uint256(uint160(sender))),
nonce,
remoteDomain,
recipient,
messageBody
);
bytes32 messageHash = keccak256(message);
vm.expectEmit(true, true, true, true);
emit Dispatch(messageHash, 0,(uint64(remoteDomain) << 32) | nonce, home.committedRoot(), message);
vm.prank(sender);
home.dispatch(remoteDomain, recipient, messageBody);
assert(home.queueContains(home.root()));
}

function test_dispatchRejectBigMessage() public {
bytes32 recipient = bytes32(uint256(uint160(vm.addr(1505))));
address sender = vm.addr(1555);
bytes memory messageBody = new bytes(2 * 2**10 + 1);
uint32 nonce = home.nonces(remoteDomain);
bytes memory message = Message.formatMessage(
homeDomain,
bytes32(uint256(uint160(sender))),
nonce,
remoteDomain,
recipient,
messageBody
);
vm.prank(sender);
vm.expectRevert("msg too long");
home.dispatch(remoteDomain, recipient, messageBody);
}

event ImproperUpdate(bytes32 oldRoot, bytes32 newRoot, bytes signature);

function test_improperUpdate() public {
bytes32 newRoot = "new root";
bytes32 oldRoot = home.committedRoot();
bytes memory sig = signHomeUpdate(updaterPK, oldRoot, newRoot);
vm.expectEmit(false, false, false, true);
emit ImproperUpdate(oldRoot, newRoot, sig);
home.improperUpdate(oldRoot, newRoot, sig);
}

event Update(
uint32 indexed homeDomain,
bytes32 indexed oldRoot,
bytes32 indexed newRoot,
bytes signature
);

function test_successfulDispatchAndUpdate() public {
bytes memory messageBody = '';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmmm not sure we should test with empty messages. matter of fact, not sure we should allow sending empty messages

uint32 destinationDomain = remoteDomain;
bytes32 recipient = bytes32(uint256(uint160(vm.addr(1505))));
home.dispatch(destinationDomain, recipient, messageBody);
bytes32 newRoot = home.root();
bytes32 oldRoot = home.committedRoot();
bytes memory sig = signHomeUpdate(updaterPK, oldRoot, newRoot);
vm.expectEmit(true, true, true, true);
emit Update(homeDomain, oldRoot, newRoot, sig);
home.update(oldRoot, newRoot, sig);
assertEq(newRoot, home.committedRoot());
}

}
20 changes: 0 additions & 20 deletions packages/contracts-core/contracts/test/MysteryMath.sol

This file was deleted.

22 changes: 0 additions & 22 deletions packages/contracts-core/contracts/test/MysteryMathV1.sol

This file was deleted.

21 changes: 0 additions & 21 deletions packages/contracts-core/contracts/test/MysteryMathV2.sol

This file was deleted.

Loading