Skip to content

Commit 6b7b6de

Browse files
maschadarboleya
andauthored
feat: ensure that we fetch node info per estimation (#3324)
* fix: ensure that we fetch node info per estimation * docs: add changeset * fix: use auto refreshing cache mechanism * docs: update changesets * fix: ensure setInterval is cleared * fix: remove unnecessary changes * Trigger CI * fix: clear interval prop * fix: update how consensus params are checked * Fixing chain cache internals * Adding tests * Removing log call * Making field optional --------- Co-authored-by: Anderson Arboleya <anderson@arboleya.me>
1 parent 987aed3 commit 6b7b6de

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
lines changed

.changeset/silent-otters-accept.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@fuel-ts/account": patch
3+
---
4+
5+
feat: ensure that we fetch node info per estimation

packages/account/src/providers/operations.graphql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,16 @@ query isUserAccount(
786786
}
787787
}
788788

789+
query getConsensusParametersVersion {
790+
chain {
791+
latestBlock {
792+
header {
793+
consensusParametersVersion
794+
}
795+
}
796+
}
797+
}
798+
789799
subscription submitAndAwait($encodedTransaction: HexString!) {
790800
submitAndAwait(tx: $encodedTransaction) {
791801
...transactionStatusSubscriptionFragment

packages/account/src/providers/provider.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2190,4 +2190,31 @@ Supported fuel-core version: ${mock.supportedVersion}.`
21902190
expect([baseAssetId, ASSET_A, ASSET_B].includes(balance.assetId)).toBeTruthy();
21912191
});
21922192
});
2193+
2194+
test('should not refetch consensus params in less than 1min', async () => {
2195+
using launched = await setupTestProviderAndWallets();
2196+
2197+
const provider = await Provider.create(launched.provider.url);
2198+
const fetchChainAndNodeInfo = vi.spyOn(provider, 'fetchChainAndNodeInfo');
2199+
2200+
// calling twice
2201+
await provider.autoRefetchConfigs();
2202+
await provider.autoRefetchConfigs();
2203+
2204+
expect(fetchChainAndNodeInfo).toHaveBeenCalledTimes(1);
2205+
});
2206+
2207+
test('should refetch consensus params if >1 min has passed', async () => {
2208+
using launched = await setupTestProviderAndWallets();
2209+
2210+
const provider = await Provider.create(launched.provider.url);
2211+
const fetchChainAndNodeInfo = vi.spyOn(provider, 'fetchChainAndNodeInfo');
2212+
2213+
// calling twice
2214+
await provider.autoRefetchConfigs();
2215+
provider.consensusParametersTimestamp = 0;
2216+
await provider.autoRefetchConfigs();
2217+
2218+
expect(fetchChainAndNodeInfo).toHaveBeenCalledTimes(2);
2219+
});
21932220
});

packages/account/src/providers/provider.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@ export default class Provider {
419419
/** @hidden */
420420
private static nodeInfoCache: NodeInfoCache = {};
421421

422+
/** @hidden */
423+
public consensusParametersTimestamp?: number;
424+
422425
options: ProviderOptions = {
423426
timeout: undefined,
424427
resourceCacheTTL: undefined,
@@ -601,17 +604,20 @@ export default class Provider {
601604

602605
/**
603606
* Return the chain and node information.
604-
*
607+
* @param ignoreCache - If true, ignores the cache and re-fetch configs.
605608
* @returns A promise that resolves to the Chain and NodeInfo.
606609
*/
607-
async fetchChainAndNodeInfo() {
610+
async fetchChainAndNodeInfo(ignoreCache: boolean = false) {
608611
let nodeInfo: NodeInfo;
609612
let chain: ChainInfo;
610613

611614
try {
615+
if (ignoreCache) {
616+
throw new Error(`Jumps to the catch block andre-fetch`);
617+
}
612618
nodeInfo = this.getNode();
613619
chain = this.getChain();
614-
} catch (error) {
620+
} catch (_err) {
615621
const data = await this.operations.getChainAndNodeInfo();
616622

617623
nodeInfo = {
@@ -623,9 +629,13 @@ export default class Provider {
623629
};
624630

625631
Provider.ensureClientVersionIsSupported(nodeInfo);
632+
626633
chain = processGqlChain(data.chain);
634+
627635
Provider.chainInfoCache[this.urlWithoutAuth] = chain;
628636
Provider.nodeInfoCache[this.urlWithoutAuth] = nodeInfo;
637+
638+
this.consensusParametersTimestamp = Date.now();
629639
}
630640

631641
return {
@@ -1149,6 +1159,34 @@ Supported fuel-core version: ${supportedVersion}.`
11491159
return results;
11501160
}
11511161

1162+
public async autoRefetchConfigs() {
1163+
const now = Date.now();
1164+
const diff = now - (this.consensusParametersTimestamp ?? 0);
1165+
1166+
if (diff < 60000) {
1167+
return;
1168+
}
1169+
1170+
const chainInfo = this.getChain();
1171+
1172+
const {
1173+
consensusParameters: { version: previous },
1174+
} = chainInfo;
1175+
1176+
const {
1177+
chain: {
1178+
latestBlock: {
1179+
header: { consensusParametersVersion: current },
1180+
},
1181+
},
1182+
} = await this.operations.getConsensusParametersVersion();
1183+
1184+
if (previous !== current) {
1185+
// calling with true to skip cache
1186+
await this.fetchChainAndNodeInfo(true);
1187+
}
1188+
}
1189+
11521190
/**
11531191
* Estimates the transaction gas and fee based on the provided transaction request.
11541192
* @param transactionRequest - The transaction request object.
@@ -1158,6 +1196,8 @@ Supported fuel-core version: ${supportedVersion}.`
11581196
const { transactionRequest } = params;
11591197
let { gasPrice } = params;
11601198

1199+
await this.autoRefetchConfigs();
1200+
11611201
const chainInfo = this.getChain();
11621202
const { gasPriceFactor, maxGasPerTx } = this.getGasConfig();
11631203

0 commit comments

Comments
 (0)