Skip to content

Commit e398422

Browse files
committed
feat: use event older blockhash with fallback providers and use testing http call as actual usable test
1 parent 875f686 commit e398422

File tree

2 files changed

+54
-33
lines changed

2 files changed

+54
-33
lines changed

packages/core/src/lib/lit-core.spec.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,21 @@ describe('LitCore', () => {
9898
timestamp: currentTime,
9999
}),
100100
};
101+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
101102
jest.spyOn(core as any, '_getProviderWithFallback').mockResolvedValue({
102-
...mockProvider,
103+
provider: mockProvider,
104+
testResult: {
105+
hash: mockBlockhash,
106+
number: 12345,
107+
timestamp: currentTime,
108+
},
103109
});
104110

105111
// Execute
106112
const result = await core.getLatestBlockhash();
107113

108114
// Assert
109115
expect(fetch).toHaveBeenCalledWith(mockBlockhashUrl);
110-
expect(mockProvider.getBlock).toHaveBeenCalledWith(-1); // safety margin
111116
expect(result).toBe(mockBlockhash);
112117
});
113118

@@ -132,16 +137,21 @@ describe('LitCore', () => {
132137
timestamp: currentTime,
133138
}),
134139
};
140+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
135141
jest.spyOn(core as any, '_getProviderWithFallback').mockResolvedValue({
136-
...mockProvider,
142+
provider: mockProvider,
143+
testResult: {
144+
hash: mockBlockhash,
145+
number: 12345,
146+
timestamp: currentTime,
147+
},
137148
});
138149

139150
// Execute
140151
const result = await core.getLatestBlockhash();
141152

142153
// Assert
143154
expect(fetch).toHaveBeenCalledWith(mockBlockhashUrl);
144-
expect(mockProvider.getBlock).toHaveBeenCalledWith(-1); // safety margin
145155
expect(result).toBe(mockBlockhash);
146156
});
147157

@@ -164,8 +174,10 @@ describe('LitCore', () => {
164174
getBlock: jest.fn().mockResolvedValue(null), // Provider also fails
165175
};
166176

177+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
167178
jest.spyOn(core as any, '_getProviderWithFallback').mockResolvedValue({
168-
...mockProvider,
179+
provider: mockProvider,
180+
testResult: null,
169181
});
170182

171183
// Execute & Assert

packages/core/src/lib/lit-core.ts

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import {
2121
LIT_CURVE,
2222
LIT_CURVE_VALUES,
2323
LIT_ENDPOINT,
24-
LIT_ERROR,
2524
LIT_ERROR_CODE,
2625
LIT_NETWORK,
2726
LIT_NETWORKS,
@@ -69,7 +68,6 @@ import {
6968
NodeClientErrorV0,
7069
NodeClientErrorV1,
7170
NodeCommandServerKeysResponse,
72-
NodeErrorV3,
7371
RejectedNodePromises,
7472
SendNodeCommand,
7573
SessionSigsMap,
@@ -82,6 +80,10 @@ import { composeLitUrl } from './endpoint-version';
8280
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8381
type Listener = (...args: any[]) => void;
8482

83+
type providerTest<T> = (
84+
provider: ethers.providers.JsonRpcProvider
85+
) => Promise<T>;
86+
8587
interface CoreNodeConfig {
8688
subnetPubKey: string;
8789
networkPubKey: string;
@@ -119,8 +121,8 @@ export type LitNodeClientConfigWithDefaults = Required<
119121
const EPOCH_PROPAGATION_DELAY = 45_000;
120122
// This interval is responsible for keeping latest block hash up to date
121123
const BLOCKHASH_SYNC_INTERVAL = 30_000;
122-
// When fetching the blockhash from a provider (not lit), we use a previous block to avoid a nodes not knowing about the new block yet
123-
const BLOCKHASH_COUNT_PROVIDER_DELAY = -1;
124+
// When fetching the blockhash from a provider (not lit), we use a 5 minutes old block to ensure the nodes centralized indexer has it
125+
const BLOCKHASH_COUNT_PROVIDER_DELAY = -30; // 30 blocks ago. Eth block are mined every 12s. 30 blocks is 6 minutes, indexer/nodes must have it by now
124126

125127
// Intentionally not including datil-dev here per discussion with Howard
126128
const NETWORKS_REQUIRING_SEV: string[] = [
@@ -766,24 +768,31 @@ export class LitCore {
766768
};
767769
}
768770

769-
private _getProviderWithFallback =
770-
async (): Promise<ethers.providers.JsonRpcProvider | null> => {
771-
for (const url of FALLBACK_RPC_URLS) {
772-
try {
773-
const provider = new ethers.providers.JsonRpcProvider({
774-
url: url,
771+
private _getProviderWithFallback = async <T>(
772+
providerTest: providerTest<T>
773+
): Promise<{
774+
provider: ethers.providers.JsonRpcProvider;
775+
testResult: T;
776+
} | null> => {
777+
for (const url of FALLBACK_RPC_URLS) {
778+
try {
779+
const provider = new ethers.providers.JsonRpcProvider({
780+
url: url,
775781

776-
// https://docs.ethers.org/v5/api/utils/web/#ConnectionInfo
777-
timeout: 60000,
778-
});
779-
await provider.getBlockNumber(); // Simple check to see if the provider is working
780-
return provider;
781-
} catch (error) {
782-
logError(`RPC URL failed: ${url}`);
783-
}
782+
// https://docs.ethers.org/v5/api/utils/web/#ConnectionInfo
783+
timeout: 60000,
784+
});
785+
const testResult = await providerTest(provider); // Check to see if the provider is working
786+
return {
787+
provider,
788+
testResult,
789+
};
790+
} catch (error) {
791+
logError(`RPC URL failed: ${url}`);
784792
}
785-
return null;
786-
};
793+
}
794+
return null;
795+
};
787796

788797
/**
789798
* Fetches the latest block hash and log any errors that are returned
@@ -854,20 +863,20 @@ export class LitCore {
854863
log(
855864
'Attempting to fetch blockhash manually using ethers with fallback RPC URLs...'
856865
);
857-
const provider = await this._getProviderWithFallback();
866+
const { testResult } =
867+
(await this._getProviderWithFallback<ethers.providers.Block>(
868+
// We use a previous block to avoid nodes not having received the latest block yet
869+
(provider) => provider.getBlock(BLOCKHASH_COUNT_PROVIDER_DELAY)
870+
)) || {};
858871

859-
if (!provider) {
872+
if (!testResult || !testResult.hash) {
860873
logError('All fallback RPC URLs failed. Unable to retrieve blockhash.');
861874
return;
862875
}
863876

864877
try {
865-
// We use a previous block to avoid nodes not having received the latest block yet
866-
const priorBlock = await provider.getBlock(
867-
BLOCKHASH_COUNT_PROVIDER_DELAY
868-
);
869-
this.latestBlockhash = priorBlock.hash;
870-
this.lastBlockHashRetrieved = priorBlock.timestamp;
878+
this.latestBlockhash = testResult.hash;
879+
this.lastBlockHashRetrieved = testResult.timestamp;
871880
log(
872881
'Successfully retrieved blockhash manually: ',
873882
this.latestBlockhash

0 commit comments

Comments
 (0)