refactor merkle tree naming

This commit is contained in:
poma 2019-11-02 16:04:17 +03:00
parent e413ccdc29
commit 2ded1f8adb
3 changed files with 53 additions and 66 deletions

View File

@ -16,123 +16,110 @@ library Hasher {
}
contract MerkleTreeWithHistory {
uint256 public levels;
uint256 public constant FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
uint256 public constant ZERO_VALUE = 5702960885942360421128284892092891246826997279710054143430547229469817701242; // = MiMC("tornado")
uint256 public constant ROOT_HISTORY_SIZE = 100;
uint256[ROOT_HISTORY_SIZE] public _roots;
uint256 public current_root_index = 0;
uint256[ROOT_HISTORY_SIZE] public roots;
uint256 public currentRootIndex = 0;
uint256[] private _filled_subtrees;
uint256[] private _zeros;
uint256 public levels;
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 {
require(tree_levels > 0, "tree_levels should be greater than zero");
levels = tree_levels;
uint256 current_zero = ZERO_VALUE;
_zeros.push(ZERO_VALUE);
_filled_subtrees.push(current_zero);
uint256 currentZero = ZERO_VALUE;
zeros.push(ZERO_VALUE);
filledSubtrees.push(currentZero);
for (uint8 i = 1; i < levels; i++) {
current_zero = hashLeftRight(current_zero, current_zero);
_zeros.push(current_zero);
_filled_subtrees.push(current_zero);
currentZero = hashLeftRight(currentZero, currentZero);
zeros.push(currentZero);
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) {
uint256 R = left; // left is already checked to be less than field_size by snark verifier
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 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);
return R;
}
function _insert(uint256 leaf) internal returns(uint256 index) {
uint32 current_index = next_index;
require(current_index != 2**levels, "Merkle tree is full. No more leafs can be added");
next_index += 1;
uint256 current_level_hash = leaf;
function _insert(uint256 _leaf) internal returns(uint256 index) {
uint32 currentIndex = nextIndex;
require(currentIndex != 2**levels, "Merkle tree is full. No more leafs can be added");
nextIndex += 1;
uint256 currentLevelHash = _leaf;
uint256 left;
uint256 right;
for (uint256 i = 0; i < levels; i++) {
if (current_index % 2 == 0) {
left = current_level_hash;
right = _zeros[i];
if (currentIndex % 2 == 0) {
left = currentLevelHash;
right = zeros[i];
_filled_subtrees[i] = current_level_hash;
filledSubtrees[i] = currentLevelHash;
} else {
left = _filled_subtrees[i];
right = current_level_hash;
left = filledSubtrees[i];
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;
_roots[current_root_index] = current_level_hash;
return next_index - 1;
currentRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;
roots[currentRootIndex] = currentLevelHash;
return nextIndex - 1;
}
function isKnownRoot(uint256 root) public view returns(bool) {
if (root == 0) {
function isKnownRoot(uint256 _root) public view returns(bool) {
if (_root == 0) {
return false;
}
// search most recent first
uint256 i;
for(i = current_root_index; i < 2**256 - 1; i--) {
if (root == _roots[i]) {
for(i = currentRootIndex; i < 2**256 - 1; i--) {
if (_root == roots[i]) {
return true;
}
}
// process the rest of roots
for(i = ROOT_HISTORY_SIZE - 1; i > current_root_index; i--) {
if (root == _roots[i]) {
for(i = ROOT_HISTORY_SIZE - 1; i > currentRootIndex; i--) {
if (_root == roots[i]) {
return true;
}
}
return false;
// or we can do that in other way
// uint256 i = _current_root;
// uint256 i = currentRootIndex;
// do {
// if (root == _roots[i]) {
// if (root == roots[i]) {
// return true;
// }
// if (i == 0) {
// i = ROOT_HISTORY_SIZE;
// }
// i--;
// } while (i != _current_root);
// } while (i != currentRootIndex);
}
function getLastRoot() public view returns(uint256) {
return _roots[current_root_index];
}
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;
return roots[currentRootIndex];
}
}

View File

@ -4,9 +4,9 @@ import '../MerkleTreeWithHistory.sol';
contract MerkleTreeWithHistoryMock is MerkleTreeWithHistory {
constructor (uint8 tree_levels) MerkleTreeWithHistory(tree_levels) public {}
constructor (uint8 _treeLevels) MerkleTreeWithHistory(_treeLevels) public {}
function insert(uint256 leaf) public {
_insert(leaf);
function insert(uint256 _leaf) public {
_insert(_leaf);
}
}

View File

@ -49,11 +49,11 @@ contract('MerkleTreeWithHistory', accounts => {
describe('#constructor', () => {
it('should initialize', async () => {
const filled_subtrees = await merkleTreeWithHistory.filled_subtrees()
const zeroValue = await merkleTreeWithHistory.ZERO_VALUE()
filled_subtrees[0].should.be.eq.BN(zeroValue)
const zeros = await merkleTreeWithHistory.zeros()
zeros[0].should.be.eq.BN(zeroValue)
const firstSubtree = await merkleTreeWithHistory.filledSubtrees(0)
firstSubtree.should.be.eq.BN(zeroValue)
const firstZero = await merkleTreeWithHistory.zeros(0)
firstZero.should.be.eq.BN(zeroValue)
})
})