diff --git a/packages/request-client.js/src/http-config-defaults.ts b/packages/request-client.js/src/http-config-defaults.ts index d60d9e5a5a..78edc29925 100644 --- a/packages/request-client.js/src/http-config-defaults.ts +++ b/packages/request-client.js/src/http-config-defaults.ts @@ -6,8 +6,8 @@ const config: ClientTypes.IHttpDataAccessConfig = { httpRequestRetryDelay: 100, httpRequestExponentialBackoffDelay: 0, httpRequestMaxExponentialBackoffDelay: 30000, - getConfirmationMaxRetry: 500, - getConfirmationRetryDelay: 3000, + getConfirmationMaxRetry: 30, + getConfirmationRetryDelay: 1000, getConfirmationExponentialBackoffDelay: 0, getConfirmationMaxExponentialBackoffDelay: 30000, getConfirmationDeferDelay: 3000, diff --git a/packages/request-client.js/src/http-data-access.ts b/packages/request-client.js/src/http-data-access.ts index 1f512fb2c0..429c73b457 100644 --- a/packages/request-client.js/src/http-data-access.ts +++ b/packages/request-client.js/src/http-data-access.ts @@ -130,7 +130,13 @@ export default class HttpDataAccess implements DataAccessTypes.IDataAccess { let error: Error = e; if (e.response.status === 404) { error = new Error( - `Transaction confirmation not receive after ${this.httpConfig.getConfirmationMaxRetry} retries`, + `Transaction confirmation not received. Try polling + getTransactionsByChannelId() until the transaction is confirmed. + deferDelay: ${this.httpConfig.getConfirmationDeferDelay}ms, + maxRetries: ${this.httpConfig.getConfirmationMaxRetry}, + retryDelay: ${this.httpConfig.getConfirmationRetryDelay}ms, + exponentialBackoffDelay: ${this.httpConfig.getConfirmationExponentialBackoffDelay}ms, + maxExponentialBackoffDelay: ${this.httpConfig.getConfirmationMaxExponentialBackoffDelay}ms`, ); } result.emit('error', error); diff --git a/packages/request-client.js/test/http-data-access.test.ts b/packages/request-client.js/test/http-data-access.test.ts index 673b0c3a11..f29929f9bd 100644 --- a/packages/request-client.js/test/http-data-access.test.ts +++ b/packages/request-client.js/test/http-data-access.test.ts @@ -25,7 +25,13 @@ describe('HttpDataAccess', () => { }); void httpDataAccess.persistTransaction({}, '', []).then((returnPersistTransaction) => { returnPersistTransaction.on('error', (e: any) => { - expect(e.message).toBe('Transaction confirmation not receive after 0 retries'); + expect(e.message).toBe(`Transaction confirmation not received. Try polling + getTransactionsByChannelId() until the transaction is confirmed. + deferDelay: 0ms, + maxRetries: 0, + retryDelay: 1000ms, + exponentialBackoffDelay: 0ms, + maxExponentialBackoffDelay: 30000ms`); done(); }); }); diff --git a/packages/request-node/src/request/confirmedTransactionStore.ts b/packages/request-node/src/request/confirmedTransactionStore.ts index 67a4ac64f9..c7beaa196c 100644 --- a/packages/request-node/src/request/confirmedTransactionStore.ts +++ b/packages/request-node/src/request/confirmedTransactionStore.ts @@ -7,13 +7,13 @@ import Keyv, { Store } from 'keyv'; * The client can call the getConfirmed entry point, to get the confirmed event. */ export default class ConfirmedTransactionStore { - private store: Keyv; + private store: Keyv; /** * Confirmed transactions store constructor */ - constructor(store?: Store) { - this.store = new Keyv({ + constructor(store?: Store) { + this.store = new Keyv({ namespace: 'ConfirmedTransactions', store, }); @@ -21,7 +21,7 @@ export default class ConfirmedTransactionStore { public async getConfirmedTransaction( transactionHash: string, - ): Promise { + ): Promise { return this.store.get(transactionHash); } @@ -37,4 +37,14 @@ export default class ConfirmedTransactionStore { ): Promise { await this.store.set(transactionHash, result); } + + /** + * Stores the error + * + * @param transactionHash hash of the transaction + * @param error error of the event "error" + */ + public async addFailedTransaction(transactionHash: string, error: Error): Promise { + await this.store.set(transactionHash, error); + } } diff --git a/packages/request-node/src/request/persistTransaction.ts b/packages/request-node/src/request/persistTransaction.ts index 3cb2b63d27..c9433efbfd 100644 --- a/packages/request-node/src/request/persistTransaction.ts +++ b/packages/request-node/src/request/persistTransaction.ts @@ -84,19 +84,17 @@ export default class PersistTransactionHandler { }); // when the transaction fails, log an error - dataAccessResponse.on('error', async (e) => { - const logData = [ - 'transactionHash', + dataAccessResponse.on('error', async (e: unknown) => { + await this.confirmedTransactionStore.addFailedTransaction( transactionHash.value, - 'channelId', - clientRequest.body.channelId, - 'topics', - clientRequest.body.topics, - 'transactionData', - JSON.stringify(clientRequest.body.transactionData), - ].join('\n'); - - this.logger.error(`persistTransaction error: ${e}. \n${logData}`); + e as Error, + ); + this.logger.error(`persistTransaction error: ${e}\n + transactionHash: ${transactionHash.value}, channelId: ${ + clientRequest.body.channelId + }, topics: ${clientRequest.body.topics}, transactionData: ${JSON.stringify( + clientRequest.body.transactionData, + )}`); }); // Log the request time diff --git a/packages/thegraph-data-access/src/data-access.ts b/packages/thegraph-data-access/src/data-access.ts index 2808e080f3..70f964013c 100644 --- a/packages/thegraph-data-access/src/data-access.ts +++ b/packages/thegraph-data-access/src/data-access.ts @@ -44,7 +44,10 @@ export class TheGraphDataAccess extends CombinedDataAccess { result.on('confirmed', (receipt) => { this.fetchConfirmedTransaction(channelId, receipt) .then((confirmedReceipt) => eventEmitter.emit('confirmed', confirmedReceipt)) - .catch(() => this.logger.warn(`Could not confirm channel ${channelId}`)); + .catch(() => { + this.logger.error(`Could not confirm channel ${channelId} after 30s`); + eventEmitter.emit('error', new Error(`Could not confirm channel ${channelId} after 30s`)); + }); }); result.on('error', (e) => eventEmitter.emit('error', e)); return Object.assign(eventEmitter, { meta: result.meta, result: result.result });