@lido-nestjs/execution 1.15.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,4 +15,5 @@ export interface SimpleFallbackProviderConfig {
15
15
  fetchMiddlewares?: MiddlewareCallback<Promise<any>>[];
16
16
  maxTimeWithoutNewBlocksMs?: number;
17
17
  requestTimeoutMs?: number;
18
+ instanceLabel?: string;
18
19
  }
@@ -46,6 +46,7 @@ export declare class SimpleFallbackJsonRpcBatchProvider extends BaseProvider {
46
46
  constructor(config: SimpleFallbackProviderConfig, logger: LoggerService);
47
47
  static _formatter: Formatter | null;
48
48
  static getFormatter(): Formatter;
49
+ protected formatLog(message: string, providerIndex?: number): string;
49
50
  on(eventName: EventType, listener: Listener): this;
50
51
  getFeeHistory(blockCount: number, newestBlock?: string | null | number, rewardPercentiles?: number[]): Promise<FeeHistory>;
51
52
  getDebugTraceBlockByHash(blockHash: string, traceConfig: Partial<TraceConfig>): Promise<TraceResult[]>;
@@ -19,6 +19,7 @@ var events = require('events');
19
19
 
20
20
  exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchProvider extends providers.BaseProvider {
21
21
  constructor(config, logger) {
22
+ var _a;
22
23
  super(config.network);
23
24
  this.detectNetworkFirstRun = true;
24
25
  this.resetTimer = null;
@@ -55,6 +56,22 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
55
56
  };
56
57
  });
57
58
  this.activeFallbackProviderIndex = 0;
59
+ // Log initialization info
60
+ const configInfo = {
61
+ providers: conns.length,
62
+ network: this.config.network,
63
+ requestPolicy: this.config.requestPolicy,
64
+ maxRetries: this.config.maxRetries,
65
+ minBackoffMs: this.config.minBackoffMs,
66
+ maxBackoffMs: this.config.maxBackoffMs,
67
+ logRetries: this.config.logRetries,
68
+ resetIntervalMs: this.config.resetIntervalMs,
69
+ fetchMiddlewares: ((_a = this.config.fetchMiddlewares) === null || _a === void 0 ? void 0 : _a.length) || 0,
70
+ maxTimeWithoutNewBlocksMs: this.config.maxTimeWithoutNewBlocksMs,
71
+ requestTimeoutMs: this.config.requestTimeoutMs || 'disabled',
72
+ instanceLabel: this.config.instanceLabel || 'none',
73
+ };
74
+ this.logger.log(this.formatLog(`Initialized SimpleFallbackJsonRpcBatchProvider: ${JSON.stringify(configInfo)}`));
58
75
  }
59
76
  static getFormatter() {
60
77
  if (this._formatter == null) {
@@ -62,6 +79,19 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
62
79
  }
63
80
  return this._formatter;
64
81
  }
82
+ formatLog(message, providerIndex) {
83
+ const parts = [];
84
+ if (this.config.instanceLabel) {
85
+ parts.push(`[${this.config.instanceLabel}]`);
86
+ }
87
+ if (providerIndex !== undefined) {
88
+ parts.push(`[provider:${providerIndex}]`);
89
+ }
90
+ if (parts.length > 0) {
91
+ return `${parts.join('')} ${message}`;
92
+ }
93
+ return message;
94
+ }
65
95
  on(eventName, listener) {
66
96
  let dieTimer = null;
67
97
  const startDieTimer = (latestObservedBlockNumber) => {
@@ -110,11 +140,13 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
110
140
  }
111
141
  switchToNextProvider() {
112
142
  if (this.fallbackProviders.length === 1) {
113
- this.logger.warn('Will not switch to next provider. No valid backup provider provided.');
143
+ this.logger.warn(this.formatLog('Will not switch to next provider. No valid backup provider provided.'));
114
144
  return;
115
145
  }
116
- this.activeFallbackProviderIndex++;
117
- this.logger.log(`Switched to next provider for execution layer`);
146
+ const oldIndex = this.activeFallbackProviderIndex;
147
+ this.activeFallbackProviderIndex =
148
+ (this.activeFallbackProviderIndex + 1) % this.fallbackProviders.length;
149
+ this.logger.log(this.formatLog(`Switched provider: [${oldIndex}] -> [${this.activeFallbackProviderIndex}] (total: ${this.fallbackProviders.length})`));
118
150
  }
119
151
  isNonRetryableError(error) {
120
152
  return (!errors.isEthersServerError(error) &&
@@ -141,9 +173,11 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
141
173
  try {
142
174
  let performRetryAttempt = 0;
143
175
  attempt++;
176
+ // Log which provider we're attempting to use
177
+ this.logger.log(this.formatLog(`Attempting request (attempt ${attempt}/${this.fallbackProviders.length})`, this.activeFallbackProviderIndex));
144
178
  // awaiting is extremely important here
145
179
  // without it, the error will not be caught in current try-catch scope
146
- return await retry(() => {
180
+ const result = await retry(() => {
147
181
  const provider = this.provider;
148
182
  const event = {
149
183
  action: 'fallback-provider:request',
@@ -162,6 +196,9 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
162
196
  }
163
197
  return performPromise;
164
198
  });
199
+ // Log successful request
200
+ this.logger.log(this.formatLog(`Request successful after ${performRetryAttempt} retry attempt(s)`, this.activeFallbackProviderIndex));
201
+ return result;
165
202
  }
166
203
  catch (e) {
167
204
  this.lastError = e;
@@ -173,10 +210,22 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
173
210
  error: e,
174
211
  };
175
212
  this._eventEmitter.emit('rpc', event);
213
+ // Log context (label + provider index) synchronously before error object
214
+ // to ensure proper ordering in async logging systems
215
+ this.logger.error(this.formatLog(`Non-retryable error occurred`, this.activeFallbackProviderIndex));
216
+ this.logger.error(e);
176
217
  throw e;
177
218
  }
178
- this.logger.error('Error while doing ETH1 RPC request. Will try to switch to another provider');
179
- this.logger.error(e);
219
+ // Log context (label + provider index) synchronously before error object
220
+ // to ensure proper ordering in async logging systems
221
+ if (e instanceof requestTimeout_error.RequestTimeoutError) {
222
+ this.logger.error(this.formatLog(`Request timeout after ${e.timeoutMs}ms. Will switch to next provider.`, this.activeFallbackProviderIndex));
223
+ this.logger.error(e);
224
+ }
225
+ else {
226
+ this.logger.error(this.formatLog(`Error occurred. Will switch to next provider.`, this.activeFallbackProviderIndex));
227
+ this.logger.error(e);
228
+ }
180
229
  // This check is needed to avoid multiple `switchToNextProvider` calls when doing one JSON-RPC batch.
181
230
  // This can happen when multiple N calls to `perform` are batched in one JSON-RPC request and
182
231
  // that request fails and throws `Error`. This `Error` is bubbled N times to corresponding `perform` calls.
@@ -234,7 +283,7 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
234
283
  if (this.detectNetworkFirstRun) {
235
284
  throw new Error(`Fallback provider [${index}] network is different to other provider's networks`);
236
285
  }
237
- this.logger.warn(`Fallback provider [${index}] network is different to other provider's networks`);
286
+ this.logger.warn(this.formatLog(`Fallback provider [${index}] network is different to other provider's networks`));
238
287
  }
239
288
  }
240
289
  else {
@@ -261,7 +310,7 @@ exports.SimpleFallbackJsonRpcBatchProvider = class SimpleFallbackJsonRpcBatchPro
261
310
  if (this.resetTimer) {
262
311
  clearTimeout(this.resetTimer);
263
312
  }
264
- this.fallbackProviders.forEach((fallbackProvider, index) => {
313
+ this.fallbackProviders.forEach((_, index) => {
265
314
  var _a;
266
315
  if (!((_a = this.fallbackProviders[index].network) === null || _a === void 0 ? void 0 : _a.chainId)) {
267
316
  this.fallbackProviders[index].unreachable = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lido-nestjs/execution",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "MIT",