Skip to content

Commit 7699737

Browse files
committed
test(chain): Add test for inserting Header into LocalChain
1 parent bf2ee94 commit 7699737

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

crates/chain/tests/test_local_chain.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![cfg(feature = "miniscript")]
22

3+
use std::collections::BTreeMap;
34
use std::ops::{Bound, RangeBounds};
45

56
use bdk_chain::{
@@ -379,6 +380,101 @@ fn local_chain_insert_block() {
379380
}
380381
}
381382

383+
#[test]
384+
fn local_chain_insert_header() {
385+
fn header(prev_blockhash: BlockHash) -> Header {
386+
Header {
387+
version: bitcoin::block::Version::default(),
388+
prev_blockhash,
389+
merkle_root: bitcoin::hash_types::TxMerkleNode::all_zeros(),
390+
time: 0,
391+
bits: bitcoin::CompactTarget::default(),
392+
nonce: 0,
393+
}
394+
}
395+
396+
// Create consecutive headers of height `n`, where the genesis header is height 0.
397+
fn build_headers(n: u32) -> Vec<Header> {
398+
let mut headers = Vec::new();
399+
let genesis = header(hash!("_"));
400+
headers.push(genesis);
401+
for i in 1..=n {
402+
let prev = headers[(i - 1) as usize].block_hash();
403+
headers.push(header(prev));
404+
}
405+
headers
406+
}
407+
408+
let headers = build_headers(5);
409+
410+
fn local_chain(data: Vec<(u32, Header)>) -> LocalChain<Header> {
411+
bdk_chain::local_chain::LocalChain::from_blocks(
412+
data.into_iter().collect::<BTreeMap<_, _>>(),
413+
)
414+
.expect("chain must have genesis block")
415+
}
416+
417+
struct TestCase {
418+
original: LocalChain<Header>,
419+
insert: (u32, Header),
420+
expected_result: Result<ChangeSet<Header>, AlterCheckPointError>,
421+
expected_final: LocalChain<Header>,
422+
}
423+
424+
let test_cases = [
425+
// Test case 1: start with only the genesis header and insert header at height 5.
426+
TestCase {
427+
original: local_chain(vec![(0, headers[0])]),
428+
insert: (5, headers[5]),
429+
expected_result: Ok([(5, Some(headers[5]))].into()),
430+
expected_final: local_chain(vec![(0, headers[0]), (5, headers[5])]),
431+
},
432+
// Test case 2: start with headers at heights 0 and 3. Insert header at height 4.
433+
TestCase {
434+
original: local_chain(vec![(0, headers[0]), (3, headers[3])]),
435+
insert: (4, headers[4]),
436+
expected_result: Ok([(4, Some(headers[4]))].into()),
437+
expected_final: local_chain(vec![(0, headers[0]), (3, headers[3]), (4, headers[4])]),
438+
},
439+
// Test case 3: start with headers at heights 0 and 4. Insert header at height 3.
440+
TestCase {
441+
original: local_chain(vec![(0, headers[0]), (4, headers[4])]),
442+
insert: (3, headers[3]),
443+
expected_result: Ok([(3, Some(headers[3]))].into()),
444+
expected_final: local_chain(vec![(0, headers[0]), (3, headers[3]), (4, headers[4])]),
445+
},
446+
// Test case 4: start with headers at heights 0 and 2. Insert the same header at height 2.
447+
TestCase {
448+
original: local_chain(vec![(0, headers[0]), (2, headers[2])]),
449+
insert: (2, headers[2]),
450+
expected_result: Ok([].into()),
451+
expected_final: local_chain(vec![(0, headers[0]), (2, headers[2])]),
452+
},
453+
// Test case 5: start with headers at heights 0 and 2. Insert conflicting header at height 2.
454+
TestCase {
455+
original: local_chain(vec![(0, headers[0]), (2, headers[2])]),
456+
insert: (2, header(hash!("conflict"))),
457+
expected_result: Err(AlterCheckPointError {
458+
height: 2,
459+
original_hash: headers[2].block_hash(),
460+
update_hash: Some(header(hash!("conflict")).block_hash()),
461+
}),
462+
expected_final: local_chain(vec![(0, headers[0]), (2, headers[2])]),
463+
},
464+
];
465+
466+
for (i, t) in test_cases.into_iter().enumerate() {
467+
let mut chain = t.original;
468+
assert_eq!(
469+
chain.insert_block(t.insert.0, t.insert.1),
470+
t.expected_result,
471+
"[{}] unexpected result when inserting block",
472+
i,
473+
);
474+
assert_eq!(chain, t.expected_final, "[{}] unexpected final chain", i,);
475+
}
476+
}
477+
382478
#[test]
383479
fn local_chain_disconnect_from() {
384480
struct TestCase {

0 commit comments

Comments
 (0)