This commit is contained in:
Alexey 2021-02-04 17:17:21 +03:00
parent 362b126e17
commit 780adf3626
4 changed files with 106 additions and 27 deletions

@ -7,6 +7,8 @@ import "torn-token/contracts/ENS.sol";
import "./interfaces/ITornadoTreesV1.sol";
import "./interfaces/IVerifier.sol";
import "hardhat/console.sol";
contract TornadoTrees is EnsResolve {
address public immutable governance;
bytes32 public depositRoot;
@ -75,35 +77,45 @@ contract TornadoTrees is EnsResolve {
depositRoot = _tornadoTreesV1.depositRoot();
withdrawalRoot = _tornadoTreesV1.withdrawalRoot();
uint256 _lastProcessedDepositLeaf = _tornadoTreesV1.lastProcessedDepositLeaf();
require(_lastProcessedDepositLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees contract state");
lastProcessedDepositLeaf = _lastProcessedDepositLeaf;
uint256 depositLeaf = _tornadoTreesV1.lastProcessedDepositLeaf();
require(depositLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees state");
lastProcessedDepositLeaf = depositLeaf;
uint256 _lastProcessedWithdrawalLeaf = _tornadoTreesV1.lastProcessedWithdrawalLeaf();
require(_lastProcessedWithdrawalLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees contract state");
lastProcessedWithdrawalLeaf = _lastProcessedWithdrawalLeaf;
uint256 withdrawalLeaf = _tornadoTreesV1.lastProcessedWithdrawalLeaf();
require(withdrawalLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees state");
lastProcessedWithdrawalLeaf = withdrawalLeaf;
uint256 i = _lastProcessedDepositLeaf + 1;
uint256 i = depositLeaf;
// todo deposits.length = _tornadoTreesV1.deposits.length
todo deposits.length = _tornadoTreesV1.deposits.length
while (true) {
bytes32 deposit = _tornadoTreesV1.deposits(i);
if (deposit == bytes32(0)) {
(bool success, bytes memory data) = address(_tornadoTreesV1).call(abi.encodeWithSignature("deposits(uint256)", i));
// console.log("success", success);
if (!success) {
break;
}
bytes32 deposit = abi.decode(data, (bytes32));
i++;
deposits.push(deposit);
}
i = _lastProcessedWithdrawalLeaf + 1;
uint256 j = withdrawalLeaf;
while (true) {
bytes32 withdrawal = _tornadoTreesV1.withdrawals(i);
if (withdrawal == bytes32(0)) {
(bool success1, bytes memory data1) = address(_tornadoTreesV1).staticcall(
abi.encodeWithSignature("withdrawals(uint256)", j)
);
// console.log("success", success);
// console.logBytes(data);
if (!success1) {
break;
}
i++;
bytes32 withdrawal = abi.decode(data1, (bytes32));
// console.logBytes32(withdrawal);
j++;
withdrawals.push(withdrawal);
}
console.log("end");
}
function registerDeposit(address _instance, bytes32 _commitment) external onlyTornadoProxy onlyInitialized {
@ -149,9 +161,6 @@ contract TornadoTrees is EnsResolve {
initialized = true;
}
// если чтото загрузит руты на старый контракт во время миграции то пизда
// todo !!! ensure that during migration the tree is filled evenly
function updateDepositTree(
bytes calldata _proof,
bytes32 _argsHash,

@ -0,0 +1,63 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
contract TornadoTreesV1Mock {
uint256 public timestamp;
uint256 public currentBlock;
bytes32[] public deposits;
uint256 public lastProcessedDepositLeaf;
bytes32[] public withdrawals;
uint256 public lastProcessedWithdrawalLeaf;
bytes32 public depositRoot;
bytes32 public withdrawalRoot;
constructor(
uint256 _lastProcessedDepositLeaf,
uint256 _lastProcessedWithdrawalLeaf,
bytes32 _depositRoot,
bytes32 _withdrawalRoot
) public {
lastProcessedDepositLeaf = _lastProcessedDepositLeaf;
lastProcessedWithdrawalLeaf = _lastProcessedWithdrawalLeaf;
depositRoot = _depositRoot;
withdrawalRoot = _withdrawalRoot;
}
function register(
address _instance,
bytes32 _commitment,
bytes32 _nullifier,
uint256 _depositBlockNumber,
uint256 _withdrawBlockNumber
) public {
setBlockNumber(_depositBlockNumber);
deposits.push(keccak256(abi.encode(_instance, _commitment, blockNumber())));
setBlockNumber(_withdrawBlockNumber);
withdrawals.push(keccak256(abi.encode(_instance, _nullifier, blockNumber())));
}
function setLastProcessedDepositLeaf(uint256 _lastProcessedDepositLeaf) public {
lastProcessedDepositLeaf = _lastProcessedDepositLeaf;
}
function setLastProcessedWithdrawalLeaf(uint256 _lastProcessedWithdrawalLeaf) public {
lastProcessedWithdrawalLeaf = _lastProcessedWithdrawalLeaf;
}
function resolve(bytes32 _addr) public pure returns (address) {
return address(uint160(uint256(_addr) >> (12 * 8)));
}
function setBlockNumber(uint256 _blockNumber) public {
currentBlock = _blockNumber;
}
function blockNumber() public view returns (uint256) {
return currentBlock == 0 ? block.number : currentBlock;
}
}

@ -20,6 +20,9 @@ task('accounts', 'Prints the list of accounts', async () => {
module.exports = {
solidity: '0.6.12',
networks: {
hardhat: {
blockGasLimit: 950000000,
},
goerli: {
url: `https://goerli.infura.io/v3/${process.env.INFURA_TOKEN}`,
accounts: [process.env.PRIVATE_KEY],

@ -36,6 +36,7 @@ describe('TornadoTrees', function () {
let tornadoProxy
let verifier
let tornadoTrees
let tornadoTreesV1
let notes
const depositEvents = []
const withdrawalEvents = []
@ -47,14 +48,8 @@ describe('TornadoTrees', function () {
const BatchTreeUpdateVerifier = await ethers.getContractFactory('BatchTreeUpdateVerifier')
verifier = await BatchTreeUpdateVerifier.deploy()
const TornadoTrees = await ethers.getContractFactory('TornadoTreesMock')
tornadoTrees = await TornadoTrees.deploy(
toEns(operator.address),
toEns(tornadoProxy.address),
toEns(verifier.address),
toFixedHex(tree.root()),
toFixedHex(tree.root()),
)
const TornadoTreesV1 = await ethers.getContractFactory('TornadoTreesV1Mock')
tornadoTreesV1 = await TornadoTreesV1.deploy(0, 0, tree.root(), tree.root())
notes = []
for (let i = 0; i < 2 ** CHUNK_TREE_HEIGHT; i++) {
@ -65,7 +60,7 @@ describe('TornadoTrees', function () {
commitment: randomBN(),
nullifierHash: randomBN(),
}
await register(notes[i], tornadoTrees, tornadoProxy)
await register(notes[i], tornadoTreesV1, tornadoProxy)
depositEvents[i] = {
hash: toFixedHex(notes[i].commitment),
instance: toFixedHex(notes[i].instance, 20),
@ -77,6 +72,15 @@ describe('TornadoTrees', function () {
block: toFixedHex(notes[i].withdrawalBlock, 4),
}
}
const TornadoTrees = await ethers.getContractFactory('TornadoTreesMock')
tornadoTrees = await TornadoTrees.deploy(
operator.address,
tornadoProxy.address,
tornadoTreesV1.address,
verifier.address,
// { gasLimit: 30e6 },
)
await tornadoTrees.migrate(depositEvents, withdrawalEvents)
})
describe('#updateDepositTree', () => {
@ -86,7 +90,7 @@ describe('TornadoTrees', function () {
expect(solHash).to.be.equal(args[0])
})
it('should prove snark', async () => {
it.only('should prove snark', async () => {
const { input, args } = controller.batchTreeUpdate(tree, depositEvents)
const proof = await controller.prove(input, './artifacts/circuits/BatchTreeUpdate')
await tornadoTrees.updateDepositTree(proof, ...args)