update search

This commit is contained in:
poma 2021-02-10 09:26:10 +03:00
parent 31d48c2b57
commit 30f029ff04
No known key found for this signature in database
GPG Key ID: BA20CB01FE165657

@ -81,12 +81,11 @@ contract TornadoTrees is EnsResolve {
treeUpdateVerifier = _treeUpdateVerifier; treeUpdateVerifier = _treeUpdateVerifier;
tornadoTreesV1 = _tornadoTreesV1; tornadoTreesV1 = _tornadoTreesV1;
depositRoot = _tornadoTreesV1.depositRoot();
withdrawalRoot = _tornadoTreesV1.withdrawalRoot();
uint256 depositLeaf = _tornadoTreesV1.lastProcessedDepositLeaf(); depositRoot = _tornadoTreesV1.depositRoot();
require(depositLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees state"); uint256 lastDepositLeaf = _tornadoTreesV1.lastProcessedDepositLeaf();
lastProcessedDepositLeaf = depositLeaf; require(lastDepositLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees state");
lastProcessedDepositLeaf = lastDepositLeaf;
depositsLength = depositV1Length = findArrayLength( depositsLength = depositV1Length = findArrayLength(
_tornadoTreesV1, _tornadoTreesV1,
"deposits(uint256)", "deposits(uint256)",
@ -94,9 +93,10 @@ contract TornadoTrees is EnsResolve {
_searchParams.depositsPerDay _searchParams.depositsPerDay
); );
uint256 withdrawalLeaf = _tornadoTreesV1.lastProcessedWithdrawalLeaf(); withdrawalRoot = _tornadoTreesV1.withdrawalRoot();
require(withdrawalLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees state"); uint256 lastWithdrawalLeaf = _tornadoTreesV1.lastProcessedWithdrawalLeaf();
lastProcessedWithdrawalLeaf = withdrawalLeaf; require(lastWithdrawalLeaf % CHUNK_SIZE == 0, "Incorrect TornadoTrees state");
lastProcessedWithdrawalLeaf = lastWithdrawalLeaf;
withdrawalsLength = withdrawalsV1Length = findArrayLength( withdrawalsLength = withdrawalsV1Length = findArrayLength(
_tornadoTreesV1, _tornadoTreesV1,
"withdrawals(uint256)", "withdrawals(uint256)",
@ -105,23 +105,25 @@ contract TornadoTrees is EnsResolve {
); );
} }
// todo make things internal. Think of dedundant calls // todo make things internal
/// @dev There is no array length getter for deposit and withdrawal arrays
/// in previous contract, so we have to find them length manually
function findArrayLength( function findArrayLength(
ITornadoTreesV1 _tornadoTreesV1, ITornadoTreesV1 _tornadoTreesV1,
string memory _type, string memory _type,
uint256 _from, uint256 _from, // most likely array length after the proposal has passed
uint256 _step uint256 _step // optimal step size to find first match, approximately equals dispersion
) public view returns (uint256) { ) public view returns (uint256) {
require(_from != 0 && _step != 0, "_from and _step should be > 0");
// require(elementExists(_tornadoTreesV1, _type, _from), "Inccorrect _from param");
uint256 index = _from + _step; // Find the segment with correct array length
while (elementExists(_tornadoTreesV1, _type, index)) { bool direction = elementExists(_tornadoTreesV1, _type, _from);
index = index + _step; do {
} _from = direction ? _from + _step : _from - _step; // safe math?
} while (direction == elementExists(_tornadoTreesV1, _type, _from));
uint256 high = direction ? _from : _from + _step;
uint256 low = direction ? _from - _step : _from;
uint256 high = index; // Perform a binary search on this segment
uint256 low = index - _step;
uint256 lastIndex = binarySearch(_tornadoTreesV1, _type, high, low); uint256 lastIndex = binarySearch(_tornadoTreesV1, _type, high, low);
return lastIndex + 1; return lastIndex + 1;
@ -133,34 +135,24 @@ contract TornadoTrees is EnsResolve {
uint256 _high, uint256 _high,
uint256 _low uint256 _low
) public view returns (uint256) { ) public view returns (uint256) {
require(_high >= _low, "Incorrect params");
uint256 mid = (_high + _low) / 2; uint256 mid = (_high + _low) / 2;
(bool isLast, bool exists) = isLastElement(_tornadoTreesV1, _type, mid); if (mid == _low) {
if (isLast) {
return mid; return mid;
} }
if (exists) { if (elementExists(_tornadoTreesV1, _type, mid)) {
return binarySearch(_tornadoTreesV1, _type, _high, mid + 1); return binarySearch(_tornadoTreesV1, _type, _high, mid);
} else { } else {
return binarySearch(_tornadoTreesV1, _type, mid - 1, _low); return binarySearch(_tornadoTreesV1, _type, mid, _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(
ITornadoTreesV1 _tornadoTreesV1, ITornadoTreesV1 _tornadoTreesV1,
string memory _type, string memory _type,
uint256 index uint256 index
) public view returns (bool success) { ) public view returns (bool success) {
// Try to get the element. If it succeeds array the length is higher, it it reverts the length is equal or lower
(success, ) = address(_tornadoTreesV1).staticcall{ gas: 2500 }(abi.encodeWithSignature(_type, index)); (success, ) = address(_tornadoTreesV1).staticcall{ gas: 2500 }(abi.encodeWithSignature(_type, index));
} }