mirror of
https://github.com/tornadocash/tornado-core.git
synced 2024-11-21 09:17:05 +01:00
add dummy test
This commit is contained in:
parent
5db6595c61
commit
641c76fa39
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.sol linguist-language=Solidity
|
16
.vscode/launch.json
vendored
Normal file
16
.vscode/launch.json
vendored
Normal 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
9
contracts/.editorconfig
Normal 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
4
contracts/README.md
Normal 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.
|
@ -8,11 +8,11 @@ contract MerkleTreeWithHistory {
|
||||
uint8 levels;
|
||||
|
||||
uint8 constant ROOT_HISTORY_SIZE = 100;
|
||||
uint256[] public roots;
|
||||
uint256[] private _roots;
|
||||
uint256 public current_root = 0;
|
||||
|
||||
uint256[] public filled_subtrees;
|
||||
uint256[] public zeros;
|
||||
uint256[] private _filled_subtrees;
|
||||
uint256[] private _zeros;
|
||||
|
||||
uint32 public next_index = 0;
|
||||
|
||||
@ -21,19 +21,19 @@ contract MerkleTreeWithHistory {
|
||||
constructor(uint8 tree_levels, uint256 zero_value) public {
|
||||
levels = tree_levels;
|
||||
|
||||
zeros.push(zero_value);
|
||||
filled_subtrees.push(zeros[0]);
|
||||
_zeros.push(zero_value);
|
||||
_filled_subtrees.push(_zeros[0]);
|
||||
|
||||
for (uint8 i = 1; i < levels; i++) {
|
||||
zeros.push(HashLeftRight(zeros[i-1], zeros[i-1]));
|
||||
filled_subtrees.push(zeros[i]);
|
||||
_zeros.push(hashLeftRight(_zeros[i-1], _zeros[i-1]));
|
||||
_filled_subtrees.push(_zeros[i]);
|
||||
}
|
||||
|
||||
roots = new uint256[](ROOT_HISTORY_SIZE);
|
||||
roots[0] = HashLeftRight(zeros[levels - 1], zeros[levels - 1]);
|
||||
_roots = new uint256[](ROOT_HISTORY_SIZE);
|
||||
_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 R = 0;
|
||||
uint256 C = 0;
|
||||
@ -47,7 +47,7 @@ contract MerkleTreeWithHistory {
|
||||
mimc_hash = R;
|
||||
}
|
||||
|
||||
function insert(uint256 leaf) internal {
|
||||
function _insert(uint256 leaf) internal {
|
||||
uint32 leaf_index = next_index;
|
||||
uint32 current_index = next_index;
|
||||
next_index += 1;
|
||||
@ -59,38 +59,38 @@ contract MerkleTreeWithHistory {
|
||||
for (uint8 i = 0; i < levels; i++) {
|
||||
if (current_index % 2 == 0) {
|
||||
left = current_level_hash;
|
||||
right = zeros[i];
|
||||
right = _zeros[i];
|
||||
|
||||
filled_subtrees[i] = current_level_hash;
|
||||
_filled_subtrees[i] = current_level_hash;
|
||||
} else {
|
||||
left = filled_subtrees[i];
|
||||
left = _filled_subtrees[i];
|
||||
right = current_level_hash;
|
||||
}
|
||||
|
||||
current_level_hash = HashLeftRight(left, right);
|
||||
current_level_hash = hashLeftRight(left, right);
|
||||
|
||||
current_index /= 2;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
function isKnownRoot(uint _root) internal view returns(bool) {
|
||||
if (_root == 0) {
|
||||
function isKnownRoot(uint root) public view returns(bool) {
|
||||
if (root == 0) {
|
||||
return false;
|
||||
}
|
||||
// search most recent first
|
||||
uint256 i;
|
||||
for(i = current_root; i >= 0; i--) {
|
||||
if (_root == roots[i]) {
|
||||
if (root == _roots[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for(i = ROOT_HISTORY_SIZE - 1; i > current_root; i--) {
|
||||
if (_root == roots[i]) {
|
||||
if (root == _roots[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -98,7 +98,19 @@ contract MerkleTreeWithHistory {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ contract Mixer is MerkleTreeWithHistory {
|
||||
|
||||
function deposit(uint256 commitment) public payable {
|
||||
require(msg.value == transferValue, "Please send `transferValue` ETH along with transaction");
|
||||
insert(commitment);
|
||||
_insert(commitment);
|
||||
emit Deposit(msg.sender, commitment);
|
||||
}
|
||||
|
||||
@ -46,4 +46,4 @@ contract Mixer is MerkleTreeWithHistory {
|
||||
}
|
||||
emit Withdraw(receiver, nullifier, fee);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
contracts/contracts/Mocks/MerkleTreeWithHistoryMock.sol
Normal file
12
contracts/contracts/Mocks/MerkleTreeWithHistoryMock.sol
Normal 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);
|
||||
}
|
||||
}
|
24
contracts/migrations/2_deploy_mimc.js
Normal file
24
contracts/migrations/2_deploy_mimc.js
Normal 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);
|
||||
});
|
||||
});
|
||||
};
|
5698
contracts/package-lock.json
generated
5698
contracts/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,14 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
45
contracts/scripts/ganacheHelper.js
Normal file
45
contracts/scripts/ganacheHelper.js
Normal 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,
|
||||
};
|
71
contracts/test/MerkleTreeWithHistory.test.js
Normal file
71
contracts/test/MerkleTreeWithHistory.test.js
Normal 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()
|
||||
})
|
||||
})
|
@ -87,13 +87,13 @@ module.exports = {
|
||||
solc: {
|
||||
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)
|
||||
// settings: { // See the solidity docs for advice about optimization and evmVersion
|
||||
// optimizer: {
|
||||
// enabled: false,
|
||||
// runs: 200
|
||||
// },
|
||||
// evmVersion: "byzantium"
|
||||
// }
|
||||
settings: { // See the solidity docs for advice about optimization and evmVersion
|
||||
optimizer: {
|
||||
enabled: false,
|
||||
runs: 200
|
||||
},
|
||||
// evmVersion: "byzantium"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user