Currently we use the JsonRpcProviders from ethers library which uses polling mechanism for getting the block number.
We have many actions in our app which instantiate a new JsonRpcProvider for different reasons. One reason is for watching on ClaimMade, RequestCreated, RequestFilled, ClaimStakeWithdrawn, Token.Transfer events in order to update the transfer state in the UI.
This means that our app instantiates a new provider (for each event listener) which polls every X seconds for checking the current block number. The more event listeners we have active the more instantiated providers we end up with (N providers poll every X seconds for new block numbers).
This is bad as we are doing a lot of RPC calls to the RPC endpoints (not optimal).
Implementation
The overall goal is having a global module that handles the subscriptions to these events which uses only one JsonRpcProvider or WebSocketProvider per chain. This should be accomplished by storing an instance of our own EthereumProvider per chain in a store. We will need #580. Our contract functions should only accept our own interface (EthereumProvider and not an rpc url). Then, we can pass the provider from the store to these functions, which will start the event subscription on the provider.
Additionally, there should be an option of choosing whether the provider should connect with a JsonRpcProvider or WebSocketProvider as some chain infrastructures don't fully support WebSocket connections. This can be easily done in the constructor by checking the provided URL scheme. We only support one internal rpc URL for reading from one chain. So there should only one provider for one chain.
A little bit about WebSocketProvider and its pros/cons:
The WebSocketProvider connects to a JSON-RPC WebSocket-compatible backend which allows for a persistent connection, multiplexing requests and pub-sub events for a more immediate event dispatching.
The WebSocket API is newer, and if running your own infrastructure, note that WebSockets are much more intensive on your server resources, as they must manage and maintain the state for each client. For this reason, many services may also charge additional fees for using their WebSocket endpoints.
This means we might end up with better UX (better real-time feeling) & significantly less RPC calls.
Acceptance Criteria
[ ] One provider per chain is stored in a store. These use our internalRpcUrl and should be used for any read operation from the chains.
[ ] The providers are passed to the contract functions instead of rpc urls.
[ ] Allow websocket connections for the rpcs inside the providers.
[ ] Use websocket urls as internalRpcUrl in the config
Rationale
Currently we use the
JsonRpcProviders
fromethers
library which uses polling mechanism for getting the block number. We have many actions in our app which instantiate a newJsonRpcProvider
for different reasons. One reason is for watching onClaimMade
,RequestCreated
,RequestFilled
,ClaimStakeWithdrawn
,Token.Transfer
events in order to update the transfer state in the UI. This means that our app instantiates a new provider (for each event listener) which polls every X seconds for checking the current block number. The more event listeners we have active the more instantiated providers we end up with (N providers poll every X seconds for new block numbers). This is bad as we are doing a lot of RPC calls to the RPC endpoints (not optimal).Implementation
The overall goal is having a global module that handles the subscriptions to these events which uses only one
JsonRpcProvider
orWebSocketProvider
per chain. This should be accomplished by storing an instance of our ownEthereumProvider
per chain in a store. We will need #580. Our contract functions should only accept our own interface (EthereumProvider
and not an rpc url). Then, we can pass the provider from the store to these functions, which will start the event subscription on the provider.Additionally, there should be an option of choosing whether the provider should connect with a
JsonRpcProvider
orWebSocketProvider
as some chain infrastructures don't fully support WebSocket connections. This can be easily done in the constructor by checking the provided URL scheme. We only support one internal rpc URL for reading from one chain. So there should only one provider for one chain.A little bit about
WebSocketProvider
and its pros/cons:This means we might end up with better UX (better real-time feeling) & significantly less RPC calls.
Acceptance Criteria
internalRpcUrl
and should be used for any read operation from the chains.internalRpcUrl
in the config