Skip to content

Commit 6b11b60

Browse files
authored
Limit concurrent RPCs for tbill balances (#3813)
* Limit concurrent RPCs for tbill balances * lint
1 parent 2d18954 commit 6b11b60

File tree

4 files changed

+307
-21
lines changed

4 files changed

+307
-21
lines changed

.changeset/nasty-baboons-switch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@chainlink/token-balance-adapter': minor
3+
---
4+
5+
Limit concurrent RPCs made for tbill balances.

packages/sources/token-balance/src/config/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,10 @@ export const config = new AdapterConfig({
3737
type: 'number',
3838
default: 10_000,
3939
},
40+
GROUP_SIZE: {
41+
description:
42+
'Number of requests to execute asynchronously before the adapter waits to execute the next group of requests. Setting this lower than the default may result in lower performance from the adapter.',
43+
type: 'number',
44+
default: 25,
45+
},
4046
})

packages/sources/token-balance/src/transport/tbill.ts

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1+
import { EndpointContext } from '@chainlink/external-adapter-framework/adapter'
12
import { TransportDependencies } from '@chainlink/external-adapter-framework/transports'
2-
import { AdapterResponse, makeLogger, sleep } from '@chainlink/external-adapter-framework/util'
33
import { SubscriptionTransport } from '@chainlink/external-adapter-framework/transports/abstract/subscription'
4-
import { EndpointContext } from '@chainlink/external-adapter-framework/adapter'
4+
import { AdapterResponse, makeLogger, sleep } from '@chainlink/external-adapter-framework/util'
55
import { AdapterInputError } from '@chainlink/external-adapter-framework/validation/error'
6+
import { ethers } from 'ethers'
67
import { BaseEndpointTypes, inputParameters } from '../endpoint/tbill'
7-
import OpenEdenTBILLProxy from '../config/OpenEdenTBILLProxy.json'
8-
import { ethers, Contract } from 'ethers'
9-
import { getRate } from './priceFeed'
8+
import { GroupedProvider, GroupedTokenContract, SharePriceType } from './utils'
109

1110
const logger = makeLogger('Token Balance - Tbill')
1211

@@ -20,9 +19,10 @@ type AddressType = {
2019
priceOracleAddress: string
2120
}
2221

23-
type SharePriceType = {
24-
value: bigint
25-
decimal: number
22+
type RequestContext = {
23+
groupedProviders: {
24+
[chainId: string]: GroupedProvider
25+
}
2626
}
2727

2828
const RESULT_DECIMALS = 18
@@ -65,8 +65,11 @@ export class TbillTransport extends SubscriptionTransport<BaseEndpointTypes> {
6565

6666
async handleRequest(context: EndpointContext<BaseEndpointTypes>, param: RequestParams) {
6767
let response: AdapterResponse<BaseEndpointTypes['Response']>
68+
const requestContext: RequestContext = {
69+
groupedProviders: {},
70+
}
6871
try {
69-
response = await this._handleRequest(context, param)
72+
response = await this._handleRequest(context, param, requestContext)
7073
} catch (e: unknown) {
7174
const errorMessage = e instanceof Error ? e.message : 'Unknown error occurred'
7275
logger.error(e, errorMessage)
@@ -86,6 +89,7 @@ export class TbillTransport extends SubscriptionTransport<BaseEndpointTypes> {
8689
async _handleRequest(
8790
context: EndpointContext<BaseEndpointTypes>,
8891
param: RequestParams,
92+
requestContext: RequestContext,
8993
): Promise<AdapterResponse<BaseEndpointTypes['Response']>> {
9094
const addresses = param.addresses.filter(
9195
(a) =>
@@ -100,7 +104,7 @@ export class TbillTransport extends SubscriptionTransport<BaseEndpointTypes> {
100104

101105
const results = await Promise.all(
102106
addresses.map(async (address: AddressType) => {
103-
return this.calculateTbillSharesUSD(context, address)
107+
return this.calculateTbillSharesUSD(context, address, requestContext)
104108
}),
105109
)
106110

@@ -121,29 +125,46 @@ export class TbillTransport extends SubscriptionTransport<BaseEndpointTypes> {
121125
}
122126
}
123127

124-
async calculateTbillSharesUSD(context: EndpointContext<BaseEndpointTypes>, address: AddressType) {
128+
getGroupedProvider(
129+
context: EndpointContext<BaseEndpointTypes>,
130+
address: AddressType,
131+
requestContext: RequestContext,
132+
): GroupedProvider {
125133
let provider!: ethers.JsonRpcProvider
126-
127134
if (address.chainId === String(context.adapterSettings.ETHEREUM_RPC_CHAIN_ID)) {
128135
provider = this.ethProvider
129136
} else if (address.chainId === String(context.adapterSettings.ARBITRUM_RPC_CHAIN_ID)) {
130137
provider = this.arbProvider
131-
}
132-
133-
if (!provider) {
138+
} else {
134139
throw new AdapterInputError({
135140
statusCode: 400,
136141
message: `ChainId ${address.chainId} not supported for Tbill.`,
137142
})
138143
}
139144

140-
const contract: Contract = new ethers.Contract(
141-
address.contractAddress,
142-
OpenEdenTBILLProxy,
143-
provider,
145+
if (!requestContext.groupedProviders[address.chainId]) {
146+
requestContext.groupedProviders[address.chainId] = new GroupedProvider(
147+
provider,
148+
context.adapterSettings.GROUP_SIZE,
149+
)
150+
}
151+
return requestContext.groupedProviders[address.chainId]
152+
}
153+
154+
async calculateTbillSharesUSD(
155+
context: EndpointContext<BaseEndpointTypes>,
156+
address: AddressType,
157+
requestContext: RequestContext,
158+
) {
159+
const groupedProvider = this.getGroupedProvider(context, address, requestContext)
160+
161+
const contract = groupedProvider.createTokenContract(address.contractAddress)
162+
const priceOracleContract = groupedProvider.createPriceOracleContract(
163+
address.priceOracleAddress,
144164
)
165+
145166
const [sharePriceUSD, sharesDecimals, queueLength, balanceResponse] = await Promise.all([
146-
getRate(address.priceOracleAddress, provider),
167+
priceOracleContract.getRate(),
147168
contract.decimals(),
148169
contract.getWithdrawalQueueLength(),
149170
Promise.all(address.wallets.map((wallet) => contract.balanceOf(wallet))),
@@ -190,7 +211,7 @@ export class TbillTransport extends SubscriptionTransport<BaseEndpointTypes> {
190211

191212
async getWithdrawalQueueAum(
192213
queueLength: bigint,
193-
tbillWithrawalQueueContract: Contract,
214+
tbillWithrawalQueueContract: GroupedTokenContract,
194215
sharePriceUSD: SharePriceType,
195216
sharesDecimals: bigint,
196217
) {

0 commit comments

Comments
 (0)