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

fix(electrum): prevent fetch_prev_txout from querying coinbase transactions #1756

Merged
merged 2 commits into from
Dec 6, 2024

Conversation

LagginTimes
Copy link
Contributor

@LagginTimes LagginTimes commented Dec 3, 2024

Fixes #1698.

Description

fetch_prev_txout should not try to query the prevouts of coinbase transactions, as it may result in the Electrum server returning an error which would cause the overall sync/full_scan to fail. Without this critical bug fix, bdk_electrum will crash when someone tracks an address being mined to.

Notes to the reviewers

Changelog notice

  • fetch_prev_txout no longer queries coinbase transactions.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

@LagginTimes LagginTimes self-assigned this Dec 3, 2024
@LagginTimes LagginTimes added bug Something isn't working audit Suggested as result of external code audit labels Dec 3, 2024
@notmandatory notmandatory added this to the 1.0.0-beta milestone Dec 3, 2024
@notmandatory
Copy link
Member

Needs a test then this looks good to go for 1.0.0.

@LagginTimes LagginTimes force-pushed the electrum_prev_txout branch 2 times, most recently from 5d3b2f5 to 2598e1d Compare December 4, 2024 07:55
@LagginTimes LagginTimes force-pushed the electrum_prev_txout branch 2 times, most recently from b4f6939 to 4cf7254 Compare December 4, 2024 14:39
@ValuedMammal
Copy link
Contributor

For the test can't we also build a SyncRequest with the same address that receives the block reward? which would cause electrum to throw an error without the fix in this PR.

@jirijakes
Copy link
Contributor

tACK ccf13ec. Test breaks when coinbase TX queried.

Failed test

running 1 test
test bdk_electrum_client::test::test_fetch_prev_txout_with_coinbase ... FAILED

failures:

failures:
bdk_electrum_client::test::test_fetch_prev_txout_with_coinbase

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.20s

--- STDERR: bdk_electrum bdk_electrum_client::test::test_fetch_prev_txout_with_coinbase ---
thread 'bdk_electrum_client::test::test_fetch_prev_txout_with_coinbase' panicked at crates/electrum/src/bdk_electrum_client.rs:570:9:
assertion failed: client.fetch_prev_txout(&mut tx_update).is_ok()

@LagginTimes
Copy link
Contributor Author

LagginTimes commented Dec 5, 2024

For the test can't we also build a SyncRequest with the same address that receives the block reward? which would cause electrum to throw an error without the fix in this PR.

Yes, something like this would work as well:

#[test]
fn test_sync_with_coinbase() -> anyhow::Result<()> {
    let env = TestEnv::new()?;
    let electrum_client = electrum_client::Client::new(env.electrsd.electrum_url.as_str())?;
    let client = BdkElectrumClient::new(electrum_client);

    // Setup address.
    let spk_to_track = ScriptBuf::new_p2wsh(&WScriptHash::all_zeros());
    let addr_to_track = Address::from_script(&spk_to_track, bdk_chain::bitcoin::Network::Regtest)?;

    // Setup receiver.
    let (mut recv_chain, _) = LocalChain::from_genesis_hash(env.bitcoind.client.get_block_hash(0)?);
    let mut recv_graph = IndexedTxGraph::<ConfirmationBlockTime, _>::new({
        let mut recv_index = SpkTxOutIndex::default();
        recv_index.insert_spk((), spk_to_track.clone());
        recv_index
    });

    // Mine some blocks.
    env.mine_blocks(101, Some(addr_to_track))?;
    env.wait_until_electrum_sees_block(Duration::from_secs(6))?;

    // Check to see if electrum syncs properly.
    assert!(sync_with_electrum(
        &client,
        [spk_to_track.clone()],
        &mut recv_chain,
        &mut recv_graph,
    )
    .is_ok());

    Ok(())
}

I believe the current implementation in the PR is more straightforward and easier to understand. However, I would appreciate hearing others' thoughts on this.

Copy link
Contributor

@ValuedMammal ValuedMammal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ccf13ec

@evanlinjin
Copy link
Member

@LagginTimes let's include both tests. The test_sync_with_coinbase is excellent.

Copy link
Member

@evanlinjin evanlinjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ccf13ec

Copy link
Member

@notmandatory notmandatory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ccf13ec

@notmandatory
Copy link
Member

Looks like this is ready to go once test_sync_with_coinbase() is added. I'm also happy to have it merged as is.

…sactions

\`fetch_prev_txout\` should not try to query the prevouts of coinbase
transactions, as it may result in the Electrum server returning an error
which would cause the overall `sync` to fail.
@LagginTimes
Copy link
Contributor Author

test_sync_with_coinbase() has been added.

Copy link
Member

@evanlinjin evanlinjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK d4ef266

@evanlinjin evanlinjin merged commit bcff89d into bitcoindevkit:master Dec 6, 2024
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
audit Suggested as result of external code audit bug Something isn't working
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

bdk_electrum: don't query prevouts of coinbase tx
5 participants