findArrayLength fix
This commit is contained in:
parent
73554b3ae3
commit
31d48c2b57
@ -105,6 +105,7 @@ contract TornadoTrees is EnsResolve {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo make things internal. Think of dedundant calls
|
||||||
function findArrayLength(
|
function findArrayLength(
|
||||||
ITornadoTreesV1 _tornadoTreesV1,
|
ITornadoTreesV1 _tornadoTreesV1,
|
||||||
string memory _type,
|
string memory _type,
|
||||||
@ -112,7 +113,7 @@ contract TornadoTrees is EnsResolve {
|
|||||||
uint256 _step
|
uint256 _step
|
||||||
) public view returns (uint256) {
|
) public view returns (uint256) {
|
||||||
require(_from != 0 && _step != 0, "_from and _step should be > 0");
|
require(_from != 0 && _step != 0, "_from and _step should be > 0");
|
||||||
require(elementExists(_tornadoTreesV1, _type, _from), "Inccorrect _from param");
|
// require(elementExists(_tornadoTreesV1, _type, _from), "Inccorrect _from param");
|
||||||
|
|
||||||
uint256 index = _from + _step;
|
uint256 index = _from + _step;
|
||||||
while (elementExists(_tornadoTreesV1, _type, index)) {
|
while (elementExists(_tornadoTreesV1, _type, index)) {
|
||||||
@ -121,21 +122,38 @@ contract TornadoTrees is EnsResolve {
|
|||||||
|
|
||||||
uint256 high = index;
|
uint256 high = index;
|
||||||
uint256 low = index - _step;
|
uint256 low = index - _step;
|
||||||
uint256 mid = (low + high) / 2;
|
uint256 lastIndex = binarySearch(_tornadoTreesV1, _type, high, low);
|
||||||
while (!elementExists(_tornadoTreesV1, _type, mid)) {
|
|
||||||
high = mid - 1;
|
return lastIndex + 1;
|
||||||
mid = (low + high) / 2;
|
}
|
||||||
|
|
||||||
|
function binarySearch(
|
||||||
|
ITornadoTreesV1 _tornadoTreesV1,
|
||||||
|
string memory _type,
|
||||||
|
uint256 _high,
|
||||||
|
uint256 _low
|
||||||
|
) public view returns (uint256) {
|
||||||
|
require(_high >= _low, "Incorrect params");
|
||||||
|
uint256 mid = (_high + _low) / 2;
|
||||||
|
(bool isLast, bool exists) = isLastElement(_tornadoTreesV1, _type, mid);
|
||||||
|
if (isLast) {
|
||||||
|
return mid;
|
||||||
}
|
}
|
||||||
|
|
||||||
high += 1;
|
if (exists) {
|
||||||
low = mid + 1;
|
return binarySearch(_tornadoTreesV1, _type, _high, mid + 1);
|
||||||
mid = (low + high) / 2;
|
} else {
|
||||||
while (elementExists(_tornadoTreesV1, _type, mid)) {
|
return binarySearch(_tornadoTreesV1, _type, mid - 1, _low);
|
||||||
low = mid + 1;
|
|
||||||
mid = (low + high) / 2;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return high == low ? high : low;
|
function isLastElement(
|
||||||
|
ITornadoTreesV1 _tornadoTreesV1,
|
||||||
|
string memory _type,
|
||||||
|
uint256 index
|
||||||
|
) public view returns (bool success, bool exists) {
|
||||||
|
exists = elementExists(_tornadoTreesV1, _type, index);
|
||||||
|
success = exists && !elementExists(_tornadoTreesV1, _type, index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function elementExists(
|
function elementExists(
|
||||||
|
@ -75,4 +75,12 @@ describe('findArrayLength', () => {
|
|||||||
)
|
)
|
||||||
expect(depositsLength).to.be.equal(deposits.length)
|
expect(depositsLength).to.be.equal(deposits.length)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should work for an array and big big step', async () => {
|
||||||
|
const deposits = Array.from(Array(30).keys())
|
||||||
|
publicArray = await PublicArray.deploy()
|
||||||
|
await publicArray.setDeposits(deposits)
|
||||||
|
const depositsLength = await tornadoTrees.findArrayLength(publicArray.address, 'deposits(uint256)', 1, 50)
|
||||||
|
expect(depositsLength).to.be.equal(deposits.length)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user