diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 92bd84867..247808ab1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -280,6 +280,10 @@ jobs: run: yarn local-up working-directory: cli + - name: Run provider tests + run: yarn vitest-provider + working-directory: cli + - name: Run deal deploy tests run: yarn vitest-deal-deploy working-directory: cli @@ -296,9 +300,9 @@ jobs: run: yarn vitest-js-to-aqua working-directory: cli - - name: Run provider tests - run: yarn vitest-provider - working-directory: cli + - name: Show Runner Load Average + run: uptime + if: always() - name: Dump container logs if: always() diff --git a/cli/docs/commands/README.md b/cli/docs/commands/README.md index 5a1b80fe8..d683b1acf 100644 --- a/cli/docs/commands/README.md +++ b/cli/docs/commands/README.md @@ -50,7 +50,7 @@ * [`fluence provider cc-rewards-withdraw`](#fluence-provider-cc-rewards-withdraw) * [`fluence provider deal-exit`](#fluence-provider-deal-exit) * [`fluence provider deal-list`](#fluence-provider-deal-list) -* [`fluence provider deal-rewards-info [DEAL-ADDRESS] [UNIT-ID]`](#fluence-provider-deal-rewards-info-deal-address-unit-id) +* [`fluence provider deal-rewards-info [DEAL-ADDRESS] [ON-CHAIN-WORKER-ID]`](#fluence-provider-deal-rewards-info-deal-address-on-chain-worker-id) * [`fluence provider deal-rewards-withdraw`](#fluence-provider-deal-rewards-withdraw) * [`fluence provider gen`](#fluence-provider-gen) * [`fluence provider info`](#fluence-provider-info) @@ -1466,18 +1466,18 @@ ALIASES _See code: [src/commands/provider/deal-list.ts](https://github.com/fluencelabs/cli/blob/fluence-cli-v0.21.0/src/commands/provider/deal-list.ts)_ -## `fluence provider deal-rewards-info [DEAL-ADDRESS] [UNIT-ID]` +## `fluence provider deal-rewards-info [DEAL-ADDRESS] [ON-CHAIN-WORKER-ID]` Deal rewards info ``` USAGE - $ fluence provider deal-rewards-info [DEAL-ADDRESS] [UNIT-ID] [--no-input] [--env ] [--priv-key ] + $ fluence provider deal-rewards-info [DEAL-ADDRESS] [ON-CHAIN-WORKER-ID] [--no-input] [--env ] [--priv-key ] ARGUMENTS - DEAL-ADDRESS Deal address - UNIT-ID Compute unit ID + DEAL-ADDRESS Deal address + ON-CHAIN-WORKER-ID On-chain worker id FLAGS --env= Fluence Environment to use when running the command diff --git a/cli/docs/configs/provider.md b/cli/docs/configs/provider.md index 88f525532..5e450a093 100644 --- a/cli/docs/configs/provider.md +++ b/cli/docs/configs/provider.md @@ -326,6 +326,7 @@ Decider service configuration | `startBlock` | string | No | Start block (deprecated) | | `walletKey` | string | No | Wallet key (deprecated) | | `workerIpfsMultiaddr` | string | No | Multiaddress of worker IPFS node | +| `workerPeriodSec` | integer | No | Worker period in seconds | ##### vm @@ -517,6 +518,7 @@ Decider service configuration | `startBlock` | string | No | Start block (deprecated) | | `walletKey` | string | No | Wallet key (deprecated) | | `workerIpfsMultiaddr` | string | No | Multiaddress of worker IPFS node | +| `workerPeriodSec` | integer | No | Worker period in seconds | ### vm diff --git a/cli/package.json b/cli/package.json index 93335843d..1b5fc1b99 100644 --- a/cli/package.json +++ b/cli/package.json @@ -35,7 +35,7 @@ "vitest-deal-update": "vitest run dealUpdate.test.ts", "vitest-smoke": "vitest run smoke.test.ts", "vitest-js-to-aqua": "vitest run jsToAqua.test.ts", - "vitest": "yarn vitest-deal-deploy && yarn vitest-deal-update && yarn vitest-smoke && yarn vitest-js-to-aqua && yarn vitest-provider", + "vitest": "yarn vitest-provider && yarn vitest-deal-deploy && yarn vitest-deal-update && yarn vitest-smoke && yarn vitest-js-to-aqua", "pack-linux-x64": "oclif pack tarballs -t \"linux-x64\" --no-xz", "pack-darwin-x64": "oclif pack tarballs -t \"darwin-x64\" --no-xz", "pack-darwin-arm64": "oclif pack tarballs -t \"darwin-arm64\" --no-xz", diff --git a/cli/src/commands/provider/deal-rewards-info.ts b/cli/src/commands/provider/deal-rewards-info.ts index ff1cc7996..272bfd7e0 100644 --- a/cli/src/commands/provider/deal-rewards-info.ts +++ b/cli/src/commands/provider/deal-rewards-info.ts @@ -40,8 +40,8 @@ export default class DealRewardsInfo extends BaseCommand< "DEAL-ADDRESS": Args.string({ description: "Deal address", }), - "UNIT-ID": Args.string({ - description: "Compute unit ID", + "ON-CHAIN-WORKER-ID": Args.string({ + description: "On-chain worker id", }), }; @@ -51,12 +51,13 @@ export default class DealRewardsInfo extends BaseCommand< const dealAddress = args["DEAL-ADDRESS"] ?? (await input({ message: "Enter deal address" })); - const unitId = - args["UNIT-ID"] ?? (await input({ message: "Enter unit id" })); + const onChainWorkerId = + args["ON-CHAIN-WORKER-ID"] ?? + (await input({ message: "Enter on-chain worker id" })); const { readonlyDealClient } = await getReadonlyDealClient(); const deal = readonlyDealClient.getDeal(dealAddress); - const rewardAmount = await deal.getRewardAmount(unitId); + const rewardAmount = await deal.getRewardAmount(onChainWorkerId); commandObj.log( `Provider reward: ${color.yellow( diff --git a/cli/src/commands/provider/deal-rewards-withdraw.ts b/cli/src/commands/provider/deal-rewards-withdraw.ts index 3919556fd..b13f2abde 100644 --- a/cli/src/commands/provider/deal-rewards-withdraw.ts +++ b/cli/src/commands/provider/deal-rewards-withdraw.ts @@ -16,6 +16,7 @@ */ import { BaseCommand, baseFlags } from "../../baseCommand.js"; +import { peerIdHexStringToBase58String } from "../../lib/chain/conversions.js"; import { ptFormatWithSymbol } from "../../lib/chain/currencies.js"; import { commandObj } from "../../lib/commandObj.js"; import { @@ -66,7 +67,20 @@ export default class DealRewardsWithdraw extends BaseCommand< let providerRewards = 0n; let stakerRewards = 0n; - for (const { onchainId } of workers) { + for (const { onchainId, peerId } of workers) { + const rewardAmount = await deal.getRewardAmount(onchainId); + + if ( + rewardAmount.providerReward === 0n && + rewardAmount.stakerReward === 0n + ) { + commandObj.logToStderr( + `No rewards to withdraw for worker ${onchainId} (${await peerIdHexStringToBase58String(peerId)})`, + ); + + continue; + } + const txReceipt = await sign({ title: `Withdraw rewards for worker ${onchainId}`, method: deal.withdrawRewards, diff --git a/cli/src/lib/chain/commitment.ts b/cli/src/lib/chain/commitment.ts index 992010e3e..a382eb342 100644 --- a/cli/src/lib/chain/commitment.ts +++ b/cli/src/lib/chain/commitment.ts @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -import { type ICapacity } from "@fluencelabs/deal-ts-clients"; +import { CommitmentStatus, type ICapacity } from "@fluencelabs/deal-ts-clients"; import { color } from "@oclif/color"; import isUndefined from "lodash-es/isUndefined.js"; import omitBy from "lodash-es/omitBy.js"; @@ -478,8 +478,10 @@ export async function collateralWithdraw( const capacity = dealClient.getCapacity(); const market = dealClient.getMarket(); - for (const commitment of commitments) { - const { commitmentId } = commitment; + for (const commitment of commitments.flatMap(({ ccInfos }) => { + return ccInfos; + })) { + const { commitmentId, noxName } = commitment; const [unitIds, isExitedStatuses] = await capacity.getUnitExitStatuses(commitmentId); @@ -570,7 +572,7 @@ export async function collateralWithdraw( } await signBatch( - `Remove compute units from capacity commitments and finish commitment ${commitmentId}`, + `Remove compute units from capacity commitments and finish commitment ${noxName === undefined ? commitmentId : `for ${noxName} (${commitmentId})`} ${commitmentId}`, [ ...units .filter(({ isExited }) => { @@ -606,7 +608,7 @@ export async function collateralRewardWithdraw(flags: CCFlags) { export function stringifyBasicCommitmentInfo( commitment: | Awaited>[number] - | Awaited>[number], + | Awaited>[number]["ccInfos"][number], ) { if ("providerConfigComputePeer" in commitment) { return `${color.yellow( @@ -637,6 +639,7 @@ export function stringifyBasicCommitmentInfo( export async function getCommitmentsInfo(flags: CCFlags) { const { readonlyDealClient } = await getReadonlyDealClient(); + const { CommitmentStatus } = await import("@fluencelabs/deal-ts-clients"); const capacity = readonlyDealClient.getCapacity(); const core = readonlyDealClient.getCore(); @@ -656,7 +659,7 @@ export async function getCommitmentsInfo(flags: CCFlags) { const dealExplorerClient = await getDealExplorerClient(); - return Promise.all( + const commitmentsInfo = await Promise.all( commitments.map(async (c) => { let commitment: Partial = "commitmentCreatedEvent" in c @@ -713,6 +716,8 @@ export async function getCommitmentsInfo(flags: CCFlags) { initTimestamp + commitment.endEpoch * epochDuration, ); + const status = Number(commitment.status); + return { ...("providerConfigComputePeer" in c ? { @@ -722,10 +727,7 @@ export async function getCommitmentsInfo(flags: CCFlags) { : {}), ccFromExplorer, commitmentId: c.commitmentId, - status: - commitment.status === undefined - ? undefined - : Number(commitment.status), + status: status in CommitmentStatus ? status : undefined, currentEpoch: bigintToStr(currentEpoch), startEpoch: optBigIntToStr(commitment.startEpoch), startDate: ccStartDate, @@ -744,6 +746,29 @@ export async function getCommitmentsInfo(flags: CCFlags) { }; }), ); + + // group commitments by status + return Array.from( + commitmentsInfo + .reduce< + Map + >((acc, v) => { + const infos = acc.get(v.status) ?? []; + infos.push(v); + + acc.set( + v.status !== undefined && v.status in CommitmentStatus + ? v.status + : undefined, + infos, + ); + + return acc; + }, new Map()) + .entries(), + ).map(([status, ccInfos]) => { + return { status, ccInfos }; + }); } function optBigIntToStr(value: bigint | undefined) { @@ -769,25 +794,46 @@ export async function printCommitmentsInfo(flags: CCFlags) { commandObj.logToStderr( ( await Promise.all( - ccInfos.map(async (ccInfo) => { - const noxName = - ccInfo.noxName === undefined - ? "" - : color.yellow(`Nox: ${ccInfo.noxName}\n`); - - return `${noxName}${await getCommitmentInfoString(ccInfo)}`; + ccInfos.map(async ({ status, ccInfos }) => { + return `${await getStatusHeading(status, ccInfos)}${( + await Promise.all( + ccInfos.map(async (ccInfo) => { + const noxName = + ccInfo.noxName === undefined + ? "" + : color.yellow(`Nox: ${ccInfo.noxName}\n`); + + return `${noxName}${await getCommitmentInfoString(ccInfo)}`; + }), + ) + ).join("\n\n")}`; }), ) ).join("\n\n"), ); } +async function getStatusHeading( + status: CommitmentStatus | undefined, + ccInfos: { noxName?: undefined | string; commitmentId: string }[], +) { + return color.yellow( + `Status: ${await ccStatusToString(status)} (${ccInfos + .map(({ commitmentId, noxName }) => { + return noxName ?? commitmentId; + }) + .join(",")})\n\n`, + ); +} + export async function printCommitmentsInfoJSON(flags: CCFlags) { commandObj.log(jsonStringify(await getCommitmentsInfo(flags))); } -export async function getCommitmentInfoString( - ccInfo: Awaited>[number], +async function getCommitmentInfoString( + ccInfo: Awaited< + ReturnType + >[number]["ccInfos"][number], ) { const { ethers } = await import("ethers"); @@ -877,7 +923,7 @@ async function ccStatusToString(status: number | undefined) { return `Unknown (${numToStr(status)})`; } - return statusStr; + return statusStr === "Inactive" ? "Completed" : statusStr; } export async function basicCCInfoAndStatusToString( @@ -885,10 +931,12 @@ export async function basicCCInfoAndStatusToString( ) { return ( await Promise.all( - ccInfos.map(async (ccInfo) => { - return `${stringifyBasicCommitmentInfo( - ccInfo, - )} Status: ${await ccStatusToString(ccInfo.status)}`; + ccInfos.map(async ({ status, ccInfos }) => { + return `${await getStatusHeading(status, ccInfos)}${ccInfos + .map((ccInfo) => { + return stringifyBasicCommitmentInfo(ccInfo); + }) + .join("\n\n")} `; }), ) ).join("\n\n"); diff --git a/cli/src/lib/chain/depositCollateral.ts b/cli/src/lib/chain/depositCollateral.ts index 1a21b08f3..176faf255 100644 --- a/cli/src/lib/chain/depositCollateral.ts +++ b/cli/src/lib/chain/depositCollateral.ts @@ -32,16 +32,14 @@ import { fltFormatWithSymbol } from "./currencies.js"; export async function depositCollateral(flags: CCFlags) { const { CommitmentStatus } = await import("@fluencelabs/deal-ts-clients"); - const [commitmentsWithInvalidStatus, commitments] = splitErrorsAndResults( - await getCommitmentsInfo(flags), - (c) => { + const [commitmentsWithInvalidStatus, commitmentsWithWaitDelegation] = + splitErrorsAndResults(await getCommitmentsInfo(flags), (c) => { if (c.status === CommitmentStatus.WaitDelegation) { return { result: c }; } return { error: c }; - }, - ); + }); if (commitmentsWithInvalidStatus.length > 0) { commandObj.warn( @@ -51,6 +49,10 @@ export async function depositCollateral(flags: CCFlags) { ); } + const commitments = commitmentsWithWaitDelegation.flatMap(({ ccInfos }) => { + return ccInfos; + }); + if (commitments.length === 0) { return commandObj.error( "No capacity commitments in the 'WaitDelegation' status found", diff --git a/cli/src/lib/chain/offer/offer.ts b/cli/src/lib/chain/offer/offer.ts index e9832201b..75b2114c3 100644 --- a/cli/src/lib/chain/offer/offer.ts +++ b/cli/src/lib/chain/offer/offer.ts @@ -18,7 +18,6 @@ import type { IMarket } from "@fluencelabs/deal-ts-clients"; import type { OfferDetail } from "@fluencelabs/deal-ts-clients/dist/dealCliClient/types/schemes.js"; import { color } from "@oclif/color"; -import type { TransactionReceipt } from "ethers"; import times from "lodash-es/times.js"; import { yamlDiffPatch } from "yaml-diff-patch"; @@ -78,6 +77,8 @@ export type OffersArgs = { export async function createOffers(flags: OffersArgs) { const allOffers = await resolveOffersFromProviderConfig(flags); + const providerConfig = await ensureReadonlyProviderConfig(); + const providerConfigPath = providerConfig.$getPath(); const { dealClient } = await getDealClient(); const market = dealClient.getMarket(); const usdc = dealClient.getUSDC(); @@ -140,11 +141,21 @@ export async function createOffers(flags: OffersArgs) { // value: OFFER_ID_PROPERTY, // }); - const registeredMarketOffers: ( + const offerRegisterResults: ( | { result: { offerId: string; offerName: string } } | { error: string } )[] = []; + function pushOfferRegisterResult( + result: (typeof offerRegisterResults)[number], + ) { + if ("error" in result) { + commandObj.warn(result.error); + } + + offerRegisterResults.push(result); + } + for (const offer of offers) { const { computePeersFromProviderConfig: allCPs, @@ -155,29 +166,16 @@ export async function createOffers(flags: OffersArgs) { maxProtocolVersion = versions.protocolVersion, } = offer; - function getOfferIdRes(txReceipt: TransactionReceipt) { - const offerId = getEventValue({ - contract: market, - eventName: MARKET_OFFER_REGISTERED_EVENT_NAME, - txReceipt, - value: OFFER_ID_PROPERTY, - }); - - return typeof offerId === "string" - ? { result: { offerId, offerName } } - : { - error: `for ${color.yellow( - offerName, - )} instead of offer id got: ${stringifyUnknown(offerId)} from ${MARKET_OFFER_REGISTERED_EVENT_NAME} event`, - }; - } - const allCUs = allCPs.flatMap(({ unitIds }) => { return unitIds; }); + let registeredCUsCount; + let addedCPs; + let offerRegisterTxReceipt; + try { - const { + ({ sliceIndex: registeredCUsCount, registeredValues: addedCPs, txReceipt: offerRegisterTxReceipt, @@ -199,47 +197,88 @@ export async function createOffers(flags: OffersArgs) { }, method: market.registerMarketOffer, validateAddress: assertProviderIsRegistered, + })); + } catch (e) { + pushOfferRegisterResult({ + error: `Error when registering offer ${offerName}: ${stringifyUnknown(e)}`, }); - const offerIdRes = getOfferIdRes(offerRegisterTxReceipt); - registeredMarketOffers.push(offerIdRes); + continue; + } + + let offerId; + + try { + offerId = getEventValue({ + contract: market, + eventName: MARKET_OFFER_REGISTERED_EVENT_NAME, + txReceipt: offerRegisterTxReceipt, + value: OFFER_ID_PROPERTY, + }); + + if (typeof offerId !== "string") { + pushOfferRegisterResult({ + error: `Got: ${stringifyUnknown(offerId)}, instead of offer id string from ${MARKET_OFFER_REGISTERED_EVENT_NAME} event for offer ${color.yellow( + offerName, + )}`, + }); - if ("error" in offerIdRes || registeredCUsCount === allCUs.length) { continue; } + } catch (e) { + pushOfferRegisterResult({ + error: `Error when getting ${OFFER_ID_PROPERTY} property from event ${MARKET_OFFER_REGISTERED_EVENT_NAME} for offer ${offerName}: ${stringifyUnknown(e)}`, + }); - const { offerId } = offerIdRes.result; + continue; + } + + const providerAddress = await getSignerAddress(); + const offerPerEnv = providerArtifactsConfig.offers[fluenceEnv] ?? {}; + offerPerEnv[offerName] = { id: offerId, providerAddress }; + providerArtifactsConfig.offers[fluenceEnv] = offerPerEnv; + await providerArtifactsConfig.$commit(); + + if (registeredCUsCount === allCUs.length) { + pushOfferRegisterResult({ result: { offerId, offerName } }); + continue; + } + + try { await addRemainingCUs({ allCPs, addedCPs, offerId, market, offerName }); await addRemainingCPs({ allCPs, addedCPs, offerId, market, offerName }); } catch (e) { - commandObj.warn( - `Error when creating offer ${offerName}: ${stringifyUnknown(e)}`, - ); + pushOfferRegisterResult({ + error: `Error when adding remaining CUs or CPs to the created offer ${color.yellow(offerName)} (${offerId}). You can try using ${color.yellow(`${CLI_NAME} provider offer-update --${OFFER_FLAG_NAME} ${offerName}`)} command to update on-chain offer to match your offer definition in ${providerConfigPath}. Error: ${stringifyUnknown(e)}`, + }); + + continue; } + + pushOfferRegisterResult({ result: { offerId, offerName } }); } - const [offerIdErrors, offerIds] = splitErrorsAndResults( - registeredMarketOffers, + const [offerCreateErrors, createdOffers] = splitErrorsAndResults( + offerRegisterResults, (res) => { return res; }, ); - if (offerIdErrors.length > 0) { + if (offerCreateErrors.length > 0) { commandObj.warn( - `When getting ${OFFER_ID_PROPERTY} property from event ${MARKET_OFFER_REGISTERED_EVENT_NAME}:\n\n${offerIdErrors.join( - ", ", + `Got the following errors when creating offers:\n\n${offerCreateErrors.join( + "\n\n", )}`, ); } - if (offerIds.length === 0) { - commandObj.logToStderr("No offers created"); - return; + if (createdOffers.length === 0) { + return commandObj.error("No offers created"); } type GetOffersInfoReturnType = Awaited< - ReturnType> + ReturnType> >; let offerInfoErrors: GetOffersInfoReturnType[0] = []; @@ -248,7 +287,7 @@ export async function createOffers(flags: OffersArgs) { const getOffersInfoRes = await setTryTimeout( "Getting offers info from indexer", async () => { - [offerInfoErrors, offersInfo] = await getOffersInfo(offerIds); + [offerInfoErrors, offersInfo] = await getOffersInfo(createdOffers); if (offerInfoErrors.length > 0) { throw new Error("Not all offers info received"); @@ -267,17 +306,7 @@ export async function createOffers(flags: OffersArgs) { commandObj.warn(stringifyUnknown(getOffersInfoRes.error)); } - const providerAddress = await getSignerAddress(); - - offerIds.forEach(({ offerName, offerId }) => { - const offerPerEnv = providerArtifactsConfig.offers[fluenceEnv] ?? {}; - offerPerEnv[offerName] = { id: offerId, providerAddress }; - providerArtifactsConfig.offers[fluenceEnv] = offerPerEnv; - }); - - await providerArtifactsConfig.$commit(); - - const offersStr = offerIds + const offersStr = createdOffers .map(({ offerName }) => { return offerName; }) diff --git a/cli/src/lib/configs/project/provider.ts b/cli/src/lib/configs/project/provider.ts index 00a74338c..79f5a26a4 100644 --- a/cli/src/lib/configs/project/provider.ts +++ b/cli/src/lib/configs/project/provider.ts @@ -193,6 +193,7 @@ type NoxConfigYAMLV0 = { }; decider?: { deciderPeriodSec?: number; + workerPeriodSec?: number; workerIpfsMultiaddr?: string; networkApiEndpoint?: string; networkId?: number; @@ -319,6 +320,11 @@ const noxConfigYAMLSchemaV0 = { type: "integer", description: `Decider period in seconds`, }, + workerPeriodSec: { + nullable: true, + type: "integer", + description: `Worker period in seconds`, + }, workerIpfsMultiaddr: { nullable: true, type: "string", @@ -555,6 +561,11 @@ const noxConfigYAMLSchemaV1 = { type: "integer", description: `Decider period in seconds`, }, + workerPeriodSec: { + nullable: true, + type: "integer", + description: `Worker period in seconds`, + }, workerIpfsMultiaddr: { nullable: true, type: "string", diff --git a/cli/test/setup/localUp.ts b/cli/test/setup/localUp.ts index c3fe67021..a44e5b7fc 100644 --- a/cli/test/setup/localUp.ts +++ b/cli/test/setup/localUp.ts @@ -15,52 +15,15 @@ * along with this program. If not, see . */ -import assert from "node:assert"; - -import { initProviderConfigWithPath } from "../../src/lib/configs/project/provider.js"; -import { numToStr } from "../../src/lib/helpers/typesafeStringify.js"; import { fluence } from "../helpers/commonWithSetupTests.js"; -import { fluenceEnv, CC_DURATION_SECONDS } from "../helpers/constants.js"; +import { fluenceEnv } from "../helpers/constants.js"; import { pathToTheTemplateWhereLocalEnvironmentIsSpunUp } from "../helpers/paths.js"; if (fluenceEnv === "local") { - const providerConfig = await initProviderConfigWithPath( - pathToTheTemplateWhereLocalEnvironmentIsSpunUp, - ); - - assert( - providerConfig !== null, - "Provider config must already exists in a quickstart template", - ); - - // add extra capacity commitments and compute peers not used in any offer - providerConfig.capacityCommitments = { - ...providerConfig.capacityCommitments, - ...Object.fromEntries( - Object.values(providerConfig.capacityCommitments).map((config, i, ar) => { - return [ - `nox-${numToStr(i + ar.length)}`, - { ...config, duration: `${numToStr(CC_DURATION_SECONDS)} seconds` }, - ] as const; - }), - ), - }; - - providerConfig.computePeers = { - ...providerConfig.computePeers, - ...Object.fromEntries( - Object.values(providerConfig.computePeers).map((config, i, ar) => { - return [`nox-${numToStr(i + ar.length)}`, config] as const; - }), - ), - }; - - await providerConfig.$commit(); - await fluence({ args: ["local", "up"], - flags: { r: true }, + flags: { r: true, "no-set-up": true }, cwd: pathToTheTemplateWhereLocalEnvironmentIsSpunUp, - timeout: 1000 * 60 * 8, // 8 minutes + timeout: 1000 * 60 * 5, // 5 minutes }); } diff --git a/cli/test/tests/provider.test.ts b/cli/test/tests/provider.test.ts index 58a8d6fa9..e3735415e 100644 --- a/cli/test/tests/provider.test.ts +++ b/cli/test/tests/provider.test.ts @@ -40,6 +40,7 @@ describe("provider tests", () => { async () => { const cwd = join("test", "tmp", "fullLifeCycle"); await initializeTemplate(cwd, "quickstart"); + const providerConfig = await initProviderConfigWithPath(cwd); assert( @@ -47,6 +48,16 @@ describe("provider tests", () => { "Provider config must already exists in a quickstart template", ); + // add extra capacity commitments and compute peers not used in any offer + providerConfig.capacityCommitments = Object.fromEntries( + Object.values(providerConfig.capacityCommitments).map((config, i) => { + return [ + `nox-${numToStr(i)}`, + { ...config, duration: `${numToStr(CC_DURATION_SECONDS)} seconds` }, + ] as const; + }), + ); + const NEW_OFFER_NAME = "newOffer"; const [defaultOffer] = Object.values(providerConfig.offers); @@ -55,26 +66,23 @@ describe("provider tests", () => { "Default offer must exist in the provider config", ); - providerConfig.offers = { - ...providerConfig.offers, - // add offer with remaining compute peers - [NEW_OFFER_NAME]: { - ...defaultOffer, - computePeers: defaultOffer.computePeers.map((_cp, i, ar) => { - return `nox-${numToStr(i + ar.length)}`; - }), - }, - }; - + providerConfig.offers = { [NEW_OFFER_NAME]: defaultOffer }; const PROVIDER_NAME = "AwesomeProvider"; providerConfig.providerName = PROVIDER_NAME; await providerConfig.$commit(); - await fluence({ - args: ["provider", "tokens-distribute"], + const TEST_DEFAULT = { flags: { ...PRIV_KEY_1, [OFFER_FLAG_NAME]: NEW_OFFER_NAME, + }, + cwd, + } as const; + + await fluence({ + args: ["provider", "tokens-distribute"], + flags: { + ...TEST_DEFAULT.flags, amount: "10", }, cwd, @@ -90,84 +98,91 @@ describe("provider tests", () => { await fluence({ args: ["provider", "offer-create"], - flags: { - ...PRIV_KEY_1, - [OFFER_FLAG_NAME]: NEW_OFFER_NAME, - }, - cwd, + ...TEST_DEFAULT, }); await fluence({ args: ["provider", "cc-create"], - flags: { - ...PRIV_KEY_1, - [OFFER_FLAG_NAME]: NEW_OFFER_NAME, - }, - cwd, + ...TEST_DEFAULT, }); await fluence({ args: ["provider", "cc-info"], - flags: { - ...PRIV_KEY_1, - [OFFER_FLAG_NAME]: NEW_OFFER_NAME, - }, - cwd, + ...TEST_DEFAULT, }); await fluence({ args: ["provider", "cc-activate"], - flags: { - ...PRIV_KEY_1, - [OFFER_FLAG_NAME]: NEW_OFFER_NAME, - }, - cwd, + ...TEST_DEFAULT, }); await fluence({ args: ["provider", "cc-info"], - flags: { - ...PRIV_KEY_1, - [OFFER_FLAG_NAME]: NEW_OFFER_NAME, - }, - cwd, + ...TEST_DEFAULT, }); await sleepSeconds(5); await fluence({ args: ["provider", "cc-info"], - flags: { - ...PRIV_KEY_1, - [OFFER_FLAG_NAME]: NEW_OFFER_NAME, - }, - cwd, + ...TEST_DEFAULT, }); await sleepSeconds(CC_DURATION_SECONDS); await fluence({ args: ["provider", "cc-info"], + ...TEST_DEFAULT, + }); + + await fluence({ + args: ["provider", "cc-finish"], + ...TEST_DEFAULT, + }); + + await fluence({ + args: ["provider", "cc-info"], + ...TEST_DEFAULT, + }); + + await fluence({ + args: ["provider", "offer-remove"], + ...TEST_DEFAULT, + }); + + // SET UP FOR THE REST OF THE TESTS + + providerConfig.capacityCommitments = Object.fromEntries( + Object.values(providerConfig.capacityCommitments).map((config, i) => { + return [ + `nox-${numToStr(i)}`, + { ...config, duration: `8 hours` }, + ] as const; + }), + ); + + await providerConfig.$commit(); + await fluence({ args: ["provider", "register"], cwd }); + + await fluence({ + args: ["provider", "offer-create"], flags: { - ...PRIV_KEY_1, [OFFER_FLAG_NAME]: NEW_OFFER_NAME, }, cwd, }); await fluence({ - args: ["provider", "cc-collateral-withdraw"], + args: ["provider", "cc-create"], flags: { - ...PRIV_KEY_1, [OFFER_FLAG_NAME]: NEW_OFFER_NAME, }, cwd, }); await fluence({ - args: ["provider", "cc-info"], + args: ["provider", "cc-activate"], flags: { - ...PRIV_KEY_1, [OFFER_FLAG_NAME]: NEW_OFFER_NAME, }, cwd,