add dummy test

This commit is contained in:
Alexey 2019-07-10 19:58:21 +03:00
parent 5db6595c61
commit 641c76fa39
13 changed files with 5931 additions and 31 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.sol linguist-language=Solidity

16
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Mocha All",
"program": "${workspaceFolder}/contracts/node_modules/truffle/build/cli.bundled.js",
"args": ["test"],
"cwd": "${workspaceFolder}/contracts"
}
]
}

9
contracts/.editorconfig Normal file
View File

@ -0,0 +1,9 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

4
contracts/README.md Normal file
View File

@ -0,0 +1,4 @@
## Testing
1. `npm i`
2. `npx truffle compile`
3. `npx truffle test` - it may fail for the first time, just run one more time.

View File

@ -8,11 +8,11 @@ contract MerkleTreeWithHistory {
uint8 levels; uint8 levels;
uint8 constant ROOT_HISTORY_SIZE = 100; uint8 constant ROOT_HISTORY_SIZE = 100;
uint256[] public roots; uint256[] private _roots;
uint256 public current_root = 0; uint256 public current_root = 0;
uint256[] public filled_subtrees; uint256[] private _filled_subtrees;
uint256[] public zeros; uint256[] private _zeros;
uint32 public next_index = 0; uint32 public next_index = 0;
@ -21,19 +21,19 @@ contract MerkleTreeWithHistory {
constructor(uint8 tree_levels, uint256 zero_value) public { constructor(uint8 tree_levels, uint256 zero_value) public {
levels = tree_levels; levels = tree_levels;
zeros.push(zero_value); _zeros.push(zero_value);
filled_subtrees.push(zeros[0]); _filled_subtrees.push(_zeros[0]);
for (uint8 i = 1; i < levels; i++) { for (uint8 i = 1; i < levels; i++) {
zeros.push(HashLeftRight(zeros[i-1], zeros[i-1])); _zeros.push(hashLeftRight(_zeros[i-1], _zeros[i-1]));
filled_subtrees.push(zeros[i]); _filled_subtrees.push(_zeros[i]);
} }
roots = new uint256[](ROOT_HISTORY_SIZE); _roots = new uint256[](ROOT_HISTORY_SIZE);
roots[0] = HashLeftRight(zeros[levels - 1], zeros[levels - 1]); _roots[0] = hashLeftRight(_zeros[levels - 1], _zeros[levels - 1]);
} }
function HashLeftRight(uint256 left, uint256 right) public pure returns (uint256 mimc_hash) { function hashLeftRight(uint256 left, uint256 right) public pure returns (uint256 mimc_hash) {
uint256 k = 21888242871839275222246405745257275088548364400416034343698204186575808495617; uint256 k = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
uint256 R = 0; uint256 R = 0;
uint256 C = 0; uint256 C = 0;
@ -47,7 +47,7 @@ contract MerkleTreeWithHistory {
mimc_hash = R; mimc_hash = R;
} }
function insert(uint256 leaf) internal { function _insert(uint256 leaf) internal {
uint32 leaf_index = next_index; uint32 leaf_index = next_index;
uint32 current_index = next_index; uint32 current_index = next_index;
next_index += 1; next_index += 1;
@ -59,38 +59,38 @@ contract MerkleTreeWithHistory {
for (uint8 i = 0; i < levels; i++) { for (uint8 i = 0; i < levels; i++) {
if (current_index % 2 == 0) { if (current_index % 2 == 0) {
left = current_level_hash; left = current_level_hash;
right = zeros[i]; right = _zeros[i];
filled_subtrees[i] = current_level_hash; _filled_subtrees[i] = current_level_hash;
} else { } else {
left = filled_subtrees[i]; left = _filled_subtrees[i];
right = current_level_hash; right = current_level_hash;
} }
current_level_hash = HashLeftRight(left, right); current_level_hash = hashLeftRight(left, right);
current_index /= 2; current_index /= 2;
} }
current_root = (current_root + 1) % ROOT_HISTORY_SIZE; current_root = (current_root + 1) % ROOT_HISTORY_SIZE;
roots[current_root] = current_level_hash; _roots[current_root] = current_level_hash;
emit LeafAdded(leaf, leaf_index); emit LeafAdded(leaf, leaf_index);
} }
function isKnownRoot(uint _root) internal view returns(bool) { function isKnownRoot(uint root) public view returns(bool) {
if (_root == 0) { if (root == 0) {
return false; return false;
} }
// search most recent first // search most recent first
uint256 i; uint256 i;
for(i = current_root; i >= 0; i--) { for(i = current_root; i >= 0; i--) {
if (_root == roots[i]) { if (root == _roots[i]) {
return true; return true;
} }
} }
for(i = ROOT_HISTORY_SIZE - 1; i > current_root; i--) { for(i = ROOT_HISTORY_SIZE - 1; i > current_root; i--) {
if (_root == roots[i]) { if (root == _roots[i]) {
return true; return true;
} }
} }
@ -98,7 +98,19 @@ contract MerkleTreeWithHistory {
} }
function getLastRoot() public view returns(uint256) { function getLastRoot() public view returns(uint256) {
return roots[current_root]; return _roots[current_root];
}
function roots() public view returns(uint256[] memory) {
return _roots;
}
function filled_subtrees() public view returns(uint256[] memory) {
return _filled_subtrees;
}
function zeros() public view returns(uint256[] memory) {
return _zeros;
} }
} }

View File

@ -24,7 +24,7 @@ contract Mixer is MerkleTreeWithHistory {
function deposit(uint256 commitment) public payable { function deposit(uint256 commitment) public payable {
require(msg.value == transferValue, "Please send `transferValue` ETH along with transaction"); require(msg.value == transferValue, "Please send `transferValue` ETH along with transaction");
insert(commitment); _insert(commitment);
emit Deposit(msg.sender, commitment); emit Deposit(msg.sender, commitment);
} }
@ -46,4 +46,4 @@ contract Mixer is MerkleTreeWithHistory {
} }
emit Withdraw(receiver, nullifier, fee); emit Withdraw(receiver, nullifier, fee);
} }
} }

View File

@ -0,0 +1,12 @@
pragma solidity ^0.5.8;
import '../MerkleTreeWithHistory.sol';
contract MerkleTreeWithHistoryMock is MerkleTreeWithHistory {
constructor (uint8 tree_levels, uint256 zero_value) MerkleTreeWithHistory(tree_levels, zero_value) public {}
function insert(uint256 leaf) public {
_insert(leaf);
}
}

View File

@ -0,0 +1,24 @@
const path = require('path');
const mimcGenContract = require('circomlib/src/mimcsponge_gencontract.js');
const Artifactor = require('truffle-artifactor');
const SEED = 'mimcsponge';
module.exports = function(deployer) {
return deployer.then( async () => {
const contractsDir = path.join(__dirname, '..', 'build/contracts');
let artifactor = new Artifactor(contractsDir);
let mimcContractName = 'MiMC';
await artifactor.save({
contractName: mimcContractName,
abi: mimcGenContract.abi,
unlinked_binary: mimcGenContract.createCode(SEED, 220),
})
.then(async () => {
const MiMC = artifacts.require(mimcContractName);
await deployer.deploy(MiMC);
});
});
};

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,14 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"openzeppelin-solidity": "^2.3.0" "bn-chai": "^1.0.1",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"circomlib": "git+https://github.com/kobigurk/circomlib.git#323966c0584bafebf9652681c44d9ea348fe9bb5",
"ganache-cli": "^6.4.5",
"openzeppelin-solidity": "^2.3.0",
"truffle": "^5.0.20",
"truffle-artifactor": "^4.0.22",
"web3-utils": "^1.0.0-beta.55"
} }
} }

View File

@ -0,0 +1,45 @@
function send(method, params = []) {
return new Promise((resolve, reject) => {
web3.currentProvider.send({
jsonrpc: '2.0',
id: Date.now(),
method,
params
}, (err, res) => {
return err ? reject(err) : resolve(res);
});
});
}
const takeSnapshot = async seconds => {
return await send('evm_snapshot');
}
const revertSnapshot = async (id) => {
await send('evm_revert', [id]);
}
const mineBlock = async (timestamp) => {
await send('evm_mine', [timestamp]);
}
const increaseTime = async (seconds) => {
await send('evm_increaseTime', [seconds]);
}
const minerStop = async () => {
await send('miner_stop', []);
}
const minerStart = async () => {
await send('miner_start', []);
}
module.exports = {
takeSnapshot,
revertSnapshot,
mineBlock,
minerStop,
minerStart,
increaseTime,
};

View File

@ -0,0 +1,71 @@
const should = require('chai')
.use(require('bn-chai')(web3.utils.BN))
.use(require('chai-as-promised'))
.should()
const { toWei, toBN } = require('web3-utils')
const { takeSnapshot, revertSnapshot, increaseTime } = require('../scripts/ganacheHelper');
const MerkleTreeWithHistory = artifacts.require('./MerkleTreeWithHistoryMock.sol')
const MiMC = artifacts.require('./MiMC.sol')
function BNArrayToStringArray(array) {
const arrayToPrint = []
array.forEach(item => {
arrayToPrint.push(item.toString())
})
return arrayToPrint
}
contract('MerkleTreeWithHistory', async accounts => {
let merkleTreeWithHistory
let miMC
const sender = accounts[0]
const emptyAddress = '0x0000000000000000000000000000000000000000'
const levels = 5
const zeroValue = 1337
let snapshotId
before(async () => {
miMC = MiMC.deployed()
await MerkleTreeWithHistory.link(MiMC, miMC.address);
merkleTreeWithHistory = await MerkleTreeWithHistory.new(levels, zeroValue)
snapshotId = await takeSnapshot()
})
describe('#constuctor', async () => {
it('should initialize', async () => {
const filled_subtrees = await merkleTreeWithHistory.filled_subtrees()
console.log('filled_subtrees', BNArrayToStringArray(filled_subtrees))
const root = await merkleTreeWithHistory.getLastRoot()
console.log('root', root.toString())
filled_subtrees[0].should.be.eq.BN(zeroValue)
const zeros = await merkleTreeWithHistory.zeros()
// console.log('zeros', BNArrayToStringArray(zeros))
zeros[0].should.be.eq.BN(zeroValue)
const roots = await merkleTreeWithHistory.roots()
// console.log('roots', BNArrayToStringArray(roots))
})
})
describe('#insert', async () => {
it('should insert', async () => {
let filled_subtrees
let root
for (i = 1; i < 11; i++) {
await merkleTreeWithHistory.insert(i)
filled_subtrees = await merkleTreeWithHistory.filled_subtrees()
console.log('filled_subtrees', BNArrayToStringArray(filled_subtrees))
root = await merkleTreeWithHistory.getLastRoot()
console.log('root', root.toString())
}
})
})
afterEach(async () => {
await revertSnapshot(snapshotId.result)
snapshotId = await takeSnapshot()
})
})

View File

@ -87,13 +87,13 @@ module.exports = {
solc: { solc: {
version: "0.5.8", // Fetch exact version from solc-bin (default: truffle's version) version: "0.5.8", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false) // docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion settings: { // See the solidity docs for advice about optimization and evmVersion
// optimizer: { optimizer: {
// enabled: false, enabled: false,
// runs: 200 runs: 200
// }, },
// evmVersion: "byzantium" // evmVersion: "byzantium"
// } }
} }
} }
} }