mirror of
https://github.com/logos-storage/logos-storage-contracts-eth.git
synced 2026-01-02 13:23:10 +00:00
182 lines
5.9 KiB
JavaScript
182 lines
5.9 KiB
JavaScript
const { ethers, ignition } = require("hardhat")
|
|
const {
|
|
exampleRequest,
|
|
exampleProof,
|
|
exampleConfiguration,
|
|
} = require("./examples")
|
|
const { maxPrice } = require("./price")
|
|
const { collateralPerSlot } = require("./collateral")
|
|
const { requestId, slotId } = require("./ids")
|
|
const {
|
|
revert,
|
|
snapshot,
|
|
ensureMinimumBlockHeight,
|
|
advanceTimeTo,
|
|
currentTime,
|
|
} = require("./evm")
|
|
const { expect } = require("chai")
|
|
const { patchOverloads } = require("./marketplace")
|
|
const { periodic } = require("./time")
|
|
const { RequestState } = require("./requests")
|
|
const MarketplaceModule = require("../ignition/modules/marketplace")
|
|
|
|
// Ensures that the actual gas costs can never deviate from the gas estimate by
|
|
// more than a certain percentage.
|
|
// The percentages from these tests should be used to pad the gas estimates in
|
|
// market.nim, for example when calling fillSlot:
|
|
// https://github.com/logos-storage/logos-storage-nim/blob/6db6bf5f72a0038b77d02f48dcf128b4d77b469a/codex/contracts/market.nim#L278
|
|
describe("Marketplace gas estimates", function () {
|
|
let marketplace
|
|
let token
|
|
let signer
|
|
|
|
async function requestStorage() {
|
|
const request = exampleRequest()
|
|
request.client = signer.address
|
|
await token.approve(await marketplace.getAddress(), maxPrice(request))
|
|
await marketplace.requestStorage(request)
|
|
return request
|
|
}
|
|
|
|
async function startRequest(request) {
|
|
const id = requestId(request)
|
|
for (let i = 0; i < request.ask.slots; i++) {
|
|
await marketplace.reserveSlot(id, i)
|
|
await token.approve(
|
|
await marketplace.getAddress(),
|
|
collateralPerSlot(request),
|
|
)
|
|
await marketplace.fillSlot(id, i, exampleProof())
|
|
}
|
|
}
|
|
|
|
beforeEach(async function () {
|
|
await snapshot()
|
|
await ensureMinimumBlockHeight(256)
|
|
|
|
signer = (await ethers.getSigners())[0]
|
|
|
|
const { testMarketplace, token: _token } = await ignition.deploy(
|
|
MarketplaceModule,
|
|
{
|
|
parameters: {
|
|
Marketplace: {
|
|
configuration: exampleConfiguration(),
|
|
},
|
|
},
|
|
},
|
|
)
|
|
|
|
marketplace = testMarketplace
|
|
patchOverloads(marketplace)
|
|
|
|
token = _token
|
|
for (let account of await ethers.getSigners()) {
|
|
await token.mint(account.address, 1_000_000_000_000_000n)
|
|
}
|
|
})
|
|
|
|
afterEach(async function () {
|
|
await revert()
|
|
})
|
|
|
|
describe("reserveSlot", function () {
|
|
it("has at most 25% deviation in gas usage", async function () {
|
|
const request = await requestStorage()
|
|
const id = requestId(request)
|
|
const gasUsage = []
|
|
for (let signer of await ethers.getSigners()) {
|
|
marketplace = marketplace.connect(signer)
|
|
for (let i = 0; i < request.ask.slots; i++) {
|
|
try {
|
|
const transaction = await marketplace.reserveSlot(id, i)
|
|
const receipt = await transaction.wait()
|
|
gasUsage.push(Number(receipt.gasUsed))
|
|
} catch (exception) {
|
|
// ignore: reservations can be full
|
|
}
|
|
}
|
|
}
|
|
const deviation = Math.max(...gasUsage) / Math.min(...gasUsage) - 1.0
|
|
expect(deviation).to.be.gt(0)
|
|
expect(deviation).to.be.lte(0.25)
|
|
})
|
|
})
|
|
|
|
describe("fillSlot", function () {
|
|
it("has at most 10% deviation in gas usage", async function () {
|
|
const request = await requestStorage()
|
|
const id = requestId(request)
|
|
const gasUsage = []
|
|
for (let i = 0; i < request.ask.slots; i++) {
|
|
await marketplace.reserveSlot(id, i)
|
|
await token.approve(
|
|
await marketplace.getAddress(),
|
|
collateralPerSlot(request),
|
|
)
|
|
const transaction = await marketplace.fillSlot(id, i, exampleProof())
|
|
const receipt = await transaction.wait()
|
|
gasUsage.push(Number(receipt.gasUsed))
|
|
}
|
|
const deviation = Math.max(...gasUsage) / Math.min(...gasUsage) - 1.0
|
|
expect(deviation).to.be.gt(0)
|
|
expect(deviation).to.be.lte(0.1)
|
|
})
|
|
})
|
|
|
|
describe("freeSlot", function () {
|
|
it("has at most 200% deviation in gas usage", async function () {
|
|
const request = await requestStorage()
|
|
const id = requestId(request)
|
|
await startRequest(request)
|
|
const gasUsage = []
|
|
for (let i = 0; i < request.ask.slots; i++) {
|
|
const slot = { request: id, index: i }
|
|
const transaction = await marketplace.freeSlot(slotId(slot))
|
|
const receipt = await transaction.wait()
|
|
gasUsage.push(Number(receipt.gasUsed))
|
|
}
|
|
const deviation = Math.max(...gasUsage) / Math.min(...gasUsage) - 1.0
|
|
expect(deviation).to.be.gt(0)
|
|
expect(deviation).to.be.lte(2.0)
|
|
})
|
|
})
|
|
|
|
describe("markProofAsMissing", function () {
|
|
let period, periodOf, periodEnd
|
|
|
|
beforeEach(async function () {
|
|
const configuration = await marketplace.configuration()
|
|
period = Number(configuration.proofs.period)
|
|
;({ periodOf, periodEnd } = periodic(period))
|
|
})
|
|
|
|
it("has at most 50% deviation in gas usage", async function () {
|
|
const request = await requestStorage()
|
|
const id = requestId(request)
|
|
await startRequest(request)
|
|
const gasUsage = []
|
|
while ((await marketplace.requestState(id)) != RequestState.Failed) {
|
|
const missingPeriod = periodOf(await currentTime())
|
|
await advanceTimeTo(periodEnd(missingPeriod) + 1)
|
|
for (let i = 0; i < request.ask.slots; i++) {
|
|
try {
|
|
const slot = { request: id, index: i }
|
|
const transaction = await marketplace.markProofAsMissing(
|
|
slotId(slot),
|
|
missingPeriod,
|
|
)
|
|
const receipt = await transaction.wait()
|
|
gasUsage.push(Number(receipt.gasUsed))
|
|
} catch (exception) {
|
|
// ignore: proof might not be missing
|
|
}
|
|
}
|
|
}
|
|
const deviation = Math.max(...gasUsage) / Math.min(...gasUsage) - 1.0
|
|
expect(deviation).to.be.gt(0)
|
|
expect(deviation).to.be.lte(0.5)
|
|
})
|
|
})
|
|
})
|