diff --git a/src/dex/bebop/constants.ts b/src/dex/bebop/constants.ts index b446d8c7c..847c67dba 100644 --- a/src/dex/bebop/constants.ts +++ b/src/dex/bebop/constants.ts @@ -6,7 +6,7 @@ export const BEBOP_API_URL = 'https://api.bebop.xyz'; export const BEBOP_WS_API_URL = 'wss://api.bebop.xyz'; export const BEBOP_GAS_COST = 120_000; export const BEBOP_AUTH_NAME = 'paraswap'; -export const BEBOP_QUOTE_TIMEOUT_MS = 2000; +export const BEBOP_QUOTE_TIMEOUT_MS = 3000; export const BEBOP_ERRORS_CACHE_KEY = 'errors'; export const BEBOP_RESTRICTED_CACHE_KEY = 'restricted'; // Restrict for BEBOP_RESTRICT_TTL_S if an error occured >= BEBOP_RESTRICT_COUNT_THRESHOLD times within BEBOP_RESTRICT_CHECK_INTERVAL_S interval diff --git a/src/dex/pancakeswap-v3/pancakeswap-v3-pool.ts b/src/dex/pancakeswap-v3/pancakeswap-v3-pool.ts index fc2fdb9f1..c80c08d54 100644 --- a/src/dex/pancakeswap-v3/pancakeswap-v3-pool.ts +++ b/src/dex/pancakeswap-v3/pancakeswap-v3-pool.ts @@ -250,6 +250,36 @@ export class PancakeSwapV3EventPool extends StatefulEventSubscriber { return TICK_BITMAP_TO_USE + TICK_BITMAP_BUFFER; } + async getOrGenerateState( + blockNumber: number, + ): Promise | null> { + const state = this.getState(blockNumber); + if (state) { + return state; + } + + this.logger.error( + `PancakeV3: No state found for ${this.name} ${this.addressesSubscribed[0]}, generating new one`, + ); + try { + const newState = await this.generateState(blockNumber); + + if (!newState) { + this.logger.error( + `PancakeV3: Could not generate state for ${this.name} ${this.addressesSubscribed[0]}`, + ); + return null; + } + this.setState(newState, blockNumber); + return newState; + } catch (error) { + this.logger.error( + `PancakeV3: Failed to generate state for ${this.name} ${this.addressesSubscribed[0]}`, + ); + return null; + } + } + async generateState(blockNumber: number): Promise> { const callData = this._getStateRequestCallData(); diff --git a/src/dex/pancakeswap-v3/pancakeswap-v3.ts b/src/dex/pancakeswap-v3/pancakeswap-v3.ts index fc267ad0f..17248a00a 100644 --- a/src/dex/pancakeswap-v3/pancakeswap-v3.ts +++ b/src/dex/pancakeswap-v3/pancakeswap-v3.ts @@ -613,6 +613,10 @@ export class PancakeswapV3 if (selectedPools.length === 0) return null; + await Promise.all( + selectedPools.map(pool => pool.getOrGenerateState(blockNumber)), + ); + const poolsToUse = selectedPools.reduce( (acc, pool) => { let state = pool.getState(blockNumber); @@ -632,6 +636,12 @@ export class PancakeswapV3 }, ); + poolsToUse.poolWithoutState.forEach(pool => { + this.logger.warn( + `PancakeV3: Pool ${pool.name} on ${this.dexKey} has no state. Fallback to rpc`, + ); + }); + const rpcResultsPromise = this.getPricingFromRpc( _srcToken, _destToken, diff --git a/src/dex/uniswap-v3/uniswap-v3-pool.ts b/src/dex/uniswap-v3/uniswap-v3-pool.ts index 2110470b2..b3b9d2143 100644 --- a/src/dex/uniswap-v3/uniswap-v3-pool.ts +++ b/src/dex/uniswap-v3/uniswap-v3-pool.ts @@ -254,6 +254,36 @@ export class UniswapV3EventPool extends StatefulEventSubscriber { return TICK_BITMAP_TO_USE + TICK_BITMAP_BUFFER; } + async getOrGenerateState( + blockNumber: number, + ): Promise | null> { + const state = this.getState(blockNumber); + if (state) { + return state; + } + + this.logger.error( + `UniV3: No state found for ${this.name} ${this.addressesSubscribed[0]}, generating new one`, + ); + try { + const newState = await this.generateState(blockNumber); + + if (!newState) { + this.logger.error( + `UniV3: Could not generate state for ${this.name} ${this.addressesSubscribed[0]}`, + ); + return null; + } + this.setState(newState, blockNumber); + return newState; + } catch (error) { + this.logger.error( + `UniV3: Failed to generate state for ${this.name} ${this.addressesSubscribed[0]}`, + ); + return null; + } + } + async generateState(blockNumber: number): Promise> { const callData = this._getStateRequestCallData(); diff --git a/src/dex/uniswap-v3/uniswap-v3.ts b/src/dex/uniswap-v3/uniswap-v3.ts index 40defeeae..e9e05771c 100644 --- a/src/dex/uniswap-v3/uniswap-v3.ts +++ b/src/dex/uniswap-v3/uniswap-v3.ts @@ -715,6 +715,10 @@ export class UniswapV3 if (selectedPools.length === 0) return null; + await Promise.all( + selectedPools.map(pool => pool.getOrGenerateState(blockNumber)), + ); + const poolsToUse = selectedPools.reduce( (acc, pool) => { let state = pool.getState(blockNumber); @@ -722,6 +726,7 @@ export class UniswapV3 this.logger.trace( `${this.dexKey}: State === null. Fallback to rpc ${pool.name}`, ); + // as we generate state (if nullified) in previous Promise.all, here should only be pools with failed initialization acc.poolWithoutState.push(pool); } else { acc.poolWithState.push(pool); @@ -734,6 +739,12 @@ export class UniswapV3 }, ); + poolsToUse.poolWithoutState.forEach(pool => { + this.logger.warn( + `UniV3: Pool ${pool.name} on ${this.dexKey} has no state. Fallback to rpc`, + ); + }); + const states = poolsToUse.poolWithState.map( p => p.getState(blockNumber)!, );