add clearing of host slots with MAX_SLOTS boundary
This commit is contained in:
parent
641892ccfa
commit
2aa50eabbf
|
@ -11,11 +11,13 @@ import "./libs/DAL.sol";
|
|||
contract Marketplace is Collateral, Proofs {
|
||||
using DAL for DAL.Database;
|
||||
using EnumerableSet for EnumerableSet.Bytes32Set;
|
||||
using DAL for EnumerableSet.Bytes32Set;
|
||||
|
||||
uint256 public immutable collateral;
|
||||
MarketplaceFunds private funds;
|
||||
mapping(DAL.RequestId => RequestContext) private requestContexts;
|
||||
DAL.Database private db;
|
||||
uint16 private constant MAX_SLOTS = 256;
|
||||
|
||||
constructor(
|
||||
IERC20 _token,
|
||||
|
@ -45,6 +47,8 @@ contract Marketplace is Collateral, Proofs {
|
|||
public
|
||||
marketplaceInvariant
|
||||
{
|
||||
require(request.ask.slots <= MAX_SLOTS, "Max slots exceeded");
|
||||
require(request.ask.maxSlotLoss <= MAX_SLOTS, "Max slot loss exceeded");
|
||||
require(request.client == msg.sender, "Invalid client address");
|
||||
|
||||
DAL.RequestId requestId = _toRequestId(request);
|
||||
|
@ -152,7 +156,14 @@ contract Marketplace is Collateral, Proofs {
|
|||
|
||||
DAL.Client storage client = db.select(request.client);
|
||||
db.remove(client.requests, requestId);
|
||||
db.remove(host.requests, requestId);
|
||||
|
||||
// Remove all request's slots from hosts.slots. This is an expensive
|
||||
// operation as it iterates all slots and removes them one-by-one.
|
||||
// An alternative is to use EnumerableExtensions.ClearableBytes32Set
|
||||
// for host.slots instead, however this would not free any storage
|
||||
// but instead use a new EnumerableSet.Bytes32Set each time it is cleared.
|
||||
db.clearSlots(host, requestId, MAX_SLOTS);
|
||||
|
||||
emit RequestFailed(requestId);
|
||||
|
||||
// TODO: burn all remaining slot collateral (note: slot collateral not
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
pragma solidity ^0.8.8;
|
||||
|
||||
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
||||
import "../Marketplace.sol";
|
||||
import "./Utils.sol";
|
||||
|
||||
library DAL {
|
||||
|
@ -18,18 +17,18 @@ library DAL {
|
|||
struct Client {
|
||||
ClientId id; // PK
|
||||
|
||||
EnumerableSet.Bytes32Set requests;
|
||||
EnumerableSet.Bytes32Set requests; // FKs
|
||||
}
|
||||
|
||||
struct Host {
|
||||
HostId id; // PK
|
||||
|
||||
EnumerableSet.Bytes32Set slots;
|
||||
EnumerableSet.Bytes32Set requests;
|
||||
EnumerableSet.Bytes32Set slots; // FKs
|
||||
EnumerableSet.Bytes32Set requests; // FKs
|
||||
}
|
||||
|
||||
struct Request {
|
||||
RequestId id;
|
||||
RequestId id; // PK
|
||||
ClientId client;
|
||||
Ask ask;
|
||||
Content content;
|
||||
|
@ -40,10 +39,10 @@ library DAL {
|
|||
}
|
||||
|
||||
struct Slot {
|
||||
SlotId id;
|
||||
HostId host;
|
||||
SlotId id; // PK
|
||||
HostId host; // FK
|
||||
bool hostPaid;
|
||||
RequestId requestId;
|
||||
RequestId requestId; // FK
|
||||
}
|
||||
|
||||
struct Ask {
|
||||
|
@ -246,6 +245,8 @@ library DAL {
|
|||
Client storage client = db.clients[request.client];
|
||||
bytes32 bRequestId = RequestId.unwrap(request.id);
|
||||
require(!client.requests.contains(bRequestId), "active request refs");
|
||||
// TODO: iterate all request's hosts and check that host.requests doesn't
|
||||
// have requestId
|
||||
|
||||
delete db.requests[request.id];
|
||||
}
|
||||
|
@ -279,6 +280,8 @@ library DAL {
|
|||
internal
|
||||
{
|
||||
require(exists(db, requestId), "request does not exist");
|
||||
// TODO: check that host.slots doesn't have a slot belonging to the request
|
||||
// being removed
|
||||
|
||||
requests.remove(RequestId.unwrap(requestId));
|
||||
}
|
||||
|
@ -293,6 +296,26 @@ library DAL {
|
|||
slots.remove(SlotId.unwrap(slotId));
|
||||
}
|
||||
|
||||
// WARNING: this may cause a transaction to run out of gas!
|
||||
function clearSlots(Database storage db,
|
||||
Host storage host,
|
||||
RequestId requestId,
|
||||
uint256 maxIterations)
|
||||
internal
|
||||
{
|
||||
require(maxIterations > 0, "maxIterations must be > 0");
|
||||
require(host.slots.length() <= maxIterations, "iterations out of bounds");
|
||||
|
||||
for (uint256 i = 0; i < host.slots.length(); i++) {
|
||||
bytes32 slotId = host.slots.at(i);
|
||||
Slot storage slot = select(db, SlotId.wrap(slotId));
|
||||
if (equals(slot.requestId, requestId)) {
|
||||
host.slots.remove(slotId);
|
||||
}
|
||||
}
|
||||
remove(db, host.requests, requestId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// *** CALCULATED PROPERTIES *** ///
|
||||
|
|
Loading…
Reference in New Issue