mirror of
https://github.com/tornadocash/tornado-nova
synced 2024-02-02 14:53:56 +01:00
test merge tx
This commit is contained in:
parent
960b6adb30
commit
a210e2a2cc
@ -57,7 +57,7 @@ contract TornadoPool is ReentrancyGuard {
|
|||||||
bytes calldata _proof,
|
bytes calldata _proof,
|
||||||
bytes32 _root,
|
bytes32 _root,
|
||||||
bytes32 _newRoot,
|
bytes32 _newRoot,
|
||||||
bytes32[2] calldata _inputNullifiers,
|
bytes32[] calldata _inputNullifiers,
|
||||||
bytes32[2] calldata _outputCommitments,
|
bytes32[2] calldata _outputCommitments,
|
||||||
uint256 _extAmount,
|
uint256 _extAmount,
|
||||||
uint256 _fee,
|
uint256 _fee,
|
||||||
@ -67,9 +67,11 @@ contract TornadoPool is ReentrancyGuard {
|
|||||||
external payable nonReentrant
|
external payable nonReentrant
|
||||||
{
|
{
|
||||||
require(currentRoot == _root, "Invalid merkle root");
|
require(currentRoot == _root, "Invalid merkle root");
|
||||||
require(!isSpent(_inputNullifiers[0]), "Input 0 is already spent");
|
for(uint256 i = 0; i < _inputNullifiers.length; i++) {
|
||||||
require(!isSpent(_inputNullifiers[1]), "Input 1 is already spent");
|
require(!isSpent(_inputNullifiers[i]), "Input is already spent");
|
||||||
|
}
|
||||||
require(uint256(_extDataHash) == uint256(keccak256(abi.encode(_extData))) % FIELD_SIZE, "Incorrect external data hash");
|
require(uint256(_extDataHash) == uint256(keccak256(abi.encode(_extData))) % FIELD_SIZE, "Incorrect external data hash");
|
||||||
|
if (_inputNullifiers.length == 2) {
|
||||||
require(verifier2.verifyProof(_proof, [
|
require(verifier2.verifyProof(_proof, [
|
||||||
uint256(_root),
|
uint256(_root),
|
||||||
uint256(_newRoot),
|
uint256(_newRoot),
|
||||||
@ -81,10 +83,40 @@ contract TornadoPool is ReentrancyGuard {
|
|||||||
_fee,
|
_fee,
|
||||||
uint256(_extDataHash)
|
uint256(_extDataHash)
|
||||||
]), "Invalid transaction proof");
|
]), "Invalid transaction proof");
|
||||||
|
} else if (_inputNullifiers.length == 16) {
|
||||||
|
require(verifier16.verifyProof(_proof, [
|
||||||
|
uint256(_root),
|
||||||
|
uint256(_newRoot),
|
||||||
|
uint256(_inputNullifiers[0]),
|
||||||
|
uint256(_inputNullifiers[1]),
|
||||||
|
uint256(_inputNullifiers[2]),
|
||||||
|
uint256(_inputNullifiers[3]),
|
||||||
|
uint256(_inputNullifiers[4]),
|
||||||
|
uint256(_inputNullifiers[5]),
|
||||||
|
uint256(_inputNullifiers[6]),
|
||||||
|
uint256(_inputNullifiers[7]),
|
||||||
|
uint256(_inputNullifiers[8]),
|
||||||
|
uint256(_inputNullifiers[9]),
|
||||||
|
uint256(_inputNullifiers[10]),
|
||||||
|
uint256(_inputNullifiers[11]),
|
||||||
|
uint256(_inputNullifiers[12]),
|
||||||
|
uint256(_inputNullifiers[13]),
|
||||||
|
uint256(_inputNullifiers[14]),
|
||||||
|
uint256(_inputNullifiers[15]),
|
||||||
|
uint256(_outputCommitments[0]),
|
||||||
|
uint256(_outputCommitments[1]),
|
||||||
|
_extAmount,
|
||||||
|
_fee,
|
||||||
|
uint256(_extDataHash)
|
||||||
|
]), "Invalid transaction proof");
|
||||||
|
} else {
|
||||||
|
revert("unsupported input count");
|
||||||
|
}
|
||||||
|
|
||||||
currentRoot = _newRoot;
|
currentRoot = _newRoot;
|
||||||
nullifierHashes[_inputNullifiers[0]] = true;
|
for(uint256 i = 0; i < _inputNullifiers.length; i++) {
|
||||||
nullifierHashes[_inputNullifiers[1]] = true;
|
nullifierHashes[_inputNullifiers[i]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
int256 extAmount = calculateExternalAmount(_extAmount);
|
int256 extAmount = calculateExternalAmount(_extAmount);
|
||||||
if (extAmount > 0) {
|
if (extAmount > 0) {
|
||||||
@ -101,9 +133,9 @@ contract TornadoPool is ReentrancyGuard {
|
|||||||
// todo enforce currentCommitmentIndex value in snark
|
// todo enforce currentCommitmentIndex value in snark
|
||||||
emit NewCommitment(_outputCommitments[0], currentCommitmentIndex++, _extData.encryptedOutput1);
|
emit NewCommitment(_outputCommitments[0], currentCommitmentIndex++, _extData.encryptedOutput1);
|
||||||
emit NewCommitment(_outputCommitments[1], currentCommitmentIndex++, _extData.encryptedOutput2);
|
emit NewCommitment(_outputCommitments[1], currentCommitmentIndex++, _extData.encryptedOutput2);
|
||||||
emit NewNullifier(_inputNullifiers[0]);
|
for(uint256 i = 0; i < _inputNullifiers.length; i++) {
|
||||||
emit NewNullifier(_inputNullifiers[1]);
|
emit NewNullifier(_inputNullifiers[i]);
|
||||||
// emit Transaction();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateExternalAmount(uint256 _extAmount) public pure returns(int256) {
|
function calculateExternalAmount(uint256 _extAmount) public pure returns(int256) {
|
||||||
|
26
src/index.js
26
src/index.js
@ -126,6 +126,30 @@ async function deposit({ tornadoPool }) {
|
|||||||
return outputs[0]
|
return outputs[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function merge({ tornadoPool }) {
|
||||||
|
const amount = 1e6
|
||||||
|
const inputs = new Array(16).fill(0).map(_ => new Utxo())
|
||||||
|
const outputs = [new Utxo({ amount }), new Utxo()]
|
||||||
|
|
||||||
|
const { proof, args } = await getProof({
|
||||||
|
inputs,
|
||||||
|
outputs,
|
||||||
|
tree: await buildMerkleTree({ tornadoPool }),
|
||||||
|
extAmount: amount,
|
||||||
|
fee: 0,
|
||||||
|
recipient: 0,
|
||||||
|
relayer: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('Sending merge transaction...', proof, args)
|
||||||
|
const receipt = await tornadoPool.transaction(proof, ...args, {
|
||||||
|
value: amount,
|
||||||
|
gasLimit: 1e6,
|
||||||
|
})
|
||||||
|
console.log(`Receipt ${receipt.hash}`)
|
||||||
|
return outputs[0]
|
||||||
|
}
|
||||||
|
|
||||||
async function transact({ tornadoPool, utxo }) {
|
async function transact({ tornadoPool, utxo }) {
|
||||||
const inputs = [utxo, new Utxo()]
|
const inputs = [utxo, new Utxo()]
|
||||||
const outputs = [
|
const outputs = [
|
||||||
@ -168,4 +192,4 @@ async function withdraw({ tornadoPool, utxo, recipient }) {
|
|||||||
console.log(`Receipt ${receipt.hash}`)
|
console.log(`Receipt ${receipt.hash}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { deposit, withdraw, transact }
|
module.exports = { deposit, withdraw, transact, merge }
|
||||||
|
@ -7,7 +7,7 @@ const { poseidonHash2, toFixedHex, takeSnapshot, revertSnapshot } = require('../
|
|||||||
const MERKLE_TREE_HEIGHT = 5
|
const MERKLE_TREE_HEIGHT = 5
|
||||||
const MerkleTree = require('fixed-merkle-tree')
|
const MerkleTree = require('fixed-merkle-tree')
|
||||||
|
|
||||||
const { deposit, transact, withdraw } = require('../src/index')
|
const { deposit, transact, withdraw, merge } = require('../src/index')
|
||||||
|
|
||||||
describe('TornadoPool', () => {
|
describe('TornadoPool', () => {
|
||||||
let snapshotId, tornadoPool
|
let snapshotId, tornadoPool
|
||||||
@ -42,6 +42,10 @@ describe('TornadoPool', () => {
|
|||||||
expect(bal).to.be.gt(0)
|
expect(bal).to.be.gt(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should work with 16 inputs', async function () {
|
||||||
|
const utxo1 = await merge({tornadoPool})
|
||||||
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
await revertSnapshot(snapshotId)
|
await revertSnapshot(snapshotId)
|
||||||
snapshotId = await takeSnapshot()
|
snapshotId = await takeSnapshot()
|
||||||
|
Loading…
Reference in New Issue
Block a user