Skip to content

Fix: blockchain.transaction.id_from_pos compatibility with electrs - #222

Open
jharveyb wants to merge 2 commits into
bitcoindevkit:masterfrom
jharveyb:fix/txid_from_pos_electrs_compat
Open

Fix: blockchain.transaction.id_from_pos compatibility with electrs#222
jharveyb wants to merge 2 commits into
bitcoindevkit:masterfrom
jharveyb:fix/txid_from_pos_electrs_compat

Conversation

@jharveyb

Copy link
Copy Markdown

While working on a lightning GossipVerifier in ldk-node, I ran into an issue with the Electrum client.

tl;dr electrs diverges from the Electrum protocol a bit, such that the blockchain.transaction.id_from_pos method doesn't work right now. Fixing this is pretty simple.

There are two issues: the 3rd parameter, merkle, not being treated as optional, and the return value formatting when merkle = false.

To reproduce, you can run the relevant test against an electrs/0.11.1 server found on https://1209k.com/bitcoin-eye/ele.php, (not qtornado, which is ElectrumX):

TEST_ELECTRUM_SERVER=electrum.tjader.xyz:50002 cargo test raw_client::test::test_txid_from_pos -- --exact

Finished `test` profile [unoptimized + debuginfo] target(s) in 0.04s
     Running unittests src/lib.rs (target/debug/deps/electrum_client-e59677bf712d816c)

running 1 test
test raw_client::test::test_txid_from_pos ... FAILED

failures:

---- raw_client::test::test_txid_from_pos stdout ----

thread 'raw_client::test::test_txid_from_pos' (3145567) panicked at src/raw_client.rs:1965:53:
called `Result::unwrap()` on an `Err` value: Protocol(Object {"code": Number(-32602), "message": String("invalid params")})
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

If the library adds the merkle = false parameter, there is still an issue with parsing the response:

running 1 test
test raw_client::test::test_txid_from_pos ... FAILED

failures:

---- raw_client::test::test_txid_from_pos stdout ----

thread 'raw_client::test::test_txid_from_pos' (3147516) panicked at src/raw_client.rs:1965:53:
called `Result::unwrap()` on an `Err` value: JSON(Error("invalid type: map, expected an ASCII hex string", line: 0, column: 0))
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

You can see the electrs behavior here:

https://github.com/romanz/electrs/blob/9cd09afa229df89214f59816e5142f0f58ff6c48/src/electrum.rs#L466

Additionally, the JSON map key was tx_id before version 0.11.1:

https://github.com/romanz/electrs/blob/800bebeea4a3ec4ca924b389338b3449c81b28d4/src/electrum.rs#L484

This PR accepts both versions. You can confirm that behavior with a public electrs v0.10.9 server (I didn't get this working with the cargo test runner):

Terminal 1: `ncat --sh-exec "ncat -k --proxy-type socks5 --proxy 127.0.0.1:9050 4vrz2q62yxlfmcntnotzdjahpqh2joirp2vrcdsayyioxthffimbp2ad.onion 50001 -v" -l 50506 -k`

Terminal 2: `echo '{"jsonrpc": "2.0", "method": "blockchain.transaction.id_from_pos", "params": [932453,139,false], "id": 0}' | netcat 127.0.0.1 50506`

{"id":0,"jsonrpc":"2.0","result":{"tx_id":"8fed750149034b9e03d5143a95aaa52ee54aa231564f6519be754cfacee0cd0d"}}

Added tests for the parsing, and the raw_client:

TEST_ELECTRUM_SERVER=electrum.tjader.xyz:50002 cargo test raw_client::test::test_txid_from_pos -- --exact
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.06s
     Running unittests src/lib.rs (target/debug/deps/electrum_client-e59677bf712d816c)

running 1 test
test raw_client::test::test_txid_from_pos ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 63 filtered out; finished in 0.77s

Everything is passing locally for me, though that electrum.tjader.xyz server seems finicky. I also tested this branch in my electrum CLI and confirmed it works against both my personal electrs server, and electrum.blockstream.info.

Something like https://github.com/testcontainers/testcontainers-rs could be useful for testing against multiple impls if there's no public (reliable) electrs instance.

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.

1 participant