From 7a566182d5facb53fb2bdc4d6a3f8e5d990abe1e Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Tue, 25 Mar 2025 09:51:28 +0100 Subject: [PATCH] marketplace: re-instate currentCollateral() So that a storage provider can know how much collateral is returned when it calls freeSlot() --- contracts/Marketplace.sol | 13 ++++++++++++- test/Marketplace.test.js | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/contracts/Marketplace.sol b/contracts/Marketplace.sol index ceaf09d..4f3fe34 100644 --- a/contracts/Marketplace.sol +++ b/contracts/Marketplace.sol @@ -67,9 +67,10 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { } struct Slot { - SlotState state; RequestId requestId; uint64 slotIndex; + uint128 currentCollateral; + SlotState state; address host; } @@ -100,6 +101,10 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { return _vault; } + function currentCollateral(SlotId slotId) public view returns (uint128) { + return _slots[slotId].currentCollateral; + } + function requestStorage(Request calldata request) public { RequestId id = request.id(); @@ -216,6 +221,8 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { _vault.designate(fund, hostAccount, designated); _vault.flow(fund, clientAccount, hostAccount, rate); + slot.currentCollateral = collateral; + _addToMySlots(slot.host, slotId); slot.state = SlotState.Filled; @@ -331,6 +338,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { _vault.designate(fund, validatorAccount, validatorReward); _vault.burnDesignated(fund, hostAccount, slashedAmount - validatorReward); + slot.currentCollateral -= slashedAmount; if (missingProofs(slotId) >= _config.collateral.maxNumberOfSlashes) { // When the number of slashings is at or above the allowed amount, // free the slot. @@ -360,6 +368,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { _removeFromMySlots(slot.host, slotId); _reservations[slotId].clear(); // We purge all the reservations for the slot slot.state = SlotState.Repair; + slot.currentCollateral = 0; slot.host = address(0); context.slotsFilled -= 1; emit SlotFreed(requestId, slot.slotIndex); @@ -385,6 +394,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { Request storage request = _requests[requestId]; context.state = RequestState.Finished; Slot storage slot = _slots[slotId]; + slot.currentCollateral = 0; _removeFromMyRequests(request.client, requestId); _removeFromMySlots(slot.host, slotId); @@ -406,6 +416,7 @@ contract Marketplace is SlotReservations, Proofs, StateRetrieval, Endian { SlotId slotId ) private requestIsKnown(requestId) { Slot storage slot = _slots[slotId]; + slot.currentCollateral = 0; _removeFromMySlots(slot.host, slotId); FundId fund = requestId.asFundId(); AccountId account = _vault.hostAccount(slot.host, slot.slotIndex); diff --git a/test/Marketplace.test.js b/test/Marketplace.test.js index fac7f66..77595a9 100644 --- a/test/Marketplace.test.js +++ b/test/Marketplace.test.js @@ -327,6 +327,13 @@ describe("Marketplace", function () { }) }) + it("updates the slot's current collateral", async function () { + await marketplace.reserveSlot(slot.request, slot.index) + await marketplace.fillSlot(slot.request, slot.index, proof) + const collateral = await marketplace.currentCollateral(slotId(slot)) + expect(collateral).to.equal(collateralPerSlot(request)) + }) + it("fails to retrieve a request of an empty slot", async function () { expect(marketplace.getActiveSlot(slotId(slot))).to.be.revertedWith( "Marketplace_SlotIsFree" @@ -583,6 +590,12 @@ describe("Marketplace", function () { await token.approve(marketplace.address, collateral) await marketplace.fillSlot(slot.request, slot.index, proof) }) + + it("updates the slot's current collateral", async function () { + await waitUntilStarted(marketplace, request, proof, token) + await marketplace.freeSlot(id) + expect(await marketplace.currentCollateral(id)).to.equal(0) + }) }) describe("paying out a slot", function () { @@ -637,6 +650,21 @@ describe("Marketplace", function () { expect(endBalance - startBalance).to.be.equal(expectedPartialPayout) }) + it("updates the collateral when freeing a finished slot", async function () { + await waitUntilStarted(marketplace, request, proof, token) + await waitUntilFinished(marketplace, requestId(request)) + await marketplace.freeSlot(slotId(slot)) + expect(await marketplace.currentCollateral(slotId(slot))).to.equal(0) + }) + + it("updates the collateral when freeing a cancelled slot", async function () { + await marketplace.reserveSlot(slot.request, slot.index) + await marketplace.fillSlot(slot.request, slot.index, proof) + await waitUntilCancelled(marketplace, request) + await marketplace.freeSlot(slotId(slot)) + expect(await marketplace.currentCollateral(slotId(slot))).to.equal(0) + }) + it("does not pay when the contract hasn't ended", async function () { await marketplace.reserveSlot(slot.request, slot.index) await marketplace.fillSlot(slot.request, slot.index, proof) @@ -1191,7 +1219,13 @@ describe("Marketplace", function () { await marketplace.markProofAsMissing(id, missedPeriod) const endBalance = await marketplace.getSlotBalance(id) expect(endBalance).to.equal(startBalance - slashAmount) + }) + it("updates the slot's current collateral", async function () { + await setNextBlockTimestamp(await currentTime()) + await marketplace.markProofAsMissing(id, missedPeriod) + const currentCollateral = await marketplace.currentCollateral(id) + expect(currentCollateral).to.equal(collateral - slashAmount) }) it("rewards validator when marking proof as missing", async function () { @@ -1234,6 +1268,11 @@ describe("Marketplace", function () { expect(await marketplace.getSlotBalance(slotId(slot))).to.equal(0) }) + it("updates the slot's current collateral", async function () { + const collateral = await marketplace.currentCollateral(slotId(slot)) + expect(collateral).to.equal(0) + }) + it("resets missed proof counter", async function () { expect(await marketplace.missingProofs(slotId(slot))).to.equal(0) })