mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-01-15 03:43:11 +00:00
- works with hardhat already running - works with ethersuite to revert snapshot (ethProvider instead of provider) - OnChainClock.now() gets latest block timestamp
281 lines
9.4 KiB
Nim
281 lines
9.4 KiB
Nim
from std/times import inMilliseconds
|
|
import pkg/chronicles
|
|
import pkg/stew/byteutils
|
|
import ../contracts/time
|
|
import ../contracts/deployment
|
|
import ../codex/helpers
|
|
import ../examples
|
|
import ./marketplacesuite
|
|
|
|
export chronicles
|
|
|
|
logScope:
|
|
topics = "integration test proofs"
|
|
|
|
marketplacesuite "Simulate invalid proofs - 1 provider node",
|
|
Nodes(
|
|
# Uncomment to start Hardhat automatically, mainly so logs can be inspected locally
|
|
# hardhat: HardhatConfig()
|
|
# .withLogFile(),
|
|
|
|
clients: NodeConfig()
|
|
.nodes(1)
|
|
.debug()
|
|
.withLogFile()
|
|
.withLogTopics("node"),
|
|
|
|
providers: NodeConfig()
|
|
.nodes(1)
|
|
.simulateProofFailuresFor(providerIdx=0, failEveryNProofs=1)
|
|
.debug()
|
|
.withLogFile()
|
|
.withLogTopics(
|
|
"marketplace",
|
|
"sales",
|
|
"reservations",
|
|
"node",
|
|
"JSONRPC-HTTP-CLIENT",
|
|
"JSONRPC-WS-CLIENT",
|
|
"ethers",
|
|
"restapi",
|
|
"clock"
|
|
),
|
|
|
|
validators: NodeConfig()
|
|
.nodes(1)
|
|
.withLogFile()
|
|
.debug()
|
|
.withLogTopics("validator", "initial-proving", "proving", "clock", "onchain", "ethers")
|
|
):
|
|
|
|
test "slot is freed after too many invalid proofs submitted":
|
|
let client0 = clients()[0].node.client
|
|
let totalProofs = 50
|
|
|
|
let data = byteutils.toHex(await exampleData())
|
|
createAvailabilities(data.len, totalProofs.periods)
|
|
|
|
let cid = client0.upload(data).get
|
|
|
|
let purchaseId = await client0.requestStorage(cid, duration=totalProofs.periods)
|
|
let requestId = client0.requestId(purchaseId).get
|
|
|
|
check eventually client0.purchaseStateIs(purchaseId, "started")
|
|
|
|
var slotWasFreed = false
|
|
proc onSlotFreed(event: SlotFreed) {.gcsafe, upraises:[].} =
|
|
if event.requestId == requestId and
|
|
event.slotIndex == 0.u256: # assume only one slot, so index 0
|
|
slotWasFreed = true
|
|
|
|
let subscription = await marketplace.subscribe(SlotFreed, onSlotFreed)
|
|
|
|
let currentPeriod = await getCurrentPeriod()
|
|
let timeUntilLastPeriod = await timeUntil(currentPeriod + totalProofs.u256 + 1)
|
|
check eventually(slotWasFreed, timeUntilLastPeriod.inMilliseconds.int)
|
|
|
|
await subscription.unsubscribe()
|
|
|
|
marketplacesuite "Simulate invalid proofs - 1 provider node",
|
|
Nodes(
|
|
# Uncomment to start Hardhat automatically, mainly so logs can be inspected locally
|
|
# hardhat: HardhatConfig()
|
|
# .withLogFile(),
|
|
|
|
clients: NodeConfig()
|
|
.nodes(1)
|
|
.debug()
|
|
.withLogFile()
|
|
.withLogTopics("node"),
|
|
|
|
providers: NodeConfig()
|
|
.nodes(1)
|
|
.simulateProofFailuresFor(providerIdx=0, failEveryNProofs=3)
|
|
.debug()
|
|
.withLogFile()
|
|
.withLogTopics(
|
|
"marketplace",
|
|
"sales",
|
|
"reservations",
|
|
"node",
|
|
"JSONRPC-HTTP-CLIENT",
|
|
"JSONRPC-WS-CLIENT",
|
|
"ethers",
|
|
"restapi",
|
|
"clock"
|
|
),
|
|
|
|
validators: NodeConfig()
|
|
.nodes(1)
|
|
.withLogFile()
|
|
.withLogTopics("validator", "initial-proving", "proving", "clock", "onchain", "ethers")
|
|
):
|
|
|
|
test "hosts submit periodic proofs for slots they fill":
|
|
let client0 = clients()[0].node.client
|
|
let totalProofs = 50
|
|
|
|
let data = byteutils.toHex(await exampleData())
|
|
createAvailabilities(data.len, totalProofs.periods)
|
|
|
|
let cid = client0.upload(data).get
|
|
|
|
let purchaseId = await client0.requestStorage(cid, duration=totalProofs.periods)
|
|
check eventually client0.purchaseStateIs(purchaseId, "started")
|
|
|
|
var proofWasSubmitted = false
|
|
proc onProofSubmitted(event: ProofSubmitted) =
|
|
proofWasSubmitted = true
|
|
|
|
let subscription = await marketplace.subscribe(ProofSubmitted, onProofSubmitted)
|
|
|
|
let currentPeriod = await getCurrentPeriod()
|
|
let timeUntilLastPeriod = await timeUntil(currentPeriod + totalProofs.u256 + 1)
|
|
check eventually(proofWasSubmitted, timeUntilLastPeriod.inMilliseconds.int)
|
|
|
|
await subscription.unsubscribe()
|
|
|
|
test "slot is not freed when not enough invalid proofs submitted":
|
|
let client0 = clients()[0].node.client
|
|
let totalProofs = 25
|
|
|
|
let data = byteutils.toHex(await exampleData())
|
|
createAvailabilities(data.len, totalProofs.periods)
|
|
|
|
let cid = client0.upload(data).get
|
|
|
|
let purchaseId = await client0.requestStorage(cid, duration=totalProofs.periods)
|
|
let requestId = client0.requestId(purchaseId).get
|
|
|
|
check eventually client0.purchaseStateIs(purchaseId, "started")
|
|
|
|
var slotWasFreed = false
|
|
proc onSlotFreed(event: SlotFreed) {.gcsafe, upraises:[].} =
|
|
if event.requestId == requestId and
|
|
event.slotIndex == 0.u256: # assume only one slot, so index 0
|
|
slotWasFreed = true
|
|
|
|
let subscription = await marketplace.subscribe(SlotFreed, onSlotFreed)
|
|
|
|
# check not freed
|
|
let currentPeriod = await getCurrentPeriod()
|
|
let timeUntilLastPeriod = await timeUntil(currentPeriod + totalProofs.u256 + 1)
|
|
check not eventually(slotWasFreed, timeUntilLastPeriod.inMilliseconds.int)
|
|
|
|
await subscription.unsubscribe()
|
|
|
|
marketplacesuite "Simulate invalid proofs",
|
|
Nodes(
|
|
# Uncomment to start Hardhat automatically, mainly so logs can be inspected locally
|
|
# hardhat: HardhatConfig()
|
|
# .withLogFile(),
|
|
|
|
clients: NodeConfig()
|
|
.nodes(1)
|
|
.debug()
|
|
.withLogFile()
|
|
.withLogTopics("node", "erasure"),
|
|
|
|
providers: NodeConfig()
|
|
.nodes(2)
|
|
.simulateProofFailuresFor(providerIdx=0, failEveryNProofs=2)
|
|
.debug()
|
|
.withLogFile()
|
|
.withLogTopics(
|
|
"marketplace",
|
|
"sales",
|
|
"reservations",
|
|
"node",
|
|
"JSONRPC-HTTP-CLIENT",
|
|
"JSONRPC-WS-CLIENT",
|
|
"ethers",
|
|
"restapi"
|
|
),
|
|
|
|
validators: NodeConfig()
|
|
.nodes(1)
|
|
.withLogFile()
|
|
.withLogTopics("validator", "initial-proving", "proving")
|
|
):
|
|
|
|
# TODO: these are very loose tests in that they are not testing EXACTLY how
|
|
# proofs were marked as missed by the validator. These tests should be
|
|
# tightened so that they are showing, as an integration test, that specific
|
|
# proofs are being marked as missed by the validator.
|
|
|
|
test "provider that submits invalid proofs is paid out less":
|
|
let client0 = clients()[0].node.client
|
|
let provider0 = providers()[0]
|
|
let provider1 = providers()[1]
|
|
let totalProofs = 25
|
|
|
|
let data = byteutils.toHex(await exampleData())
|
|
# createAvailabilities(data.len, totalProofs.periods)
|
|
|
|
discard provider0.node.client.postAvailability(
|
|
size=data.len.u256, # should match 1 slot only
|
|
duration=totalProofs.periods.u256,
|
|
minPrice=300.u256,
|
|
maxCollateral=200.u256
|
|
)
|
|
|
|
let cid = client0.upload(data).get
|
|
|
|
let purchaseId = await client0.requestStorage(
|
|
cid,
|
|
duration=totalProofs.periods,
|
|
# tolerance=1
|
|
)
|
|
|
|
without requestId =? client0.requestId(purchaseId):
|
|
fail()
|
|
|
|
|
|
var provider0slotIndex = none UInt256
|
|
proc onSlotFilled(event: SlotFilled) {.upraises:[].} =
|
|
provider0slotIndex = some event.slotIndex
|
|
|
|
let subscription = await marketplace.subscribe(SlotFilled, onSlotFilled)
|
|
|
|
# wait til first slot is filled
|
|
check eventually provider0slotIndex.isSome
|
|
|
|
# now add availability for provider1, which should allow provider1 to put
|
|
# the remaining slot in its queue
|
|
discard provider1.node.client.postAvailability(
|
|
size=data.len.u256, # should match 1 slot only
|
|
duration=totalProofs.periods.u256,
|
|
minPrice=300.u256,
|
|
maxCollateral=200.u256
|
|
)
|
|
let provider1slotIndex = if provider0slotIndex == some 0.u256: 1.u256 else: 0.u256
|
|
let provider0slotId = slotId(requestId, !provider0slotIndex)
|
|
let provider1slotId = slotId(requestId, provider1slotIndex)
|
|
|
|
# Wait til second slot is filled. SaleFilled happens too quickly, check SaleProving instead.
|
|
check eventually provider1.node.client.saleStateIs(provider1slotId, "SaleProving")
|
|
|
|
check eventually client0.purchaseStateIs(purchaseId, "started")
|
|
|
|
let currentPeriod = await getCurrentPeriod()
|
|
let timeUntilLastPeriod = await timeUntil(currentPeriod + totalProofs.u256 + 1)
|
|
# check eventually(
|
|
# client0.purchaseStateIs(purchaseId, "finished"),
|
|
# timeUntilLastPeriod.inMilliseconds.int)
|
|
check eventually(
|
|
# SaleFinished happens too quickly, check SalePayout instead
|
|
provider0.node.client.saleStateIs(provider0slotId, "SalePayout"),
|
|
timeUntilLastPeriod.inMilliseconds.int)
|
|
|
|
check eventually(
|
|
# SaleFinished happens too quickly, check SalePayout instead
|
|
provider1.node.client.saleStateIs(provider1slotId, "SalePayout"),
|
|
timeUntilLastPeriod.inMilliseconds.int)
|
|
|
|
check eventually(
|
|
(await token.balanceOf(!provider1.address)) >
|
|
(await token.balanceOf(!provider0.address))
|
|
)
|
|
|
|
await subscription.unsubscribe()
|