Generic JSON RPC Client for UTXO Chains
Currently UTXO chain clients leverage the following forks of btcsuite
for RPC clients and types:
- https://github.com/eager7/dogd
- https://github.com/gcash/bchd
- https://github.com/ltcsuite/ltcd
- https://github.com/btcsuite/btcd
During mempool scanning in all UTXO clients we fanout (https://gitlab.com/thorchain/thornode/-/blob/develop/bifrost/pkg/chainclients/bitcoin/client.go#L530) to perform verbose transaction lookup for transaction hashes in the mempool. The RPC clients do not support a provided HTTP client or transport and do not re-use connections, which incurs load and latency due to connection re-establishment and DNS lookups for every RPC call. Sampling Bifrost this is about half of current load:
In addition to the fanout on mempool transactions, this problem is exacerbated for Dogecoin - as dogecoind
does not support the verbosity flag for getblock
(https://github.com/dogecoin/dogecoin/issues/1625) so we must additionally fan out for all transactions in a block (https://gitlab.com/thorchain/thornode/-/blob/develop/bifrost/pkg/chainclients/dogecoin/client.go#L798). Since Dogecoin transaction counts have increased drastically in recent weeks this has a compounding effect and is causing periodic network-wide observation lag for the chain:
The btcsuite
clients have a large API footprint, but we leverage less than a dozen. Creation of a generic UTXO client (like we did for evm
with !2859 (merged)) which uses JSON RPC directly and places chain-specific logic in switch
statements allows us to solve multiple concerns in one pass:
- Reduce dependencies on multiple variants of the
btcsuite
library (in particulardogd
which is entirely unmaintained). - Implement connection re-use to reduce load on Bifrost and node-local DNS, along with reduced observation latency due to head of line blocking.
- Leverage JSON RPC batch requests for the verbose transaction fan out on all chains to further reduce load and observation latency.
- Remove copy-pasted UTXO chain clients for cleanliness and maintainability, as the code is almost entirely shared.
The intended approach will be to implement a generic utxo
client and use it to replace the current dogecoin
client, which is the most problematic at the moment. After successfully replacing dogecoin
, we can iterate through the remaining packages to fold them in one at a time.