You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Router as is right now consumes a lot of rpc resources, and that's not ideal for Rain solver use case, as everytime solver tries to get market quote it needs to fetch all the pools' data for all the available dexes of the operating chain, which equates to tens of calls, and also it will end up spreading the calls into multiple blocks because of the concurrency limits, and some other issues.
The idea here is to make the router to work as an indexer where pools' data can be fetched cheaply and at realtime.
And by works like an indexer it means it will be able to update pool data by using pool's event that are emitted in realtime as blocks get mined and txs get mined for a pool.
Benchmark
This is a sample benchmark of time and rpc request count between an indexer vs non indexer pool data fetching for a single token pair USDC/USDT on Polygon chain and with having only 3 following dexes (UniswapV3, QuickswapV2 (is univ2 type dex), QuickswapV3 (is algebra type dex)) as liquiity providers, times are in milliseconds:
50 blocks apart
2000 blocks apart
Challenges
There are 2 possible approaches for this case:
Extend the router lib to work as an indexer in a separate repo
Make changes to this repo directly
The issue with first approach is that, because of how router lib is designed, that most of the stuff that are needed in order to extend it to work as an indexer are not exposed in API and are deep inside the logic and trying to expose them so they can be potentially extended means a lot of stuff need to change.
I elaborate on this briefly, all that is exposed on API is a simple class object called DataFecther, this class object on instantiation takes a viem client and just a list of Dex names, then it will internally handles everything, each Dex in router lib is a class object with its own Dex literals, and depending on if it is a univ2 or univ3 it is a child of a deeper class object called UniswapV2Base and UniswapV3Base, these 2 are the main logic for fetching/handling pool data.
Once one needs to get a market quote for a token pair, a method on DataFecther is called, that method then expands to each dex internally and each dex internally to the univ2/3 base classes to fetch data and then pass the data back through the path. So I think it is self evident that making router lib extendable cannot be achieved without making fundamental and breaking changes to the API and how things are designed. So this leaves us with 2nd approach.
Proposed Solution - (rain folder)
We'll create a rain folder, as the folder for holding all our changes that are added on to the repo, we'll be adding 2 new classes RainUniswapV2BaseProvider and RainUniswapV3BaseProvider, these 2 will inherit from the original univ2/v3 classes that have all the methods/logic for handling pool data, so we can then override some of their methods as a child class as we need for indexer functionalities, after that we just need to update all dexes to use these 2 new classes as their parent classes to inherit from instead fo the original univ2/3 classes.
Next we need a new class RainDataFetcher in rain folder, which inherits from original DataFetcher, we need to override a coulpe fo tis methods slightly, so now using this new class methods, pools data can be fetched and updated and used for getting market quotes and routes.
This approach ensures that no changes are done to the logic of any original files and no structural changes. and all the maintenance will be done on the rain folder.
Maintainability
Ofc with this approach all the changes are standalone in rain so this would be much more aligned to what has been discussed in tg chat.
Motivation
Router as is right now consumes a lot of rpc resources, and that's not ideal for Rain solver use case, as everytime solver tries to get market quote it needs to fetch all the pools' data for all the available dexes of the operating chain, which equates to tens of calls, and also it will end up spreading the calls into multiple blocks because of the concurrency limits, and some other issues.
The idea here is to make the router to work as an indexer where pools' data can be fetched cheaply and at realtime.
And by
works like an indexer
it means it will be able to update pool data by using pool's event that are emitted in realtime as blocks get mined and txs get mined for a pool.Benchmark
This is a sample benchmark of time and rpc request count between an indexer vs non indexer pool data fetching for a single token pair

USDC/USDT
on Polygon chain and with having only 3 following dexes (UniswapV3
,QuickswapV2 (is univ2 type dex)
,QuickswapV3 (is algebra type dex)
) as liquiity providers, times are in milliseconds:50 blocks apart
2000 blocks apart

Challenges
There are 2 possible approaches for this case:
The issue with first approach is that, because of how router lib is designed, that most of the stuff that are needed in order to extend it to work as an indexer are not exposed in API and are deep inside the logic and trying to expose them so they can be potentially extended means a lot of stuff need to change.
I elaborate on this briefly, all that is exposed on API is a simple class object called
DataFecther
, this class object on instantiation takes a viem client and just a list of Dex names, then it will internally handles everything, each Dex in router lib is a class object with its own Dex literals, and depending on if it is a univ2 or univ3 it is a child of a deeper class object calledUniswapV2Base
andUniswapV3Base
, these 2 are the main logic for fetching/handling pool data.Once one needs to get a market quote for a token pair, a method on
DataFecther
is called, that method then expands to each dex internally and each dex internally to the univ2/3 base classes to fetch data and then pass the data back through the path. So I think it is self evident that making router lib extendable cannot be achieved without making fundamental and breaking changes to the API and how things are designed. So this leaves us with 2nd approach.Proposed Solution - (rain folder)
We'll create a
rain
folder, as the folder for holding all our changes that are added on to the repo, we'll be adding 2 new classesRainUniswapV2BaseProvider
andRainUniswapV3BaseProvider
, these 2 will inherit from the original univ2/v3 classes that have all the methods/logic for handling pool data, so we can then override some of their methods as a child class as we need for indexer functionalities, after that we just need to update all dexes to use these 2 new classes as their parent classes to inherit from instead fo the original univ2/3 classes.Next we need a new class
RainDataFetcher
inrain
folder, which inherits from originalDataFetcher
, we need to override a coulpe fo tis methods slightly, so now using this new class methods, pools data can be fetched and updated and used for getting market quotes and routes.This approach ensures that no changes are done to the logic of any original files and no structural changes. and all the maintenance will be done on the
rain
folder.Maintainability
Ofc with this approach all the changes are standalone in
rain
so this would be much more aligned to what has been discussed in tg chat.Current PR:
The text was updated successfully, but these errors were encountered: