Skip to content

Commit

Permalink
chore: merged main into settings
Browse files Browse the repository at this point in the history
  • Loading branch information
jigar-arc10 committed Dec 10, 2024
2 parents 7c81903 + 14d73fa commit 11c3906
Show file tree
Hide file tree
Showing 44 changed files with 556 additions and 226 deletions.
32 changes: 32 additions & 0 deletions apps/api/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@


## [2.38.0-beta.1](https://github.com/akash-network/console/compare/console-api/v2.38.0-beta.0...console-api/v2.38.0-beta.1) (2024-12-10)


### Features

* **deployment:** auto top up custodial deployment with available amount ([0792a36](https://github.com/akash-network/console/commit/0792a367f64d83ed040043c021b98e5be2d82c80)), closes [#524](https://github.com/akash-network/console/issues/524)

## [2.38.0-beta.0](https://github.com/akash-network/console/compare/console-api/v2.37.0...console-api/v2.38.0-beta.0) (2024-12-09)


### Features

* **deployment:** add context to top up error logging ([d8ab845](https://github.com/akash-network/console/commit/d8ab845a3ab6f337f2eefeacec5534a7d90c5837))

## [2.37.0](https://github.com/akash-network/console/compare/console-api/v2.37.0-beta.0...console-api/v2.37.0) (2024-12-06)

## [2.37.0-beta.0](https://github.com/akash-network/console/compare/console-api/v2.36.0...console-api/v2.37.0-beta.0) (2024-12-05)


### Features

* **deployment:** auto top up managed deployment with available amount ([644332f](https://github.com/akash-network/console/commit/644332ffb6b7dffab2150f4ec6dfb70601df6816))

## [2.36.0](https://github.com/akash-network/console/compare/console-api/v2.36.0-beta.0...console-api/v2.36.0) (2024-12-04)

## [2.36.0-beta.0](https://github.com/akash-network/console/compare/console-api/v2.35.4-beta.0...console-api/v2.36.0-beta.0) (2024-12-04)


### Features

* **deployment:** add concurrency for top up deployment ([0b4abf5](https://github.com/akash-network/console/commit/0b4abf5510eca6986257081ba5481936b6cb54f6)), closes [#519](https://github.com/akash-network/console/issues/519)

## [2.35.4-beta.0](https://github.com/akash-network/console/compare/console-api/v2.35.3...console-api/v2.35.4-beta.0) (2024-12-03)


Expand Down
2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@akashnetwork/console-api",
"version": "2.35.4-beta.0",
"version": "2.38.0-beta.1",
"description": "Api providing data to the deploy tool",
"repository": {
"type": "git",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,12 @@ import { singleton } from "tsyringe";
import { BillingConfig, InjectBillingConfig } from "@src/billing/providers";
import { UserWalletOutput, UserWalletRepository } from "@src/billing/repositories";
import { ManagedUserWalletService, RpcMessageService } from "@src/billing/services";
import { ProviderCleanupParams } from "@src/billing/types/provider-cleanup";
import { ErrorService } from "@src/core/services/error/error.service";
import { ProviderCleanupSummarizer } from "@src/deployment/lib/provider-cleanup-summarizer/provider-cleanup-summarizer";
import { DeploymentRepository } from "@src/deployment/repositories/deployment/deployment.repository";
import { TxSignerService } from "../tx-signer/tx-signer.service";

export interface ProviderCleanupParams {
concurrency: number;
provider: string;
dryRun: boolean;
}

@singleton()
export class ProviderCleanupService {
private readonly logger = LoggerService.forContext(ProviderCleanupService.name);
Expand Down
5 changes: 5 additions & 0 deletions apps/api/src/billing/types/provider-cleanup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ConcurrencyOptions, DryRunOptions } from "@src/core/types/console";

export interface ProviderCleanupParams extends DryRunOptions, ConcurrencyOptions {
provider: string;
}
3 changes: 2 additions & 1 deletion apps/api/src/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ program
program
.command("top-up-deployments")
.description("Refill deployments with auto top up enabled")
.option("-c, --concurrency <number>", "How many wallets is processed concurrently", value => z.number({ coerce: true }).optional().default(10).parse(value))
.option("-d, --dry-run", "Dry run the top up deployments", false)
.action(async (options, command) => {
await executeCliHandler(command.name(), async () => {
await container.resolve(TopUpDeploymentsController).topUpDeployments({ dryRun: options.dryRun });
await container.resolve(TopUpDeploymentsController).topUpDeployments(options);
});
});

Expand Down
5 changes: 5 additions & 0 deletions apps/api/src/core/types/console.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export interface DryRunOptions {
dryRun: boolean;
}

export interface ConcurrencyOptions {
concurrency?: number;
}

Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { singleton } from "tsyringe";

import {
CleanUpStaleDeploymentsParams,
StaleManagedDeploymentsCleanerService
} from "@src/deployment/services/stale-managed-deployments-cleaner/stale-managed-deployments-cleaner.service";
import { StaleManagedDeploymentsCleanerService } from "@src/deployment/services/stale-managed-deployments-cleaner/stale-managed-deployments-cleaner.service";
import { TopUpCustodialDeploymentsService } from "@src/deployment/services/top-up-custodial-deployments/top-up-custodial-deployments.service";
import { TopUpManagedDeploymentsService } from "@src/deployment/services/top-up-managed-deployments/top-up-managed-deployments.service";
import { TopUpDeploymentsOptions } from "@src/deployment/types/deployments-refiller";
import { CleanUpStaleDeploymentsParams } from "@src/deployment/types/state-deployments";

@singleton()
export class TopUpDeploymentsController {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { singleton } from "tsyringe";

import { ProviderCleanupParams, ProviderCleanupService } from "@src/billing/services/provider-cleanup/provider-cleanup.service";
import { ProviderCleanupService } from "@src/billing/services/provider-cleanup/provider-cleanup.service";
import { ProviderCleanupParams } from "@src/billing/types/provider-cleanup";
import { TrialProvidersService } from "@src/deployment/services/trial-providers/trial-providers.service";

@singleton()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ import { TxSignerService } from "@src/billing/services/tx-signer/tx-signer.servi
import { BlockRepository } from "@src/chain/repositories/block.repository";
import { ErrorService } from "@src/core/services/error/error.service";
import { DeploymentRepository } from "@src/deployment/repositories/deployment/deployment.repository";
import { CleanUpStaleDeploymentsParams } from "@src/deployment/types/state-deployments";
import { averageBlockTime } from "@src/utils/constants";

export interface CleanUpStaleDeploymentsParams {
concurrency: number;
}

@singleton()
export class StaleManagedDeploymentsCleanerService {
private readonly logger = LoggerService.forContext(StaleManagedDeploymentsCleanerService.name);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
interface Balances {
denom: string;
feesLimit: number;
deploymentLimit: number;
balance: number;
feesBalance?: number;
}

export class TopUpCustodialBalanceService {
constructor(readonly balances: Balances) {}

recordTx(amount: number, fees: number) {
this.balances.deploymentLimit -= amount;
this.balances.balance -= amount;
this.balances.feesLimit -= fees;

if (this.balances.denom === "uakt") {
this.balances.balance -= fees;
} else {
this.balances.feesBalance -= fees;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import "@test/mocks/logger-service.mock";

import { AllowanceHttpService, BalanceHttpService, Denom } from "@akashnetwork/http-sdk";
import { faker } from "@faker-js/faker";
import { MsgExec } from "cosmjs-types/cosmos/authz/v1beta1/tx";
import { secondsInWeek } from "date-fns/constants";
import { describe } from "node:test";
import { container } from "tsyringe";

Expand All @@ -25,6 +25,8 @@ import { DrainingDeploymentSeeder } from "@test/seeders/draining-deployment.seed
import { FeesAuthorizationSeeder } from "@test/seeders/fees-authorization.seeder";
import { stub } from "@test/services/stub";

const USDC_IBC_DENOM = "ibc/170C677610AC31DF0904FFE09CD3B5C657492170E7E52372E48756B71E56F2F1";

describe(TopUpCustodialDeploymentsService.name, () => {
const CURRENT_BLOCK_HEIGHT = 7481457;
const UAKT_TOP_UP_MASTER_WALLET_ADDRESS = AkashAddressSeeder.create();
Expand Down Expand Up @@ -71,13 +73,14 @@ describe(TopUpCustodialDeploymentsService.name, () => {

type SeedParams = {
denom: Denom;
balance?: string;
balance?: number;
feesBalance?: number;
grantee: string;
expectedDeploymentsTopUpCount?: 0 | 1 | 2;
hasDeployments?: boolean;
};

const seedFor = ({ denom, balance = "100000000", grantee, expectedDeploymentsTopUpCount = 2, hasDeployments = true }: SeedParams) => {
const seedFor = ({ denom, balance = 100000000, feesBalance = 1000000, grantee, expectedDeploymentsTopUpCount = 2, hasDeployments = true }: SeedParams) => {
const owner = AkashAddressSeeder.create();

return {
Expand All @@ -90,8 +93,9 @@ describe(TopUpCustodialDeploymentsService.name, () => {
feeAllowance: FeesAuthorizationSeeder.create({
granter: owner,
grantee: grantee,
allowance: { spend_limit: { denom } }
allowance: { spend_limit: { denom: "uakt" } }
}),
feesBalance: denom === "uakt" ? undefined : BalanceSeeder.create({ denom: "uakt", amount: feesBalance }),
drainingDeployments: hasDeployments
? [
{
Expand All @@ -113,24 +117,66 @@ describe(TopUpCustodialDeploymentsService.name, () => {
grantee: UAKT_TOP_UP_MASTER_WALLET_ADDRESS
}),
seedFor({
denom: "ibc/170C677610AC31DF0904FFE09CD3B5C657492170E7E52372E48756B71E56F2F1",
denom: USDC_IBC_DENOM,
grantee: USDT_TOP_UP_MASTER_WALLET_ADDRESS
}),
seedFor({
denom: USDC_IBC_DENOM,
grantee: USDT_TOP_UP_MASTER_WALLET_ADDRESS,
balance: 5500000,
expectedDeploymentsTopUpCount: 2
}),
seedFor({
denom: USDC_IBC_DENOM,
grantee: USDT_TOP_UP_MASTER_WALLET_ADDRESS,
balance: 5040000,
expectedDeploymentsTopUpCount: 1
}),
seedFor({
denom: USDC_IBC_DENOM,
grantee: USDT_TOP_UP_MASTER_WALLET_ADDRESS,
balance: 5500000,
expectedDeploymentsTopUpCount: 2
}),
seedFor({
denom: USDC_IBC_DENOM,
grantee: USDT_TOP_UP_MASTER_WALLET_ADDRESS,
feesBalance: 0,
expectedDeploymentsTopUpCount: 0
}),
seedFor({
denom: USDC_IBC_DENOM,
grantee: USDT_TOP_UP_MASTER_WALLET_ADDRESS,
feesBalance: 5000,
expectedDeploymentsTopUpCount: 1
}),
seedFor({
denom: "uakt",
balance: 5045000,
grantee: UAKT_TOP_UP_MASTER_WALLET_ADDRESS,
expectedDeploymentsTopUpCount: 1
}),
seedFor({
denom: "uakt",
balance: "5500000",
balance: 5000,
grantee: UAKT_TOP_UP_MASTER_WALLET_ADDRESS,
expectedDeploymentsTopUpCount: 0
}),
seedFor({
denom: "uakt",
balance: 10000,
grantee: UAKT_TOP_UP_MASTER_WALLET_ADDRESS,
expectedDeploymentsTopUpCount: 1
}),
seedFor({
denom: "uakt",
balance: "5500000",
balance: 5500000,
grantee: UAKT_TOP_UP_MASTER_WALLET_ADDRESS,
hasDeployments: false
}),
seedFor({
denom: "uakt",
balance: "0",
balance: 0,
grantee: UAKT_TOP_UP_MASTER_WALLET_ADDRESS,
expectedDeploymentsTopUpCount: 0
})
Expand All @@ -143,12 +189,20 @@ describe(TopUpCustodialDeploymentsService.name, () => {
return data.find(({ grant }) => grant.granter === granter && grant.grantee === grantee)?.feeAllowance;
});
jest.spyOn(balanceHttpService, "getBalance").mockImplementation(async (address: string, denom: Denom) => {
return (
data.find(({ grant }) => grant.granter === address)?.balance || {
amount: "0",
denom
}
);
const record = data.find(({ grant }) => grant.granter === address);

if (record?.balance.denom === denom) {
return record.balance;
}

if (record?.feesBalance.denom === denom) {
return record.feesBalance;
}

return {
amount: 0,
denom
};
});
jest.spyOn(drainingDeploymentService, "findDeployments").mockImplementation(async (owner, denom) => {
return (
Expand All @@ -157,18 +211,22 @@ describe(TopUpCustodialDeploymentsService.name, () => {
?.drainingDeployments?.map(({ deployment }) => deployment) || []
);
});
jest.spyOn(drainingDeploymentService, "calculateTopUpAmount").mockImplementation(async () => faker.number.int({ min: 3500000, max: 4000000 }));
jest.spyOn(drainingDeploymentService, "calculateTopUpAmount").mockImplementation(async ({ blockRate }) => (blockRate * secondsInWeek) / 6);

it("should top up draining deployment given owners have sufficient grants and balances", async () => {
await topUpDeploymentsService.topUpDeployments({ dryRun: false });

expect(uaktMasterSigningClientService.executeTx).toHaveBeenCalledTimes(3);
expect(usdtMasterSigningClientService.executeTx).toHaveBeenCalledTimes(2);
let uaktCount = 0;
let usdtCount = 0;

data.forEach(({ drainingDeployments, grant }) => {
drainingDeployments.forEach(({ isExpectedToTopUp, deployment }) => {
if (isExpectedToTopUp) {
const client = deployment.denom === "uakt" ? uaktMasterSigningClientService : usdtMasterSigningClientService;
const isAkt = deployment.denom === "uakt";
const client = isAkt ? uaktMasterSigningClientService : usdtMasterSigningClientService;
uaktCount += isAkt ? 1 : 0;
usdtCount += isAkt ? 0 : 1;

expect(client.executeTx).toHaveBeenCalledWith(
[
{
Expand All @@ -189,6 +247,9 @@ describe(TopUpCustodialDeploymentsService.name, () => {
}
});
});

expect(uaktMasterSigningClientService.executeTx).toHaveBeenCalledTimes(uaktCount);
expect(usdtMasterSigningClientService.executeTx).toHaveBeenCalledTimes(usdtCount);
});

xdescribe("actual top up deployment tx on demand", () => {
Expand Down
Loading

0 comments on commit 11c3906

Please sign in to comment.