From e063041d696963de94d1f78aa5dcb527ae9f649e Mon Sep 17 00:00:00 2001 From: Eric Mastro Date: Thu, 24 Nov 2022 19:32:55 +1100 Subject: [PATCH] WIP: cleanup checkpoint --- contracts/Marketplace.sol | 79 ++++-------- contracts/libs/Debug.sol | 52 ++++---- contracts/libs/Mappings.sol | 212 ++++++++++++++++++++++++++++++++ contracts/libs/ORM2.sol | 233 ------------------------------------ test/Marketplace.test.js | 3 - 5 files changed, 269 insertions(+), 310 deletions(-) create mode 100644 contracts/libs/Mappings.sol delete mode 100644 contracts/libs/ORM2.sol diff --git a/contracts/Marketplace.sol b/contracts/Marketplace.sol index e1cead5..ddc08ef 100644 --- a/contracts/Marketplace.sol +++ b/contracts/Marketplace.sol @@ -8,9 +8,7 @@ import "./Collateral.sol"; import "./Proofs.sol"; import "./libs/SetMap.sol"; import "./libs/Utils.sol"; -import "./libs/ORM2.sol"; - -import "hardhat/console.sol"; // DELETE ME +import "./libs/Mappings.sol"; contract Marketplace is Collateral, Proofs { using EnumerableSet for EnumerableSet.Bytes32Set; @@ -18,7 +16,7 @@ contract Marketplace is Collateral, Proofs { using SetMap for SetMap.Bytes32SetMap; using SetMap for SetMap.AddressBytes32SetMap; using SetMap for SetMap.Bytes32AddressSetMap; - using ORM2 for ORM2.OneToMany; + using Mappings for Mappings.Mapping; type RequestId is bytes32; type SlotId is bytes32; @@ -33,12 +31,12 @@ contract Marketplace is Collateral, Proofs { // ORM.Table private activeRequestsForHosts; // sales SetMap.Bytes32SetMap private activeSlots; // sales - ORM2.OneToMany private activeClientRequests; + Mappings.Mapping private activeClientRequests; // address => RequestId - ORM2.OneToMany private activeHostRequests; + Mappings.Mapping private activeHostRequests; // RequestId => SlotId - ORM2.OneToMany private activeRequestSlots; + Mappings.Mapping private activeRequestSlots; constructor( @@ -58,7 +56,7 @@ contract Marketplace is Collateral, Proofs { function myRequests() public view returns (RequestId[] memory) { uint256 counter = 0; bytes32[] storage requestIds = - activeClientRequests.getManyKeys(_toBytes32(msg.sender)); + activeClientRequests.getValueIds(_toBytes32(msg.sender)); bytes32[] memory result = new bytes32[](requestIds.length); for (uint8 i = 0; i < requestIds.length; i++) { // There may exist slots that are still "active", but are part of a request @@ -81,15 +79,13 @@ contract Marketplace is Collateral, Proofs { returns (SlotId[] memory) { uint256 counter = 0; - uint256 totalSlots = activeRequestSlots.getTotalManyCount(); // set this bigger than our possible filtered list size - console.log("[mySlots] total slotIds: ", totalSlots); + uint256 totalSlots = activeRequestSlots.getManyCount(); // set this bigger than our possible filtered list size if (totalSlots == 0) { return new SlotId[](0); } bytes32[] memory result = new bytes32[](totalSlots); bytes32[] storage requestIds = - activeHostRequests.getManyKeys(_toBytes32(msg.sender)); - console.log("[mySlots] total requestIds: ", requestIds.length); + activeHostRequests.getValueIds(_toBytes32(msg.sender)); for (uint256 i = 0; i < requestIds.length; i++) { // There may exist slots that are still "active", but are part of a request // that is expired but has not been set to the cancelled state yet. In that @@ -99,11 +95,8 @@ contract Marketplace is Collateral, Proofs { if (_isCancelled(RequestId.wrap(requestId))) { continue; } - if (activeRequestSlots.isOne(requestIds[i])) { - bytes32[] storage slotIds = activeRequestSlots.getManyKeys(requestIds[i]); - console.log("[mySlots] requestId: "); - console.logBytes32(requestIds[i]); - console.log("[mySlots] total slotsIds for requestId: ", slotIds.length); + if (activeRequestSlots.keyExists(requestIds[i])) { + bytes32[] storage slotIds = activeRequestSlots.getValueIds(requestIds[i]); for (uint256 j = 0; j < slotIds.length; j++) { result[counter] = slotIds[j]; counter++; @@ -133,15 +126,10 @@ contract Marketplace is Collateral, Proofs { _setProofEnd(_toEndId(id), context.endsAt); bytes32 addrBytes32 = _toBytes32(request.client); - if (!activeClientRequests.isOne(addrBytes32)) { - activeClientRequests.createOne(addrBytes32); - } - if (!activeClientRequests.isMany(RequestId.unwrap(id))) { - activeClientRequests.createMany(addrBytes32, RequestId.unwrap(id)); - } + activeClientRequests.insert(addrBytes32, RequestId.unwrap(id)); - if (!activeRequestSlots.isOne(RequestId.unwrap(id))) { - activeRequestSlots.createOne(RequestId.unwrap(id)); + if (!activeRequestSlots.keyExists(RequestId.unwrap(id))) { + activeRequestSlots.insertKey(RequestId.unwrap(id)); } _createLock(_toLockId(id), request.expiry); @@ -179,22 +167,12 @@ contract Marketplace is Collateral, Proofs { RequestContext storage context = _context(requestId); context.slotsFilled += 1; - console.log("FILLING slotId: "); - console.logBytes32(SlotId.unwrap(slotId)); - bytes32 sender = _toBytes32(msg.sender); - if (!activeHostRequests.isOne(sender)) { - activeHostRequests.createOne(sender); - } // address => RequestId - if (!activeHostRequests.isMany(RequestId.unwrap(requestId))) { - activeHostRequests.createMany(sender, RequestId.unwrap(requestId)); - } + activeHostRequests.insert(sender, RequestId.unwrap(requestId)); // RequestId => SlotId - if (!activeRequestSlots.isMany(SlotId.unwrap(slotId))) { - activeRequestSlots.createMany(RequestId.unwrap(requestId), SlotId.unwrap(slotId)); - } + activeRequestSlots.insert(RequestId.unwrap(requestId), SlotId.unwrap(slotId)); emit SlotFilled(requestId, slotIndex, slotId); if (context.slotsFilled == request.ask.slots) { @@ -222,10 +200,8 @@ contract Marketplace is Collateral, Proofs { _unexpectProofs(_toProofId(slotId)); - console.log("FREEING slotId: "); - console.logBytes32(SlotId.unwrap(slotId)); - if (activeRequestSlots.isMany(SlotId.unwrap(slotId))) { - activeRequestSlots.deleteMany(SlotId.unwrap(slotId)); + if (activeRequestSlots.valueExists(SlotId.unwrap(slotId))) { + activeRequestSlots.deleteValue(SlotId.unwrap(slotId)); } slot.host = address(0); slot.requestId = RequestId.wrap(0); @@ -241,11 +217,8 @@ contract Marketplace is Collateral, Proofs { context.state = RequestState.Failed; _setProofEnd(_toEndId(requestId), block.timestamp - 1); context.endsAt = block.timestamp - 1; - console.log("about to delete many"); - activeClientRequests.deleteMany(RequestId.unwrap(requestId)); - console.log("about to clear all manys"); - activeRequestSlots.clearAllManys(RequestId.unwrap(requestId)); - console.log("about to cleared all manys"); + activeClientRequests.deleteValue(RequestId.unwrap(requestId)); + activeRequestSlots.clearValues(RequestId.unwrap(requestId)); emit RequestFailed(requestId); // TODO: burn all remaining slot collateral (note: slot collateral not @@ -262,16 +235,16 @@ contract Marketplace is Collateral, Proofs { RequestContext storage context = _context(requestId); // Request storage request = _request(requestId); context.state = RequestState.Finished; - if (activeClientRequests.isMany(RequestId.unwrap(requestId))) { - activeClientRequests.deleteMany(RequestId.unwrap(requestId)); + if (activeClientRequests.valueExists(RequestId.unwrap(requestId))) { + activeClientRequests.deleteValue(RequestId.unwrap(requestId)); } SlotId slotId = _toSlotId(requestId, slotIndex); Slot storage slot = _slot(slotId); require(!slot.hostPaid, "Already paid"); - activeRequestSlots.deleteMany(SlotId.unwrap(slotId)); + activeRequestSlots.deleteValue(SlotId.unwrap(slotId)); if (activeRequestSlots.getManyCount() == 0) { - activeRequestSlots.deleteOne(RequestId.unwrap(requestId)); - activeHostRequests.deleteMany(RequestId.unwrap(requestId)); + activeRequestSlots.deleteKey(RequestId.unwrap(requestId)); + activeHostRequests.deleteValue(RequestId.unwrap(requestId)); } uint256 amount = pricePerSlot(requests[requestId]); funds.sent += amount; @@ -293,9 +266,9 @@ contract Marketplace is Collateral, Proofs { // Update request state to Cancelled. Handle in the withdraw transaction // as there needs to be someone to pay for the gas to update the state context.state = RequestState.Cancelled; - activeClientRequests.deleteMany(RequestId.unwrap(requestId)); + activeClientRequests.deleteValue(RequestId.unwrap(requestId)); - activeRequestSlots.clearAllManys(RequestId.unwrap(requestId)); + activeRequestSlots.clearValues(RequestId.unwrap(requestId)); // TODO: handle dangling RequestId in activeHostRequests (for address) emit RequestCancelled(requestId); diff --git a/contracts/libs/Debug.sol b/contracts/libs/Debug.sol index e3e164d..1ddcde0 100644 --- a/contracts/libs/Debug.sol +++ b/contracts/libs/Debug.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.8; -import "./ORM2.sol"; +import "./Mappings.sol"; import "hardhat/console.sol"; // DELETE ME library Debug { @@ -26,35 +26,45 @@ library Debug { return string (abi.encodePacked ("0x", _toHex16 (bytes16 (data)), _toHex16 (bytes16 (data << 128)))); } - // @notice Prints the contents of the one-to-many table - // Usage example (from ORM): Debug._printTable(db._oneList, - // getManyKeys(db, oneId), - // getTotalManyCount(db)); - // @dev Explain to a developer any extra details - // @param oneList list of one ids - // @param manyKeys list of one ids - // @param totalManyCount list of one ids - // function _printTable(bytes32[] storage oneList, - // bytes32[] storage manyKeys, - // uint256 totalManyCount) - function _printTable(ORM2.OneToMany storage db) + /// Prints contents of mapping, eg: + /// |-----------------------------------------------------------------------------------------------------------------------------------------| + /// | Key | Value | + /// | ------------------------------------------------------------------ | ------------------------------------------------------------------ | + /// | 0x53D746B6815B837EFBA3C26A4330F442632016E3C91DE8AB01B96AC7DF46FB9C | | + /// | | 0x79A8114055CCBC6FC73B36443E970318D607301126CD5C0B28952D7703079282 | + /// | 0xB229F333E9967EC6B91027ADEB6BD4FAB57E56E4383737A2778CA9AE826E222D | | + /// | | 0x7B7751C5591B3B6691A98FE57334D044BEDEC1F1748DF39637B2FD38B69C60E4 | + /// | | 0xA0F0D711FD9D1D71E328ED76D2B2B2F2F56C0FF17535FAA55087F7A52F048B51 | + /// | | 0x5248D5C5BC2A6D395C07F4A99E27D2BDD9F643C009BA59CA2C39AB5534F740E8 | + /// | | 0x002CAD0D878B163AD63EE9C098391A6F9443CD3D48916C4E63A2485F832BE57F | + /// |_________________________________________________________________________________________________________________________________________| + /// Referenced values: 4 + /// Unreferenced values: 1 + /// TOTAL Values: 5 + function _printTable(Mappings.Mapping storage db, string memory message) internal view { + console.log(message); console.log("|-----------------------------------------------------------------------------------------------------------------------------------------|"); console.log("| Key | Value |"); console.log("| ------------------------------------------------------------------ | ------------------------------------------------------------------ |"); - for(uint8 i = 0; i < db._oneList.length; i++) { - bytes32 oneId = db._oneList[i]; - console.log("|", _toHex(oneId), "| |"); + uint256 referencedValues = 0; + for(uint8 i = 0; i < db._keyIds.length; i++) { + bytes32 keyId = db._keyIds[i]; + console.log("|", _toHex(keyId), "| |"); - bytes32[] storage manyKeys = ORM2.getManyKeys(db, oneId); - for(uint8 j = 0; j < manyKeys.length; j++) { - bytes32 slotId = manyKeys[j]; - console.log("| |", _toHex(slotId), "|"); + bytes32[] storage valueIds = Mappings.getValueIds(db, keyId); + for(uint8 j = 0; j < valueIds.length; j++) { + bytes32 valueId = valueIds[j]; + console.log("| |", _toHex(valueId), "|"); } + referencedValues += valueIds.length; } console.log("|_________________________________________________________________________________________________________________________________________|"); - console.log(" TOTAL Values: ", ORM2.getTotalManyCount(db)); + console.log(" Referenced values: ", referencedValues); + uint256 totalValues = Mappings.getManyCount(db); + console.log(" Unreferenced values: ", totalValues - referencedValues, " (total values not deleted but are unused)"); + console.log(" TOTAL Values: ", totalValues); } } diff --git a/contracts/libs/Mappings.sol b/contracts/libs/Mappings.sol new file mode 100644 index 0000000..c01ba92 --- /dev/null +++ b/contracts/libs/Mappings.sol @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: MIT +// heavily inspired by: https://bitbucket.org/rhitchens2/soliditystoragepatterns/src/master/GeneralizedCollection.sol +pragma solidity ^0.8.8; + +import "./Debug.sol"; // DELETE ME + +library Mappings { + // first entity is called a "One" + struct Key { + // needed to delete a "One" + uint256 _oneListPointer; + // One has many "Many" + bytes32[] _valueIds; + mapping(bytes32 => uint256) _valueIdsIndex; // valueId => row of local _valueIds + // more app data + } + + // other entity is called a "Many" + struct Value { + // needed to delete a "Many" + uint256 _valueIdsIndex; + // many has exactly one "One" + bytes32 _keyId; + // add app fields + } + + struct Mapping { + mapping(bytes32 => Key) _keys; + bytes32[] _keyIds; + mapping(bytes32 => Value) _values; + bytes32[] _valueIds; + } + + function keyCount(Mapping storage db) + internal + view + returns(uint256) + { + return db._keyIds.length; + } + + function getManyCount(Mapping storage db) internal view returns(uint256) { + return db._valueIds.length; + } + + function getManyCount(Mapping storage db, bytes32 keyId) + internal + view + returns(uint256 manyCount) + { + require(keyExists(db, keyId), "key does not exist"); + return _getValueIds(db, keyId).length; + } + + function keyExists(Mapping storage db, bytes32 keyId) + internal + view + returns(bool) + { + if(keyCount(db) == 0) return false; + return db._keyIds[db._keys[keyId]._oneListPointer] == keyId; + } + + function valueExists(Mapping storage db, bytes32 valueId) + internal + view + returns(bool) + { + if(getManyCount(db) == 0) return false; + uint256 row = db._values[valueId]._valueIdsIndex; + bool retVal = db._valueIds[row] == valueId; + return retVal; + } + + function _getValueIds(Mapping storage db, + bytes32 keyId) + internal + view + returns(bytes32[] storage) + { + require(keyExists(db, keyId), "key does not exist"); + return db._keys[keyId]._valueIds; + } + + function getValueIds(Mapping storage db, + bytes32 keyId) + internal + view + returns(bytes32[] storage) + { + require(keyExists(db, keyId), "key does not exist"); + return _getValueIds(db, keyId); + } + + // Insert + function insertKey(Mapping storage db, bytes32 keyId) + internal + returns(bool) + { + require(!keyExists(db, keyId), "key already exists"); // duplicate key prohibited + + db._keyIds.push(keyId); + db._keys[keyId]._oneListPointer = keyCount(db) - 1; + return true; + } + + function insertValue(Mapping storage db, bytes32 keyId, bytes32 valueId) + internal + returns(bool) + { + require(keyExists(db, keyId), "key does not exist"); + require(!valueExists(db, valueId), "value already exists"); // duplicate key prohibited + + Value storage value = db._values[valueId]; + db._valueIds.push(valueId); + value._valueIdsIndex = getManyCount(db) - 1; + value._keyId = keyId; // each many has exactly one "One", so this is mandatory + + // We also maintain a list of "Many" that refer to the "One", so ... + Key storage key = db._keys[keyId]; + key._valueIds.push(valueId); + key._valueIdsIndex[valueId] = key._valueIds.length - 1; + return true; + } + + function insert(Mapping storage db, bytes32 keyId, bytes32 valueId) + internal + returns(bool success) + { + if (!keyExists(db, keyId)) { + success = insertKey(db, keyId); + if (!success) { + return false; + } + } + if (!valueExists(db, valueId)) { + success = insertValue(db, keyId, valueId); + } + return success; + } + + + // Delete + function deleteKey(Mapping storage db, bytes32 keyId) + internal + returns(bool) + { + require(keyExists(db, keyId), "key does not exist"); + require(_getValueIds(db, keyId).length == 0, "references manys"); // this would break referential integrity + + uint256 rowToDelete = db._keys[keyId]._oneListPointer; + bytes32 keyToMove = db._keyIds[keyCount(db)-1]; + db._keyIds[rowToDelete] = keyToMove; + db._keys[keyToMove]._oneListPointer = rowToDelete; + db._keyIds.pop(); + delete db._keys[keyId]; + return true; + } + + function deleteValue(Mapping storage db, bytes32 valueId) + internal + returns(bool) + { + require(valueExists(db, valueId), "value does not exist"); // non-existant key + + // delete from the Many table + uint256 toDeleteIndex = db._values[valueId]._valueIdsIndex; + + uint256 lastIndex = getManyCount(db) - 1; + + if (lastIndex != toDeleteIndex) { + bytes32 lastValue = db._valueIds[lastIndex]; + + // Move the last value to the index where the value to delete is + db._valueIds[toDeleteIndex] = lastValue; + // Update the index for the moved value + db._values[lastValue]._valueIdsIndex = toDeleteIndex; // Replace lastvalue's index to valueIndex + } + db._valueIds.pop(); + + bytes32 keyId = db._values[valueId]._keyId; + Key storage oneRow = db._keys[keyId]; + toDeleteIndex = oneRow._valueIdsIndex[valueId]; + lastIndex = oneRow._valueIds.length - 1; + if (lastIndex != toDeleteIndex) { + bytes32 lastValue = oneRow._valueIds[lastIndex]; + + // Move the last value to the index where the value to delete is + oneRow._valueIds[toDeleteIndex] = lastValue; + // Update the index for the moved value + oneRow._valueIdsIndex[lastValue] = toDeleteIndex; // Replace lastvalue's index to valueIndex + } + oneRow._valueIds.pop(); + delete oneRow._valueIdsIndex[valueId]; + delete db._values[valueId]; + return true; + } + + function clearValues(Mapping storage db, bytes32 keyId) + internal + returns(bool) + { + require(keyExists(db, keyId), "key does not exist"); // non-existant key + + Debug._printTable(db, "[clearValues] BEFORE clearing"); + // delete db._valueIds; + delete db._keys[keyId]._valueIds; + bool result = deleteKey(db, keyId); + Debug._printTable(db, "[clearValues] AFTER clearing"); + return result; + } +} diff --git a/contracts/libs/ORM2.sol b/contracts/libs/ORM2.sol deleted file mode 100644 index 224715a..0000000 --- a/contracts/libs/ORM2.sol +++ /dev/null @@ -1,233 +0,0 @@ -// SPDX-License-Identifier: MIT -// heavily inspired by: https://bitbucket.org/rhitchens2/soliditystoragepatterns/src/master/GeneralizedCollection.sol -pragma solidity ^0.8.8; - -import "hardhat/console.sol"; -import "./Debug.sol"; // DELETE ME - -library ORM2 { - // first entity is called a "One" - struct OneStruct { - // needed to delete a "One" - uint _oneListPointer; - // One has many "Many" - bytes32[] _manyIds; - mapping(bytes32 => uint) _manyIdPointers; // manyId => row of _manyIds - // more app data - } - - // other entity is called a "Many" - struct ManyStruct { - // needed to delete a "Many" - uint _manyListPointer; - // many has exactly one "One" - bytes32 _oneId; - // add app fields - } - - struct OneToMany { - mapping(bytes32 => OneStruct) _oneStructs; - bytes32[] _oneList; - mapping(bytes32 => ManyStruct) _manyStructs; - bytes32[] _manyList; - } - - function getOneCount(OneToMany storage db) - internal - view - returns(uint) - { - return db._oneList.length; - } - - function getManyCount(OneToMany storage db) internal view returns(uint) { - return db._manyList.length; - } - - function isOne(OneToMany storage db, bytes32 oneId) - internal - view - returns(bool) - { - if(db._oneList.length == 0) return false; - return db._oneList[db._oneStructs[oneId]._oneListPointer] == oneId; - } - - function isMany(OneToMany storage db, bytes32 manyId) - internal - view - returns(bool) - { - if(db._manyList.length == 0) return false; - uint256 row = db._manyStructs[manyId]._manyListPointer; - bool retVal = db._manyList[row] == manyId; - return retVal; - } - - // Iterate over a One's Many keys - function getManyCount(OneToMany storage db, bytes32 oneId) - internal - view - returns(uint manyCount) - { - require(isOne(db, oneId), "oneId does not exist"); - return db._oneStructs[oneId]._manyIds.length; - } - - function getTotalManyCount(OneToMany storage db) - internal - view - returns(uint manyCount) - { - return db._manyList.length; - } - - function getManyKeyAtIndex(OneToMany storage db, - bytes32 oneId, - uint row) - internal - view - returns(bytes32 manyKey) - { - require(isOne(db, oneId), "oneId does not exist"); - return db._oneStructs[oneId]._manyIds[row]; - } - - function getManyKeys(OneToMany storage db, - bytes32 oneId) - internal - view - returns(bytes32[] storage manyKeys) - { - require(isOne(db, oneId), "oneId does not exist"); - return db._oneStructs[oneId]._manyIds; - } - - // Insert - function createOne(OneToMany storage db, bytes32 oneId) - internal - returns(bool) - { - require(!isOne(db, oneId), "oneId already exists"); // duplicate key prohibited - - db._oneList.push(oneId); - db._oneStructs[oneId]._oneListPointer = getOneCount(db) - 1; - return true; - } - - function createMany(OneToMany storage db, bytes32 oneId, bytes32 manyId) - internal - returns(bool) - { - require(isOne(db, oneId), "oneId does not exist"); - require(!isMany(db, manyId), "manyId already exists"); // duplicate key prohibited - - ManyStruct storage manyRow = db._manyStructs[manyId]; - db._manyList.push(manyId); - manyRow._manyListPointer = db._manyList.length - 1; - manyRow._oneId = oneId; // each many has exactly one "One", so this is mandatory - - // We also maintain a list of "Many" that refer to the "One", so ... - OneStruct storage oneRow = db._oneStructs[oneId]; - oneRow._manyIds.push(manyId); - oneRow._manyIdPointers[manyId] = oneRow._manyIds.length - 1; - return true; - } - - // Delete - function deleteOne(OneToMany storage db, bytes32 oneId) - internal - returns(bool) - { - require(isOne(db, oneId), "oneId does not exist"); - require(db._oneStructs[oneId]._manyIds.length == 0, "references manys"); // this would break referential integrity - - uint rowToDelete = db._oneStructs[oneId]._oneListPointer; - bytes32 keyToMove = db._oneList[db._oneList.length-1]; - db._oneList[rowToDelete] = keyToMove; - db._oneStructs[keyToMove]._oneListPointer = rowToDelete; - db._oneList.pop(); - delete db._oneStructs[oneId]; - return true; - } - - function deleteMany(OneToMany storage db, bytes32 manyId) - internal - returns(bool) - { - require(isMany(db, manyId), "manys do not exist"); // non-existant key - - console.log("deleting many, manyId: "); - console.logBytes32(manyId); - // delete from the Many table - uint256 toDeleteIndex = db._manyStructs[manyId]._manyListPointer; - - uint256 lastIndex = db._manyList.length - 1; - - if (lastIndex != toDeleteIndex) { - bytes32 lastValue = db._manyList[lastIndex]; - - // Move the last value to the index where the value to delete is - db._manyList[toDeleteIndex] = lastValue; - // Update the index for the moved value - db._manyStructs[lastValue]._manyListPointer = toDeleteIndex; // Replace lastvalue's index to valueIndex - } - db._manyList.pop(); - - bytes32 oneId = db._manyStructs[manyId]._oneId; - OneStruct storage oneRow = db._oneStructs[oneId]; - toDeleteIndex = oneRow._manyIdPointers[manyId]; - lastIndex = oneRow._manyIds.length - 1; - if (lastIndex != toDeleteIndex) { - bytes32 lastValue = oneRow._manyIds[lastIndex]; - - // Move the last value to the index where the value to delete is - oneRow._manyIds[toDeleteIndex] = lastValue; - // Update the index for the moved value - oneRow._manyIdPointers[lastValue] = toDeleteIndex; // Replace lastvalue's index to valueIndex - } - oneRow._manyIds.pop(); - delete oneRow._manyIdPointers[manyId]; - - delete db._manyStructs[manyId]; - - - - // uint rowToDelete = db._manyStructs[manyId]._manyListPointer; - // console.log("row to delete: ", rowToDelete); - // bytes32 keyToMove = db._manyList[db._manyList.length-1]; - // db._manyList[rowToDelete] = keyToMove; - // uint rowToMove = db._manyStructs[keyToMove]._manyListPointer; - // db._manyStructs[manyId]._manyListPointer = rowToDelete; - // db._manyStructs[keyToMove]._manyListPointer = rowToMove; - // db._manyList.pop(); - - // we ALSO have to delete this key from the list in the ONE that was joined to this Many - // bytes32 oneId = db._manyStructs[manyId]._oneId; // it's still there, just not dropped from index - // rowToDelete = db._oneStructs[oneId]._manyIdPointers[manyId]; - // keyToMove = db._oneStructs[oneId]._manyIds[db._oneStructs[oneId]._manyIds.length-1]; - // db._oneStructs[oneId]._manyIds[rowToDelete] = keyToMove; - // db._oneStructs[oneId]._manyIdPointers[keyToMove] = rowToDelete; - // db._oneStructs[oneId]._manyIds.pop(); - return true; - } - - - - function clearAllManys(OneToMany storage db, bytes32 oneId) - internal - returns(bool) - { - require(isOne(db, oneId), "oneId does not exist"); // non-existant key - - console.log("[clearAllMany] clearing all slotIds for requestId: ", Debug._toHex(oneId)); - console.log("[clearAllMany] BEFORE clearing"); - Debug._printTable(db); - // delete db._manyList; - delete db._oneStructs[oneId]._manyIds; - bool result = deleteOne(db, oneId); - console.log("[clearAllMany] AFTER clearing"); - Debug._printTable(db); - return result; - } -} diff --git a/test/Marketplace.test.js b/test/Marketplace.test.js index b113cc9..a9af23b 100644 --- a/test/Marketplace.test.js +++ b/test/Marketplace.test.js @@ -811,9 +811,6 @@ describe("Marketplace", function () { // wait until first request fails await waitUntilFailed(marketplace, request, slot) - console.log("1st requestId: ", requestId(request)) - console.log("2nd requestId: ", requestId(request2)) - // check that our active slots only contains slotIds from second request let expected = [] let expectedSlot = { ...slot, index: 0, request: requestId(request2) }