Skip to content

Commit a69b140

Browse files
committed
Add terminations tracking job
1 parent c01cc10 commit a69b140

File tree

15 files changed

+418
-59
lines changed

15 files changed

+418
-59
lines changed

src/blockchain/abis/client-abi.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { Abi } from "viem";
2+
3+
export const CLIENT_CONTRACT_ABI = [
4+
{
5+
type: "function",
6+
name: "getSPClients",
7+
inputs: [
8+
{
9+
name: "provider",
10+
type: "uint64",
11+
internalType: "CommonTypes.FilActorId",
12+
},
13+
],
14+
outputs: [
15+
{
16+
name: "clients",
17+
type: "address[]",
18+
internalType: "address[]",
19+
},
20+
],
21+
stateMutability: "view",
22+
},
23+
{
24+
type: "function",
25+
name: "getClientAllocationIdsPerProvider",
26+
inputs: [
27+
{
28+
name: "provider",
29+
type: "uint64",
30+
internalType: "CommonTypes.FilActorId",
31+
},
32+
{
33+
name: "client",
34+
type: "address",
35+
internalType: "address",
36+
},
37+
],
38+
outputs: [
39+
{
40+
name: "",
41+
type: "uint64[]",
42+
internalType: "CommonTypes.FilActorId[]",
43+
},
44+
],
45+
stateMutability: "view",
46+
},
47+
{
48+
type: "function",
49+
name: "claimsTerminatedEarly",
50+
inputs: [
51+
{
52+
name: "claims",
53+
type: "uint64[]",
54+
internalType: "uint64[]",
55+
},
56+
],
57+
outputs: [],
58+
stateMutability: "nonpayable",
59+
},
60+
] as const satisfies Abi;

src/blockchain/abis/sla-allocator-abi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Abi } from "viem";
22

3-
export const SLA_ALLOCATOR_ABI = [
3+
export const SLA_ALLOCATOR_CONTRACT_ABI = [
44
{
55
type: "function",
66
name: "providers",

src/blockchain/abis/sli-oracle-abi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export const SLI_ORACLE_ABI = [
1+
export const SLI_ORACLE_CONTRACT_ABI = [
22
{
33
type: "function",
44
name: "setSLI",
Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
import { Address } from "viem";
22
import { SERVICE_CONFIG } from "../config/env.js";
3-
import { logger } from "../utils/logger.js";
4-
import { SLA_ALLOCATOR_ABI } from "./abis/sla-allocator-abi.js";
3+
import { baseLogger } from "../utils/logger.js";
4+
import { SLA_ALLOCATOR_CONTRACT_ABI } from "./abis/sla-allocator-abi.js";
55
import { getRpcClient } from "./blockchain-client.js";
66

7+
const childLogger = baseLogger.child(
8+
{ avengers: "assemble" },
9+
{ msgPrefix: "[SLA Allocator Contract] " },
10+
);
11+
712
export async function getProvidersFromSlaAllocatorContract(): Promise<
813
number[]
914
> {
1015
const rpcClient = getRpcClient();
1116

12-
logger.info("Fetching providers from SLA Allocator contract...");
17+
childLogger.info("Fetching providers from contract...");
1318

1419
const providers = await rpcClient.readContract({
1520
address: SERVICE_CONFIG.SLA_ALLOCATOR_CONTRACT_ADDRESS as Address,
16-
abi: SLA_ALLOCATOR_ABI,
21+
abi: SLA_ALLOCATOR_CONTRACT_ABI,
1722
functionName: "getProviders",
1823
});
1924

20-
logger.info(
21-
`Fetched ${providers.length} providers from SLA Allocator contract`,
22-
);
25+
childLogger.info(`Fetched ${providers.length} providers from contract`);
2326

2427
return providers.map((p) => Number(p));
2528
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { Address } from "viem";
2+
import { SERVICE_CONFIG } from "../config/env.js";
3+
4+
import { baseLogger } from "../utils/logger.js";
5+
import { CLIENT_CONTRACT_ABI } from "./abis/client-abi.js";
6+
import { getRpcClient, getWalletClient } from "./blockchain-client.js";
7+
8+
const childLogger = baseLogger.child(
9+
{ avengers: "assemble" },
10+
{ msgPrefix: "[SLA Client Contract] " },
11+
);
12+
13+
export async function getClientsForSPFromClientContract(
14+
storageProviderId: number,
15+
): Promise<number[]> {
16+
const rpcClient = getRpcClient();
17+
18+
childLogger.info("Fetching clients for storage provider...");
19+
20+
const spClients = await rpcClient.readContract({
21+
address: SERVICE_CONFIG.CLIENT_CONTRACT_ADDRESS as Address,
22+
abi: CLIENT_CONTRACT_ABI,
23+
functionName: "getSPClients",
24+
args: [BigInt(storageProviderId)],
25+
});
26+
27+
childLogger.info(
28+
`Fetched ${spClients.length} clients for SP ${storageProviderId}`,
29+
);
30+
31+
return spClients.map((p) => Number(p));
32+
}
33+
34+
export async function getClientAllocationIdsPerProvider(
35+
storageProviderId: number,
36+
clientAddresses: number[],
37+
): Promise<number[]> {
38+
const rpcClient = getRpcClient();
39+
40+
childLogger.info(
41+
`Fetching allocation ID for clients and storage providers ${storageProviderId}...`,
42+
);
43+
44+
const multicallData = clientAddresses.map((clientId) => ({
45+
address: SERVICE_CONFIG.CLIENT_CONTRACT_ADDRESS as Address,
46+
abi: CLIENT_CONTRACT_ABI,
47+
functionName: "getClientAllocationIdsPerProvider",
48+
args: [storageProviderId, clientId],
49+
}));
50+
51+
const multicall = await rpcClient.multicall({
52+
contracts: multicallData,
53+
});
54+
55+
childLogger.info(
56+
`Fetched ${multicall.length} allocations for storage provider ${storageProviderId}...`,
57+
);
58+
59+
return multicall.flat().map(Number);
60+
}
61+
62+
export async function setClaimTerminatedEarly(allocationIds: bigint[]) {
63+
const rpcClient = getRpcClient();
64+
const walletClient = getWalletClient();
65+
66+
const oracleContractAddress =
67+
SERVICE_CONFIG.ORACLE_CONTRACT_ADDRESS as Address;
68+
69+
childLogger.info("claimsTerminatedEarly: Simulating request...");
70+
71+
const { request } = await rpcClient.simulateContract({
72+
address: oracleContractAddress,
73+
abi: CLIENT_CONTRACT_ABI,
74+
functionName: "claimsTerminatedEarly",
75+
args: [allocationIds],
76+
account: walletClient.account,
77+
});
78+
79+
childLogger.info("claimsTerminatedEarly: Sending transaction...");
80+
81+
const txHash = await walletClient.writeContract(request);
82+
83+
childLogger.info(
84+
`claimsTerminatedEarly: Transaction sent: ${txHash}, waiting for confirmation...`,
85+
);
86+
87+
const receipt = await rpcClient.waitForTransactionReceipt({
88+
hash: txHash,
89+
});
90+
91+
childLogger.info(
92+
`claimsTerminatedEarly: Transaction executed in block ${receipt.blockNumber}`,
93+
);
94+
}

src/blockchain/sli-oracle-contract.ts

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import { Address, encodeFunctionData } from "viem";
22
import { SERVICE_CONFIG } from "../config/env.js";
3-
import { logger } from "../utils/logger.js";
3+
import { baseLogger } from "../utils/logger.js";
44
import {
55
CdpSliResponse,
66
SLIAttestation,
77
StorageProvidersSLIMetric,
88
} from "../utils/types.js";
9-
import { SLI_ORACLE_ABI } from "./abis/sli-oracle-abi.js";
9+
import { SLI_ORACLE_CONTRACT_ABI } from "./abis/sli-oracle-abi.js";
1010
import { getRpcClient, getWalletClient } from "./blockchain-client.js";
1111

12+
const childLogger = baseLogger.child(
13+
{ avengers: "assemble" },
14+
{ msgPrefix: "[SLI Oracle Contract] " },
15+
);
16+
1217
export async function setSliOnOracleContract(
1318
sliDataForProviders: CdpSliResponse[],
1419
) {
@@ -22,7 +27,7 @@ export async function setSliOnOracleContract(
2227
provider: bigint;
2328
sli: SLIAttestation;
2429
}[] = sliDataForProviders.map((provider) => {
25-
logger.info(
30+
childLogger.info(
2631
`Preparing SLI data for provider ${provider.storageProviderId}`,
2732
);
2833
const availabilityMetric =
@@ -82,68 +87,73 @@ export async function setSliOnOracleContract(
8287

8388
const encodedCalls = buildedSliData.map((req) =>
8489
encodeFunctionData({
85-
abi: SLI_ORACLE_ABI,
90+
abi: SLI_ORACLE_CONTRACT_ABI,
8691
functionName: "setSLI",
8792
args: [req.provider, req.sli],
8893
}),
8994
);
9095

91-
logger.info("Simulating request to oracle contract...");
96+
childLogger.info("setSLI: Simulating request...");
9297

9398
const { request } = await rpcClient.simulateContract({
9499
address: oracleContractAddress,
95-
abi: SLI_ORACLE_ABI,
100+
abi: SLI_ORACLE_CONTRACT_ABI,
96101
functionName: "multicall",
97102
args: [encodedCalls],
98103
account: walletClient.account,
99104
});
100105

101-
logger.info("Simulation successful.");
102-
103-
logger.info("Sending transaction to oracle contract...");
106+
childLogger.info("setSLI: Sending transaction...");
104107

105108
const txHash = await walletClient.writeContract(request);
106109

107-
logger.info(`Transaction sent: ${txHash}`);
108-
logger.info(`Waiting for confirmation...`);
110+
childLogger.info(
111+
`setSLI: Transaction sent: ${txHash}, waiting for confirmation...`,
112+
);
109113

110114
const receipt = await rpcClient.waitForTransactionReceipt({
111115
hash: txHash,
112116
});
113117

114-
logger.info(`Transaction executed in block ${receipt.blockNumber}`);
118+
childLogger.info(
119+
`setSLI: Transaction executed in block ${receipt.blockNumber}`,
120+
);
115121
}
116122

117123
export async function getSPEmptyAttestations(): Promise<void> {
118124
const rpcClient = getRpcClient();
119125

120-
logger.info(
126+
childLogger.info(
121127
"Fetching Attestations from SLI Oracle contract for SP: f03315260",
122128
);
123129

124130
const providers = await rpcClient.readContract({
125131
address: SERVICE_CONFIG.ORACLE_CONTRACT_ADDRESS as Address,
126-
abi: SLI_ORACLE_ABI,
132+
abi: SLI_ORACLE_CONTRACT_ABI,
127133
functionName: "attestations",
128134
args: [90999],
129135
});
130136

131-
logger.info(`Fetched Attestation from SLI Oracle contract: ` + providers);
137+
childLogger.info(
138+
`Fetched Attestation from SLI Oracle contract: ` + providers,
139+
);
132140
}
133141

134142
export async function getSPFillAttestations(): Promise<void> {
135143
const rpcClient = getRpcClient();
136144

137-
logger.info(
145+
childLogger.info(
138146
"Fetching Attestations from SLI Oracle contract for SP: f03315260",
139147
);
140148

141149
const providers = await rpcClient.readContract({
142150
address: SERVICE_CONFIG.ORACLE_CONTRACT_ADDRESS as Address,
143-
abi: SLI_ORACLE_ABI,
151+
abi: SLI_ORACLE_CONTRACT_ABI,
144152
functionName: "attestations",
145153
args: [3315260],
146154
});
147155

148-
logger.info(`Fetched Attestations from SLI Oracle contract: ` + providers);
156+
childLogger.info(
157+
`Fetched Attestations from SLI Oracle contract: ` + providers,
158+
);
149159
}

src/config/env.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const EnvKeys = {
1111
CDP_SERVICE_URL: "CDP_SERVICE_URL",
1212
JOB_TRIGGER_AUTH_TOKEN: "JOB_TRIGGER_AUTH_TOKEN",
1313
APP_PORT: "APP_PORT",
14+
CLIENT_CONTRACT_ADDRESS: "CLIENT_CONTRACT_ADDRESS",
1415
} as const;
1516

1617
type EnvKey = (typeof EnvKeys)[keyof typeof EnvKeys];
@@ -27,4 +28,5 @@ export const SERVICE_CONFIG: Record<EnvKey, string> = {
2728
CDP_SERVICE_URL: process.env.CDP_SERVICE_URL || "",
2829
JOB_TRIGGER_AUTH_TOKEN: process.env.JOB_TRIGGER_AUTH_TOKEN || "",
2930
APP_PORT: process.env.APP_PORT || "3000",
31+
CLIENT_CONTRACT_ADDRESS: process.env.CLIENT_CONTRACT_ADDRESS || "",
3032
};

src/http-server/server.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import express, { NextFunction, Request, Response } from "express";
33
// import { setSliOracleJob } from "../jobs/set-sli-job.js";
44
import { SERVICE_CONFIG } from "../config/env.js";
55
import { setSliOracleJob } from "../jobs/set-sli-job.js";
6-
import { logger } from "../utils/logger.js";
6+
import { baseLogger } from "../utils/logger.js";
77

88
const app = express();
99

@@ -18,7 +18,7 @@ function authMiddleware(req: Request, res: Response, next: NextFunction) {
1818
const authHeader = req.headers["authorization"];
1919

2020
if (!AUTH_TOKEN) {
21-
logger.warn("Missing JOB_TRIGGER_TOKEN env variable — skipping auth");
21+
baseLogger.warn("Missing JOB_TRIGGER_TOKEN env variable — skipping auth");
2222
return next();
2323
}
2424

@@ -38,26 +38,23 @@ app.post(
3838
"/trigger-now",
3939
authMiddleware,
4040
async (req: Request, res: Response) => {
41-
logger.info("Manual trigger received via /trigger-now");
41+
baseLogger.info("Manual trigger received via /trigger-now");
4242

4343
try {
44-
// await getSPEmptyAttestations();
45-
4644
await setSliOracleJob();
4745

48-
// await getSPFillAttestations();
4946
res.json({ status: "ok", message: "Job triggered successfully" });
5047
} catch (err) {
5148
const message = err instanceof Error ? err.message : String(err);
52-
logger.error(`Manual job trigger failed: ${message}`);
49+
baseLogger.error(`Manual job trigger failed: ${message}`);
5350
res.status(500).json({ error: message });
5451
}
5552
},
5653
);
5754

5855
app.listen(port, () => {
59-
logger.info("Oracle service started on port " + port);
60-
logger.info(`Health/trigger server running on port ${port}`);
61-
logger.info(`Health endpoint: GET /health`);
62-
logger.info(`Manual trigger: POST /trigger-now`);
56+
baseLogger.info("Oracle service started on port " + port);
57+
baseLogger.info(`Health/trigger server running on port ${port}`);
58+
baseLogger.info(`Health endpoint: GET /health`);
59+
baseLogger.info(`Manual trigger: POST /trigger-now`);
6360
});

0 commit comments

Comments
 (0)