forked from bitcoindevkit/bdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge bitcoindevkit#1110: fix(esplora): use saturating_add in update_…
…tx_graph() bf9a425 ci: fix MSRV build by pinning tokio-util to 0.7.8 (Steve Myers) d35668e ci(esplora): fix wasm cargo check by setting workspace resolver to version 2 (Steve Myers) 31d52e1 ci: fix msrv dependency versions for rustls-webpki and zip (Steve Myers) 6a5c9d7 fix(esplora): use saturating_add in update_tx_graph() (Steve Myers) 4d1a9fd test(esplora): add async_ext and blocking_ext integration tests (Steve Myers) Pull request description: ### Description This fixes overflow error when calling update_tx_graph() from update_tx_graph_without_keychain(). ### Notes to the reviewers You can reproduce the error by reverting 66a2bf5. The tests could use some cleanup but get the job done for this PR. ### Changelog notice None ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### Bugfixes: * [ ] This pull request breaks the existing API * [x] I've added tests to reproduce the issue which are now passing * [ ] I'm linking the issue being fixed by this PR Top commit has no ACKs. Tree-SHA512: eace00e0c289a7ac161985c4b8e46ad660ec0d6777cd74027ef1f0ab245daea87e34258233281796efb60473cf4f18d2647c090a14c0f05f3dc8a1950ebe9dab
- Loading branch information
Showing
8 changed files
with
252 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
[workspace] | ||
resolver = "2" | ||
members = [ | ||
"crates/bdk", | ||
"crates/chain", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
use bdk_esplora::EsploraAsyncExt; | ||
use electrsd::bitcoind::bitcoincore_rpc::RpcApi; | ||
use electrsd::bitcoind::{self, anyhow, BitcoinD}; | ||
use electrsd::{Conf, ElectrsD}; | ||
use esplora_client::{self, AsyncClient, Builder}; | ||
use std::str::FromStr; | ||
use std::thread::sleep; | ||
use std::time::Duration; | ||
|
||
use bdk_chain::bitcoin::{Address, Amount, BlockHash, Txid}; | ||
|
||
struct TestEnv { | ||
bitcoind: BitcoinD, | ||
#[allow(dead_code)] | ||
electrsd: ElectrsD, | ||
client: AsyncClient, | ||
} | ||
|
||
impl TestEnv { | ||
fn new() -> Result<Self, anyhow::Error> { | ||
let bitcoind_exe = | ||
bitcoind::downloaded_exe_path().expect("bitcoind version feature must be enabled"); | ||
let bitcoind = BitcoinD::new(bitcoind_exe).unwrap(); | ||
|
||
let mut electrs_conf = Conf::default(); | ||
electrs_conf.http_enabled = true; | ||
let electrs_exe = | ||
electrsd::downloaded_exe_path().expect("electrs version feature must be enabled"); | ||
let electrsd = ElectrsD::with_conf(electrs_exe, &bitcoind, &electrs_conf)?; | ||
|
||
let base_url = format!("http://{}", &electrsd.esplora_url.clone().unwrap()); | ||
let client = Builder::new(base_url.as_str()).build_async()?; | ||
|
||
Ok(Self { | ||
bitcoind, | ||
electrsd, | ||
client, | ||
}) | ||
} | ||
|
||
fn mine_blocks( | ||
&self, | ||
count: usize, | ||
address: Option<Address>, | ||
) -> anyhow::Result<Vec<BlockHash>> { | ||
let coinbase_address = match address { | ||
Some(address) => address, | ||
None => self | ||
.bitcoind | ||
.client | ||
.get_new_address(None, None)? | ||
.assume_checked(), | ||
}; | ||
let block_hashes = self | ||
.bitcoind | ||
.client | ||
.generate_to_address(count as _, &coinbase_address)?; | ||
Ok(block_hashes) | ||
} | ||
} | ||
|
||
#[tokio::test] | ||
pub async fn test_update_tx_graph_without_keychain() -> anyhow::Result<()> { | ||
let env = TestEnv::new()?; | ||
let receive_address0 = | ||
Address::from_str("bcrt1qc6fweuf4xjvz4x3gx3t9e0fh4hvqyu2qw4wvxm")?.assume_checked(); | ||
let receive_address1 = | ||
Address::from_str("bcrt1qfjg5lv3dvc9az8patec8fjddrs4aqtauadnagr")?.assume_checked(); | ||
|
||
let misc_spks = [ | ||
receive_address0.script_pubkey(), | ||
receive_address1.script_pubkey(), | ||
]; | ||
|
||
let _block_hashes = env.mine_blocks(101, None)?; | ||
let txid1 = env.bitcoind.client.send_to_address( | ||
&receive_address1, | ||
Amount::from_sat(10000), | ||
None, | ||
None, | ||
None, | ||
None, | ||
Some(1), | ||
None, | ||
)?; | ||
let txid2 = env.bitcoind.client.send_to_address( | ||
&receive_address0, | ||
Amount::from_sat(20000), | ||
None, | ||
None, | ||
None, | ||
None, | ||
Some(1), | ||
None, | ||
)?; | ||
let _block_hashes = env.mine_blocks(1, None)?; | ||
while env.client.get_height().await.unwrap() < 102 { | ||
sleep(Duration::from_millis(10)) | ||
} | ||
|
||
let graph_update = env | ||
.client | ||
.scan_txs( | ||
misc_spks.into_iter(), | ||
vec![].into_iter(), | ||
vec![].into_iter(), | ||
1, | ||
) | ||
.await?; | ||
|
||
let mut graph_update_txids: Vec<Txid> = graph_update.full_txs().map(|tx| tx.txid).collect(); | ||
graph_update_txids.sort(); | ||
let mut expected_txids = vec![txid1, txid2]; | ||
expected_txids.sort(); | ||
assert_eq!(graph_update_txids, expected_txids); | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
use bdk_esplora::EsploraExt; | ||
use electrsd::bitcoind::bitcoincore_rpc::RpcApi; | ||
use electrsd::bitcoind::{self, anyhow, BitcoinD}; | ||
use electrsd::{Conf, ElectrsD}; | ||
use esplora_client::{self, BlockingClient, Builder}; | ||
use std::str::FromStr; | ||
use std::thread::sleep; | ||
use std::time::Duration; | ||
|
||
use bdk_chain::bitcoin::{Address, Amount, BlockHash, Txid}; | ||
|
||
struct TestEnv { | ||
bitcoind: BitcoinD, | ||
#[allow(dead_code)] | ||
electrsd: ElectrsD, | ||
client: BlockingClient, | ||
} | ||
|
||
impl TestEnv { | ||
fn new() -> Result<Self, anyhow::Error> { | ||
let bitcoind_exe = | ||
bitcoind::downloaded_exe_path().expect("bitcoind version feature must be enabled"); | ||
let bitcoind = BitcoinD::new(bitcoind_exe).unwrap(); | ||
|
||
let mut electrs_conf = Conf::default(); | ||
electrs_conf.http_enabled = true; | ||
let electrs_exe = | ||
electrsd::downloaded_exe_path().expect("electrs version feature must be enabled"); | ||
let electrsd = ElectrsD::with_conf(electrs_exe, &bitcoind, &electrs_conf)?; | ||
|
||
let base_url = format!("http://{}", &electrsd.esplora_url.clone().unwrap()); | ||
let client = Builder::new(base_url.as_str()).build_blocking()?; | ||
|
||
Ok(Self { | ||
bitcoind, | ||
electrsd, | ||
client, | ||
}) | ||
} | ||
|
||
fn mine_blocks( | ||
&self, | ||
count: usize, | ||
address: Option<Address>, | ||
) -> anyhow::Result<Vec<BlockHash>> { | ||
let coinbase_address = match address { | ||
Some(address) => address, | ||
None => self | ||
.bitcoind | ||
.client | ||
.get_new_address(None, None)? | ||
.assume_checked(), | ||
}; | ||
let block_hashes = self | ||
.bitcoind | ||
.client | ||
.generate_to_address(count as _, &coinbase_address)?; | ||
Ok(block_hashes) | ||
} | ||
} | ||
|
||
#[test] | ||
pub fn test_update_tx_graph_without_keychain() -> anyhow::Result<()> { | ||
let env = TestEnv::new()?; | ||
let receive_address0 = | ||
Address::from_str("bcrt1qc6fweuf4xjvz4x3gx3t9e0fh4hvqyu2qw4wvxm")?.assume_checked(); | ||
let receive_address1 = | ||
Address::from_str("bcrt1qfjg5lv3dvc9az8patec8fjddrs4aqtauadnagr")?.assume_checked(); | ||
|
||
let misc_spks = [ | ||
receive_address0.script_pubkey(), | ||
receive_address1.script_pubkey(), | ||
]; | ||
|
||
let _block_hashes = env.mine_blocks(101, None)?; | ||
let txid1 = env.bitcoind.client.send_to_address( | ||
&receive_address1, | ||
Amount::from_sat(10000), | ||
None, | ||
None, | ||
None, | ||
None, | ||
Some(1), | ||
None, | ||
)?; | ||
let txid2 = env.bitcoind.client.send_to_address( | ||
&receive_address0, | ||
Amount::from_sat(20000), | ||
None, | ||
None, | ||
None, | ||
None, | ||
Some(1), | ||
None, | ||
)?; | ||
let _block_hashes = env.mine_blocks(1, None)?; | ||
while env.client.get_height().unwrap() < 102 { | ||
sleep(Duration::from_millis(10)) | ||
} | ||
|
||
let graph_update = env.client.scan_txs( | ||
misc_spks.into_iter(), | ||
vec![].into_iter(), | ||
vec![].into_iter(), | ||
1, | ||
)?; | ||
|
||
let mut graph_update_txids: Vec<Txid> = graph_update.full_txs().map(|tx| tx.txid).collect(); | ||
graph_update_txids.sort(); | ||
let mut expected_txids = vec![txid1, txid2]; | ||
expected_txids.sort(); | ||
assert_eq!(graph_update_txids, expected_txids); | ||
Ok(()) | ||
} |