Skip to content

Commit

Permalink
feat: added electrsd support for TestEnv
Browse files Browse the repository at this point in the history
Added `electrsd` support so that `TestEnv` can serve `esplora` and
`electrum`.
  • Loading branch information
LagginTimes committed Oct 17, 2023
1 parent 0be5338 commit 12403a1
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 64 deletions.
103 changes: 66 additions & 37 deletions crates/bitcoind_rpc/tests/test_emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,23 @@ fn block_to_chain_update(block: &bitcoin::Block, height: u32) -> local_chain::Up
pub fn test_sync_local_chain() -> anyhow::Result<()> {
let env = TestEnv::new()?;
let mut local_chain = LocalChain::default();
let mut emitter = Emitter::from_height(&env.client, 0);
let tip = env.rpc_client().get_block_count()?;
let mut emitter = Emitter::from_height(env.rpc_client(), tip as u32);

// mine some blocks and returned the actual block hashes
let exp_hashes = {
let mut hashes = vec![env.client.get_block_hash(0)?]; // include genesis block
hashes.extend(env.mine_blocks(101, None)?);
let mut hashes = (0..=tip)
.map(|height| env.rpc_client().get_block_hash(height))
.collect::<Result<Vec<_>, _>>()?; // includes genesis block
hashes.extend(env.mine_blocks(101 - tip as usize, None, &env.bitcoind)?);
hashes
};

(0..tip).for_each(|height| {
let changeset = BTreeMap::from([(height as u32, Some(exp_hashes[height as usize]))]);
local_chain.apply_changeset(&changeset);
});

// see if the emitter outputs the right blocks
println!("first sync:");
while let Some((height, block)) = emitter.next_block()? {
Expand Down Expand Up @@ -141,13 +149,22 @@ fn test_into_tx_graph() -> anyhow::Result<()> {
let env = TestEnv::new()?;

println!("getting new addresses!");
let addr_0 = env.client.get_new_address(None, None)?.assume_checked();
let addr_1 = env.client.get_new_address(None, None)?.assume_checked();
let addr_2 = env.client.get_new_address(None, None)?.assume_checked();
let addr_0 = env
.rpc_client()
.get_new_address(None, None)?
.assume_checked();
let addr_1 = env
.rpc_client()
.get_new_address(None, None)?
.assume_checked();
let addr_2 = env
.rpc_client()
.get_new_address(None, None)?
.assume_checked();
println!("got new addresses!");

println!("mining block!");
env.mine_blocks(101, None)?;
env.mine_blocks(101, None, &env.bitcoind)?;
println!("mined blocks!");

let mut chain = LocalChain::default();
Expand All @@ -159,7 +176,7 @@ fn test_into_tx_graph() -> anyhow::Result<()> {
index
});

let emitter = &mut Emitter::from_height(&env.client, 0);
let emitter = &mut Emitter::from_height(env.rpc_client(), 0);

while let Some((height, block)) = emitter.next_block()? {
let _ = chain.apply_update(block_to_chain_update(&block, height))?;
Expand All @@ -171,7 +188,7 @@ fn test_into_tx_graph() -> anyhow::Result<()> {
let exp_txids = {
let mut txids = BTreeSet::new();
for _ in 0..3 {
txids.insert(env.client.send_to_address(
txids.insert(env.rpc_client().send_to_address(
&addr_0,
Amount::from_sat(10_000),
None,
Expand Down Expand Up @@ -206,8 +223,8 @@ fn test_into_tx_graph() -> anyhow::Result<()> {
}

// mine a block that confirms the 3 txs
let exp_block_hash = env.mine_blocks(1, None)?[0];
let exp_block_height = env.client.get_block_info(&exp_block_hash)?.height as u32;
let exp_block_hash = env.mine_blocks(1, None, &env.bitcoind)?[0];
let exp_block_height = env.rpc_client().get_block_info(&exp_block_hash)?.height as u32;
let exp_anchors = exp_txids
.iter()
.map({
Expand Down Expand Up @@ -247,9 +264,9 @@ fn ensure_block_emitted_after_reorg_is_at_reorg_height() -> anyhow::Result<()> {
const CHAIN_TIP_HEIGHT: usize = 110;

let env = TestEnv::new()?;
let mut emitter = Emitter::from_height(&env.client, EMITTER_START_HEIGHT as _);
let mut emitter = Emitter::from_height(env.rpc_client(), EMITTER_START_HEIGHT as _);

env.mine_blocks(CHAIN_TIP_HEIGHT, None)?;
env.mine_blocks(CHAIN_TIP_HEIGHT, None, &env.bitcoind)?;
while emitter.next_header()?.is_some() {}

for reorg_count in 1..=10 {
Expand Down Expand Up @@ -315,10 +332,13 @@ fn tx_can_become_unconfirmed_after_reorg() -> anyhow::Result<()> {
const SEND_AMOUNT: Amount = Amount::from_sat(10_000);

let env = TestEnv::new()?;
let mut emitter = Emitter::from_height(&env.client, 0);
let mut emitter = Emitter::from_height(env.rpc_client(), 0);

// setup addresses
let addr_to_mine = env.client.get_new_address(None, None)?.assume_checked();
let addr_to_mine = env
.rpc_client()
.get_new_address(None, None)?
.assume_checked();
let spk_to_track = ScriptBuf::new_v0_p2wsh(&WScriptHash::all_zeros());
let addr_to_track = Address::from_script(&spk_to_track, bitcoin::Network::Regtest)?;

Expand All @@ -331,15 +351,15 @@ fn tx_can_become_unconfirmed_after_reorg() -> anyhow::Result<()> {
});

// mine and sync receiver up to tip
env.mine_blocks(PREMINE_COUNT, Some(addr_to_mine))?;
env.mine_blocks(PREMINE_COUNT, Some(addr_to_mine), &env.bitcoind)?;

// create transactions that are tracked by our receiver
for _ in 0..ADDITIONAL_COUNT {
let txid = env.send(&addr_to_track, SEND_AMOUNT)?;

// lock outputs that send to `addr_to_track`
let outpoints_to_lock = env
.client
.rpc_client()
.get_transaction(&txid, None)?
.transaction()?
.output
Expand All @@ -348,9 +368,9 @@ fn tx_can_become_unconfirmed_after_reorg() -> anyhow::Result<()> {
.filter(|(_, txo)| txo.script_pubkey == spk_to_track)
.map(|(vout, _)| OutPoint::new(txid, vout as _))
.collect::<Vec<_>>();
env.client.lock_unspent(&outpoints_to_lock)?;
env.rpc_client().lock_unspent(&outpoints_to_lock)?;

let _ = env.mine_blocks(1, None)?;
let _ = env.mine_blocks(1, None, &env.bitcoind)?;
}

// get emitter up to tip
Expand Down Expand Up @@ -396,11 +416,14 @@ fn mempool_avoids_re_emission() -> anyhow::Result<()> {
const MEMPOOL_TX_COUNT: usize = 2;

let env = TestEnv::new()?;
let mut emitter = Emitter::from_height(&env.client, 0);
let mut emitter = Emitter::from_height(env.rpc_client(), 0);

// mine blocks and sync up emitter
let addr = env.client.get_new_address(None, None)?.assume_checked();
env.mine_blocks(BLOCKS_TO_MINE, Some(addr.clone()))?;
let addr = env
.rpc_client()
.get_new_address(None, None)?
.assume_checked();
env.mine_blocks(BLOCKS_TO_MINE, Some(addr.clone()), &env.bitcoind)?;
while emitter.next_header()?.is_some() {}

// have some random txs in mempool
Expand Down Expand Up @@ -451,11 +474,14 @@ fn mempool_re_emits_if_tx_introduction_height_not_reached() -> anyhow::Result<()
const MEMPOOL_TX_COUNT: usize = 21;

let env = TestEnv::new()?;
let mut emitter = Emitter::from_height(&env.client, 0);
let mut emitter = Emitter::from_height(env.rpc_client(), 0);

// mine blocks to get initial balance, sync emitter up to tip
let addr = env.client.get_new_address(None, None)?.assume_checked();
env.mine_blocks(PREMINE_COUNT, Some(addr.clone()))?;
let addr = env
.rpc_client()
.get_new_address(None, None)?
.assume_checked();
env.mine_blocks(PREMINE_COUNT, Some(addr.clone()), &env.bitcoind)?;
while emitter.next_header()?.is_some() {}

// mine blocks to introduce txs to mempool at different heights
Expand Down Expand Up @@ -528,11 +554,14 @@ fn mempool_during_reorg() -> anyhow::Result<()> {
const PREMINE_COUNT: usize = 101;

let env = TestEnv::new()?;
let mut emitter = Emitter::from_height(&env.client, 0);
let mut emitter = Emitter::from_height(env.rpc_client(), 0);

// mine blocks to get initial balance
let addr = env.client.get_new_address(None, None)?.assume_checked();
env.mine_blocks(PREMINE_COUNT, Some(addr.clone()))?;
let addr = env
.rpc_client()
.get_new_address(None, None)?
.assume_checked();
env.mine_blocks(PREMINE_COUNT, Some(addr.clone()), &env.bitcoind)?;

// introduce mempool tx at each block extension
for _ in 0..TIP_DIFF {
Expand All @@ -549,7 +578,7 @@ fn mempool_during_reorg() -> anyhow::Result<()> {
.into_iter()
.map(|(tx, _)| tx.txid())
.collect::<BTreeSet<_>>(),
env.client
env.rpc_client()
.get_raw_mempool()?
.into_iter()
.collect::<BTreeSet<_>>(),
Expand All @@ -568,7 +597,7 @@ fn mempool_during_reorg() -> anyhow::Result<()> {
// emission.
// TODO: How can have have reorg logic in `TestEnv` NOT blacklast old blocks first?
let tx_introductions = dbg!(env
.client
.rpc_client()
.get_raw_mempool_verbose()?
.into_iter()
.map(|(txid, entry)| (txid, entry.height as usize))
Expand Down Expand Up @@ -643,10 +672,10 @@ fn no_agreement_point() -> anyhow::Result<()> {
let env = TestEnv::new()?;

// start height is 99
let mut emitter = Emitter::from_height(&env.client, (PREMINE_COUNT - 2) as u32);
let mut emitter = Emitter::from_height(env.rpc_client(), (PREMINE_COUNT - 2) as u32);

// mine 101 blocks
env.mine_blocks(PREMINE_COUNT, None)?;
env.mine_blocks(PREMINE_COUNT, None, &env.bitcoind)?;

// emit block 99a
let (_, block_header_99a) = emitter.next_header()?.expect("block 99a header");
Expand All @@ -658,15 +687,15 @@ fn no_agreement_point() -> anyhow::Result<()> {
let block_hash_100a = block_header_100a.block_hash();

// get hash for block 101a
let block_hash_101a = env.client.get_block_hash(101)?;
let block_hash_101a = env.rpc_client().get_block_hash(101)?;

// invalidate blocks 99a, 100a, 101a
env.client.invalidate_block(&block_hash_99a)?;
env.client.invalidate_block(&block_hash_100a)?;
env.client.invalidate_block(&block_hash_101a)?;
env.rpc_client().invalidate_block(&block_hash_99a)?;
env.rpc_client().invalidate_block(&block_hash_100a)?;
env.rpc_client().invalidate_block(&block_hash_101a)?;

// mine new blocks 99b, 100b, 101b
env.mine_blocks(3, None)?;
env.mine_blocks(3, None, &env.bitcoind)?;

// emit block header 99b
let (_, block_header_99b) = emitter.next_header()?.expect("block 99b header");
Expand Down
3 changes: 1 addition & 2 deletions crates/testenv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ edition = "2021"
bitcoin = { version = "0.30", default-features = false }
bitcoincore-rpc = { version = "0.17" }
bdk_chain = { path = "../chain", version = "0.6", default-features = false }
bdk_bitcoind_rpc = { path = "../bitcoind_rpc", version = "0.1.0", default-features = false }
bitcoind = { version = "0.33", features = ["25_0"] }
electrsd = { version= "0.25.0", features = ["bitcoind_25_0", "esplora_a33e97e1", "legacy"] }
anyhow = { version = "1" }

[features]
Expand Down
Loading

0 comments on commit 12403a1

Please sign in to comment.