Skip to content

Commit

Permalink
simplifies the validation integration tests by waiting for failed req…
Browse files Browse the repository at this point in the history
…uest instead of tracking slots
  • Loading branch information
marcinczenko committed Oct 16, 2024
1 parent c950321 commit 22d4c36
Showing 1 changed file with 20 additions and 75 deletions.
95 changes: 20 additions & 75 deletions tests/integration/testvalidator.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from std/times import inMilliseconds, initDuration, inSeconds, fromUnix
import std/sets
import pkg/codex/logutils
import ../contracts/time
import ../contracts/deployment
Expand All @@ -17,47 +16,6 @@ marketplacesuite "Validation":
let nodes = 3
let tolerance = 1
let proofProbability = 1
var slotsFilled: seq[SlotId]
var slotsFreed: seq[SlotId]

proc trackSlotsFilled(marketplace: Marketplace):
Future[provider.Subscription] {.async.} =
slotsFilled = newSeq[SlotId]()
proc onSlotFilled(event: SlotFilled) =
let slotId = slotId(event.requestId, event.slotIndex)
slotsFilled.add(slotId)
debug "SlotFilled", requestId = event.requestId, slotIndex = event.slotIndex,
slotId = slotId

let subscription = await marketplace.subscribe(SlotFilled, onSlotFilled)
subscription

proc trackSlotsFreed(marketplace: Marketplace, requestId: RequestId):
Future[provider.Subscription] {.async.} =
slotsFreed = newSeq[SlotId]()
proc onSlotFreed(event: SlotFreed) =
if event.requestId == requestId:
let slotId = slotId(event.requestId, event.slotIndex)
slotsFreed.add(slotId)
debug "SlotFreed", requestId = requestId, slotIndex = event.slotIndex,
slotId = slotId, slotsFreed = slotsFreed.len

let subscription = await marketplace.subscribe(SlotFreed, onSlotFreed)
subscription

proc checkSlotsFailed(slotsFilled: seq[SlotId],
slotsFreed: seq[SlotId], marketplace: Marketplace) {.async.} =
let slotsNotFreed = slotsFilled.filter(
slotId => not slotsFreed.contains(slotId)
).toHashSet
var slotsFailed = initHashSet[SlotId]()
for slotId in slotsFilled:
let state = await marketplace.slotState(slotId)
if state == SlotState.Failed:
slotsFailed.incl(slotId)

debug "slots failed", slotsFailed = slotsFailed, slotsNotFreed = slotsNotFreed
check slotsNotFreed == slotsFailed

test "validator marks proofs as missing when using validation groups", NodeConfigs(
# Uncomment to start Hardhat automatically, typically so logs can be inspected locally
Expand All @@ -69,6 +27,7 @@ marketplacesuite "Validation":
# .debug() # uncomment to enable console log output
# .withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
# .withLogTopics("node", "marketplace", "clock")
# .withLogTopics("node", "purchases", "slotqueue", "market")
.some,

providers:
Expand All @@ -87,7 +46,6 @@ marketplacesuite "Validation":
# .debug() # uncomment to enable console log output
# .withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
# .withLogTopics("validator") # each topic as a separate string argument
# .withLogTopics("validator", "integration", "ethers", "clock")
.some
):
let client0 = clients()[0].client
Expand All @@ -103,8 +61,6 @@ marketplacesuite "Validation":
# testproofs.nim - we may want to address it or remove the comment.
createAvailabilities(data.len * 2, duration)

let slotFilledSubscription = await marketplace.trackSlotsFilled()

let cid = client0.upload(data).get

let purchaseId = await client0.requestStorage(
Expand All @@ -127,20 +83,15 @@ marketplacesuite "Validation":

debug "validation suite", secondsTillRequestEnd = secondsTillRequestEnd.seconds

let slotFreedSubscription =
await marketplace.trackSlotsFreed(requestId)

let expectedSlotsFreed = tolerance + 1
check eventually((slotsFreed.len == expectedSlotsFreed),
timeout=(secondsTillRequestEnd + 60) * 1000)

# Because of erasure coding, after (tolerance + 1) slots are freed, the
# remaining nodes are be freed but marked as "Failed" as the whole
# request fails. To capture this we need an extra check:
await checkSlotsFailed(slotsFilled, slotsFreed, marketplace)

await slotFilledSubscription.unsubscribe()
await slotFreedSubscription.unsubscribe()
# Because of Erasure Coding, the expected number of slots being freed
# is tolerance + 1. When more than tolerance slots are freed, the whole
# request will fail. Thus, awaiting for a failing state should
# be sufficient to conclude that validators did their job correctly.
# NOTICE: We actually have to wait for the "errored" state, because
# immediately after withdrawing the funds the purchasing state machine
# transitions to the "errored" state.
check eventually(client0.purchaseStateIs(purchaseId, "errored"),
timeout = (secondsTillRequestEnd + 60) * 1000)

test "validator uses historical state to mark missing proofs", NodeConfigs(
# Uncomment to start Hardhat automatically, typically so logs can be inspected locally
Expand All @@ -152,6 +103,7 @@ marketplacesuite "Validation":
# .debug() # uncomment to enable console log output
# .withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
# .withLogTopics("node", "marketplace", "clock")
# .withLogTopics("node", "purchases", "slotqueue", "market")
.some,

providers:
Expand All @@ -175,8 +127,6 @@ marketplacesuite "Validation":
# testproofs.nim - we may want to address it or remove the comment.
createAvailabilities(data.len * 2, duration)

let slotFilledSubscription = await marketplace.trackSlotsFilled()

let cid = client0.upload(data).get

let purchaseId = await client0.requestStorage(
Expand Down Expand Up @@ -219,18 +169,13 @@ marketplacesuite "Validation":
let secondsTillRequestEnd = (requestEndTime - currentTime.truncate(uint64)).int

debug "validation suite", secondsTillRequestEnd = secondsTillRequestEnd.seconds

let slotFreedSubscription =
await marketplace.trackSlotsFreed(requestId)

let expectedSlotsFreed = tolerance + 1
check eventually((slotsFreed.len == expectedSlotsFreed),
timeout=(secondsTillRequestEnd + 60) * 1000)

# Because of erasure coding, after (tolerance + 1) slots are freed, the
# remaining nodes are be freed but marked as "Failed" as the whole
# request fails. To capture this we need an extra check:
await checkSlotsFailed(slotsFilled, slotsFreed, marketplace)

await slotFilledSubscription.unsubscribe()
await slotFreedSubscription.unsubscribe()
# Because of Erasure Coding, the expected number of slots being freed
# is tolerance + 1. When more than tolerance slots are freed, the whole
# request will fail. Thus, awaiting for a failing state should
# be sufficient to conclude that validators did their job correctly.
# NOTICE: We actually have to wait for the "errored" state, because
# immediately after withdrawing the funds the purchasing state machine
# transitions to the "errored" state.
check eventually(client0.purchaseStateIs(purchaseId, "errored"),
timeout = (secondsTillRequestEnd + 60) * 1000)

0 comments on commit 22d4c36

Please sign in to comment.