Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: provider cache #3278

Merged
merged 34 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
05d6bdd
remove latest block from query chain
Torres-ssf Oct 8, 2024
c7bb3ea
release PR
Torres-ssf Oct 8, 2024
65d1927
properly using chain and node cache
Torres-ssf Oct 8, 2024
369e40d
Adding changeset
arboleya Oct 8, 2024
8881b7c
fix callstack error
Torres-ssf Oct 8, 2024
9bbdc5e
Merge branch 'st/chore/remove-latest-block-from-chain-query' of githu…
Torres-ssf Oct 8, 2024
bac2c7b
fix get latest getblock
Torres-ssf Oct 8, 2024
2b67eff
Merge branch 'master' into st/chore/remove-latest-block-from-chain-query
petertonysmith94 Oct 9, 2024
bbe808d
fix changeset
Torres-ssf Oct 9, 2024
19713ae
revert changes related to latest block removal
Torres-ssf Oct 9, 2024
9c00434
unrelease PR
Torres-ssf Oct 9, 2024
622ae16
Merge branch 'st/chore/remove-latest-block-from-chain-query' of githu…
Torres-ssf Oct 9, 2024
8507e23
reverting changes
Torres-ssf Oct 9, 2024
bb983c7
implement Provider instance clearChainAndNodeCaches
Torres-ssf Oct 9, 2024
5fa4d27
made static clearChainAndNodeCaches private
Torres-ssf Oct 9, 2024
3edaf8d
made fetchChainAndNodeInfo to use cached data
Torres-ssf Oct 9, 2024
bdccd19
adjusting provider tests
Torres-ssf Oct 9, 2024
4689652
update transaction upgrade test suite
Torres-ssf Oct 9, 2024
5a58f67
add test case
Torres-ssf Oct 9, 2024
c579e09
fixed changeset
Torres-ssf Oct 9, 2024
ead7761
update test case
Torres-ssf Oct 9, 2024
be7eeba
Merge branch 'master' into st/chore/remove-latest-block-from-chain-query
Torres-ssf Oct 10, 2024
9795430
revert cache approach
Torres-ssf Oct 10, 2024
3fdc284
update tests
Torres-ssf Oct 10, 2024
248fce2
update tests
Torres-ssf Oct 10, 2024
e00f7ce
adjusting tests
Torres-ssf Oct 10, 2024
329ccb2
fix changeset
Torres-ssf Oct 10, 2024
e96b817
adjust test
Torres-ssf Oct 10, 2024
8165cf6
update proxy contract factory
Torres-ssf Oct 10, 2024
0bd37df
adjusting tests again
Torres-ssf Oct 10, 2024
4d89bd1
Merge branch 'master' into st/chore/remove-latest-block-from-chain-query
Torres-ssf Oct 10, 2024
cb8fb8c
rollback change proxy contract
Torres-ssf Oct 10, 2024
df631f6
Merge branch 'st/chore/remove-latest-block-from-chain-query' of githu…
Torres-ssf Oct 10, 2024
26e5f1c
Merge branch 'master' into st/chore/remove-latest-block-from-chain-query
arboleya Oct 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/mighty-impalas-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/account": patch
---

fix: provider cache
61 changes: 32 additions & 29 deletions packages/account/src/providers/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ const createBasicAuth = (launchNodeUrl: string) => {
* @group node
*/
describe('Provider', () => {
afterEach(() => {
vi.restoreAllMocks();
});

it('should ensure supports basic auth', async () => {
using launched = await setupTestProviderAndWallets();
const {
Expand Down Expand Up @@ -143,11 +147,11 @@ describe('Provider', () => {

it('should ensure that custom requestMiddleware is not overwritten by basic auth', async () => {
using launched = await setupTestProviderAndWallets();
const {
provider: { url },
} = launched;
const { provider } = launched;

Provider.clearChainAndNodeCaches();

const { urlWithAuth } = createBasicAuth(url);
const { urlWithAuth } = createBasicAuth(provider.url);

const requestMiddleware = vi.fn().mockImplementation((options) => options);

Expand Down Expand Up @@ -1046,47 +1050,43 @@ describe('Provider', () => {
expect(provider.getNode()).toBeDefined();
});

it('should cache chain and node info', async () => {
Provider.clearChainAndNodeCaches();

it('should ensure getChain and getNode uses the cache and does not fetch new data', async () => {
using launched = await setupTestProviderAndWallets();
const { provider } = launched;

expect(provider.getChain()).toBeDefined();
expect(provider.getNode()).toBeDefined();
});

it('should ensure getChain and getNode uses the cache and does not fetch new data', async () => {
Provider.clearChainAndNodeCaches();
const { error } = await safeExec(() => {
provider.getChain();
provider.getNode();
});

const spyFetchChainAndNodeInfo = vi.spyOn(Provider.prototype, 'fetchChainAndNodeInfo');
const spyFetchChain = vi.spyOn(Provider.prototype, 'fetchChain');
const spyFetchNode = vi.spyOn(Provider.prototype, 'fetchNode');
expect(error).toBeUndefined();
});

it('should ensure creating new instances should not re-fetch chain and node info', async () => {
using launched = await setupTestProviderAndWallets();
const { provider } = launched;

expect(spyFetchChainAndNodeInfo).toHaveBeenCalledTimes(1);
const spyFetchChainAndNodeInfo = vi.spyOn(Provider.prototype, 'fetchChainAndNodeInfo');
const spyGetChainAndNodeInfo = vi.spyOn(provider.operations, 'getChainAndNodeInfo');

provider.getChain();
provider.getNode();
const INSTANCES_NUM = 5;

expect(spyFetchChainAndNodeInfo).toHaveBeenCalledTimes(1);
expect(spyFetchChain).toHaveBeenCalledTimes(0);
expect(spyFetchNode).toHaveBeenCalledTimes(0);
});
const promises = Array.from({ length: INSTANCES_NUM }, async () =>
Provider.create(provider.url)
);
await Promise.all(promises);

it('should ensure fetchChainAndNodeInfo always fetch new data', async () => {
Provider.clearChainAndNodeCaches();
expect(spyFetchChainAndNodeInfo).toHaveBeenCalledTimes(INSTANCES_NUM);

const spyFetchChainAndNodeInfo = vi.spyOn(Provider.prototype, 'fetchChainAndNodeInfo');
expect(spyGetChainAndNodeInfo).not.toHaveBeenCalled();
});

it('should ensure fetchChainAndNodeInfo uses cached data', async () => {
using launched = await setupTestProviderAndWallets();

expect(spyFetchChainAndNodeInfo).toHaveBeenCalledTimes(1);

const { provider } = launched;

Provider.clearChainAndNodeCaches();

const spyOperation = vi.spyOn(provider.operations, 'getChainAndNodeInfo');

await provider.fetchChainAndNodeInfo();
Expand Down Expand Up @@ -1691,6 +1691,7 @@ Supported fuel-core version: ${mock.supportedVersion}.`
test('requestMiddleware modifies the request before being sent to the node [sync]', async () => {
using launched = await setupTestProviderAndWallets();
const { provider } = launched;
Provider.clearChainAndNodeCaches();

const fetchSpy = vi.spyOn(global, 'fetch');
await Provider.create(provider.url, {
Expand All @@ -1711,6 +1712,7 @@ Supported fuel-core version: ${mock.supportedVersion}.`
test('requestMiddleware modifies the request before being sent to the node [async]', async () => {
using launched = await setupTestProviderAndWallets();
const { provider } = launched;
Provider.clearChainAndNodeCaches();

const fetchSpy = vi.spyOn(global, 'fetch');
await Provider.create(provider.url, {
Expand Down Expand Up @@ -1762,6 +1764,7 @@ Supported fuel-core version: ${mock.supportedVersion}.`
test('custom fetch works with requestMiddleware', async () => {
using launched = await setupTestProviderAndWallets();
const { provider } = launched;
Provider.clearChainAndNodeCaches();

let requestHeaders: HeadersInit | undefined;
await Provider.create(provider.url, {
Expand Down
38 changes: 22 additions & 16 deletions packages/account/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -604,26 +604,32 @@ export default class Provider {
* @returns A promise that resolves to the Chain and NodeInfo.
*/
async fetchChainAndNodeInfo() {
const { nodeInfo, chain } = await this.operations.getChainAndNodeInfo();
let nodeInfo: NodeInfo;
let chain: ChainInfo;

const processedNodeInfo: NodeInfo = {
maxDepth: bn(nodeInfo.maxDepth),
maxTx: bn(nodeInfo.maxTx),
nodeVersion: nodeInfo.nodeVersion,
utxoValidation: nodeInfo.utxoValidation,
vmBacktrace: nodeInfo.vmBacktrace,
};

Provider.ensureClientVersionIsSupported(processedNodeInfo);

const processedChain = processGqlChain(chain);
try {
nodeInfo = this.getNode();
chain = this.getChain();
} catch (error) {
const data = await this.operations.getChainAndNodeInfo();

nodeInfo = {
maxDepth: bn(data.nodeInfo.maxDepth),
maxTx: bn(data.nodeInfo.maxTx),
nodeVersion: data.nodeInfo.nodeVersion,
utxoValidation: data.nodeInfo.utxoValidation,
vmBacktrace: data.nodeInfo.vmBacktrace,
};

Provider.chainInfoCache[this.urlWithoutAuth] = processedChain;
Provider.nodeInfoCache[this.urlWithoutAuth] = processedNodeInfo;
Provider.ensureClientVersionIsSupported(nodeInfo);
chain = processGqlChain(data.chain);
Provider.chainInfoCache[this.urlWithoutAuth] = chain;
Provider.nodeInfoCache[this.urlWithoutAuth] = nodeInfo;
}

return {
chain: processedChain,
nodeInfo: processedNodeInfo,
chain,
nodeInfo,
};
}

Expand Down
17 changes: 12 additions & 5 deletions packages/fuel-gauge/src/transaction-upgrade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
UpgradeTransactionRequest,
Wallet,
UploadTransactionRequest,
sleep,
Provider,
} from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

Expand Down Expand Up @@ -40,12 +42,12 @@ const setupTestNode = async () => {

const { provider, wallets, cleanup } = await launchTestNode({
nodeOptions: {
args: ['--poa-instant', 'false', '--poa-interval-period', '1ms'],
args: ['--poa-instant', 'false', '--poa-interval-period', '1s'],
loggingEnabled: false,
snapshotConfig,
},
});
privileged.provider = provider;
privileged.provider = await Provider.create(provider.url);

return { provider, privileged, wallets, cleanup, [Symbol.dispose]: cleanup };
};
Expand Down Expand Up @@ -99,9 +101,11 @@ describe('Transaction upgrade consensus', () => {
using launched = await setupTestNode();
const { privileged, provider } = launched;

const mainProvider = await Provider.create(provider.url);

const {
chain: { consensusParameters: consensusBeforeUpgrade },
} = await provider.fetchChainAndNodeInfo();
} = await mainProvider.fetchChainAndNodeInfo();

// Update the gas costs to free
const { isStatusSuccess, isTypeUpgrade } = await upgradeConsensusParameters(
Expand All @@ -111,11 +115,14 @@ describe('Transaction upgrade consensus', () => {
expect(isStatusSuccess).toBeTruthy();
expect(isTypeUpgrade).toBeTruthy();

// Waiting for the next block to ensure upgraded value are reflected
await sleep(1000);
Provider.clearChainAndNodeCaches();

// Fetch the upgraded gas costs, they should be different from before
const {
chain: { consensusParameters: consensusAfterUpgrade },
} = await provider.fetchChainAndNodeInfo();

} = await mainProvider.fetchChainAndNodeInfo();
expect(consensusBeforeUpgrade.gasCosts).not.toEqual(consensusAfterUpgrade.gasCosts);
});
});
Expand Down