test(indexed_tx_graph): Add test_get_chain_position
This commit is contained in:
parent
36f58870cb
commit
2ce4bb4dfc
@ -520,3 +520,147 @@ fn test_list_owned_txouts() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Given a `LocalChain`, `IndexedTxGraph`, and a `Transaction`, when we insert some anchor
|
||||||
|
/// (possibly non-canonical) and/or a last-seen timestamp into the graph, we expect the
|
||||||
|
/// result of `get_chain_position` in these cases:
|
||||||
|
///
|
||||||
|
/// - tx with no anchors or last_seen has no `ChainPosition`
|
||||||
|
/// - tx with any last_seen will be `Unconfirmed`
|
||||||
|
/// - tx with an anchor in best chain will be `Confirmed`
|
||||||
|
/// - tx with an anchor not in best chain (no last_seen) has no `ChainPosition`
|
||||||
|
#[test]
|
||||||
|
fn test_get_chain_position() {
|
||||||
|
use bdk_chain::local_chain::CheckPoint;
|
||||||
|
use bdk_chain::BlockId;
|
||||||
|
use bdk_chain::SpkTxOutIndex;
|
||||||
|
|
||||||
|
struct TestCase<A> {
|
||||||
|
name: &'static str,
|
||||||
|
tx: Transaction,
|
||||||
|
anchor: Option<A>,
|
||||||
|
last_seen: Option<u64>,
|
||||||
|
exp_pos: Option<ChainPosition<A>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// addr: bcrt1qc6fweuf4xjvz4x3gx3t9e0fh4hvqyu2qw4wvxm
|
||||||
|
let spk = ScriptBuf::from_hex("0014c692ecf13534982a9a2834565cbd37add8027140").unwrap();
|
||||||
|
let mut graph = IndexedTxGraph::new({
|
||||||
|
let mut index = SpkTxOutIndex::default();
|
||||||
|
let _ = index.insert_spk(0u32, spk.clone());
|
||||||
|
index
|
||||||
|
});
|
||||||
|
|
||||||
|
// Anchors to test
|
||||||
|
let blocks = vec![block_id!(0, "g"), block_id!(1, "A"), block_id!(2, "B")];
|
||||||
|
|
||||||
|
let cp = CheckPoint::from_block_ids(blocks.clone()).unwrap();
|
||||||
|
let chain = LocalChain::from_tip(cp).unwrap();
|
||||||
|
|
||||||
|
// The test will insert a transaction into the indexed tx graph
|
||||||
|
// along with any anchors and timestamps, then check the value
|
||||||
|
// returned by `get_chain_position`.
|
||||||
|
fn run(
|
||||||
|
chain: &LocalChain,
|
||||||
|
graph: &mut IndexedTxGraph<BlockId, SpkTxOutIndex<u32>>,
|
||||||
|
test: TestCase<BlockId>,
|
||||||
|
) {
|
||||||
|
let TestCase {
|
||||||
|
name,
|
||||||
|
tx,
|
||||||
|
anchor,
|
||||||
|
last_seen,
|
||||||
|
exp_pos,
|
||||||
|
} = test;
|
||||||
|
|
||||||
|
// add data to graph
|
||||||
|
let txid = tx.compute_txid();
|
||||||
|
let _ = graph.insert_tx(tx);
|
||||||
|
if let Some(anchor) = anchor {
|
||||||
|
let _ = graph.insert_anchor(txid, anchor);
|
||||||
|
}
|
||||||
|
if let Some(seen_at) = last_seen {
|
||||||
|
let _ = graph.insert_seen_at(txid, seen_at);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check chain position
|
||||||
|
let res = graph
|
||||||
|
.graph()
|
||||||
|
.get_chain_position(chain, chain.tip().block_id(), txid);
|
||||||
|
assert_eq!(
|
||||||
|
res.map(ChainPosition::cloned),
|
||||||
|
exp_pos,
|
||||||
|
"failed test case: {name}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[
|
||||||
|
TestCase {
|
||||||
|
name: "tx no anchors or last_seen - no chain pos",
|
||||||
|
tx: Transaction {
|
||||||
|
output: vec![TxOut {
|
||||||
|
value: Amount::ONE_BTC,
|
||||||
|
script_pubkey: spk.clone(),
|
||||||
|
}],
|
||||||
|
..common::new_tx(0)
|
||||||
|
},
|
||||||
|
anchor: None,
|
||||||
|
last_seen: None,
|
||||||
|
exp_pos: None,
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
name: "tx last_seen - unconfirmed",
|
||||||
|
tx: Transaction {
|
||||||
|
output: vec![TxOut {
|
||||||
|
value: Amount::ONE_BTC,
|
||||||
|
script_pubkey: spk.clone(),
|
||||||
|
}],
|
||||||
|
..common::new_tx(1)
|
||||||
|
},
|
||||||
|
anchor: None,
|
||||||
|
last_seen: Some(2),
|
||||||
|
exp_pos: Some(ChainPosition::Unconfirmed(2)),
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
name: "tx anchor in best chain - confirmed",
|
||||||
|
tx: Transaction {
|
||||||
|
output: vec![TxOut {
|
||||||
|
value: Amount::ONE_BTC,
|
||||||
|
script_pubkey: spk.clone(),
|
||||||
|
}],
|
||||||
|
..common::new_tx(2)
|
||||||
|
},
|
||||||
|
anchor: Some(blocks[1]),
|
||||||
|
last_seen: None,
|
||||||
|
exp_pos: Some(ChainPosition::Confirmed(blocks[1])),
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
name: "tx unknown anchor with last_seen - unconfirmed",
|
||||||
|
tx: Transaction {
|
||||||
|
output: vec![TxOut {
|
||||||
|
value: Amount::ONE_BTC,
|
||||||
|
script_pubkey: spk.clone(),
|
||||||
|
}],
|
||||||
|
..common::new_tx(3)
|
||||||
|
},
|
||||||
|
anchor: Some(block_id!(2, "B'")),
|
||||||
|
last_seen: Some(2),
|
||||||
|
exp_pos: Some(ChainPosition::Unconfirmed(2)),
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
name: "tx unknown anchor - no chain pos",
|
||||||
|
tx: Transaction {
|
||||||
|
output: vec![TxOut {
|
||||||
|
value: Amount::ONE_BTC,
|
||||||
|
script_pubkey: spk.clone(),
|
||||||
|
}],
|
||||||
|
..common::new_tx(4)
|
||||||
|
},
|
||||||
|
anchor: Some(block_id!(2, "B'")),
|
||||||
|
last_seen: None,
|
||||||
|
exp_pos: None,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|t| run(&chain, &mut graph, t));
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user