diff --git a/.circleci/config.yml b/.circleci/config.yml index 9b3ccdba8f..265d17bbed 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -204,7 +204,7 @@ jobs: sed -i "s/000000000000000000000000000000deadbeef18/$(parity account new --chain ./parity-genesis.json --keys-path ./keys --password ./parityPassword)/g" ./parity-genesis.json - run: name: "Running gas cost tests" - command: pnpm run test:contracts:gasCosts && npx codechecks + command: pnpm run test:contracts:gas && npx codechecks - run: name: "Running ganache upgrade tests" command: pnpm run test:contracts:upgrade:ganache @@ -241,7 +241,7 @@ jobs: root: ./ paths: - coverage-contracts - coverage-test-upgrade: + coverage-test/upgrade: <<: *job_common steps: - checkout @@ -506,7 +506,7 @@ workflows: context: dockerhub-credentials - coverage-test-chainid: context: dockerhub-credentials - - coverage-test-upgrade: + - coverage-test/upgrade: context: dockerhub-credentials - coverage-test-bridging: context: dockerhub-credentials @@ -517,5 +517,5 @@ workflows: - coverage-test-extensions - coverage-test-reputation - coverage-test-chainid - - coverage-test-upgrade + - coverage-test/upgrade - coverage-test-bridging diff --git a/package.json b/package.json index 3cd0f8818f..7e1aa34b98 100644 --- a/package.json +++ b/package.json @@ -40,20 +40,20 @@ "pretest:contracts:extensions": "pnpm run stop:blockchain:client", "test:contracts": "pnpm run start:blockchain:client && npx hardhat test ./test/contracts-network/* ./test/packages/* --network development", "test:contracts:extensions": "pnpm run start:blockchain:client && npx hardhat test ./test/extensions/* --network development", - "test:contracts:upgrade:parity": "pnpm run clean:test:contracts | pnpm run start:blockchain:client parity & pnpm run generate:test:contracts && npx hardhat test ./test-upgrade/* --network integration", - "test:contracts:upgrade:ganache": "pnpm run clean:test:contracts | pnpm run start:blockchain:client ganache & pnpm run generate:test:contracts && npx hardhat test ./test-upgrade/* --network development", - "test:contracts:gasCosts": "pnpm run start:blockchain:client && npx hardhat test test-gas-costs/gasCosts.js --network development", + "test:contracts:upgrade:parity": "pnpm run clean:test:contracts | pnpm run start:blockchain:client parity & pnpm run generate:test:contracts && npx hardhat test ./test/upgrade/* --network integration", + "test:contracts:upgrade:ganache": "pnpm run clean:test:contracts | pnpm run start:blockchain:client ganache & pnpm run generate:test:contracts && npx hardhat test ./test/upgrade/* --network development", + "test:contracts:gas": "pnpm run start:blockchain:client && npx hardhat test test/misc/gas-costs.js --network development", "test:contracts:patricia": "pnpm run start:blockchain:client ganache && npx hardhat test packages/reputation-miner/patricia-test.js --network integration", "test:contracts:bridging:1": "CHAIN_ID_1=265669100 CHAIN_ID_2=265669101 pnpm run start:blockchain:client:both && HARDHAT_FOREIGN=false MINING_CHAIN_ID=265669100 npx hardhat test ./test/cross-chain/* --network development", "test:contracts:bridging:2": "CHAIN_ID_1=265669101 CHAIN_ID_2=265669100 pnpm run start:blockchain:client:both && HARDHAT_FOREIGN=true MINING_CHAIN_ID=265669100 CHAIN_ID=265669101 npx hardhat test ./test/cross-chain/* --network development", - "test:contracts:chainid": "pnpm run start:blockchain:client && npx hardhat test ./test-chainid/*", - "test:contracts:e2e": "pnpm run start:blockchain:client && npx hardhat test test-system/end-to-end.js --network development", + "test:contracts:chainid": "pnpm run start:blockchain:client && npx hardhat test ./test/misc/chainid.js", + "test:contracts:e2e": "pnpm run start:blockchain:client && npx hardhat test test/misc/end-to-end.js --network development", "test:contracts:coverage": "npx hardhat coverage --temp build-coverage --testfiles './test/contracts-network/*'", "test:contracts:extensions:coverage": "npx hardhat compile && NODE_OPTIONS='--max-old-space-size=6144' npx hardhat coverage --solcoverjs ./.solcover.extensions.js --temp build-coverage --testfiles './test/extensions/*'", "test:contracts:bridging:1:coverage": "CHAIN_ID=265669101 pnpm run start:blockchain:client:2 && HARDHAT_FOREIGN=false MINING_CHAIN_ID=265669100 npx hardhat --show-stack-traces coverage --solcoverjs ./.solcover.crosschain.js --temp build-coverage --testfiles './test/cross-chain/**/*'", "test:contracts:bridging:2:coverage": "CHAIN_ID=265669100 pnpm run start:blockchain:client:2 && HARDHAT_FOREIGN=true MINING_CHAIN_ID=265669100 CHAIN_ID=265669101 npx hardhat coverage --solcoverjs ./.solcover.crosschain.js --temp build-coverage --testfiles './test/cross-chain/**/*'", - "test:contracts:chainid:coverage": "npx hardhat coverage --solcoverjs ./.solcover.chainid.js --temp build-coverage --testfiles './test-chainid/**/*'", - "test:contracts:upgrade:coverage": "pnpm run generate:test:contracts && npx hardhat coverage --solcoverjs ./.solcover.upgrade.js --temp build-coverage --testfiles './test-upgrade/*'", + "test:contracts:chainid:coverage": "npx hardhat coverage --solcoverjs ./.solcover.chainid.js --temp build-coverage --testfiles './test/misc/chainid.js'", + "test:contracts:upgrade:coverage": "pnpm run generate:test:contracts && npx hardhat coverage --solcoverjs ./.solcover.upgrade.js --temp build-coverage --testfiles './test/upgrade/*'", "test:reputation:1": "pnpm run start:blockchain:client && npx hardhat test ./test/reputation-system/*.js --network development", "test:reputation:2": "pnpm run start:blockchain:client && npx hardhat test ./test/reputation-system/reputation-mining-client/* --network development", "test:reputation:1:anotherChain": "CHAIN_ID=101010101 pnpm run start:blockchain:client && MINING_CHAIN_ID=101010101 CHAIN_ID=101010101 npx hardhat test ./test/reputation-system/*.js --network development", @@ -64,7 +64,7 @@ "posttest:contracts:extensions": "pnpm run stop:blockchain:client", "posttest:contracts:upgrade:parity": "pnpm run clean:test:contracts | pnpm run stop:blockchain:client", "posttest:contracts:upgrade:ganache": "pnpm run clean:test:contracts | pnpm run stop:blockchain:client", - "posttest:contracts:gasCosts": "pnpm run stop:blockchain:client", + "posttest:contracts:gas": "pnpm run stop:blockchain:client", "posttest:contracts:patricia": "pnpm run stop:blockchain:client", "viz:bootstrap": "pnpm run start:blockchain:client && HARDHAT_NETWORK=development npx hardhat run scripts/viz-bootstrap.js", "kyc:bootstrap": "pnpm run start:blockchain:client && HARDHAT_NETWORK=development npx hardhat run scripts/kyc-bootstrap.js" diff --git a/test-smoke/colony-storage-consistent.js b/test-smoke/colony-storage-consistent.js deleted file mode 100644 index fa772c00a2..0000000000 --- a/test-smoke/colony-storage-consistent.js +++ /dev/null @@ -1,167 +0,0 @@ -/* global artifacts */ -const chai = require("chai"); -const bnChai = require("bn-chai"); -const BN = require("bn.js"); - -const { UINT256_MAX, WAD } = require("../helpers/constants"); -const { fundColonyWithTokens, setupColony } = require("../helpers/test-data-generator"); - -const { expect } = chai; -chai.use(bnChai(web3.utils.BN)); - -const EtherRouter = artifacts.require("EtherRouter"); -const IColonyNetwork = artifacts.require("IColonyNetwork"); -const IMetaColony = artifacts.require("IMetaColony"); -const Token = artifacts.require("Token"); -const ContractEditing = artifacts.require("ContractEditing"); -const Resolver = artifacts.require("Resolver"); - -const TokenAuthority = artifacts.require("contracts/common/TokenAuthority.sol:TokenAuthority"); - -contract("Contract Storage", (accounts) => { - const SLOT0 = 0; - - const RECIPIENT = accounts[3]; - const ADMIN = accounts[4]; - const ARBITRATOR = accounts[5]; - - let colony; - let token; - let localSkillId; - let otherToken; - let colonyNetwork; - let metaColony; - let domain1; - let tokenLockingAddress; - - before(async () => { - // We use our own providers for these test(s) so we can really get in to it... - - const cnAddress = (await EtherRouter.deployed()).address; - const etherRouter = await EtherRouter.at(cnAddress); - colonyNetwork = await IColonyNetwork.at(etherRouter.address); - const metaColonyAddress = await colonyNetwork.getMetaColony(); - metaColony = await IMetaColony.at(metaColonyAddress); - - token = await Token.new("name", "symbol", 18); - await token.unlock(); - - colony = await setupColony(colonyNetwork, token.address); - - await colony.addLocalSkill(); - localSkillId = await colonyNetwork.getSkillCount(); - - tokenLockingAddress = await colonyNetwork.getTokenLocking(); - const tokenAuthority = await TokenAuthority.new(token.address, colony.address, [tokenLockingAddress]); - await token.setAuthority(tokenAuthority.address); - - await colony.setRewardInverse(100); - await colony.setAdministrationRole(1, UINT256_MAX, ADMIN, 1, true); - await colony.setArbitrationRole(1, UINT256_MAX, ARBITRATOR, 1, true); - await fundColonyWithTokens(colony, token, UINT256_MAX); - domain1 = await colony.getDomain(1); - - otherToken = await Token.new("otherName", "otherSymbol", 18); - await otherToken.unlock(); - await fundColonyWithTokens(colony, otherToken, UINT256_MAX); - }); - - function getAddressStateHash(address) { - return new Promise((resolve, reject) => { - web3.currentProvider - .request({ method: "eth_getProof", params: [address, [], "latest"] }) - .then((result) => { - return resolve(result.storageHash); - }) - .catch((e) => { - reject(e); - }); - }); - } - - describe("Smoke tests to check our storage layout does not change", () => { - // There are many things you could do that one would expect to change these hashes. If you've made changes that change the contents of storage of a - // contract, then these hashes will change. This could include adding an extra transaction somewhere, which could cause the address a contract is - // deployed to change, which if it is stored somewhere would cause the state hash of the storage to change. - - // If you haven't touched the contracts, however, and this test fails, then something is afoot. - // In theory, the storage slots used by solidity could change in an upgrade, - // which this test was written with in mind to try and detect. They don't guarantee this hasn't happened if they pass, but if they fail without just - // cause then we need to think very carefully about what's going on. - - it("storage contents should be as expected", async () => { - await colony.makeExpenditure(1, UINT256_MAX, 1, { from: ADMIN }); - const expenditureId = await colony.getExpenditureCount(); - - await colony.setExpenditureRecipient(expenditureId, SLOT0, RECIPIENT, { from: ADMIN }); - await colony.setExpenditurePayout(expenditureId, SLOT0, token.address, WAD, { from: ADMIN }); - await colony.setExpenditureSkills(expenditureId, [SLOT0], [localSkillId], { from: ADMIN }); - - const expenditure = await colony.getExpenditure(expenditureId); - await colony.moveFundsBetweenPots(1, UINT256_MAX, UINT256_MAX, domain1.fundingPotId, expenditure.fundingPotId, WAD, token.address); - await colony.finalizeExpenditure(expenditureId, { from: ADMIN }); - await colony.claimExpenditurePayout(expenditureId, SLOT0, token.address); - - const miningCycleAddress = await colonyNetwork.getReputationMiningCycle(false); - const miningCycleStateHash = await getAddressStateHash(miningCycleAddress); - - // For this test to be reproducible, have to zero timestamps / time depenedent things - // For colonyNetwork, that means the mining staking timestamp - - const contractEditing = await ContractEditing.new(); - const networkAsER = await EtherRouter.at(colonyNetwork.address); - const colonyNetworkResolverAddress = await networkAsER.resolver(); - const colonyNetworkResolver = await Resolver.at(colonyNetworkResolverAddress); - await colonyNetworkResolver.register("setStorageSlot(uint256,bytes32)", contractEditing.address); - const editableNetwork = await ContractEditing.at(colonyNetwork.address); - - // Following - // https://solidity.readthedocs.io/en/v0.6.8/internals/layout_in_storage.html#mappings-and-dynamic-arrays - // This is the hash of the key (the address) and the storage slot containing the mapping (33) - let hashable = `0x000000000000000000000000${accounts[5].slice(2)}${new BN(33).toString(16, 64)}`; - let hashed = web3.utils.soliditySha3(hashable); - let slot = new BN(hashed.slice(2), 16); - // To get the slot containing the timestamp of the miner submission, we add one to where the struct starts - // (see ColonyNetworkDataTypes) - slot = slot.addn(1); - - await editableNetwork.setStorageSlot(slot, "0x0000000000000000000000000000000000000000000000000000000000000000"); - - // Also zero out the slot containing the current colony version - await editableNetwork.setStorageSlot(7, "0x0000000000000000000000000000000000000000000000000000000000000000"); - - const colonyNetworkStateHash = await getAddressStateHash(colonyNetwork.address); - - // We did a whole expenditure above, so let's take out the finalized timestamp - // This is the hash of the expenditure id (1) with the storage slot (25) to find the location of the struct - hashable = `0x${new BN(1).toString(16, 64)}${new BN(25).toString(16, 64)}`; - hashed = web3.utils.soliditySha3(hashable); - slot = new BN(hashed.slice(2), 16); - // To find the slot storing the timestamp, we add three to where the struct starts (see ColonyDataTypes). - slot = slot.addn(3); - - const colonyAsER = await EtherRouter.at(colony.address); - const colonyResolverAddress = await colonyAsER.resolver(); - const colonyResolver = await Resolver.at(colonyResolverAddress); - await colonyResolver.register("setStorageSlot(uint256,bytes32)", contractEditing.address); - const editableColony = await ContractEditing.at(colony.address); - await editableColony.setStorageSlot(slot, "0x0000000000000000000000000000000000000000000000000000000000000000"); - - const colonyStateHash = await getAddressStateHash(colony.address); - const metaColonyStateHash = await getAddressStateHash(metaColony.address); - const tokenLockingStateHash = await getAddressStateHash(tokenLockingAddress); - - console.log("colonyNetworkStateHash:", colonyNetworkStateHash); - console.log("colonyStateHash:", colonyStateHash); - console.log("metaColonyStateHash:", metaColonyStateHash); - console.log("miningCycleStateHash:", miningCycleStateHash); - console.log("tokenLockingStateHash:", tokenLockingStateHash); - - expect(colonyNetworkStateHash).to.equal("0x66b279547b6eab5c688ac6b6a6bd7dedc0849a9e9d2218e5a1dcf0eeac8847f8"); - expect(colonyStateHash).to.equal("0x156061470e5ed4c0f091adb726dbb819692d23bc8338bd06a660a9a4cc48eea6"); - expect(metaColonyStateHash).to.equal("0x4c2b0dba6abe7feee2c052e3a5f07ccb71adb5d0bd5c32d21b16559b313ecf82"); - expect(miningCycleStateHash).to.equal("0x179caec9074f4db8b06afcb6dad20c8091b31d7b483bd1c6cb469d79d1bc3649"); - expect(tokenLockingStateHash).to.equal("0xd128da36044b6c399c522f379a78591a572394423814b8aeb511cf2a3a07701f"); - }); - }); -}); diff --git a/test-chainid/chainid-dependent-behaviour.js b/test/misc/chainid.js similarity index 97% rename from test-chainid/chainid-dependent-behaviour.js rename to test/misc/chainid.js index aac1b53085..d539e707ee 100644 --- a/test-chainid/chainid-dependent-behaviour.js +++ b/test/misc/chainid.js @@ -4,14 +4,14 @@ const bnChai = require("bn-chai"); const BN = require("bn.js"); const ethers = require("ethers"); -const { setupENSRegistrar } = require("../helpers/upgradable-contracts"); +const { setupENSRegistrar } = require("../../helpers/upgradable-contracts"); const { setupColonyNetwork, setupMetaColonyWithLockedCLNYToken, giveUserCLNYTokens, giveUserCLNYTokensAndStake, unlockCLNYToken, -} = require("../helpers/test-data-generator"); +} = require("../../helpers/test-data-generator"); const { forwardTime, getActiveRepCycle, @@ -23,8 +23,8 @@ const { isMainnet, isXdai, getChainId, -} = require("../helpers/test-helper"); -const { MINING_CYCLE_DURATION, MIN_STAKE, CHALLENGE_RESPONSE_WINDOW_DURATION, WAD, DEFAULT_STAKE, XDAI_CHAINID } = require("../helpers/constants"); +} = require("../../helpers/test-helper"); +const { MINING_CYCLE_DURATION, MIN_STAKE, CHALLENGE_RESPONSE_WINDOW_DURATION, WAD, DEFAULT_STAKE, XDAI_CHAINID } = require("../../helpers/constants"); const { expect } = chai; const ENSRegistry = artifacts.require("ENSRegistry"); diff --git a/test-system/end-to-end.js b/test/misc/end-to-end.js similarity index 97% rename from test-system/end-to-end.js rename to test/misc/end-to-end.js index e73da0188d..70843aaf9b 100644 --- a/test-system/end-to-end.js +++ b/test/misc/end-to-end.js @@ -6,7 +6,7 @@ const chai = require("chai"); const bnChai = require("bn-chai"); const ethers = require("ethers"); -const { TruffleLoader } = require("../packages/package-utils"); +const { TruffleLoader } = require("../../packages/package-utils"); const { submitAndForwardTimeToDispute, getActiveRepCycle, @@ -16,7 +16,7 @@ const { makeReputationValue, removeSubdomainLimit, getChainId, -} = require("../helpers/test-helper"); +} = require("../../helpers/test-helper"); const { giveUserCLNYTokensAndStake, @@ -25,12 +25,12 @@ const { setupColonyNetwork, setupMetaColonyWithLockedCLNYToken, setupClaimedExpenditure, -} = require("../helpers/test-data-generator"); +} = require("../../helpers/test-data-generator"); -const { DEFAULT_STAKE, INITIAL_FUNDING } = require("../helpers/constants"); +const { DEFAULT_STAKE, INITIAL_FUNDING } = require("../../helpers/constants"); -const ReputationMinerTestWrapper = require("../packages/reputation-miner/test/ReputationMinerTestWrapper"); -const MaliciousReputationMinerExtraRep = require("../packages/reputation-miner/test/MaliciousReputationMinerExtraRep"); +const ReputationMinerTestWrapper = require("../../packages/reputation-miner/test/ReputationMinerTestWrapper"); +const MaliciousReputationMinerExtraRep = require("../../packages/reputation-miner/test/MaliciousReputationMinerExtraRep"); const { expect } = chai; chai.use(bnChai(web3.utils.BN)); diff --git a/test-gas-costs/gasCosts.js b/test/misc/gas-costs.js similarity index 97% rename from test-gas-costs/gasCosts.js rename to test/misc/gas-costs.js index 9f7bb3f519..f6d90d31ff 100644 --- a/test-gas-costs/gasCosts.js +++ b/test/misc/gas-costs.js @@ -14,7 +14,7 @@ const { INITIAL_FUNDING, MINING_CYCLE_DURATION, CHALLENGE_RESPONSE_WINDOW_DURATION, -} = require("../helpers/constants"); +} = require("../../helpers/constants"); const { getTokenArgs, @@ -27,14 +27,14 @@ const { advanceMiningCycleNoContest, submitAndForwardTimeToDispute, accommodateChallengeAndInvalidateHash, -} = require("../helpers/test-helper"); +} = require("../../helpers/test-helper"); -const { giveUserCLNYTokensAndStake, fundColonyWithTokens, setupRandomColony } = require("../helpers/test-data-generator"); +const { giveUserCLNYTokensAndStake, fundColonyWithTokens, setupRandomColony } = require("../../helpers/test-data-generator"); -const { TruffleLoader } = require("../packages/package-utils"); -const PatriciaTree = require("../packages/reputation-miner/patricia"); -const ReputationMinerTestWrapper = require("../packages/reputation-miner/test/ReputationMinerTestWrapper"); -const MaliciousReputationMinerExtraRep = require("../packages/reputation-miner/test/MaliciousReputationMinerExtraRep"); +const { TruffleLoader } = require("../../packages/package-utils"); +const PatriciaTree = require("../../packages/reputation-miner/patricia"); +const ReputationMinerTestWrapper = require("../../packages/reputation-miner/test/ReputationMinerTestWrapper"); +const MaliciousReputationMinerExtraRep = require("../../packages/reputation-miner/test/MaliciousReputationMinerExtraRep"); const Token = artifacts.require("Token"); const IColony = artifacts.require("IColony"); @@ -50,7 +50,7 @@ const IVotingReputation = artifacts.require("IVotingReputation"); const REAL_PROVIDER_PORT = 8545; const contractLoader = new TruffleLoader({ - contractRoot: path.resolve(__dirname, "..", "artifacts", "contracts"), + contractRoot: path.resolve(__dirname, "..", "..", "artifacts", "contracts"), }); contract("All", function (accounts) { diff --git a/test-upgrade/colony-network-upgrade.js b/test/upgrade/colony-network-upgrade.js similarity index 95% rename from test-upgrade/colony-network-upgrade.js rename to test/upgrade/colony-network-upgrade.js index e375e075aa..864c0bf24c 100644 --- a/test-upgrade/colony-network-upgrade.js +++ b/test/upgrade/colony-network-upgrade.js @@ -1,5 +1,5 @@ /* globals artifacts */ -const { setupRandomColony } = require("../helpers/test-data-generator"); +const { setupRandomColony } = require("../../helpers/test-data-generator"); const IColonyNetwork = artifacts.require("IColonyNetwork"); const EtherRouter = artifacts.require("EtherRouter"); diff --git a/test-upgrade/colony-upgrade.js b/test/upgrade/colony-upgrade.js similarity index 93% rename from test-upgrade/colony-upgrade.js rename to test/upgrade/colony-upgrade.js index 11bdb6642d..90e2d92d88 100644 --- a/test-upgrade/colony-upgrade.js +++ b/test/upgrade/colony-upgrade.js @@ -1,8 +1,8 @@ /* globals artifacts */ -const { getColonyEditable } = require("../helpers/test-helper"); -const { setupColonyVersionResolver } = require("../helpers/upgradable-contracts"); -const { ROOT_ROLE } = require("../helpers/constants"); -const { makeExpenditure, setupRandomColony } = require("../helpers/test-data-generator"); +const { getColonyEditable } = require("../../helpers/test-helper"); +const { setupColonyVersionResolver } = require("../../helpers/upgradable-contracts"); +const { ROOT_ROLE } = require("../../helpers/constants"); +const { makeExpenditure, setupRandomColony } = require("../../helpers/test-data-generator"); const IColonyNetwork = artifacts.require("IColonyNetwork"); const IMetaColony = artifacts.require("IMetaColony"); diff --git a/test-upgrade/reputation-mining-cycle-upgrade.js b/test/upgrade/reputation-mining-cycle-upgrade.js similarity index 93% rename from test-upgrade/reputation-mining-cycle-upgrade.js rename to test/upgrade/reputation-mining-cycle-upgrade.js index f85df2d4d2..af4649c4d3 100644 --- a/test-upgrade/reputation-mining-cycle-upgrade.js +++ b/test/upgrade/reputation-mining-cycle-upgrade.js @@ -1,6 +1,6 @@ /* globals artifacts */ -const { setupReputationMiningCycleResolver } = require("../helpers/upgradable-contracts"); -const { advanceMiningCycleNoContest } = require("../helpers/test-helper"); +const { setupReputationMiningCycleResolver } = require("../../helpers/upgradable-contracts"); +const { advanceMiningCycleNoContest } = require("../../helpers/test-helper"); const IColonyNetwork = artifacts.require("IColonyNetwork"); const EtherRouter = artifacts.require("EtherRouter");