nim-codex/tests/integration/testproofs.nim

267 lines
9.9 KiB
Nim
Raw Normal View History

2023-11-02 12:00:35 +00:00
from std/times import inMilliseconds
import pkg/chronicles
fix: unknown state goes to payout when slot state is finished (#555) Support logging to file Log the entire config and fix build error Process slot queue on reservation callback onMarkUnused Add Reservation object, rename reserve > create refactor Reservations api to include Reservation CRUD All tests that use the Reservation module updated - add requestId and slotIndex to Reservation (hopefully these will prove to be useful when we persist Reservations until request are completed, to add back bytes to Availability) - add querying of all reservations, with accompanying tests - change from find to findAvailabilities - move onCleanUp from SalesContext to SalesAgent as it was getting overwritten for each slot processed - remove sales agent AFTER deleting reservation, as this was causing some SIGSEGVs - retrofit testsales and testslotqueue to match updated Reservations module API Add deletion of inactive reservations on sales load clean up add exception message detail util Apply to onStore errors as we are seeing undetailed errors in the dist tests logs add missing file change slotsize to reflect current implemenation Fix slotSize to reduce by one block Revert change to slotSize that reduces it by one block Add additional test check for querying reservations/availabilities filter past requests based on availability Because availability filtering on push was removed, when availability is added and past storage request events are queried, those requests need to be filtered by availability before being added to the queue. Revert "filter past requests based on availability" This reverts commit 0c2362658b523e0de425794b1fa30ebd53bd30ae. Add debugging for dist tests Add cancel on error during filling state When calling fillSlot, any transaction errors that occur (possibly during estimate gas) will cause that tx to be replaced with a cancellation transaction (a 0-valued tx to ourselves). more debug logging fix build wait for fillSlot to be mined (so that a revert error can be extracted) fix confirmation of fillSlot add more debugging moar debugging debugging: change echo to trace bump ethers to add chronicles fix contracts tests switch to earlier nim-ethers commit bump json-rpc and nim-ethers bump nim-ethers to prevent parsing newHeads log from crashing sales state machine moar debugging moar debugging moar debugging bump ethers to fix "key not found: data" error ethers debug logging bump ethers - better Transaction object deserialization bump ethers to replay tx with past tx format bump ethers to add serialization for PastTransaction ethers bump: better logging, separate logic for revert reason string fix build ethers: update revert reason retreival remove unneeded confirm ethers: try replay without decrementing blockNumber ethers: include type and chainId in replayed txs ethers: add gas into and remove type from replayed txs ensure gas is being serialized in Transaction ethers: fix build error bump ethers: rebased on top of cancel tx due to estimateGas error PR Fix proving with latest ethers bump (tested on master) Update multinode suite for better simulateFailedProofs enabling, add proofs test Improve multinode suite for better debug options, including logging to file There is a 503 "sales unavailable" error improve multinode test suite, add logging to file
2023-09-27 13:57:41 +00:00
import pkg/stew/byteutils
import ../contracts/time
import ../contracts/deployment
fix: unknown state goes to payout when slot state is finished (#555) Support logging to file Log the entire config and fix build error Process slot queue on reservation callback onMarkUnused Add Reservation object, rename reserve > create refactor Reservations api to include Reservation CRUD All tests that use the Reservation module updated - add requestId and slotIndex to Reservation (hopefully these will prove to be useful when we persist Reservations until request are completed, to add back bytes to Availability) - add querying of all reservations, with accompanying tests - change from find to findAvailabilities - move onCleanUp from SalesContext to SalesAgent as it was getting overwritten for each slot processed - remove sales agent AFTER deleting reservation, as this was causing some SIGSEGVs - retrofit testsales and testslotqueue to match updated Reservations module API Add deletion of inactive reservations on sales load clean up add exception message detail util Apply to onStore errors as we are seeing undetailed errors in the dist tests logs add missing file change slotsize to reflect current implemenation Fix slotSize to reduce by one block Revert change to slotSize that reduces it by one block Add additional test check for querying reservations/availabilities filter past requests based on availability Because availability filtering on push was removed, when availability is added and past storage request events are queried, those requests need to be filtered by availability before being added to the queue. Revert "filter past requests based on availability" This reverts commit 0c2362658b523e0de425794b1fa30ebd53bd30ae. Add debugging for dist tests Add cancel on error during filling state When calling fillSlot, any transaction errors that occur (possibly during estimate gas) will cause that tx to be replaced with a cancellation transaction (a 0-valued tx to ourselves). more debug logging fix build wait for fillSlot to be mined (so that a revert error can be extracted) fix confirmation of fillSlot add more debugging moar debugging debugging: change echo to trace bump ethers to add chronicles fix contracts tests switch to earlier nim-ethers commit bump json-rpc and nim-ethers bump nim-ethers to prevent parsing newHeads log from crashing sales state machine moar debugging moar debugging moar debugging bump ethers to fix "key not found: data" error ethers debug logging bump ethers - better Transaction object deserialization bump ethers to replay tx with past tx format bump ethers to add serialization for PastTransaction ethers bump: better logging, separate logic for revert reason string fix build ethers: update revert reason retreival remove unneeded confirm ethers: try replay without decrementing blockNumber ethers: include type and chainId in replayed txs ethers: add gas into and remove type from replayed txs ensure gas is being serialized in Transaction ethers: fix build error bump ethers: rebased on top of cancel tx due to estimateGas error PR Fix proving with latest ethers bump (tested on master) Update multinode suite for better simulateFailedProofs enabling, add proofs test Improve multinode suite for better debug options, including logging to file There is a 503 "sales unavailable" error improve multinode test suite, add logging to file
2023-09-27 13:57:41 +00:00
import ../codex/helpers
2023-10-26 04:47:08 +00:00
import ../examples
import ./marketplacesuite
fix: unknown state goes to payout when slot state is finished (#555) Support logging to file Log the entire config and fix build error Process slot queue on reservation callback onMarkUnused Add Reservation object, rename reserve > create refactor Reservations api to include Reservation CRUD All tests that use the Reservation module updated - add requestId and slotIndex to Reservation (hopefully these will prove to be useful when we persist Reservations until request are completed, to add back bytes to Availability) - add querying of all reservations, with accompanying tests - change from find to findAvailabilities - move onCleanUp from SalesContext to SalesAgent as it was getting overwritten for each slot processed - remove sales agent AFTER deleting reservation, as this was causing some SIGSEGVs - retrofit testsales and testslotqueue to match updated Reservations module API Add deletion of inactive reservations on sales load clean up add exception message detail util Apply to onStore errors as we are seeing undetailed errors in the dist tests logs add missing file change slotsize to reflect current implemenation Fix slotSize to reduce by one block Revert change to slotSize that reduces it by one block Add additional test check for querying reservations/availabilities filter past requests based on availability Because availability filtering on push was removed, when availability is added and past storage request events are queried, those requests need to be filtered by availability before being added to the queue. Revert "filter past requests based on availability" This reverts commit 0c2362658b523e0de425794b1fa30ebd53bd30ae. Add debugging for dist tests Add cancel on error during filling state When calling fillSlot, any transaction errors that occur (possibly during estimate gas) will cause that tx to be replaced with a cancellation transaction (a 0-valued tx to ourselves). more debug logging fix build wait for fillSlot to be mined (so that a revert error can be extracted) fix confirmation of fillSlot add more debugging moar debugging debugging: change echo to trace bump ethers to add chronicles fix contracts tests switch to earlier nim-ethers commit bump json-rpc and nim-ethers bump nim-ethers to prevent parsing newHeads log from crashing sales state machine moar debugging moar debugging moar debugging bump ethers to fix "key not found: data" error ethers debug logging bump ethers - better Transaction object deserialization bump ethers to replay tx with past tx format bump ethers to add serialization for PastTransaction ethers bump: better logging, separate logic for revert reason string fix build ethers: update revert reason retreival remove unneeded confirm ethers: try replay without decrementing blockNumber ethers: include type and chainId in replayed txs ethers: add gas into and remove type from replayed txs ensure gas is being serialized in Transaction ethers: fix build error bump ethers: rebased on top of cancel tx due to estimateGas error PR Fix proving with latest ethers bump (tested on master) Update multinode suite for better simulateFailedProofs enabling, add proofs test Improve multinode suite for better debug options, including logging to file There is a 503 "sales unavailable" error improve multinode test suite, add logging to file
2023-09-27 13:57:41 +00:00
export chronicles
fix: unknown state goes to payout when slot state is finished (#555) Support logging to file Log the entire config and fix build error Process slot queue on reservation callback onMarkUnused Add Reservation object, rename reserve > create refactor Reservations api to include Reservation CRUD All tests that use the Reservation module updated - add requestId and slotIndex to Reservation (hopefully these will prove to be useful when we persist Reservations until request are completed, to add back bytes to Availability) - add querying of all reservations, with accompanying tests - change from find to findAvailabilities - move onCleanUp from SalesContext to SalesAgent as it was getting overwritten for each slot processed - remove sales agent AFTER deleting reservation, as this was causing some SIGSEGVs - retrofit testsales and testslotqueue to match updated Reservations module API Add deletion of inactive reservations on sales load clean up add exception message detail util Apply to onStore errors as we are seeing undetailed errors in the dist tests logs add missing file change slotsize to reflect current implemenation Fix slotSize to reduce by one block Revert change to slotSize that reduces it by one block Add additional test check for querying reservations/availabilities filter past requests based on availability Because availability filtering on push was removed, when availability is added and past storage request events are queried, those requests need to be filtered by availability before being added to the queue. Revert "filter past requests based on availability" This reverts commit 0c2362658b523e0de425794b1fa30ebd53bd30ae. Add debugging for dist tests Add cancel on error during filling state When calling fillSlot, any transaction errors that occur (possibly during estimate gas) will cause that tx to be replaced with a cancellation transaction (a 0-valued tx to ourselves). more debug logging fix build wait for fillSlot to be mined (so that a revert error can be extracted) fix confirmation of fillSlot add more debugging moar debugging debugging: change echo to trace bump ethers to add chronicles fix contracts tests switch to earlier nim-ethers commit bump json-rpc and nim-ethers bump nim-ethers to prevent parsing newHeads log from crashing sales state machine moar debugging moar debugging moar debugging bump ethers to fix "key not found: data" error ethers debug logging bump ethers - better Transaction object deserialization bump ethers to replay tx with past tx format bump ethers to add serialization for PastTransaction ethers bump: better logging, separate logic for revert reason string fix build ethers: update revert reason retreival remove unneeded confirm ethers: try replay without decrementing blockNumber ethers: include type and chainId in replayed txs ethers: add gas into and remove type from replayed txs ensure gas is being serialized in Transaction ethers: fix build error bump ethers: rebased on top of cancel tx due to estimateGas error PR Fix proving with latest ethers bump (tested on master) Update multinode suite for better simulateFailedProofs enabling, add proofs test Improve multinode suite for better debug options, including logging to file There is a 503 "sales unavailable" error improve multinode test suite, add logging to file
2023-09-27 13:57:41 +00:00
logScope:
topics = "integration test proofs"
marketplacesuite "Hosts submit regular proofs":
test "hosts submit periodic proofs for slots they fill", NodeConfigs(
# Uncomment to start Hardhat automatically, mainly so logs can be inspected locally
# hardhat: HardhatConfig().withLogFile()
clients:
NodeConfig()
.nodes(1)
# .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"),
providers:
NodeConfig()
.nodes(1)
# .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("marketplace", "sales", "reservations", "node"),
):
let client0 = clients()[0].node.client
let totalPeriods = 50
2023-11-06 02:10:23 +00:00
let data = byteutils.toHex(await exampleData())
createAvailabilities(data.len, totalPeriods.periods)
2023-11-06 02:10:23 +00:00
let cid = client0.upload(data).get
2023-11-06 02:10:23 +00:00
let purchaseId = await client0.requestStorage(cid, duration=totalPeriods.periods)
check eventually client0.purchaseStateIs(purchaseId, "started")
2023-11-06 02:10:23 +00:00
var proofWasSubmitted = false
proc onProofSubmitted(event: ProofSubmitted) =
proofWasSubmitted = true
2023-11-06 02:10:23 +00:00
let subscription = await marketplace.subscribe(ProofSubmitted, onProofSubmitted)
2023-11-06 02:10:23 +00:00
let currentPeriod = await getCurrentPeriod()
check eventuallyP(proofWasSubmitted, currentPeriod + totalPeriods.u256 + 1)
await subscription.unsubscribe()
2023-11-06 02:10:23 +00:00
marketplacesuite "Simulate invalid proofs":
2023-11-06 02:10:23 +00:00
# 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 "slot is freed after too many invalid proofs submitted", NodeConfigs(
# Uncomment to start Hardhat automatically, mainly so logs can be inspected locally
# hardhat: HardhatConfig().withLogFile()
clients:
NodeConfig()
.nodes(1)
# .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"),
providers:
NodeConfig()
.nodes(1)
.simulateProofFailuresFor(providerIdx=0, failEveryNProofs=1)
# .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
2023-11-23 01:39:23 +00:00
.withLogTopics("marketplace", "sales", "reservations", "node"),
validators:
NodeConfig()
.nodes(1)
.withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
# .debug() # uncomment to enable console log output
2023-11-23 01:39:23 +00:00
.withLogTopics("validator", "onchain", "ethers")
2023-11-06 02:10:23 +00:00
):
let client0 = clients()[0].node.client
let totalPeriods = 50
2023-11-06 02:10:23 +00:00
let data = byteutils.toHex(await exampleData())
createAvailabilities(data.len, totalPeriods.periods)
2023-11-06 02:10:23 +00:00
let cid = client0.upload(data).get
2023-11-06 02:10:23 +00:00
let purchaseId = await client0.requestStorage(cid, duration=totalPeriods.periods)
let requestId = client0.requestId(purchaseId).get
2023-11-06 02:10:23 +00:00
check eventually client0.purchaseStateIs(purchaseId, "started")
2023-11-06 02:10:23 +00:00
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
2023-11-06 02:10:23 +00:00
let subscription = await marketplace.subscribe(SlotFreed, onSlotFreed)
2023-11-06 02:10:23 +00:00
let currentPeriod = await getCurrentPeriod()
check eventuallyP(slotWasFreed, currentPeriod + totalPeriods.u256 + 1)
2023-11-06 02:10:23 +00:00
await subscription.unsubscribe()
2023-11-06 02:10:23 +00:00
test "slot is not freed when not enough invalid proofs submitted", NodeConfigs(
# Uncomment to start Hardhat automatically, mainly so logs can be inspected locally
# hardhat: HardhatConfig().withLogFile()
clients:
NodeConfig()
.nodes(1)
# .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"),
providers:
NodeConfig()
.nodes(1)
.simulateProofFailuresFor(providerIdx=0, failEveryNProofs=3)
# .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
2023-11-23 01:39:23 +00:00
.withLogTopics("marketplace", "sales", "reservations", "node"),
validators:
NodeConfig()
.nodes(1)
# .debug()
.withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
2023-11-23 01:39:23 +00:00
.withLogTopics("validator", "onchain", "ethers")
):
let client0 = clients()[0].node.client
let totalPeriods = 25
2023-11-06 02:10:23 +00:00
let data = byteutils.toHex(await exampleData())
createAvailabilities(data.len, totalPeriods.periods)
2023-11-06 02:10:23 +00:00
let cid = client0.upload(data).get
2023-11-06 02:10:23 +00:00
let purchaseId = await client0.requestStorage(cid, duration=totalPeriods.periods)
let requestId = client0.requestId(purchaseId).get
2023-11-06 02:10:23 +00:00
check eventually client0.purchaseStateIs(purchaseId, "started")
2023-11-06 02:10:23 +00:00
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
2023-11-06 02:10:23 +00:00
let subscription = await marketplace.subscribe(SlotFreed, onSlotFreed)
2023-11-06 02:10:23 +00:00
# check not freed
let currentPeriod = await getCurrentPeriod()
check not eventuallyP(slotWasFreed, currentPeriod + totalPeriods.u256 + 1)
2023-11-06 02:10:23 +00:00
await subscription.unsubscribe()
2023-11-02 12:00:35 +00:00
test "host that submits invalid proofs is paid out less", NodeConfigs(
# Uncomment to start Hardhat automatically, mainly so logs can be inspected locally
# hardhat: HardhatConfig().withLogFile()
clients:
NodeConfig()
.nodes(1)
# .debug() # uncomment to enable console log output.debug()
.withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
.withLogTopics("node", "erasure", "clock", "purchases"),
providers:
NodeConfig()
.nodes(2)
.simulateProofFailuresFor(providerIdx=0, failEveryNProofs=2)
# .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
2023-11-23 01:39:23 +00:00
.withLogTopics("marketplace", "sales", "reservations", "node"),
validators:
NodeConfig()
.nodes(1)
# .debug()
.withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
.withLogTopics("validator")
fix: unknown state goes to payout when slot state is finished (#555) Support logging to file Log the entire config and fix build error Process slot queue on reservation callback onMarkUnused Add Reservation object, rename reserve > create refactor Reservations api to include Reservation CRUD All tests that use the Reservation module updated - add requestId and slotIndex to Reservation (hopefully these will prove to be useful when we persist Reservations until request are completed, to add back bytes to Availability) - add querying of all reservations, with accompanying tests - change from find to findAvailabilities - move onCleanUp from SalesContext to SalesAgent as it was getting overwritten for each slot processed - remove sales agent AFTER deleting reservation, as this was causing some SIGSEGVs - retrofit testsales and testslotqueue to match updated Reservations module API Add deletion of inactive reservations on sales load clean up add exception message detail util Apply to onStore errors as we are seeing undetailed errors in the dist tests logs add missing file change slotsize to reflect current implemenation Fix slotSize to reduce by one block Revert change to slotSize that reduces it by one block Add additional test check for querying reservations/availabilities filter past requests based on availability Because availability filtering on push was removed, when availability is added and past storage request events are queried, those requests need to be filtered by availability before being added to the queue. Revert "filter past requests based on availability" This reverts commit 0c2362658b523e0de425794b1fa30ebd53bd30ae. Add debugging for dist tests Add cancel on error during filling state When calling fillSlot, any transaction errors that occur (possibly during estimate gas) will cause that tx to be replaced with a cancellation transaction (a 0-valued tx to ourselves). more debug logging fix build wait for fillSlot to be mined (so that a revert error can be extracted) fix confirmation of fillSlot add more debugging moar debugging debugging: change echo to trace bump ethers to add chronicles fix contracts tests switch to earlier nim-ethers commit bump json-rpc and nim-ethers bump nim-ethers to prevent parsing newHeads log from crashing sales state machine moar debugging moar debugging moar debugging bump ethers to fix "key not found: data" error ethers debug logging bump ethers - better Transaction object deserialization bump ethers to replay tx with past tx format bump ethers to add serialization for PastTransaction ethers bump: better logging, separate logic for revert reason string fix build ethers: update revert reason retreival remove unneeded confirm ethers: try replay without decrementing blockNumber ethers: include type and chainId in replayed txs ethers: add gas into and remove type from replayed txs ensure gas is being serialized in Transaction ethers: fix build error bump ethers: rebased on top of cancel tx due to estimateGas error PR Fix proving with latest ethers bump (tested on master) Update multinode suite for better simulateFailedProofs enabling, add proofs test Improve multinode suite for better debug options, including logging to file There is a 503 "sales unavailable" error improve multinode test suite, add logging to file
2023-09-27 13:57:41 +00:00
):
2023-11-02 12:00:35 +00:00
let client0 = clients()[0].node.client
let provider0 = providers()[0]
let provider1 = providers()[1]
let totalPeriods = 25
2023-11-02 12:00:35 +00:00
let data = byteutils.toHex(await exampleData())
2023-11-02 12:00:35 +00:00
discard provider0.node.client.postAvailability(
size=data.len.u256, # should match 1 slot only
duration=totalPeriods.periods.u256,
2023-11-02 12:00:35 +00:00
minPrice=300.u256,
maxCollateral=200.u256
)
2023-11-02 12:00:35 +00:00
let cid = client0.upload(data).get
2023-11-02 12:00:35 +00:00
let purchaseId = await client0.requestStorage(
cid,
duration=totalPeriods.periods,
expiry=10.periods
2023-11-02 12:00:35 +00:00
)
2023-11-02 12:00:35 +00:00
without requestId =? client0.requestId(purchaseId):
fail()
2023-11-02 12:00:35 +00:00
var provider0slotIndex = none UInt256
proc onSlotFilled(event: SlotFilled) {.upraises:[].} =
provider0slotIndex = some event.slotIndex
2023-11-02 12:00:35 +00:00
let subscription = await marketplace.subscribe(SlotFilled, onSlotFilled)
2023-11-02 12:00:35 +00:00
# wait til first slot is filled
check eventually provider0slotIndex.isSome
2023-11-02 12:00:35 +00:00
# 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=totalPeriods.periods.u256,
2023-11-02 12:00:35 +00:00
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)
2023-11-06 02:10:23 +00:00
# Wait til second slot is filled. SaleFilled happens too quickly, check SaleProving instead.
check eventually provider1.node.client.saleStateIs(provider1slotId, "SaleProving")
2023-11-02 12:00:35 +00:00
check eventually client0.purchaseStateIs(purchaseId, "started")
2023-11-02 12:00:35 +00:00
let currentPeriod = await getCurrentPeriod()
check eventuallyP(
2023-11-06 02:10:23 +00:00
# SaleFinished happens too quickly, check SalePayout instead
provider0.node.client.saleStateIs(provider0slotId, "SalePayout"),
currentPeriod + totalPeriods.u256 + 1)
check eventuallyP(
2023-11-06 02:10:23 +00:00
# SaleFinished happens too quickly, check SalePayout instead
provider1.node.client.saleStateIs(provider1slotId, "SalePayout"),
currentPeriod + totalPeriods.u256 + 1)
2023-11-02 12:00:35 +00:00
check eventually(
(await token.balanceOf(!provider1.address)) >
(await token.balanceOf(!provider0.address))
)
2023-11-02 12:00:35 +00:00
await subscription.unsubscribe()