add tests for DAL
This commit is contained in:
parent
2aa50eabbf
commit
c03206c2b8
|
@ -11,7 +11,6 @@ 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;
|
||||
|
|
|
@ -84,8 +84,8 @@ library DAL {
|
|||
function insert(Database storage db,
|
||||
RequestId requestId,
|
||||
ClientId clientId,
|
||||
Ask memory ask,
|
||||
Content memory content,
|
||||
Ask calldata ask,
|
||||
Content calldata content,
|
||||
uint256 expiry,
|
||||
bytes32 nonce)
|
||||
internal
|
||||
|
@ -104,6 +104,18 @@ library DAL {
|
|||
r.nonce = nonce;
|
||||
}
|
||||
|
||||
function insert(Database storage db, Slot memory slot ) internal {
|
||||
require(!_isDefault(slot.id), "slot id required");
|
||||
require(!isDefault(slot.requestId), "request id required");
|
||||
require(exists(db, slot.requestId), "request does not exist");
|
||||
require(!exists(db, slot.id), "slot already exists");
|
||||
require(exists(db, slot.host), "host does not exist");
|
||||
db.slots[slot.id] = slot;
|
||||
|
||||
Request storage request = db.requests[slot.requestId];
|
||||
request.slots.add(SlotId.unwrap(slot.id));
|
||||
}
|
||||
|
||||
function insert(Database storage db, ClientId clientId) internal {
|
||||
require (!exists(db, clientId), "client already exists");
|
||||
require (!_isDefault(clientId), "address required");
|
||||
|
@ -120,18 +132,6 @@ library DAL {
|
|||
// NOTE: by default db.hosts[host].slots already exists but has a default value
|
||||
}
|
||||
|
||||
function insert(Database storage db, Slot memory slot ) internal {
|
||||
require(!_isDefault(slot.id), "slot id required");
|
||||
require(!isDefault(slot.requestId), "request id required");
|
||||
require(exists(db, slot.requestId), "request does not exist");
|
||||
require(!exists(db, slot.id), "slot already exists");
|
||||
require(exists(db, slot.host), "host does not exist");
|
||||
db.slots[slot.id] = slot;
|
||||
|
||||
Request storage request = db.requests[slot.requestId];
|
||||
request.slots.add(SlotId.unwrap(slot.id));
|
||||
}
|
||||
|
||||
function insert(Database storage db,
|
||||
EnumerableSet.Bytes32Set storage requests,
|
||||
RequestId requestId)
|
||||
|
@ -251,6 +251,17 @@ library DAL {
|
|||
delete db.requests[request.id];
|
||||
}
|
||||
|
||||
function remove(Database storage db, Slot storage slot) internal {
|
||||
require(exists(db, slot.requestId), "request does not exist");
|
||||
Host storage host = db.hosts[slot.host];
|
||||
bytes32 bSlotId = SlotId.unwrap(slot.id);
|
||||
require(!host.slots.contains(bSlotId), "active slot refs");
|
||||
|
||||
Request storage request = db.requests[slot.requestId];
|
||||
request.slots.remove(bSlotId);
|
||||
delete db.slots[slot.id];
|
||||
}
|
||||
|
||||
function remove(Database storage db, Client storage client) internal {
|
||||
require(client.requests.length() == 0, "active request refs");
|
||||
|
||||
|
@ -263,17 +274,6 @@ library DAL {
|
|||
delete db.hosts[host.id];
|
||||
}
|
||||
|
||||
function remove(Database storage db, Slot storage slot) internal {
|
||||
require(exists(db, slot.requestId), "request does not exist");
|
||||
Host storage host = db.hosts[slot.host];
|
||||
bytes32 bSlotId = SlotId.unwrap(slot.id);
|
||||
require(!host.slots.contains(bSlotId), "active slot refs");
|
||||
|
||||
Request storage request = db.requests[slot.requestId];
|
||||
request.slots.remove(bSlotId);
|
||||
delete db.slots[slot.id];
|
||||
}
|
||||
|
||||
function remove(Database storage db,
|
||||
EnumerableSet.Bytes32Set storage requests,
|
||||
RequestId requestId)
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
||||
import "./DAL.sol";
|
||||
|
||||
// exposes public functions for testing
|
||||
contract TestDAL {
|
||||
using DAL for DAL.Database;
|
||||
using EnumerableSet for EnumerableSet.Bytes32Set;
|
||||
|
||||
event OperationResult(bool result);
|
||||
|
||||
DAL.Database private _db;
|
||||
|
||||
function insertRequest(DAL.RequestId requestId,
|
||||
DAL.ClientId clientId,
|
||||
DAL.Ask calldata ask,
|
||||
DAL.Content calldata content,
|
||||
uint256 expiry,
|
||||
bytes32 nonce)
|
||||
public
|
||||
{
|
||||
_db.insert(requestId, clientId, ask, content, expiry, nonce);
|
||||
}
|
||||
|
||||
function insertSlot(DAL.Slot memory slot) public {
|
||||
_db.insert(slot);
|
||||
}
|
||||
|
||||
function insertClient(DAL.ClientId clientId) public {
|
||||
_db.insert(clientId);
|
||||
}
|
||||
|
||||
function insertHost(DAL.HostId hostId) public {
|
||||
_db.insert(hostId);
|
||||
}
|
||||
|
||||
function insertHostRequest(DAL.HostId hostId,
|
||||
DAL.RequestId requestId)
|
||||
public
|
||||
{
|
||||
DAL.Host storage host = _db.select(hostId);
|
||||
_db.insert(host.requests, requestId);
|
||||
}
|
||||
|
||||
function insertClientRequest(DAL.ClientId clientId,
|
||||
DAL.RequestId requestId)
|
||||
public
|
||||
{
|
||||
DAL.Client storage client = _db.select(clientId);
|
||||
_db.insert(client.requests, requestId);
|
||||
}
|
||||
|
||||
function insertHostSlot(DAL.HostId hostId,
|
||||
DAL.SlotId slotId)
|
||||
public
|
||||
{
|
||||
DAL.Host storage host = _db.select(hostId);
|
||||
_db.insert(host.slots, slotId);
|
||||
}
|
||||
|
||||
function selectRequest(DAL.RequestId requestId)
|
||||
public
|
||||
view
|
||||
returns (DAL.RequestId,
|
||||
DAL.ClientId,
|
||||
DAL.Ask memory,
|
||||
DAL.Content memory,
|
||||
uint256,
|
||||
bytes32,
|
||||
bytes32[] memory)
|
||||
{
|
||||
DAL.Request storage request = _db.select(requestId);
|
||||
return (request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce,
|
||||
request.slots.values());
|
||||
}
|
||||
|
||||
function selectSlot(DAL.SlotId slotId)
|
||||
public
|
||||
view
|
||||
returns (DAL.SlotId, DAL.HostId, bool, DAL.RequestId)
|
||||
{
|
||||
DAL.Slot storage slot = _db.select(slotId);
|
||||
return (slot.id, slot.host, slot.hostPaid, slot.requestId);
|
||||
}
|
||||
|
||||
function selectClient(DAL.ClientId clientId)
|
||||
public
|
||||
view
|
||||
returns (DAL.ClientId, bytes32[] memory)
|
||||
{
|
||||
DAL.Client storage client = _db.select(clientId);
|
||||
return (client.id, client.requests.values());
|
||||
}
|
||||
|
||||
function selectHost(DAL.HostId hostId)
|
||||
public
|
||||
view
|
||||
returns (DAL.HostId, bytes32[] memory, bytes32[] memory)
|
||||
{
|
||||
DAL.Host storage host = _db.select(hostId);
|
||||
return (host.id, host.slots.values(), host.requests.values());
|
||||
}
|
||||
|
||||
function requestExists(DAL.RequestId requestId)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _db.exists(requestId);
|
||||
}
|
||||
|
||||
function slotExists(DAL.SlotId slotId)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _db.exists(slotId);
|
||||
}
|
||||
|
||||
function clientExists(DAL.ClientId clientId)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _db.exists(clientId);
|
||||
}
|
||||
|
||||
function hostExists(DAL.HostId hostId)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _db.exists(hostId);
|
||||
}
|
||||
|
||||
function removeRequest(DAL.RequestId requestId) public {
|
||||
DAL.Request storage request = _db.select(requestId);
|
||||
_db.remove(request);
|
||||
}
|
||||
|
||||
function removeSlot(DAL.SlotId slotId) public {
|
||||
DAL.Slot storage slot = _db.select(slotId);
|
||||
_db.remove(slot);
|
||||
}
|
||||
|
||||
function removeClient(DAL.ClientId clientId) public {
|
||||
DAL.Client storage client = _db.select(clientId);
|
||||
_db.remove(client);
|
||||
}
|
||||
|
||||
function removeHost(DAL.HostId hostId) public {
|
||||
DAL.Host storage host = _db.select(hostId);
|
||||
_db.remove(host);
|
||||
}
|
||||
|
||||
function removeClientRequest(DAL.ClientId clientId,
|
||||
DAL.RequestId requestId)
|
||||
public
|
||||
{
|
||||
DAL.Client storage client = _db.select(clientId);
|
||||
_db.remove(client.requests, requestId);
|
||||
}
|
||||
|
||||
function removeHostRequest(DAL.HostId hostId,
|
||||
DAL.RequestId requestId)
|
||||
public
|
||||
{
|
||||
DAL.Host storage host = _db.select(hostId);
|
||||
_db.remove(host.requests, requestId);
|
||||
}
|
||||
|
||||
function removeHostSlot(DAL.HostId hostId,
|
||||
DAL.SlotId slotId)
|
||||
public
|
||||
{
|
||||
DAL.Host storage host = _db.select(hostId);
|
||||
_db.remove(host.slots, slotId);
|
||||
}
|
||||
|
||||
function clearSlots(DAL.HostId hostId,
|
||||
DAL.RequestId requestId,
|
||||
uint256 maxIterations)
|
||||
public
|
||||
{
|
||||
DAL.Host storage host = _db.select(hostId);
|
||||
_db.clearSlots(host, requestId, maxIterations);
|
||||
}
|
||||
|
||||
function activeSlots(DAL.HostId hostId)
|
||||
public
|
||||
view
|
||||
returns (DAL.SlotId[] memory)
|
||||
{
|
||||
DAL.Host storage host = _db.select(hostId);
|
||||
return _db.activeSlots(host);
|
||||
}
|
||||
|
||||
function toSlotId(DAL.RequestId requestId, uint256 slotIndex)
|
||||
public
|
||||
pure
|
||||
returns (DAL.SlotId)
|
||||
{
|
||||
return toSlotId(requestId, slotIndex);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,600 @@
|
|||
const { ethers } = require("hardhat")
|
||||
const { expect, Assertion } = require("chai")
|
||||
const { hexlify, randomBytes } = ethers.utils
|
||||
const { exampleAddress, exampleRequest, zeroBytesHex } = require("./examples")
|
||||
const { slotId, requestId, requestToArray, askToArray } = require("./ids")
|
||||
const { BigNumber } = ethers
|
||||
const { supportDAL } = require("./dal")
|
||||
|
||||
supportDAL(Assertion)
|
||||
|
||||
describe("DAL", function () {
|
||||
let account
|
||||
let contract
|
||||
let request
|
||||
let slot
|
||||
let host
|
||||
let client
|
||||
|
||||
describe("Database", function () {
|
||||
beforeEach(async function () {
|
||||
let DAL = await ethers.getContractFactory("TestDAL")
|
||||
contract = await DAL.deploy()
|
||||
;[account] = await ethers.getSigners()
|
||||
request = await exampleRequest()
|
||||
request.id = requestId(request)
|
||||
request.slots = []
|
||||
client = {
|
||||
id: await exampleAddress(),
|
||||
requests: [],
|
||||
}
|
||||
request.client = client.id
|
||||
host = {
|
||||
id: await exampleAddress(),
|
||||
requests: [],
|
||||
slots: [],
|
||||
}
|
||||
slot = {
|
||||
id: slotId({ request: request.id, index: 0 }),
|
||||
host: host.id,
|
||||
hostPaid: false,
|
||||
requestId: request.id,
|
||||
}
|
||||
})
|
||||
|
||||
describe("Create: successful", function () {
|
||||
it("inserts a request", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await expect(await contract.requestExists(request.id)).to.be.true
|
||||
})
|
||||
|
||||
it("inserts a slot", async function () {
|
||||
await expect(await contract.slotExists(slot.id)).to.be.false
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertSlot(slot)
|
||||
await expect(await contract.slotExists(slot.id)).to.be.true
|
||||
})
|
||||
|
||||
it("inserts a client", async function () {
|
||||
await expect(await contract.clientExists(client.id)).to.be.false
|
||||
await contract.insertClient(client.id)
|
||||
await expect(await contract.clientExists(client.id)).to.be.true
|
||||
})
|
||||
|
||||
it("inserts a host", async function () {
|
||||
await expect(await contract.hostExists(host.id)).to.be.false
|
||||
await contract.insertHost(host.id)
|
||||
await expect(await contract.hostExists(host.id)).to.be.true
|
||||
})
|
||||
|
||||
it("inserts a host request", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertHostRequest(host.id, request.id)
|
||||
let [id, slots, requests] = await contract.selectHost(host.id)
|
||||
await expect(requests.includes(request.id)).to.be.true
|
||||
})
|
||||
|
||||
it("inserts a client request", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertClientRequest(client.id, request.id)
|
||||
let [id, requests] = await contract.selectClient(client.id)
|
||||
await expect(requests.includes(request.id)).to.be.true
|
||||
})
|
||||
|
||||
it("inserts a host slot", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertHostRequest(host.id, request.id)
|
||||
await contract.insertSlot(slot)
|
||||
await contract.insertHostSlot(host.id, slot.id)
|
||||
let [id, slots, requests] = await contract.selectHost(host.id)
|
||||
await expect(slots.includes(slot.id)).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
describe("Create: failure", function () {
|
||||
it("fails to insert a request when request id not provided", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
await expect(
|
||||
contract.insertRequest(
|
||||
zeroBytesHex(32),
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
).to.be.revertedWith("request id required")
|
||||
})
|
||||
it("fails to insert a request when client id (address) not provided", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
await expect(
|
||||
contract.insertRequest(
|
||||
request.id,
|
||||
zeroBytesHex(20),
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
).to.be.revertedWith("client address required")
|
||||
})
|
||||
it("fails to insert a request when client doesn't exist", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
await expect(
|
||||
contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
).to.be.revertedWith("client does not exist")
|
||||
})
|
||||
it("fails to insert a request when request already exists", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await expect(
|
||||
contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
).to.be.revertedWith("request already exists")
|
||||
})
|
||||
it("fails to insert a slot when slot id not provided", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
slot.id = zeroBytesHex(32)
|
||||
await expect(contract.insertSlot(slot)).to.be.revertedWith(
|
||||
"slot id required"
|
||||
)
|
||||
})
|
||||
it("fails to insert a slot when request id not provided", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
slot.requestId = zeroBytesHex(32)
|
||||
await expect(contract.insertSlot(slot)).to.be.revertedWith(
|
||||
"request id required"
|
||||
)
|
||||
})
|
||||
it("fails to insert a slot when request id not provided", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
slot.requestId = zeroBytesHex(32)
|
||||
await expect(contract.insertSlot(slot)).to.be.revertedWith(
|
||||
"request id required"
|
||||
)
|
||||
})
|
||||
it("fails to insert a slot when request doesn't exist", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
await expect(contract.insertSlot(slot)).to.be.revertedWith(
|
||||
"request does not exist"
|
||||
)
|
||||
})
|
||||
it("fails to insert a slot when the slot already exists", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertSlot(slot)
|
||||
await expect(contract.insertSlot(slot)).to.be.revertedWith(
|
||||
"slot already exists"
|
||||
)
|
||||
})
|
||||
it("fails to insert a slot when the host does not exist", async function () {
|
||||
await expect(await contract.requestExists(request.id)).to.be.false
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await expect(contract.insertSlot(slot)).to.be.revertedWith(
|
||||
"host does not exist"
|
||||
)
|
||||
})
|
||||
it("fails to insert a client when the client already exists", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await expect(contract.insertClient(client.id)).to.be.revertedWith(
|
||||
"client already exists"
|
||||
)
|
||||
})
|
||||
it("fails to insert a client when the address wasn't provided", async function () {
|
||||
client.id = zeroBytesHex(20)
|
||||
await expect(contract.insertClient(client.id)).to.be.revertedWith(
|
||||
"address required"
|
||||
)
|
||||
})
|
||||
it("fails to insert a host when the host already exists", async function () {
|
||||
await contract.insertHost(host.id)
|
||||
await expect(contract.insertHost(host.id)).to.be.revertedWith(
|
||||
"host already exists"
|
||||
)
|
||||
})
|
||||
it("fails to insert a host when the address wasn't provided", async function () {
|
||||
host.id = zeroBytesHex(20)
|
||||
await expect(contract.insertHost(host.id)).to.be.revertedWith(
|
||||
"address required"
|
||||
)
|
||||
})
|
||||
it("fails to insert a host request when request doesn't exist", async function () {
|
||||
await contract.insertHost(host.id)
|
||||
await expect(
|
||||
contract.insertHostRequest(host.id, request.id)
|
||||
).to.be.revertedWith("request does not exist")
|
||||
})
|
||||
it("fails to insert a client request when request doesn't exist", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await expect(
|
||||
contract.insertClientRequest(client.id, request.id)
|
||||
).to.be.revertedWith("request does not exist")
|
||||
})
|
||||
|
||||
it("fails to insert a host slot when slot doesn't exist", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertHost(host.id)
|
||||
await expect(
|
||||
contract.insertHostSlot(host.id, slot.id)
|
||||
).to.be.revertedWith("slot does not exist")
|
||||
})
|
||||
|
||||
it("fails to insert a host slot when host doesn't exist", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await expect(
|
||||
contract.insertHostSlot(host.id, slot.id)
|
||||
).to.be.revertedWith("Host does not exist")
|
||||
})
|
||||
|
||||
it("fails to insert a host slot when the host request doesn't exist", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertSlot(slot)
|
||||
await expect(
|
||||
contract.insertHostSlot(host.id, slot.id)
|
||||
).to.be.revertedWith("slot request not active")
|
||||
})
|
||||
})
|
||||
|
||||
describe("Read: success", function () {
|
||||
it("selects a request", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await expect(await contract.selectRequest(request.id)).to.equalsRequest(
|
||||
request
|
||||
)
|
||||
})
|
||||
it("selects a slot", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertSlot(slot)
|
||||
await expect(await contract.selectSlot(slot.id)).to.equalsSlot(slot)
|
||||
})
|
||||
it("selects a client", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await expect(await contract.selectClient(client.id)).to.be.equalsClient(
|
||||
client
|
||||
)
|
||||
})
|
||||
it("selects a host", async function () {
|
||||
await contract.insertHost(host.id)
|
||||
await expect(await contract.selectHost(host.id)).to.be.equalsHost(host)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Read: failure", function () {
|
||||
it("fails to select a request when request doesn't exist", async function () {
|
||||
await expect(contract.selectRequest(request.id)).to.be.revertedWith(
|
||||
"Unknown request"
|
||||
)
|
||||
})
|
||||
it("fails to select a slot when slot is empty", async function () {
|
||||
await expect(contract.selectSlot(slot.id)).to.be.revertedWith(
|
||||
"Slot empty"
|
||||
)
|
||||
})
|
||||
it("fails to select a client when client doesn't exist", async function () {
|
||||
await expect(contract.selectClient(client.id)).to.be.revertedWith(
|
||||
"Client does not exist"
|
||||
)
|
||||
})
|
||||
it("fails to select a host when host doesn't exist", async function () {
|
||||
await expect(contract.selectHost(host.id)).to.be.revertedWith(
|
||||
"Host does not exist"
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Delete: success", function () {
|
||||
it("deletes a request", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.removeRequest(request.id)
|
||||
await expect(contract.selectRequest(request.id)).to.be.revertedWith(
|
||||
"Unknown request"
|
||||
)
|
||||
})
|
||||
it("deletes a slot", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertSlot(slot)
|
||||
await contract.removeSlot(slot.id)
|
||||
await expect(contract.selectSlot(slot.id)).to.be.revertedWith(
|
||||
"Slot empty"
|
||||
)
|
||||
})
|
||||
it("deletes a client", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.removeClient(client.id)
|
||||
await expect(contract.selectClient(client.id)).to.be.revertedWith(
|
||||
"Client does not exist"
|
||||
)
|
||||
})
|
||||
it("deletes a host", async function () {
|
||||
await contract.insertHost(host.id)
|
||||
await contract.removeHost(host.id)
|
||||
await expect(contract.selectHost(host.id)).to.be.revertedWith(
|
||||
"Host does not exist"
|
||||
)
|
||||
})
|
||||
it("deletes a client request", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertClientRequest(client.id, request.id)
|
||||
let [id, requests] = await contract.selectClient(client.id)
|
||||
await expect(requests.length).to.equal(1)
|
||||
await contract.removeClientRequest(client.id, request.id)
|
||||
;[id, requests] = await contract.selectClient(client.id)
|
||||
await expect(requests.length).to.equal(0)
|
||||
})
|
||||
it("deletes a host request", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertHostRequest(host.id, request.id)
|
||||
let [id, slots, requests] = await contract.selectHost(host.id)
|
||||
await expect(requests.length).to.equal(1)
|
||||
await contract.removeHostRequest(host.id, request.id)
|
||||
;[id, slots, requests] = await contract.selectHost(host.id)
|
||||
await expect(requests.length).to.equal(0)
|
||||
})
|
||||
it("deletes a host slot", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertHostRequest(host.id, request.id)
|
||||
await contract.insertSlot(slot)
|
||||
await contract.insertHostSlot(host.id, slot.id)
|
||||
let [id, slots, requests] = await contract.selectHost(host.id)
|
||||
await expect(slots.length).to.equal(1)
|
||||
await contract.removeHostSlot(host.id, slot.id)
|
||||
;[id, slots, requests] = await contract.selectHost(host.id)
|
||||
await expect(slots.length).to.equal(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Delete: failure", function () {
|
||||
it("fails to delete a request when it references slots", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertSlot(slot)
|
||||
await expect(contract.removeRequest(request.id)).to.be.revertedWith(
|
||||
"references slots"
|
||||
)
|
||||
})
|
||||
it("fails to delete a request when its client has request references", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertClientRequest(client.id, request.id)
|
||||
await expect(contract.removeRequest(request.id)).to.be.revertedWith(
|
||||
"active request refs"
|
||||
)
|
||||
})
|
||||
it("fails to delete a client when it has request references", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertClientRequest(client.id, request.id)
|
||||
await expect(contract.removeClient(client.id)).to.be.revertedWith(
|
||||
"active request refs"
|
||||
)
|
||||
})
|
||||
it("fails to delete a request when its host has slot references", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertSlot(slot)
|
||||
await contract.insertHostRequest(host.id, request.id)
|
||||
await contract.insertHostSlot(host.id, slot.id)
|
||||
await expect(contract.removeSlot(slot.id)).to.be.revertedWith(
|
||||
"active slot refs"
|
||||
)
|
||||
})
|
||||
it("fails to delete a host when it has slot references", async function () {
|
||||
await contract.insertClient(client.id)
|
||||
await contract.insertHost(host.id)
|
||||
await contract.insertRequest(
|
||||
request.id,
|
||||
request.client,
|
||||
request.ask,
|
||||
request.content,
|
||||
request.expiry,
|
||||
request.nonce
|
||||
)
|
||||
await contract.insertSlot(slot)
|
||||
await contract.insertHostRequest(host.id, request.id)
|
||||
await contract.insertHostSlot(host.id, slot.id)
|
||||
await expect(contract.removeHost(host.id)).to.be.revertedWith(
|
||||
"active slot refs"
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,111 @@
|
|||
const { BigNumber } = require("ethers")
|
||||
const { hexlify } = ethers.utils
|
||||
|
||||
function isBigNumberish(bn) {
|
||||
return bn._isBigNumber === true
|
||||
}
|
||||
|
||||
function normalizeBn(bn) {
|
||||
return isBigNumberish(bn) ? bn.toNumber() : bn
|
||||
}
|
||||
|
||||
function supportDAL(Assertion) {
|
||||
Assertion.addMethod("equalsRequest", function (request) {
|
||||
const evmRequest = requestFromArray(this._obj)
|
||||
request.content.por.u = hexlify(request.content.por.u)
|
||||
request.content.por.publicKey = hexlify(request.content.por.publicKey)
|
||||
request.content.por.name = hexlify(request.content.por.name)
|
||||
new Assertion(evmRequest).to.deep.equal(request)
|
||||
})
|
||||
Assertion.addMethod("equalsSlot", function (slot) {
|
||||
const evmSlot = slotFromArray(this._obj)
|
||||
new Assertion(evmSlot).to.deep.equal(slot)
|
||||
})
|
||||
Assertion.addMethod("equalsClient", function (client) {
|
||||
const evmClient = clientFromArray(this._obj)
|
||||
new Assertion(evmClient).to.deep.equal(client)
|
||||
})
|
||||
Assertion.addMethod("equalsHost", function (host) {
|
||||
const evmHost = hostFromArray(this._obj)
|
||||
new Assertion(evmHost).to.deep.equal(host)
|
||||
})
|
||||
}
|
||||
|
||||
function parse(keys, object) {
|
||||
let obj = {}
|
||||
keys.forEach((key, i) => (obj[key] = normalizeBn(object[i])))
|
||||
return obj
|
||||
}
|
||||
|
||||
function porFromArray(por) {
|
||||
return {
|
||||
u: por.u,
|
||||
publicKey: por.publicKey,
|
||||
name: por.name,
|
||||
}
|
||||
}
|
||||
|
||||
function erasureFromArray(erasure) {
|
||||
return {
|
||||
totalChunks: normalizeBn(erasure.totalChunks),
|
||||
}
|
||||
}
|
||||
|
||||
function contentFromArray(ask) {
|
||||
return {
|
||||
cid: ask.cid,
|
||||
erasure: erasureFromArray(ask.erasure),
|
||||
por: porFromArray(ask.por),
|
||||
}
|
||||
}
|
||||
|
||||
function askFromArray(ask) {
|
||||
return {
|
||||
slots: normalizeBn(ask.slots),
|
||||
slotSize: normalizeBn(ask.slotSize),
|
||||
duration: normalizeBn(ask.duration),
|
||||
proofProbability: normalizeBn(ask.proofProbability),
|
||||
reward: normalizeBn(ask.reward),
|
||||
maxSlotLoss: normalizeBn(ask.maxSlotLoss),
|
||||
}
|
||||
}
|
||||
|
||||
function requestFromArray(request) {
|
||||
return {
|
||||
id: request[0],
|
||||
client: request[1],
|
||||
ask: askFromArray(request[2]),
|
||||
content: contentFromArray(request[3]),
|
||||
expiry: normalizeBn(request[4]),
|
||||
nonce: request[5],
|
||||
slots: normalizeBn(request[6]),
|
||||
}
|
||||
}
|
||||
|
||||
function slotFromArray(slot) {
|
||||
return {
|
||||
id: slot[0],
|
||||
host: slot[1],
|
||||
hostPaid: slot[2],
|
||||
requestId: slot[3],
|
||||
}
|
||||
}
|
||||
|
||||
function clientFromArray(client) {
|
||||
return {
|
||||
id: client[0],
|
||||
requests: client[1],
|
||||
}
|
||||
}
|
||||
|
||||
function hostFromArray(host) {
|
||||
return {
|
||||
id: host[0],
|
||||
slots: host[1],
|
||||
requests: host[2],
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
supportDAL,
|
||||
}
|
|
@ -40,5 +40,12 @@ const exampleLock = async () => {
|
|||
const exampleAddress = () => {
|
||||
return getAddress(hexlify(randomBytes(20)))
|
||||
}
|
||||
const zeroBytesHex = (bytes) => {
|
||||
let hex = "0x"
|
||||
for (let i = 0; i < bytes; i++) {
|
||||
hex += "00"
|
||||
}
|
||||
return hex
|
||||
}
|
||||
|
||||
module.exports = { exampleRequest, exampleLock, exampleAddress }
|
||||
module.exports = { exampleRequest, exampleLock, exampleAddress, zeroBytesHex }
|
||||
|
|
Loading…
Reference in New Issue