diff --git a/contracts/Marketplace.sol b/contracts/Marketplace.sol index 999a198..9e92634 100644 --- a/contracts/Marketplace.sol +++ b/contracts/Marketplace.sol @@ -94,7 +94,7 @@ contract Marketplace is Collateral, Proofs { slot.requestId = requestId; RequestContext storage context = _context(requestId); context.slotsFilled += 1; - activeSlots[request.client].add(SlotId.unwrap(slotId)); + activeSlots[slot.host].add(SlotId.unwrap(slotId)); emit SlotFilled(requestId, slotIndex, slotId); if (context.slotsFilled == request.ask.slots) { context.state = RequestState.Started; @@ -108,6 +108,7 @@ contract Marketplace is Collateral, Proofs { internal slotMustAcceptProofs(slotId) marketplaceInvariant + // TODO: restrict senders that can call this function { Slot storage slot = _slot(slotId); RequestId requestId = slot.requestId; @@ -120,6 +121,7 @@ contract Marketplace is Collateral, Proofs { _unexpectProofs(_toProofId(slotId)); + activeSlots[slot.host].remove(SlotId.unwrap(slotId)); slot.host = address(0); slot.requestId = RequestId.wrap(0); context.slotsFilled -= 1; @@ -135,6 +137,9 @@ contract Marketplace is Collateral, Proofs { _setProofEnd(_toEndId(requestId), block.timestamp - 1); context.endsAt = block.timestamp - 1; activeRequests[request.client].remove(RequestId.unwrap(requestId)); + // NOTE: not removing any remaining active slots for the host as listing + // values of enumerable set could be too expensive (copies from storage to + // memory) emit RequestFailed(requestId); // TODO: burn all remaining slot collateral (note: slot collateral not @@ -155,6 +160,7 @@ contract Marketplace is Collateral, Proofs { SlotId slotId = _toSlotId(requestId, slotIndex); Slot storage slot = _slot(slotId); require(!slot.hostPaid, "Already paid"); + activeSlots[slot.host].remove(SlotId.unwrap(slotId)); uint256 amount = pricePerSlot(requests[requestId]); funds.sent += amount; funds.balance -= amount; diff --git a/test/Marketplace.test.js b/test/Marketplace.test.js index ff3bfa8..7d50c1b 100644 --- a/test/Marketplace.test.js +++ b/test/Marketplace.test.js @@ -731,4 +731,47 @@ describe("Marketplace", function () { expect(await marketplace.myRequests()).to.deep.equal([]) }) }) + + describe("list of active slots", function () { + beforeEach(async function () { + switchAccount(client) + await token.approve(marketplace.address, price(request)) + await marketplace.requestStorage(request) + switchAccount(host) + await token.approve(marketplace.address, collateral) + await marketplace.deposit(collateral) + }) + + it("adds slot to list when filling slot", async function () { + await marketplace.fillSlot(slot.request, slot.index, proof) + let slot1 = { ...slot, index: slot.index + 1 } + await marketplace.fillSlot(slot.request, slot1.index, proof) + expect(await marketplace.mySlots()).to.deep.equal([ + slotId(slot), + slotId(slot1), + ]) + }) + + it("removes request from list when slot is freed", async function () { + await marketplace.fillSlot(slot.request, slot.index, proof) + let slot1 = { ...slot, index: slot.index + 1 } + await marketplace.fillSlot(slot.request, slot1.index, proof) + await marketplace.freeSlot(slotId(slot)) + expect(await marketplace.mySlots()).to.deep.equal([slotId(slot1)]) + }) + + it("removes all slots from list when request fails", async function () { + await waitUntilStarted(marketplace, request, proof) + await waitUntilFailed(marketplace, request, slot) + let expectedLength = request.ask.slots - (request.ask.maxSlotLoss + 1) + expect((await marketplace.mySlots()).length).to.equal(expectedLength) + }) + + it("removes slots from list when request finishes", async function () { + await waitUntilStarted(marketplace, request, proof) + await waitUntilFinished(marketplace, requestId(request)) + await marketplace.payoutSlot(slot.request, slot.index) + expect(await marketplace.mySlots()).to.not.contain(slotId(slot)) + }) + }) })