Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TS: Support Blockstream's Esplora/Electrs servers for electrum protocol integration #501

Merged
merged 7 commits into from
Jan 26, 2023

Conversation

nkuba
Copy link
Member

@nkuba nkuba commented Jan 25, 2023

Closes: #422

In this PR we update the implementation of TypeScript Electrum integration to support Esplora/Electrs servers.

As per Blockstream/electrs#36 verbose transactions are not supported by Esplora/Electrs.
This affects our implementation of getTransaction and getTransactionConfirmations functions.

For a consistent code in the client without alternative paths for different Electrum servers implementations I decided to not use verbose transactions at all.

getTransactionConfirmations

  1. Get the raw transaction
  2. Deserialize the raw transaction
  3. Find transaction block height by finding it in a history of
    transactions for the output script included in the transaction.
  4. Get the latest block height
  5. Calculate number of confirmations by subtracting the transaction
    block height from the latest block height and adding one.

getTransaction

We get a raw transaction and deserialize it with bcoin. This lets us define a consistent type for returned transactions (093d4ec). Before these changes, I observed that Electrum server implementations are not consistent with data returned in verbose JSON.

Electrum tests

We can test electrum integration against different kinds of servers.
The most popular implementations are:

  • ElectrumX
  • Fulcrum
  • Electrs/Esplora

We can find a list of public servers here: https://1209k.com/bitcoin-eye/ele.php?chain=tbtc

The electrs-esplora server seems pretty unstable, so we don't want to enable it in tests until we add retries (#485).

As Esplora/Electrs doesn't support verbose transactions details in the
response, that would contain the confirmations number we need to
workaround it. (See: Blockstream/electrs#36)

The workaround:
1. Get the raw transaction
2. Deserialize the raw transaction
3. Find transaction block height by finding it in a history of
   transactions for the output script included in the transaction.
4. Get the latest block height
5. Calculate number of confirmations by subtracting the transaction
   block height from the latest block height and adding one.
The simpliest solution is to request verbose format of transaction.
Unfortunatelly it's not compatible with Esplora/Electrs implementation of
ElectrumX server. (see: Blockstream/electrs#36)

As a workaround to cover integration with Esplora/Electrs we get a raw
transaction and deserialize it.
We can test exact block number, not only it being greater than 6.
For that we need to fetch the current block height to compare it with
the one we get. We use blockstream as a source of truth.
We can test electrum integration against different kinds of servers.
The most popular implementations are:
- ElectrumX
- Fulcrum
- Electrs/Esplora

We can find list of public servers here: https://1209k.com/bitcoin-eye/ele.php?chain=tbtc

The electrs-esplora server seems pretty unstable, so we don't want to
enable it in tests untill we add retries.
Before a7aedd1
under these two properties we returned exactly the valu that was
retruned from electrum server. This was causing some unexpected
bahaviour as it could happen that different implementation and instances
of servers were returning different results.
The only thing that we can relay on is a hex value for bytes that were
used in the transaction.
Here we switch to hexadecimal value to have consistent behaviour and be
able to support all major electrum server implementations (ElectrumX,
Electrs/Esplora and Fulcrum).
The change here is similiar to what we implemented in the Keep Client.
The servers are working now, so we can try enabling the tests.

We still need to work on stable results for electrs-esplora server.
@nkuba
Copy link
Member Author

nkuba commented Jan 26, 2023

An alternative approach that I would also like to investigate would be to use verbose transactions as before and fallback to the logic proposed in this PR only in case verbose is not supported by the server.

@nkuba nkuba marked this pull request as draft January 26, 2023 09:13
@nkuba nkuba marked this pull request as ready for review January 26, 2023 09:27
@nkuba
Copy link
Member Author

nkuba commented Jan 26, 2023

An alternative approach that I would also like to investigate would be to use verbose transactions as before and fallback to the logic proposed in this PR only in case verbose is not supported by the server.

I tested it and it did not result in any improvement in test execution time. This is probably as if we get verbose transactions the processing has to be done on the server side. Let's leave it as is and update it in the future if necessary.

@lukasz-zimnoch lukasz-zimnoch merged commit 99d10e5 into main Jan 26, 2023
@lukasz-zimnoch lukasz-zimnoch deleted the ts-electrum-electrs branch January 26, 2023 11:16
@shesek
Copy link

shesek commented Jan 27, 2023

I tested it and it did not result in any improvement in test execution time

Interesting, I would've expected verbose transactions to perform better than fetching the entire address history and looking it up there.

Which electrum server implementation did you benchmark this against? Did you try with transactions that use reused addresses, such that looking up the address returns other historical transactions too?

(For example 3ae54f00613ca0a39bbb202e49dc7f2abba9e5ed4c3fcdaed768c7effeeca403, which sends to an address with nearly 700k historical txs -- I guess it might not work at all if there are that many of them?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TS: getTransactionConfirmations won't work with Electrs
3 participants