diff --git a/tests/integration/hardhatconfig.nim b/tests/integration/hardhatconfig.nim index bd454e36..637b40c0 100644 --- a/tests/integration/hardhatconfig.nim +++ b/tests/integration/hardhatconfig.nim @@ -3,4 +3,4 @@ import ./nodeconfig export nodeconfig type - HardhatConfig* = ref object of NodeConfig \ No newline at end of file + HardhatConfig* = ref object of NodeConfig diff --git a/tests/integration/marketplacesuite.nim b/tests/integration/marketplacesuite.nim index 9d1d44b9..65389c11 100644 --- a/tests/integration/marketplacesuite.nim +++ b/tests/integration/marketplacesuite.nim @@ -1,8 +1,12 @@ import pkg/chronos +import pkg/ethers/erc20 +from pkg/libp2p import Cid import pkg/codex/contracts/marketplace as mp import pkg/codex/periods import pkg/codex/utils/json import ./multinodes +import ../contracts/time +import ../contracts/deployment export mp export multinodes diff --git a/tests/integration/multinodes.nim b/tests/integration/multinodes.nim index 9f1e5117..22e21c3e 100644 --- a/tests/integration/multinodes.nim +++ b/tests/integration/multinodes.nim @@ -10,6 +10,7 @@ import ./hardhatprocess import ./codexprocess import ./hardhatconfig import ./codexconfig +import ../checktest export asynctest export ethers except `%` diff --git a/tests/integration/testIntegration.nim b/tests/integration/testIntegration.nim index 2287fd59..e05aa6f9 100644 --- a/tests/integration/testIntegration.nim +++ b/tests/integration/testIntegration.nim @@ -228,82 +228,3 @@ twonodessuite "Integration tests", debug1 = false, debug2 = false: check responseBefore.body == "Expiry has to be before the request's end (now + duration)" -marketplacesuite "Marketplace payouts": - - test "expired request partially pays out for stored time", - NodeConfigs( - # Uncomment to start Hardhat automatically, typically so logs can be inspected locally - # hardhat: HardhatConfig().withLogFile() - - clients: - CodexConfig() - .nodes(1) - # .debug() # uncomment to enable console log output.debug() - .withLogFile() # uncomment to output log file to tests/integration/logs/ //_.log - .withLogTopics("node", "erasure"), - - providers: - CodexConfig() - .nodes(1) - # .debug() # uncomment to enable console log output - .withLogFile() # uncomment to output log file to tests/integration/logs/ //_.log - .withLogTopics("marketplace", "sales", "reservations", "node", "proving", "clock"), - ): - let reward = 400.u256 - let duration = 100.periods - let collateral = 200.u256 - let expiry = 4.periods - let data = byteutils.toHex(await exampleData()) - let client = clients()[0] - let provider = providers()[0] - let clientApi = client.client - let providerApi = provider.client - let startBalanceProvider = await token.balanceOf(provider.ethAccount) - let startBalanceClient = await token.balanceOf(client.ethAccount) - - # provider makes storage available - discard providerApi.postAvailability( - size=data.len.u256, - duration=duration.u256, - minPrice=reward, - maxCollateral=collateral) - - let cid = clientApi.upload(data).get - - var slotIdxFilled = none UInt256 - proc onSlotFilled(event: SlotFilled) {.upraises:[].} = - slotIdxFilled = some event.slotIndex - let subscription = await marketplace.subscribe(SlotFilled, onSlotFilled) - - # client requests storage but requires two nodes to host the content - let id = await clientApi.requestStorage( - cid, - duration=duration, - reward=reward, - expiry=expiry, - collateral=collateral, - nodes=2 - ) - - # wait until one slot is filled - check eventually slotIdxFilled.isSome - - # wait until sale is cancelled - without requestId =? clientApi.requestId(id): - fail() - let slotId = slotId(requestId, !slotIdxFilled) - check eventually(providerApi.saleStateIs(slotId, "SaleCancelled")) - - check eventually ( - let endBalanceProvider = (await token.balanceOf(provider.ethAccount)); - let difference = endBalanceProvider - startBalanceProvider; - difference > 0 and - difference < expiry.u256*reward - ) - check eventually ( - let endBalanceClient = (await token.balanceOf(client.ethAccount)); - let endBalanceProvider = (await token.balanceOf(provider.ethAccount)); - (startBalanceClient - endBalanceClient) == (endBalanceProvider - startBalanceProvider) - ) - - await subscription.unsubscribe() diff --git a/tests/integration/testmarketplace.nim b/tests/integration/testmarketplace.nim new file mode 100644 index 00000000..924b2d03 --- /dev/null +++ b/tests/integration/testmarketplace.nim @@ -0,0 +1,83 @@ +import pkg/stew/byteutils +import ./marketplacesuite +import ../examples + +marketplacesuite "Marketplace payouts": + + test "expired request partially pays out for stored time", + NodeConfigs( + # Uncomment to start Hardhat automatically, typically so logs can be inspected locally + # hardhat: HardhatConfig().withLogFile() + + clients: + CodexConfig() + .nodes(1) + # .debug() # uncomment to enable console log output.debug() + .withLogFile() # uncomment to output log file to tests/integration/logs/ //_.log + .withLogTopics("node", "erasure"), + + providers: + CodexConfig() + .nodes(1) + # .debug() # uncomment to enable console log output + .withLogFile() # uncomment to output log file to tests/integration/logs/ //_.log + .withLogTopics("marketplace", "sales", "reservations", "node", "proving", "clock"), + ): + let reward = 400.u256 + let duration = 100.periods + let collateral = 200.u256 + let expiry = 4.periods + let data = byteutils.toHex(await exampleData()) + let client = clients()[0] + let provider = providers()[0] + let clientApi = client.client + let providerApi = provider.client + let startBalanceProvider = await token.balanceOf(provider.ethAccount) + let startBalanceClient = await token.balanceOf(client.ethAccount) + + # provider makes storage available + discard providerApi.postAvailability( + size=data.len.u256, + duration=duration.u256, + minPrice=reward, + maxCollateral=collateral) + + let cid = clientApi.upload(data).get + + var slotIdxFilled = none UInt256 + proc onSlotFilled(event: SlotFilled) {.upraises:[].} = + slotIdxFilled = some event.slotIndex + let subscription = await marketplace.subscribe(SlotFilled, onSlotFilled) + + # client requests storage but requires two nodes to host the content + let id = await clientApi.requestStorage( + cid, + duration=duration, + reward=reward, + expiry=expiry, + collateral=collateral, + nodes=2 + ) + + # wait until one slot is filled + check eventually slotIdxFilled.isSome + + # wait until sale is cancelled + without requestId =? clientApi.requestId(id): + fail() + let slotId = slotId(requestId, !slotIdxFilled) + check eventually(providerApi.saleStateIs(slotId, "SaleCancelled")) + + check eventually ( + let endBalanceProvider = (await token.balanceOf(provider.ethAccount)); + let difference = endBalanceProvider - startBalanceProvider; + difference > 0 and + difference < expiry.u256*reward + ) + check eventually ( + let endBalanceClient = (await token.balanceOf(client.ethAccount)); + let endBalanceProvider = (await token.balanceOf(provider.ethAccount)); + (startBalanceClient - endBalanceClient) == (endBalanceProvider - startBalanceProvider) + ) + + await subscription.unsubscribe() \ No newline at end of file diff --git a/tests/testIntegration.nim b/tests/testIntegration.nim index 926e992a..eca2e957 100644 --- a/tests/testIntegration.nim +++ b/tests/testIntegration.nim @@ -1,6 +1,7 @@ import ./integration/testcli import ./integration/testIntegration import ./integration/testblockexpiration +import ./integration/testmarketplace import ./integration/testproofs {.warning[UnusedImport]:off.}