Skip to content

Commit

Permalink
merge with testnet
Browse files Browse the repository at this point in the history
  • Loading branch information
mikecot committed Jan 16, 2025
1 parent b169905 commit 3db9ec2
Show file tree
Hide file tree
Showing 27 changed files with 5,145 additions and 117 deletions.
22 changes: 17 additions & 5 deletions PUBLICAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,27 @@ Returns a comprehensive list of all Lava Network providers, including:
- Supported chains and specifications
- Staking details (amounts, delegation limits)
- Commission rates and current status
- And for each stake - the stakestatus (active/frozen/jailed)

#### `/providers`

Returns list of all providers
Returns list of all providers (addresses only)

#### `/active_providers`

Returns list of all active providers (addresses only)

#### `/consumers`

Returns list of all consumers
Returns list of all consumers (addresses only)

#### `/specs`

Returns list of all specs/chains
Returns list of all specs/chains (spec names only)

#### `/validators`

Returns list of all validators
Returns list of all validators (full info)

### Example Response

Expand All @@ -70,6 +75,10 @@ Returns list of all validators
}
```

#### `/active_validators`

Returns list of all active validators (addresses only)

## Supply Endpoints

#### `/supply/circulating`
Expand All @@ -87,6 +96,7 @@ Returns list of all validators
#### `/lava_chain_restakers`

- Returns current and monthly unique staker counts
- only delegation of active providers are taken into account
- Response format:

```json
Expand All @@ -109,7 +119,8 @@ Returns list of all validators
- Empty provider delegations are excluded from restaker counts

3. Monthly Metrics:
- Represent unique users over the trailing 30-day period

- Represent unique users over 30-day period back from today
- Updated continuously based on blockchain data

## APR (Annual Percentage Rewards) Endpoint
Expand Down Expand Up @@ -248,3 +259,4 @@ Both staking and restaking APRs are calculated similarly:
- APR values represent potential returns before fees and slashing
- Actual returns may vary based on validator/provider performance
- Calculations include all reward types (LAVA + other tokens)
- APR calculation only considers active validators/providers (not jailed or frozen)
36 changes: 35 additions & 1 deletion src/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ if (!IsIndexerProcess()) {

import * as consts from './indexer/indexerConsts';
import { IndexerThreadCallerStart } from './indexer/indexerThreadCaller';
import { APRMonitor } from './indexer/restrpc_agregators/AprMonitor';

// import { APRMonitor } from './indexer/restrpc_agregators/AprMonitor';
// import { queryRpc } from './indexer/utils/lavajsRpc';
// import { LavaClient } from './indexer/lavaTypes';
// import { SpecAndConsumerService } from './redis/resources/global/SpecAndConsumerResource';
// import { JSONStringify } from './utils/fmt';

const indexer = async (): Promise<void> => {
logger.info(`Starting indexer, rpc: ${consts.JSINFO_INDEXER_LAVA_RPC}, start height: ${consts.JSINFO_INDEXER_START_BLOCK}`);
Expand All @@ -21,6 +26,35 @@ const indexer = async (): Promise<void> => {
}
}

// const allSpecs = await SpecAndConsumerService.GetAllSpecs();
// for (const spec of allSpecs) {
// const response = await queryRpc(
// async (_, __, lavaClient: LavaClient) => lavaClient.lavanet.lava.pairing.providers({ chainID: spec, showFrozen: true }),
// 'pairing.getProviders'
// );

// for (const provider of response.stakeEntry) {
// const jailEndTime = Number(provider.jailEndTime);
// const now = Math.floor(Date.now() / 1000);

// const jailEndDate = new Date(jailEndTime * 1000).toISOString();
// const isJailed = jailEndTime > now;

// if (!isJailed) continue;
// console.log({
// provider: provider.address,
// jail_info: {
// end_timestamp: jailEndTime,
// end_date: jailEndDate,
// is_currently_jailed: isJailed,
// time_remaining: isJailed ?
// `${((jailEndTime - now) / (24 * 60 * 60)).toFixed(2)} days` :
// 'Not jailed'
// }
// });
// }
// }

// const aprMonitor = APRMonitor;
// console.log("stating apr monitor")
// aprMonitor.start();
Expand Down
26 changes: 19 additions & 7 deletions src/indexer/blockchainEntities/blockchainEntitiesStakeUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { logger } from '@jsinfo/utils/logger';
import { queryRpc } from '../utils/lavajsRpc';
import { SpecAndConsumerService } from '@jsinfo/redis/resources/global/SpecAndConsumerResource';
import { LavaClient } from '../lavaTypes';
import { IsMeaningfulText } from '@jsinfo/utils/fmt';

function processStakeEntry(
height: number,
dbStakes: Map<string, JsinfoSchema.InsertProviderStake[]>,
providerStake: StakeEntry,
isUnstaking: boolean,
) {
// Log the start of processing for the provider stake

Expand All @@ -35,15 +35,27 @@ function processStakeEntry(
let stakeArr: JsinfoSchema.InsertProviderStake[] = dbStakes.get(providerStake.address)!


// status
// Explanation 16/01/25:
// In provider who is not active is either Frozen of Jailed
// Frozen : stakeAppliedBlock is MAX_INT (parsed here as -1)
// Jailed : jailedEndTime is bigger then now

const appliedHeight = ToSignedIntOrMinusOne(providerStake.stakeAppliedBlock)

let status = JsinfoSchema.LavaProviderStakeStatus.Active
if (isUnstaking) {
status = JsinfoSchema.LavaProviderStakeStatus.Unstaking
} else if (appliedHeight == -1) {
if (appliedHeight == -1) {
status = JsinfoSchema.LavaProviderStakeStatus.Frozen
}

if (providerStake.jailEndTime && IsMeaningfulText(providerStake.jailEndTime + "")) {
const jailEndTime = Number(providerStake.jailEndTime);
const now = Math.floor(Date.now() / 1000);
const isJailed = jailEndTime > now;
if (isJailed) {
status = JsinfoSchema.LavaProviderStakeStatus.Jailed
}
}

let data: JsinfoSchema.InsertProviderStake = {
provider: providerStake.address,
blockId: height,
Expand All @@ -53,7 +65,7 @@ function processStakeEntry(
extensions: extensionsStr,
status: status,
stake: ToSignedBigIntOrMinusOne(providerStake.stake.amount),
delegateLimit: 0n,//ToSignedBigIntOrMinusOne(providerStake.delegateLimit.amount),
delegateLimit: 0n,
delegateTotal: ToSignedBigIntOrMinusOne(providerStake.delegateTotal.amount),
delegateCommission: ToSignedBigIntOrMinusOne(providerStake.delegateCommission),
appliedHeight: ToSignedIntOrMinusOne(appliedHeight),
Expand All @@ -79,7 +91,7 @@ export async function UpdateStakeInformation(
'pairing.getProviders'
);
providers.stakeEntry.forEach(stake => {
processStakeEntry(height, dbStakes, stake, false);
processStakeEntry(height, dbStakes, stake);
});
}

Expand Down
14 changes: 10 additions & 4 deletions src/indexer/restrpc_agregators/AprMonitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { queryJsinfo } from '@jsinfo/utils/db';
import { HashJson } from '@jsinfo/utils/fmt';
import { sql } from 'drizzle-orm';
import { IsTestnet } from '@jsinfo/utils/env';
import { ActiveProvidersService } from '@jsinfo/redis/resources/index/ActiveProvidersResource';

// Constants
const LAVA_RPC_BENCHMARK_AMOUNT = 10000 * 1000000;
Expand Down Expand Up @@ -306,7 +307,7 @@ class APRMonitorClass {
try {
const batchData = Array.from(aprValues.entries()).map(([provider, value]) => ({
address: provider,
value: value.toString(),
value: Number(value).toFixed(18),
timestamp: new Date(),
type: caller
}));
Expand Down Expand Up @@ -459,9 +460,15 @@ class APRMonitorClass {

// 1) Calculate Restaking APR and update the database
logger.info('Calculating Restaking APR...');
const providers = await ActiveProvidersService.fetch();
if (!providers) {
logger.error('No providers found');
return;
}

promises.push(
retry(() => this.calculateAPROnLavaAddresses(
() => RpcPeriodicEndpointCache.GetProviders(),
() => Promise.resolve(providers),
(provider) => RpcOnDemandEndpointCache.GetEstimatedProviderRewards(provider, LAVA_RPC_BENCHMARK_AMOUNT, LAVA_RPC_BENCHMARK_DENOM),
'Restaking APR'
)).then(aprRestaking => {
Expand All @@ -473,7 +480,6 @@ class APRMonitorClass {
// 2) Update APR for each provider concurrently
const updateRestakingAPR = async () => {
logger.info('Updating APR for each provider...');
const providers = await RpcPeriodicEndpointCache.GetProviders();
for (const provider of providers) {
const estimatedRewards = await RpcOnDemandEndpointCache.GetEstimatedProviderRewards(provider, LAVA_RPC_BENCHMARK_AMOUNT, LAVA_RPC_BENCHMARK_DENOM);
const apr = await retry(() => this.calculateAPROnLavaAddresses(
Expand All @@ -490,7 +496,7 @@ class APRMonitorClass {
// 3) Calculate Staking APR and update the database
promises.push(
retry(() => this.calculateAPROnLavaAddresses(
() => RpcPeriodicEndpointCache.GetAllValidatorsAddresses(),
() => RpcPeriodicEndpointCache.GetAllActiveValidatorsAddresses(),
(validator) => RpcOnDemandEndpointCache.GetEstimatedValidatorRewards(validator, LAVA_RPC_BENCHMARK_AMOUNT, LAVA_RPC_BENCHMARK_DENOM),
'Staking APR',
6
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FastifyRequest, FastifyReply, RouteShorthandOptions } from 'fastify';
import { IpRpcEndpointsIndexService } from '@jsinfo/redis/resources/IpRpcEndpointsIndex/IpRpcEndpointsResource';
import { JSONStringify } from '@jsinfo/utils/fmt';

export const IpRpcEndpointsIndexHandlerOpts: RouteShorthandOptions = {
schema: {
response: {
200: {
type: 'string'
}
}
}
};

export async function IpRpcEndpointsIndexHandler(_: FastifyRequest, reply: FastifyReply) {
try {
const endpoints = await IpRpcEndpointsIndexService.fetch({});
reply.header('Content-Type', 'application/json');
return reply.send(JSONStringify(endpoints));
} catch (error) {
return reply.status(500).send({ error: 'Failed to fetch IP RPC endpoints' });
}
}
21 changes: 21 additions & 0 deletions src/query/handlers/ajax/providersHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { FastifyRequest, FastifyReply, RouteShorthandOptions } from 'fastify';
import { ProviderMonikerService } from '@jsinfo/redis/resources/global/ProviderMonikerSpecResource'
import { ActiveProvidersService } from '@jsinfo/redis/resources/index/ActiveProvidersResource';

export const ProvidersPaginatedHandlerOpts: RouteShorthandOptions = {
schema: {
Expand All @@ -25,3 +26,23 @@ export async function ProvidersPaginatedHandler(request: FastifyRequest, reply:
providers: providers,
}
}

export const ActiveProvidersPaginatedHandlerOpts: RouteShorthandOptions = {
schema: {
response: {
200: {
type: 'object',
properties: {
providers: { type: 'array' },
}
}
}
}
}

export async function ActiveProvidersPaginatedHandler(request: FastifyRequest, reply: FastifyReply) {
const providers = await ActiveProvidersService.fetch();
return {
providers: providers,
}
}
2 changes: 0 additions & 2 deletions src/query/handlers/ajax/specsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ export const SpecsPaginatedHandlerOpts: RouteShorthandOptions = {
}

export async function SpecsPaginatedHandler(request: FastifyRequest, reply: FastifyReply) {


const res = await SpecAndConsumerService.GetAllSpecs();
return {
specs: res,
Expand Down
20 changes: 20 additions & 0 deletions src/query/handlers/ajax/validatorsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,24 @@ export async function ValidatorsPaginatedHandler(request: FastifyRequest, reply:
datetime: latestDatetime,
validators: validatorInfo
};
}

export const ActiveValidatorsPaginatedHandlerOpts: RouteShorthandOptions = {
schema: {
response: {
200: {
type: 'object',
properties: {
validators: { type: 'array' },
}
}
}
}
}

export async function ActiveValidatorsPaginatedHandler(request: FastifyRequest, reply: FastifyReply) {
const validators = await RpcPeriodicEndpointCache.GetAllActiveValidatorsAddresses();
return {
validators: validators,
}
}
13 changes: 12 additions & 1 deletion src/query/handlers/spec/specChartsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ProviderMonikerService } from '@jsinfo/redis/resources/global/ProviderM
import { PgColumn } from 'drizzle-orm/pg-core';
import { JSONStringifySpaced } from '@jsinfo/utils/fmt';
import { queryJsinfo } from '@jsinfo/utils/db';
import { ActiveProvidersService } from '@jsinfo/redis/resources/index/ActiveProvidersResource';

type SpecChartCuRelay = {
provider: string;
Expand Down Expand Up @@ -106,13 +107,23 @@ class SpecChartsData extends RequestHandlerBase<SpecChartResponse> {
return this.specTop10ProvidersCache;
}

let activeProviders = await ActiveProvidersService.fetch();
if (GetDataLength(activeProviders) === 0 || !activeProviders) {
return {};
}

// First query to get top 10 providers
let top10Providers = await queryJsinfo(
async (db) => await db.select({
provider: JsinfoSchema.providerStakes.provider,
})
.from(JsinfoSchema.providerStakes)
.where(eq(JsinfoSchema.providerStakes.specId, this.spec))
.where(
and(
eq(JsinfoSchema.providerStakes.specId, this.spec),
inArray(JsinfoSchema.providerStakes.provider, activeProviders)
)
)
.orderBy(desc(JsinfoSchema.providerStakes.stake))
.limit(10),
`SpecCharts_getSpecTop10Providers_${this.spec}`
Expand Down
10 changes: 8 additions & 2 deletions src/query/queryRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { AllProviderAPRRawHandlerOpts, AllProviderAPRRawHandler } from './handle
import { ListProvidersRawHandlerOpts, ListProvidersRawHandler } from './handlers/ajax/listProvidersHandler';

// -- Server meta ajax --
import { ProvidersPaginatedHandler, ProvidersPaginatedHandlerOpts } from './handlers/ajax/providersHandler';
import { ActiveProvidersPaginatedHandler, ActiveProvidersPaginatedHandlerOpts, ProvidersPaginatedHandler, ProvidersPaginatedHandlerOpts } from './handlers/ajax/providersHandler';
import { SpecsPaginatedHandler, SpecsPaginatedHandlerOpts } from './handlers/ajax/specsHandler';
import { ConsumersPaginatedHandler, ConsumersPaginatedHandlerOpts } from './handlers/ajax/consumersHandler';

Expand Down Expand Up @@ -98,10 +98,11 @@ import {
// -- Internal data endpoints --
import { ConsumerV2CahcedHandler, ConsumerV2CahcedHandlerOpts } from './handlers/consumer/consumerV2Handler';
import { ChainWalletApiHandlerOpts, LavaChainRestakersHandler, LavaChainStakersHandler } from './handlers/ajax/chainWalletApiHandlers';
import { ValidatorsPaginatedHandler, ValidatorsPaginatedHandlerOpts } from './handlers/ajax/validatorsHandler';
import { ActiveValidatorsPaginatedHandler, ActiveValidatorsPaginatedHandlerOpts, ValidatorsPaginatedHandler, ValidatorsPaginatedHandlerOpts } from './handlers/ajax/validatorsHandler';
import { TotalLockedValueHandler, TotalLockedValueHandlerOpts } from './handlers/ajax/totalLockedValueHandler';
import { TotalLockedValuesComponentsHandler, TotalLockedValuesComponentsHandlerOpts } from './handlers/ajax/totalLockedValuesComponentsHandler';
import { AllLockedValuesHandler, AllLockedValuesHandlerOpts } from './handlers/ajax/allLockedValuesHandler';
import { IpRpcEndpointsIndexHandler, IpRpcEndpointsIndexHandlerOpts } from './handlers/IpRpcEndpointsIndex/IpRpcEndpointsIndexHandler';

// -- Server status ajax --
GetServerInstance().get('/latest', LatestRawHandlerOpts, LatestRawHandler);
Expand Down Expand Up @@ -130,9 +131,11 @@ GetServerInstance().get('/listProviders', ListProvidersRawHandlerOpts, ListProvi

// -- Server meta ajax --
GetServerInstance().get('/providers', ProvidersPaginatedHandlerOpts, ProvidersPaginatedHandler);
GetServerInstance().get('/active_providers', ActiveProvidersPaginatedHandlerOpts, ActiveProvidersPaginatedHandler);
GetServerInstance().get('/specs', SpecsPaginatedHandlerOpts, SpecsPaginatedHandler);
GetServerInstance().get('/consumers', ConsumersPaginatedHandlerOpts, ConsumersPaginatedHandler);
GetServerInstance().get('/validators', ValidatorsPaginatedHandlerOpts, ValidatorsPaginatedHandler);
GetServerInstance().get('/active_validators', ActiveValidatorsPaginatedHandlerOpts, ActiveValidatorsPaginatedHandler);

// -- All pages ajax --
GetServerInstance().get('/autoCompleteLinksV2Handler', AutoCompleteLinksV2PaginatedHandlerOpts, AutoCompleteLinksV2PaginatedHandler);
Expand Down Expand Up @@ -240,3 +243,6 @@ tvlComponentsRoutes.forEach(route => {
});

GetServerInstance().get("/all_locked_values", AllLockedValuesHandlerOpts, AllLockedValuesHandler);

// lava_iprpc_endpoints
GetServerInstance().get('/lava_iprpc_endpoints', IpRpcEndpointsIndexHandlerOpts, IpRpcEndpointsIndexHandler);
Loading

0 comments on commit 3db9ec2

Please sign in to comment.