-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathConfigurationService.ts
More file actions
77 lines (73 loc) · 3.95 KB
/
Copy pathConfigurationService.ts
File metadata and controls
77 lines (73 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { Factory, Singleton } from "typescript-ioc";
import { readJSON } from "../utils/config-utils";
import { INetworkConfigJson } from "../utils/interfaces";
import { logException } from "../logger/logger";
// Unauthenticated, the p-chain indexer allows 60 requests/min — measured 2026-08-21: request 61
// refused with `Retry-After: 60`. A full delegator sweep is 100+ requests, so it needs its own
// pacing, well below the RPC's. Request latency adds to the sleep, so 1/s yields an effective
// ~0.85/s (~50 req/min) and stays under the limit. An INDEXER_API_KEY_{NETWORK} lifts it: the
// same sweep ran 107 requests at 239 req/min with no 429.
const DEFAULT_INDEXER_REQUESTS_PER_SECOND = 1;
@Singleton
@Factory(() => new ConfigurationService())
export class ConfigurationService {
network!: string;
networkRPC!: string;
maxBlocksForEventReads!: number;
maxRequestsPerSecond!: number | string;
indexerRequestsPerSecond!: number;
indexerApiKey?: string | undefined;
rewardEpoch?: number;
requiredFtsoPerformanceWei!: string;
boostingFactor!: number;
votePowerCapBIPS!: number;
uptimeVotigPeriodLengthSeconds!: number;
uptimeVotingThreshold?: number;
minForBEBGwei!: string;
rewardAmountEpochWei?: string;
apiPath?: string;
numEpochs!: number;
constructor() {
if (process.env.CONFIG_FILE) {
let configFile: INetworkConfigJson;
try {
configFile = readJSON<INetworkConfigJson>(process.env.CONFIG_FILE);
} catch (error) {
logException(error, `ConfigFile doesn't exist`);
configFile = {} as INetworkConfigJson;
}
this.network = configFile.NETWORK ?? "flare";
const rpcOverride = process.env[`RPC_URL_${this.network.toUpperCase()}`];
// Selects the indexer host, e.g. to fail over to a mirror. Not a secret — the key is
// supplied separately so it can be a masked CI variable (GitLab refuses to mask a value
// containing `?`, so it cannot live inside a URL).
const apiPathOverride = process.env[`API_PATH_${this.network.toUpperCase()}`];
this.networkRPC = rpcOverride ?? configFile.RPC ?? "https://flare-api.flare.network/ext/C/rpc";
this.maxBlocksForEventReads = configFile.MAX_BLOCKS_FOR_EVENT_READS ?? 30;
this.maxRequestsPerSecond = rpcOverride ? "Infinity" : (configFile.MAX_REQUESTS_PER_SECOND ?? 3);
// Network-scoped: the coston2 jobs hit a different indexer host, so a single global key
// would be sent to a host it was not issued for.
this.indexerApiKey = process.env[`INDEXER_API_KEY_${this.network.toUpperCase()}`] ?? undefined;
// The key lifts the request limit, so pacing is unnecessary once one is set. An explicit
// INDEXER_REQUESTS_PER_SECOND wins over both, so the rate can be dialled back from CI
// without a code change if the key's budget ever turns out to be finite after all.
const indexerRps = Number(
process.env.INDEXER_REQUESTS_PER_SECOND ??
(this.indexerApiKey ? "Infinity" : configFile.INDEXER_REQUESTS_PER_SECOND) ??
DEFAULT_INDEXER_REQUESTS_PER_SECOND
);
this.indexerRequestsPerSecond =
Number.isNaN(indexerRps) || indexerRps <= 0 ? DEFAULT_INDEXER_REQUESTS_PER_SECOND : indexerRps;
this.rewardEpoch = configFile.REWARD_EPOCH ?? undefined;
this.requiredFtsoPerformanceWei = configFile.REQUIRED_FTSO_PERFORMANCE_WEI ?? "0";
this.boostingFactor = configFile.BOOSTING_FACTOR ?? 5;
this.votePowerCapBIPS = configFile.VOTE_POWER_CAP_BIPS ?? 500;
this.uptimeVotigPeriodLengthSeconds = configFile.UPTIME_VOTING_PERIOD_LENGTH_SECONDS ?? 600;
this.uptimeVotingThreshold = configFile.UPTIME_VOTING_THRESHOLD ?? undefined;
this.minForBEBGwei = configFile.MIN_FOR_BEB_GWEI ?? "1000000000000000";
this.rewardAmountEpochWei = configFile.REWARD_AMOUNT_EPOCH_WEI ?? undefined;
this.apiPath = apiPathOverride ?? configFile.API_PATH ?? undefined;
this.numEpochs = configFile.NUM_EPOCHS ? configFile.NUM_EPOCHS : 4;
}
}
}