Skip to content

Commit 0a39fa7

Browse files
committed
test(chain): Add test for inserting Header into LocalChain
1 parent 4b52510 commit 0a39fa7

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::{
@@ -378,6 +379,101 @@ fn local_chain_insert_block() {
378379
}
379380
}
380381

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

0 commit comments

Comments
 (0)