mirror of
https://github.com/tornadocash/tornado-core.git
synced 2024-11-22 09:47:13 +01:00
refactor merkle tree naming
This commit is contained in:
parent
e413ccdc29
commit
2ded1f8adb
@ -16,123 +16,110 @@ library Hasher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
contract MerkleTreeWithHistory {
|
contract MerkleTreeWithHistory {
|
||||||
uint256 public levels;
|
|
||||||
|
|
||||||
uint256 public constant FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
uint256 public constant FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||||
uint256 public constant ZERO_VALUE = 5702960885942360421128284892092891246826997279710054143430547229469817701242; // = MiMC("tornado")
|
uint256 public constant ZERO_VALUE = 5702960885942360421128284892092891246826997279710054143430547229469817701242; // = MiMC("tornado")
|
||||||
|
|
||||||
uint256 public constant ROOT_HISTORY_SIZE = 100;
|
uint256 public constant ROOT_HISTORY_SIZE = 100;
|
||||||
uint256[ROOT_HISTORY_SIZE] public _roots;
|
uint256[ROOT_HISTORY_SIZE] public roots;
|
||||||
uint256 public current_root_index = 0;
|
uint256 public currentRootIndex = 0;
|
||||||
|
|
||||||
uint256[] private _filled_subtrees;
|
uint256 public levels;
|
||||||
uint256[] private _zeros;
|
uint32 public nextIndex = 0;
|
||||||
|
uint256[] public filledSubtrees;
|
||||||
|
uint256[] public zeros;
|
||||||
|
|
||||||
uint32 public next_index = 0;
|
constructor(uint256 _treeLevels) public {
|
||||||
|
require(_treeLevels > 0, "_treeLevels should be greater than zero");
|
||||||
|
levels = _treeLevels;
|
||||||
|
|
||||||
constructor(uint256 tree_levels) public {
|
uint256 currentZero = ZERO_VALUE;
|
||||||
require(tree_levels > 0, "tree_levels should be greater than zero");
|
zeros.push(ZERO_VALUE);
|
||||||
levels = tree_levels;
|
filledSubtrees.push(currentZero);
|
||||||
|
|
||||||
uint256 current_zero = ZERO_VALUE;
|
|
||||||
_zeros.push(ZERO_VALUE);
|
|
||||||
_filled_subtrees.push(current_zero);
|
|
||||||
|
|
||||||
for (uint8 i = 1; i < levels; i++) {
|
for (uint8 i = 1; i < levels; i++) {
|
||||||
current_zero = hashLeftRight(current_zero, current_zero);
|
currentZero = hashLeftRight(currentZero, currentZero);
|
||||||
_zeros.push(current_zero);
|
zeros.push(currentZero);
|
||||||
_filled_subtrees.push(current_zero);
|
filledSubtrees.push(currentZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
_roots[0] = hashLeftRight(current_zero, current_zero);
|
roots[0] = hashLeftRight(currentZero, currentZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hashLeftRight(uint256 left, uint256 right) public pure returns (uint256 hash) {
|
function hashLeftRight(uint256 _left, uint256 _right) public pure returns (uint256 hash) {
|
||||||
uint256 R = left; // left is already checked to be less than field_size by snark verifier
|
uint256 R = _left; // left is already checked to be less than field_size by snark verifier
|
||||||
uint256 C = 0;
|
uint256 C = 0;
|
||||||
|
|
||||||
(R, C) = Hasher.MiMCSponge(R, C, 0);
|
(R, C) = Hasher.MiMCSponge(R, C, 0);
|
||||||
|
|
||||||
R = addmod(R, right, FIELD_SIZE);
|
R = addmod(R, _right, FIELD_SIZE);
|
||||||
(R, C) = Hasher.MiMCSponge(R, C, 0);
|
(R, C) = Hasher.MiMCSponge(R, C, 0);
|
||||||
|
|
||||||
return R;
|
return R;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _insert(uint256 leaf) internal returns(uint256 index) {
|
function _insert(uint256 _leaf) internal returns(uint256 index) {
|
||||||
uint32 current_index = next_index;
|
uint32 currentIndex = nextIndex;
|
||||||
require(current_index != 2**levels, "Merkle tree is full. No more leafs can be added");
|
require(currentIndex != 2**levels, "Merkle tree is full. No more leafs can be added");
|
||||||
next_index += 1;
|
nextIndex += 1;
|
||||||
uint256 current_level_hash = leaf;
|
uint256 currentLevelHash = _leaf;
|
||||||
uint256 left;
|
uint256 left;
|
||||||
uint256 right;
|
uint256 right;
|
||||||
|
|
||||||
for (uint256 i = 0; i < levels; i++) {
|
for (uint256 i = 0; i < levels; i++) {
|
||||||
if (current_index % 2 == 0) {
|
if (currentIndex % 2 == 0) {
|
||||||
left = current_level_hash;
|
left = currentLevelHash;
|
||||||
right = _zeros[i];
|
right = zeros[i];
|
||||||
|
|
||||||
_filled_subtrees[i] = current_level_hash;
|
filledSubtrees[i] = currentLevelHash;
|
||||||
} else {
|
} else {
|
||||||
left = _filled_subtrees[i];
|
left = filledSubtrees[i];
|
||||||
right = current_level_hash;
|
right = currentLevelHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_level_hash = hashLeftRight(left, right);
|
currentLevelHash = hashLeftRight(left, right);
|
||||||
|
|
||||||
current_index /= 2;
|
currentIndex /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_root_index = (current_root_index + 1) % ROOT_HISTORY_SIZE;
|
currentRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;
|
||||||
_roots[current_root_index] = current_level_hash;
|
roots[currentRootIndex] = currentLevelHash;
|
||||||
return next_index - 1;
|
return nextIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isKnownRoot(uint256 root) public view returns(bool) {
|
function isKnownRoot(uint256 _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_index; i < 2**256 - 1; i--) {
|
for(i = currentRootIndex; i < 2**256 - 1; i--) {
|
||||||
if (root == _roots[i]) {
|
if (_root == roots[i]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// process the rest of roots
|
// process the rest of roots
|
||||||
for(i = ROOT_HISTORY_SIZE - 1; i > current_root_index; i--) {
|
for(i = ROOT_HISTORY_SIZE - 1; i > currentRootIndex; i--) {
|
||||||
if (root == _roots[i]) {
|
if (_root == roots[i]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// or we can do that in other way
|
// or we can do that in other way
|
||||||
// uint256 i = _current_root;
|
// uint256 i = currentRootIndex;
|
||||||
// do {
|
// do {
|
||||||
// if (root == _roots[i]) {
|
// if (root == roots[i]) {
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
// if (i == 0) {
|
// if (i == 0) {
|
||||||
// i = ROOT_HISTORY_SIZE;
|
// i = ROOT_HISTORY_SIZE;
|
||||||
// }
|
// }
|
||||||
// i--;
|
// i--;
|
||||||
// } while (i != _current_root);
|
// } while (i != currentRootIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLastRoot() public view returns(uint256) {
|
function getLastRoot() public view returns(uint256) {
|
||||||
return _roots[current_root_index];
|
return roots[currentRootIndex];
|
||||||
}
|
|
||||||
|
|
||||||
function roots() public view returns(uint256[ROOT_HISTORY_SIZE] memory) {
|
|
||||||
return _roots;
|
|
||||||
}
|
|
||||||
|
|
||||||
function filled_subtrees() public view returns(uint256[] memory) {
|
|
||||||
return _filled_subtrees;
|
|
||||||
}
|
|
||||||
|
|
||||||
function zeros() public view returns(uint256[] memory) {
|
|
||||||
return _zeros;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@ import '../MerkleTreeWithHistory.sol';
|
|||||||
|
|
||||||
contract MerkleTreeWithHistoryMock is MerkleTreeWithHistory {
|
contract MerkleTreeWithHistoryMock is MerkleTreeWithHistory {
|
||||||
|
|
||||||
constructor (uint8 tree_levels) MerkleTreeWithHistory(tree_levels) public {}
|
constructor (uint8 _treeLevels) MerkleTreeWithHistory(_treeLevels) public {}
|
||||||
|
|
||||||
function insert(uint256 leaf) public {
|
function insert(uint256 _leaf) public {
|
||||||
_insert(leaf);
|
_insert(_leaf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,11 @@ contract('MerkleTreeWithHistory', accounts => {
|
|||||||
|
|
||||||
describe('#constructor', () => {
|
describe('#constructor', () => {
|
||||||
it('should initialize', async () => {
|
it('should initialize', async () => {
|
||||||
const filled_subtrees = await merkleTreeWithHistory.filled_subtrees()
|
|
||||||
const zeroValue = await merkleTreeWithHistory.ZERO_VALUE()
|
const zeroValue = await merkleTreeWithHistory.ZERO_VALUE()
|
||||||
filled_subtrees[0].should.be.eq.BN(zeroValue)
|
const firstSubtree = await merkleTreeWithHistory.filledSubtrees(0)
|
||||||
const zeros = await merkleTreeWithHistory.zeros()
|
firstSubtree.should.be.eq.BN(zeroValue)
|
||||||
zeros[0].should.be.eq.BN(zeroValue)
|
const firstZero = await merkleTreeWithHistory.zeros(0)
|
||||||
|
firstZero.should.be.eq.BN(zeroValue)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user