Skip to content

Commit f1807a7

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

17 files changed

+472
-72
lines changed

.env.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
WALLET_PRIVATE_KEY=
55
RPC_URL=
66
CHAIN_ID=
7-
TRIGGER_INTERVAL_HOURS=
7+
TRIGGER_SLI_JOB_INTERVAL_CRON=
8+
TRIGGER_CLAIMS_TRACKING_JOB_INTERVAL_CRON=
89
CDP_SERVICE_URL=
910
JOB_TRIGGER_AUTH_TOKEN=
1011
APP_PORT=

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",

src/blockchain/blockchain-client.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
import { privateKeyToAccount } from "viem/accounts";
1111
import { filecoin, filecoinCalibration } from "viem/chains";
1212
import { SERVICE_CONFIG } from "../config/env.js";
13+
import { baseLogger } from "../utils/logger.js";
1314

1415
export const getChain = (chainId: number) => {
1516
switch (chainId) {
@@ -30,6 +31,12 @@ export const getChain = (chainId: number) => {
3031
default: { http: ["http://fidlabs.servehttp.com:1234/rpc/v1"] },
3132
},
3233
testnet: true,
34+
contracts: {
35+
multicall3: {
36+
address: "0xe1C001010343EAEfa2E80bf0F1072f93b867616A",
37+
blockCreated: 1657068,
38+
},
39+
},
3340
});
3441
default:
3542
throw new Error(`Unsupported chain ID: ${chainId}`);
@@ -50,6 +57,7 @@ export function getRpcClient() {
5057
chain,
5158
transport: http(SERVICE_CONFIG.RPC_URL),
5259
});
60+
baseLogger.info("RPC client created on chain ID " + chain.id);
5361
}
5462

5563
return rpcClient;
@@ -62,6 +70,8 @@ export function getWalletClient() {
6270
chain,
6371
transport: http(SERVICE_CONFIG.RPC_URL),
6472
});
73+
74+
baseLogger.info("Wallet client created on chain ID " + chain.id);
6575
}
6676

6777
return walletClient;
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: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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<Address[]> {
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 as Address[];
32+
}
33+
34+
export async function getClientAllocationIdsPerProvider(
35+
storageProviderId: number,
36+
clientAddresses: Address[],
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: [BigInt(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+
const ids = multicall
60+
.filter((response) => !response.error)
61+
.flatMap((response) => Number(response.result));
62+
63+
return ids;
64+
}
65+
66+
export async function setClaimTerminatedEarly(allocationIds: bigint[]) {
67+
const rpcClient = getRpcClient();
68+
const walletClient = getWalletClient();
69+
70+
childLogger.info("claimsTerminatedEarly: Simulating request...");
71+
72+
const { request } = await rpcClient.simulateContract({
73+
address: SERVICE_CONFIG.CLIENT_CONTRACT_ADDRESS as Address,
74+
abi: CLIENT_CONTRACT_ABI,
75+
functionName: "claimsTerminatedEarly",
76+
args: [allocationIds],
77+
account: walletClient.account,
78+
});
79+
80+
childLogger.info("claimsTerminatedEarly: Sending transaction...");
81+
82+
const txHash = await walletClient.writeContract(request);
83+
84+
childLogger.info(
85+
`claimsTerminatedEarly: Transaction sent: ${txHash}, waiting for confirmation...`,
86+
);
87+
88+
const receipt = await rpcClient.waitForTransactionReceipt({
89+
hash: txHash,
90+
});
91+
92+
childLogger.info(
93+
`claimsTerminatedEarly: Transaction executed in block ${receipt.blockNumber}`,
94+
);
95+
}

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
}

0 commit comments

Comments
 (0)