Skip to content

Commit

Permalink
feat: ensure that we fetch node info per estimation (#3324)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
maschad and arboleya authored Oct 14, 2024
1 parent 987aed3 commit 6b7b6de
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/silent-otters-accept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/account": patch
---

feat: ensure that we fetch node info per estimation
10 changes: 10 additions & 0 deletions packages/account/src/providers/operations.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,16 @@ query isUserAccount(
}
}

query getConsensusParametersVersion {
chain {
latestBlock {
header {
consensusParametersVersion
}
}
}
}

subscription submitAndAwait($encodedTransaction: HexString!) {
submitAndAwait(tx: $encodedTransaction) {
...transactionStatusSubscriptionFragment
Expand Down
27 changes: 27 additions & 0 deletions packages/account/src/providers/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2190,4 +2190,31 @@ Supported fuel-core version: ${mock.supportedVersion}.`
expect([baseAssetId, ASSET_A, ASSET_B].includes(balance.assetId)).toBeTruthy();
});
});

test('should not refetch consensus params in less than 1min', async () => {
using launched = await setupTestProviderAndWallets();

const provider = await Provider.create(launched.provider.url);
const fetchChainAndNodeInfo = vi.spyOn(provider, 'fetchChainAndNodeInfo');

// calling twice
await provider.autoRefetchConfigs();
await provider.autoRefetchConfigs();

expect(fetchChainAndNodeInfo).toHaveBeenCalledTimes(1);
});

test('should refetch consensus params if >1 min has passed', async () => {
using launched = await setupTestProviderAndWallets();

const provider = await Provider.create(launched.provider.url);
const fetchChainAndNodeInfo = vi.spyOn(provider, 'fetchChainAndNodeInfo');

// calling twice
await provider.autoRefetchConfigs();
provider.consensusParametersTimestamp = 0;
await provider.autoRefetchConfigs();

expect(fetchChainAndNodeInfo).toHaveBeenCalledTimes(2);
});
});
46 changes: 43 additions & 3 deletions packages/account/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,9 @@ export default class Provider {
/** @hidden */
private static nodeInfoCache: NodeInfoCache = {};

/** @hidden */
public consensusParametersTimestamp?: number;

options: ProviderOptions = {
timeout: undefined,
resourceCacheTTL: undefined,
Expand Down Expand Up @@ -601,17 +604,20 @@ export default class Provider {

/**
* Return the chain and node information.
*
* @param ignoreCache - If true, ignores the cache and re-fetch configs.
* @returns A promise that resolves to the Chain and NodeInfo.
*/
async fetchChainAndNodeInfo() {
async fetchChainAndNodeInfo(ignoreCache: boolean = false) {
let nodeInfo: NodeInfo;
let chain: ChainInfo;

try {
if (ignoreCache) {
throw new Error(`Jumps to the catch block andre-fetch`);
}
nodeInfo = this.getNode();
chain = this.getChain();
} catch (error) {
} catch (_err) {
const data = await this.operations.getChainAndNodeInfo();

nodeInfo = {
Expand All @@ -623,9 +629,13 @@ export default class Provider {
};

Provider.ensureClientVersionIsSupported(nodeInfo);

chain = processGqlChain(data.chain);

Provider.chainInfoCache[this.urlWithoutAuth] = chain;
Provider.nodeInfoCache[this.urlWithoutAuth] = nodeInfo;

this.consensusParametersTimestamp = Date.now();
}

return {
Expand Down Expand Up @@ -1149,6 +1159,34 @@ Supported fuel-core version: ${supportedVersion}.`
return results;
}

public async autoRefetchConfigs() {
const now = Date.now();
const diff = now - (this.consensusParametersTimestamp ?? 0);

if (diff < 60000) {
return;
}

const chainInfo = this.getChain();

const {
consensusParameters: { version: previous },
} = chainInfo;

const {
chain: {
latestBlock: {
header: { consensusParametersVersion: current },
},
},
} = await this.operations.getConsensusParametersVersion();

if (previous !== current) {
// calling with true to skip cache
await this.fetchChainAndNodeInfo(true);
}
}

/**
* Estimates the transaction gas and fee based on the provided transaction request.
* @param transactionRequest - The transaction request object.
Expand All @@ -1158,6 +1196,8 @@ Supported fuel-core version: ${supportedVersion}.`
const { transactionRequest } = params;
let { gasPrice } = params;

await this.autoRefetchConfigs();

const chainInfo = this.getChain();
const { gasPriceFactor, maxGasPerTx } = this.getGasConfig();

Expand Down

0 comments on commit 6b7b6de

Please sign in to comment.