Skip to content

Commit 7e9f40e

Browse files
committed
fix: self-report status code
1 parent 4ceadaa commit 7e9f40e

File tree

7 files changed

+600
-175
lines changed

7 files changed

+600
-175
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"pino-pretty": "^13.1.1"
2121
},
2222
"devDependencies": {
23-
"@aws-sdk/client-s3": "^3.899.0",
23+
"@aws-sdk/client-s3": "^3.901.0",
2424
"@biomejs/biome": "^2.2.4",
2525
"@commander-js/extra-typings": "^14.0.0",
2626
"@commitlint/cli": "^20.1.0",

src/services/Client.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { exceptionsAbis } from "../data/index.js";
3838
import { DI } from "../di.js";
3939
import { TransactionRevertedError } from "../errors/TransactionRevertedError.js";
4040
import { type ILogger, Logger } from "../log/index.js";
41+
import type { StatusCode } from "../utils/index.js";
4142
import type { INotifier } from "./notifier/index.js";
4243
import { LowBalanceMessage } from "./notifier/index.js";
4344

@@ -65,7 +66,7 @@ export default class Client {
6566

6667
#testClient?: AnvilClient;
6768

68-
#balance?: { value: bigint; healthy: boolean };
69+
#balance?: { value: bigint; status: StatusCode };
6970

7071
public async launch(): Promise<void> {
7172
const { chainId, network, optimistic, privateKey, pollingInterval } =
@@ -241,7 +242,10 @@ export default class Client {
241242
const balance = await this.pub.getBalance({ address: this.address });
242243
this.#balance = {
243244
value: balance,
244-
healthy: !!this.config.minBalance && balance >= this.config.minBalance,
245+
status:
246+
!this.config.minBalance || balance >= this.config.minBalance
247+
? "healthy"
248+
: "alert",
245249
};
246250
this.logger.debug(`liquidator balance is ${formatEther(balance)}`);
247251
if (balance < this.config.minBalance) {
@@ -288,7 +292,7 @@ export default class Client {
288292
return this.wallet.account.address;
289293
}
290294

291-
public get balance(): { value: bigint; healthy: boolean } | undefined {
295+
public get balance(): { value: bigint; status: StatusCode } | undefined {
292296
return this.#balance;
293297
}
294298

src/services/HealthCheckerService.ts

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { Config } from "../config/index.js";
1111
import { DI } from "../di.js";
1212
import type { ILogger } from "../log/index.js";
1313
import { Logger } from "../log/index.js";
14+
import { maxStatusCode, type StatusCode } from "../utils/index.js";
1415
import version from "../version.js";
1516
import type Client from "./Client.js";
1617
import type { Scanner } from "./Scanner.js";
@@ -47,39 +48,10 @@ export default class HealthCheckerService {
4748
}
4849

4950
const server = createServer(async (req, res) => {
50-
const timestamp = Number(this.sdk.timestamp);
51-
const now = Math.ceil(Date.now() / 1000);
52-
const threshold = this.config.staleBlockThreshold;
5351
// Routing
5452
if (req.url === "/") {
5553
res.writeHead(200, { "Content-Type": "application/json" });
56-
res.end(
57-
json_stringify({
58-
startTime: this.#start,
59-
version,
60-
network: this.config.network,
61-
family: "liquidators",
62-
liquidationMode: this.config.liquidationMode,
63-
address: this.client.address,
64-
balance: this.client.balance,
65-
currentBlock: this.sdk.currentBlock,
66-
timestamp: {
67-
value: timestamp,
68-
healthy: !!threshold && now - timestamp <= threshold,
69-
},
70-
marketsConfigurators:
71-
this.sdk.marketRegister.marketConfigurators.map(mc => mc.address),
72-
pools: this.sdk.marketRegister.pools.map(p => p.pool.address),
73-
creditManagers: this.sdk.marketRegister.creditManagers.map(
74-
cm => cm.creditManager.address,
75-
),
76-
providers: (
77-
this.sdk.provider.publicClient as PublicClient<
78-
Transport<"revolver", RevolverTransportValue>
79-
>
80-
).transport.statuses(),
81-
}),
82-
);
54+
res.end(json_stringify(this.#healthStatus));
8355
} else if (req.url === "/metrics") {
8456
try {
8557
res.writeHead(200, { "Content-Type": "text/plain" });
@@ -106,6 +78,54 @@ export default class HealthCheckerService {
10678
this.log.info("launched");
10779
}
10880

81+
get #healthStatus() {
82+
const timestamp = Number(this.sdk.timestamp);
83+
const now = Math.ceil(Date.now() / 1000);
84+
const threshold = this.config.staleBlockThreshold;
85+
const result = {
86+
status: "healthy" as StatusCode,
87+
startTime: this.#start,
88+
version,
89+
network: this.config.network,
90+
family: "liquidators",
91+
liquidationMode: this.config.liquidationMode,
92+
address: this.client.address,
93+
balance: this.client.balance,
94+
currentBlock: this.sdk.currentBlock,
95+
timestamp: {
96+
value: timestamp,
97+
status: (!!threshold && now - timestamp <= threshold
98+
? "healthy"
99+
: "alert") as StatusCode,
100+
},
101+
marketsConfigurators: this.sdk.marketRegister.marketConfigurators.map(
102+
mc => mc.address,
103+
),
104+
pools: this.sdk.marketRegister.pools.map(p => p.pool.address),
105+
creditManagers: this.sdk.marketRegister.creditManagers.map(
106+
cm => cm.creditManager.address,
107+
),
108+
liquidatableAccounts: {
109+
value: this.scanner.liquidatableAccounts,
110+
status: (this.scanner.liquidatableAccounts > 0
111+
? "alert"
112+
: "healthy") as StatusCode,
113+
},
114+
providers: (
115+
this.sdk.provider.publicClient as PublicClient<
116+
Transport<"revolver", RevolverTransportValue>
117+
>
118+
).transport.statuses(),
119+
};
120+
result.status = maxStatusCode(
121+
result.status,
122+
result.timestamp.status,
123+
result.balance?.status,
124+
result.liquidatableAccounts.status,
125+
);
126+
return result;
127+
}
128+
109129
public async stop(): Promise<void> {
110130
this.log.info("stopping");
111131
return new Promise(resolve => {

src/services/Scanner.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export class Scanner {
6060
#minHealthFactor = 0n;
6161
#unwatch?: () => void;
6262
#lastZeroHFNotification = 0;
63+
#liquidatableAccounts = 0;
6364

6465
public async launch(): Promise<void> {
6566
await this.liquidatorService.launch();
@@ -208,6 +209,7 @@ export class Scanner {
208209
this.log.debug(
209210
`${accounts.length} accounts to ${verb}${blockS}, time: ${time}s`,
210211
);
212+
this.#liquidatableAccounts = accounts.length;
211213

212214
if (this.config.optimistic) {
213215
await this.liquidatorService.liquidateOptimistic(accounts);
@@ -412,6 +414,10 @@ export class Scanner {
412414
return this.#lastUpdated;
413415
}
414416

417+
public get liquidatableAccounts(): number {
418+
return this.#liquidatableAccounts;
419+
}
420+
415421
public async stop(): Promise<void> {
416422
this.#unwatch?.();
417423
this.log.info("stopped");

src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from "./createTransport.js";
22
export * from "./formatters.js";
33
export * from "./retry.js";
4+
export * from "./status.js";
45
export * from "./types.js";
56
export * from "./typescript.js";

src/utils/status.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export type StatusCode = "healthy" | "warning" | "alert";
2+
3+
const statusCodeOrder: Record<StatusCode, number> = {
4+
healthy: 0,
5+
warning: 1,
6+
alert: 2,
7+
};
8+
9+
export function maxStatusCode(
10+
...codes: Array<StatusCode | undefined>
11+
): StatusCode {
12+
let status: StatusCode = "healthy";
13+
for (const code of codes) {
14+
if (!code) {
15+
continue;
16+
}
17+
status = statusCodeOrder[code] > statusCodeOrder[status] ? code : status;
18+
}
19+
return status;
20+
}

0 commit comments

Comments
 (0)