From 0ffe5d7697dc614657056cf0aa48908af66f3c0d Mon Sep 17 00:00:00 2001 From: Eric Mastro Date: Wed, 21 Sep 2022 19:18:52 +1000 Subject: [PATCH] [marketplace] free slot after too many proofs missed Needs tests --- contracts/AccountLocks.sol | 19 +++++++++++++++++++ contracts/Collateral.sol | 6 ++++++ contracts/Marketplace.sol | 23 +++++++++++++++++++++++ contracts/Proofs.sol | 1 + contracts/Storage.sol | 1 - 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/contracts/AccountLocks.sol b/contracts/AccountLocks.sol index 65fecab..5c9ed72 100644 --- a/contracts/AccountLocks.sol +++ b/contracts/AccountLocks.sol @@ -64,6 +64,25 @@ contract AccountLocks { require(accountLocks.length == 0, "Account locked"); } + /// Removes an account lock + function _removeAccountLock(address account, bytes32 lockId) internal { + require(accounts[account].locks.length > 0, "Account lock doesn't exist"); + bytes32[] storage accountLocks = accounts[account].locks; + uint256 index = 0; + while (true) { + if (index >= accountLocks.length) { + return; + } + if (accountLocks[index] == lockId) { + accountLocks[index] = accountLocks[accountLocks.length - 1]; + accountLocks.pop(); + } else { + index++; + } + } + + } + function removeInactiveLocks(bytes32[] storage lockIds) private { uint256 index = 0; while (true) { diff --git a/contracts/Collateral.sol b/contracts/Collateral.sol index efca0da..015af31 100644 --- a/contracts/Collateral.sol +++ b/contracts/Collateral.sol @@ -51,6 +51,12 @@ contract Collateral is AccountLocks { internal collateralInvariant { + // TODO: perhaps we need to add a minCollateral parameter so that + // a host's collateral can't drop below a certain amount, possibly + // preventing malicious behaviour when collateral drops too low for it + // to matter that it will be lost. Also, we need collateral to be high + // enough to cover repair costs in case of repair as well as marked + // proofs as missing fees. uint256 amount = (balanceOf(account) * percentage) / 100; funds.slashed += amount; subtract(account, amount); diff --git a/contracts/Marketplace.sol b/contracts/Marketplace.sol index 2c076ac..e1392f7 100644 --- a/contracts/Marketplace.sol +++ b/contracts/Marketplace.sol @@ -47,6 +47,29 @@ contract Marketplace is Collateral, Proofs { emit StorageRequested(id, request.ask); } + function _freeSlot( + bytes32 slotId + ) internal marketplaceInvariant { + bytes32 requestId = _getRequestIdForSlot(slotId); + RequestContext storage context = requestContexts[requestId]; + require(context.state == RequestState.Started, "Invalid state"); + require(!_isCancelled(requestId), "Request cancelled"); + + Slot storage slot = _slot(slotId); + require(slot.host != address(0), "Slot not filled"); + + _removeAccountLock(slot.host, requestId); + // TODO: burn host's collateral except for repair costs + mark proof + // missing reward + + _unexpectProofs(slotId); + + slot.host = address(0); + slot.requestId = 0; + context.slotsFilled -= 1; + emit SlotFreed(requestId, slotId); + } + function fillSlot( bytes32 requestId, uint256 slotIndex, diff --git a/contracts/Proofs.sol b/contracts/Proofs.sol index 0bd0f12..822c1d2 100644 --- a/contracts/Proofs.sol +++ b/contracts/Proofs.sol @@ -118,6 +118,7 @@ contract Proofs { pointer = _getPointer(id, proofPeriod); bytes32 challenge = _getChallenge(pointer); uint256 probability = (probabilities[id] * (256 - downtime)) / 256; + // TODO: add test for below change isRequired = ids[id] && uint256(challenge) % probability == 0; } diff --git a/contracts/Storage.sol b/contracts/Storage.sol index 7699c45..6d9593c 100644 --- a/contracts/Storage.sol +++ b/contracts/Storage.sol @@ -32,7 +32,6 @@ contract Storage is Collateral, Marketplace { collateralAmount = _collateralAmount; slashMisses = _slashMisses; slashPercentage = _slashPercentage; - minCollateralThreshold = _minCollateralThreshold; } function getRequest(bytes32 requestId) public view returns (Request memory) {