Skip to content

Commit 3d7a4b7

Browse files
committed
Check exact balances using ERC20 transfer subscription
1 parent bf5ae2e commit 3d7a4b7

File tree

1 file changed

+65
-23
lines changed

1 file changed

+65
-23
lines changed

tests/integration/30_minutes/testmarketplace.nim

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ marketplacesuite(name = "Marketplace", stopOnRequestFail = true):
8585

8686
# host makes storage available
8787
let startBalanceHost = await token.balanceOf(hostAccount)
88+
let startBalanceClient = await token.balanceOf(clientAccount)
8889
discard (
8990
await host.postAvailability(
9091
totalSize = size,
@@ -94,8 +95,65 @@ marketplacesuite(name = "Marketplace", stopOnRequestFail = true):
9495
)
9596
).get
9697

98+
let slotSize = slotSize(blocks, ecNodes, ecTolerance)
99+
100+
var filledAtPerSlot: seq[UInt256] = @[]
101+
102+
proc storeFilledAtTimestamps() {.async.} =
103+
let filledAt = await ethProvider.blockTime(BlockTag.latest)
104+
filledAtPerSlot.add(filledAt)
105+
106+
proc onSlotFilled(eventResult: ?!SlotFilled) =
107+
assert not eventResult.isErr
108+
let event = !eventResult
109+
asyncSpawn storeFilledAtTimestamps()
110+
111+
let filledSubscription = await marketplace.subscribe(SlotFilled, onSlotFilled)
112+
97113
# client requests storage
98114
let cid = (await client.upload(data)).get
115+
116+
let pricePerSlotPerSecond = minPricePerBytePerSecond * slotSize
117+
var requestEnd = 0.SecondsSince1970
118+
var hostRewardEvent = newAsyncEvent()
119+
120+
proc checkHostRewards() {.async.} =
121+
var rewards = 0.u256
122+
123+
for filledAt in filledAtPerSlot:
124+
rewards += (requestEnd.u256 - filledAt) * pricePerSlotPerSecond
125+
126+
let endBalanceHost = await token.balanceOf(hostAccount)
127+
128+
if rewards + startBalanceHost == endBalanceHost:
129+
hostRewardEvent.fire()
130+
131+
var clientFundsEvent = newAsyncEvent()
132+
133+
proc checkHostFunds() {.async.} =
134+
var hostRewards = 0.u256
135+
136+
for filledAt in filledAtPerSlot:
137+
hostRewards += (requestEnd.u256 - filledAt) * pricePerSlotPerSecond
138+
139+
let requestPrice = minPricePerBytePerSecond * slotSize * duration.u256 * 3
140+
let fundsBackToClient = requestPrice - hostRewards
141+
let endBalanceClient = await token.balanceOf(clientAccount)
142+
143+
if startBalanceClient + fundsBackToClient - requestPrice == endBalanceClient:
144+
clientFundsEvent.fire()
145+
146+
var transferEvent = newAsyncEvent()
147+
148+
proc onTransfer(eventResult: ?!Transfer) =
149+
assert not eventResult.isErr
150+
151+
let data = eventResult.get()
152+
if data.receiver == hostAccount:
153+
asyncSpawn checkHostRewards()
154+
if data.receiver == clientAccount:
155+
asyncSpawn checkHostFunds()
156+
99157
let id = await client.requestStorage(
100158
cid,
101159
duration = duration,
@@ -107,40 +165,24 @@ marketplacesuite(name = "Marketplace", stopOnRequestFail = true):
107165
tolerance = ecTolerance,
108166
)
109167

110-
discard await waitForRequestToStart()
111-
112-
var counter = 0
113-
var transferEvent = newAsyncEvent()
114-
proc onTransfer(eventResult: ?!Transfer) =
115-
assert not eventResult.isErr
116-
counter += 1
117-
if counter == 6:
118-
transferEvent.fire()
119-
120-
let tokenSubscription = await token.subscribe(Transfer, onTransfer)
121-
122-
let purchase = (await client.getPurchase(id)).get
123-
check purchase.error == none string
168+
let requestId = (await client.requestId(id)).get
124169

125-
let clientBalanceBeforeFinished = await token.balanceOf(clientAccount)
170+
discard await waitForRequestToStart()
126171

127172
# Proving mechanism uses blockchain clock to do proving/collect/cleanup round
128173
# hence we must use `advanceTime` over `sleepAsync` as Hardhat does mine new blocks
129174
# only with new transaction
130175
await ethProvider.advanceTime(duration.u256)
131176

132-
await transferEvent.wait().wait(timeout = chronos.seconds(60))
177+
requestEnd = await marketplace.requestEnd(requestId)
133178

134-
# Checking that the hosting node received reward for at least the time between <expiry;end>
135-
let slotSize = slotSize(blocks, ecNodes, ecTolerance)
136-
let pricePerSlotPerSecond = minPricePerBytePerSecond * slotSize
137-
check (await token.balanceOf(hostAccount)) - startBalanceHost >=
138-
(duration - 5 * 60).u256 * pricePerSlotPerSecond * ecNodes.u256
179+
let tokenSubscription = await token.subscribe(Transfer, onTransfer)
139180

140-
# Checking that client node receives some funds back that were not used for the host nodes
141-
check ((await token.balanceOf(clientAccount)) - clientBalanceBeforeFinished > 0)
181+
await clientFundsEvent.wait().wait(timeout = chronos.seconds(60))
182+
await hostRewardEvent.wait().wait(timeout = chronos.seconds(60))
142183

143184
await tokenSubscription.unsubscribe()
185+
await filledSubscription.unsubscribe()
144186

145187
test "SP are able to process slots after workers were busy with other slots and ignored them",
146188
NodeConfigs(

0 commit comments

Comments
 (0)