Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
minaxolone committed Jul 31, 2024
1 parent 25801b6 commit be8a80b
Show file tree
Hide file tree
Showing 28 changed files with 539 additions and 752 deletions.
48 changes: 40 additions & 8 deletions api/src/ol/community-wallets/community-wallet.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Field, ObjectType } from '@nestjs/graphql';

interface CommunityWalletInput {
rank: number;
address: string;
name?: string;
description?: string;
balance: number;
}

@ObjectType()
export class CommunityWallet {
@Field()
Expand All @@ -17,11 +25,22 @@ export class CommunityWallet {
@Field()
balance: number;

constructor(partial: Partial<CommunityWallet>) {
Object.assign(this, partial);
public constructor(input: CommunityWalletInput) {
this.rank = input.rank;
this.address = input.address;
this.name = input.name;
this.description = input.description;
this.balance = input.balance;
}
}

interface CommunityWalletStatsInput {
totalBalance: number;
totalPaid: number;
totalPending: number;
totalVetoed: number;
}

@ObjectType()
export class CommunityWalletStats {
@Field()
Expand All @@ -36,11 +55,22 @@ export class CommunityWalletStats {
@Field()
totalVetoed: number;

constructor(partial: Partial<CommunityWalletStats>) {
Object.assign(this, partial);
public constructor(input: CommunityWalletStatsInput) {
this.totalBalance = input.totalBalance;
this.totalPaid = input.totalPaid;
this.totalPending = input.totalPending;
this.totalVetoed = input.totalVetoed;
}
}

interface PaymentInput {
deadline: string;
payee: string;
value: number;
description: string;
status: string;
}

@ObjectType()
export class Payment {
@Field()
Expand All @@ -58,8 +88,12 @@ export class Payment {
@Field()
status: string;

constructor(partial: Partial<Payment>) {
Object.assign(this, partial);
public constructor(input: PaymentInput) {
this.deadline = input.deadline;
this.payee = input.payee;
this.value = input.value;
this.description = input.description;
this.status = input.status;
}
}

Expand Down Expand Up @@ -92,8 +126,6 @@ export class CommunityWalletDetails {
@Field()
isMultiAction: boolean;

// also nullable
// @Field(() => [Number])
@Field(() => [Number], { nullable: true })
threshold?: number[];

Expand Down
18 changes: 10 additions & 8 deletions api/src/ol/community-wallets/community-wallets.processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ import _ from 'lodash';
import { InjectQueue, Processor, WorkerHost } from '@nestjs/bullmq';
import { Inject, OnModuleInit } from '@nestjs/common';
import { Job, Queue } from 'bullmq';

import { ICommunityWalletsService } from './interfaces.js';
import { redisClient } from '../../redis/redis.service.js';
import { Types } from '../../types.js';

import { COMMUNITY_WALLETS_CACHE_KEY } from '../constants.js';

@Processor('community-wallets')
export class CommunityWalletsProcessor extends WorkerHost implements OnModuleInit {
public constructor(
Expand All @@ -21,11 +19,15 @@ export class CommunityWalletsProcessor extends WorkerHost implements OnModuleIni
}

public async onModuleInit() {
await this.communityWalletsQueue.add('updateCommunityWalletsCaches', undefined, {
repeat: {
every: 60 * 60 * 1_000, // 1 hour
},
});
await this.communityWalletsQueue.add(
'updateCommunityWalletsCaches',
undefined,
{
repeat: {
every: 60 * 60 * 1_000, // 1 hour
},
}
);

// Execute the job immediately on startup
await this.updateCommunityWalletsCaches();
Expand Down
54 changes: 19 additions & 35 deletions api/src/ol/community-wallets/community-wallets.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Injectable } from '@nestjs/common';
import _ from 'lodash';
import { ConfigService } from '@nestjs/config';

import { redisClient } from '../../redis/redis.service.js';
import { OlService } from '../ol.service.js';
import {
Expand All @@ -8,7 +10,7 @@ import {
CommunityWalletPayments,
CommunityWalletDetails,
} from './community-wallet.model.js';
import { parseAddress } from '../../utils.js';
import { parseAddress, parseHexString } from '../../utils.js';
import { communityWallets } from './community-wallets.js';
import { ICommunityWalletsService } from './interfaces.js';
import {
Expand All @@ -18,32 +20,31 @@ import {
COMMUNITY_WALLETS_DETAILS_CACHE_KEY,
} from '../constants.js';

function formatCoin(value: number): number {
return Math.floor(value / 1e6);
}

@Injectable()
export class CommunityWalletsService implements ICommunityWalletsService {
private readonly cacheEnabled: boolean;

public constructor(private readonly olService: OlService) {
this.cacheEnabled = process.env.CACHE_ENABLED === 'true';
public constructor(
private readonly olService: OlService,
config: ConfigService,
) {
this.cacheEnabled = config.get<boolean>('cacheEnabled')!;
}

private async getFromCache<T>(key: string): Promise<T | null> {
try {
const cachedData = await redisClient.get(key);
if (cachedData) {
return JSON.parse(cachedData) as T;
}
} catch (error) {
console.error(`Error getting data from cache for key ${key}:`, error);
const cachedData = await redisClient.get(key);
if (cachedData) {
return JSON.parse(cachedData) as T;
}
return null;
}

private async setCache<T>(key: string, data: T): Promise<void> {
try {
await redisClient.set(key, JSON.stringify(data));
} catch (error) {
console.error(`Error setting data to cache for key ${key}:`, error);
}
await redisClient.set(key, JSON.stringify(data));
}

public async getCommunityWallets(): Promise<CommunityWallet[]> {
Expand Down Expand Up @@ -211,10 +212,10 @@ export class CommunityWalletsService implements ICommunityWalletsService {
return payments
.filter((payment) => status !== 'pending' || payment.deadline > currentEpoch)
.map((payment) => ({
deadline: String(payment.deadline),
payee: String(payment.tx.payee),
deadline: payment.deadline,
payee: payment.tx.payee,
value: formatCoin(payment.tx.value),
description: hexToAscii(payment.tx.description),
description: Buffer.from(parseHexString(payment.tx.description)).toString('utf-8'),
status,
}));
};
Expand Down Expand Up @@ -333,20 +334,3 @@ export class CommunityWalletsService implements ICommunityWalletsService {
await this.setCache(COMMUNITY_WALLETS_DETAILS_CACHE_KEY, details);
}
}

function hexToAscii(hex: string): string {
// Remove the "0x" prefix if it exists
hex = hex.startsWith('0x') ? hex.slice(2) : hex;

// Split the hex string into pairs of characters
const hexPairs = hex.match(/.{1,2}/g) || [];

// Convert each pair of hex characters to an ASCII character
const asciiStr = hexPairs.map((hexPair) => String.fromCharCode(parseInt(hexPair, 16))).join('');

return asciiStr;
}

function formatCoin(value: number): number {
return Math.floor(value / 1000000);
}
74 changes: 1 addition & 73 deletions api/src/stats/stats.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ export class StatsService {
config: ConfigService,
) {
this.dataApiHost = config.get('dataApiHost')!;

this.cacheEnabled = process.env.CACHE_ENABLED === 'true';
this.cacheEnabled = config.get<boolean>('cacheEnabled')!;
}

private async setCache<T>(key: string, data: T): Promise<void> {
Expand All @@ -63,49 +62,17 @@ export class StatsService {
}

public async getStats(): Promise<Stats> {
console.time('getSupplyStats');
const supplyStats = await this.olService.getSupplyStats();
console.timeEnd('getSupplyStats');

console.time('getTotalSupply');
const totalSupply: number = supplyStats.totalSupply;
console.timeEnd('getTotalSupply');

console.time('getSlowWalletsCountOverTime');
const slowWalletsCountOverTime = await this.getSlowWalletsCountOverTime();
console.timeEnd('getSlowWalletsCountOverTime');

console.time('getBurnsOverTime');
const burnOverTime = await this.getBurnsOverTime();
console.timeEnd('getBurnsOverTime');

console.time('getAccountsOnChainOverTime');
const accountsOnChainOverTime = await this.getAccountsOnChainOverTime();
console.timeEnd('getAccountsOnChainOverTime');

console.time('getSupplyAndCapital');
const supplyAndCapital = await this.getSupplyAndCapital(supplyStats);
console.timeEnd('getSupplyAndCapital');

console.time('getCommunityWalletsBalanceBreakdown');
const communityWalletsBalanceBreakdown = await this.getCommunityWalletsBalanceBreakdown();
console.timeEnd('getCommunityWalletsBalanceBreakdown');

console.time('getLastEpochTotalUnlockedAmount');
const lastEpochTotalUnlockedAmount = await this.getLastEpochTotalUnlockedAmount();
console.timeEnd('getLastEpochTotalUnlockedAmount');

console.time('getPOFValues');
const pofValues = await this.getPOFValues(); // Empty table?
console.timeEnd('getPOFValues');

console.time('getLiquidSupplyConcentration');
const liquidSupplyConcentration = await this.getLiquidSupplyConcentration();
console.timeEnd('getLiquidSupplyConcentration');

console.time('calculateLiquidityConcentrationLocked');
const lockedSupplyConcentration = await this.calculateLiquidityConcentrationLocked();
console.timeEnd('calculateLiquidityConcentrationLocked');

// calculate KPIS
// circulating
Expand Down Expand Up @@ -452,42 +419,6 @@ export class StatsService {
}
}

private async getSlowWalletsUnlockedAmount(): Promise<number> {
try {
const query = `
SELECT
hex(SW.address) AS address,
(latest_balance - max(SW.unlocked)) / 1e6 AS locked_balance
FROM
slow_wallet SW
JOIN
(SELECT
address,
argMax(balance, timestamp) as latest_balance
FROM coin_balance
WHERE coin_module = 'libra_coin'
GROUP BY address) AS CB
ON SW.address = CB.address
GROUP BY SW.address, latest_balance
`;

const resultSet = await this.clickhouseService.client.query({
query: query,
format: 'JSONEachRow',
});

const rows = await resultSet.json<{ locked_balance: number }>();

// Sum the locked Amount
const totalLockedAmount = rows.reduce((acc, row) => acc + row.locked_balance, 0);

return totalLockedAmount;
} catch (error) {
console.error('Error in getSlowWalletsUnlockedAmount:', error);
throw error;
}
}

private async getLastEpochTotalUnlockedAmount(): Promise<number> {
try {
// Query the slow_wallet table to get the addresses and unlocked balances
Expand Down Expand Up @@ -551,7 +482,6 @@ export class StatsService {
const latest_balance = balanceMap.get(row.address) ?? 0;
const unlocked_balance = row.unlocked_balance;
const locked_balance = latest_balance - unlocked_balance;
// console.log(`Address: ${row.address}, Latest Balance: ${latest_balance}, Unlocked Balance: ${unlocked_balance}, Locked Balance: ${locked_balance}`);
return {
address: row.address,
locked_balance,
Expand Down Expand Up @@ -1344,7 +1274,6 @@ export class StatsService {

// Query to get the top unlocked balance accounts
private async queryTopLiquidAccounts(): Promise<TopLiquidAccount[]> {
console.time('queryTopLiquidAccounts');
const limit = 100;
const circulatingSupply = await this.getCirculatingSupply();

Expand Down Expand Up @@ -1444,7 +1373,6 @@ export class StatsService {
liquidShare: item.percentOfCirculating,
}),
);
console.timeEnd('queryTopLiquidAccounts');
return ret;
} catch (error) {
console.error('Error in getTopUnlockedBalanceWallets:', error);
Expand Down
16 changes: 11 additions & 5 deletions web-app/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
const API_HOST: string = import.meta.env.VITE_API_HOST;
const VITE_DATA_API_HOST: string = import.meta.env.VITE_DATA_API_HOST;
const DATA_API_HOST: string = import.meta.env.VITE_DATA_API_HOST;

export interface Config {
apiHost: string;
dataApiHost: string;
}

const localhost = {
apiHost: API_HOST,
dataApiHost: DATA_API_HOST,
};

const configMap = new Map<string, Config>([
[
'0l.fyi',
Expand All @@ -23,10 +28,11 @@ const configMap = new Map<string, Config>([
],
[
'127.0.0.1',
{
apiHost: API_HOST,
dataApiHost: VITE_DATA_API_HOST,
},
localhost
],
[
'localhost',
localhost
],
]);

Expand Down
Loading

0 comments on commit be8a80b

Please sign in to comment.