Skip to content

Commit 9c14492

Browse files
committed
refactor(testenv): update tx_template to use Cow
-update TxTemplate struct to use Cow pointer - add utility methods to TxTemplate
1 parent f62470c commit 9c14492

1 file changed

Lines changed: 79 additions & 15 deletions

File tree

crates/testenv/src/tx_template.rs

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,29 @@ use bitcoin::{
1010
Sequence, Transaction, TxIn, TxOut, Txid, Witness,
1111
};
1212
use rand::distributions::{Alphanumeric, DistString};
13-
use std::collections::HashMap;
13+
use std::{borrow::Cow, collections::HashMap};
1414

1515
/// Template for creating a transaction in a [`TxGraph`].
1616
///
1717
/// This is the main building block for constructing complex transaction histories
1818
/// for tests. It allows you to refer to previous transactions by name instead of
1919
/// manually managing txids and outpoints.
20-
#[derive(Clone, Copy, Default)]
21-
pub struct TxTemplate<'a, A> {
20+
#[derive(Clone)]
21+
pub struct TxTemplate<A>
22+
where
23+
A: Clone + 'static,
24+
{
2225
/// A unique name used to refer to this transaction in other templates.
23-
pub tx_name: &'a str,
26+
pub tx_name: Cow<'static, str>,
2427

2528
/// The inputs of this transaction.
26-
pub inputs: &'a [TxInTemplate<'a>],
29+
pub inputs: Cow<'static, [TxInTemplate]>,
2730

2831
/// The outputs of this transaction.
29-
pub outputs: &'a [TxOutTemplate],
32+
pub outputs: Cow<'static, [TxOutTemplate]>,
3033

3134
/// Anchors (confirmations) for this transaction.
32-
pub anchors: &'a [A],
35+
pub anchors: Cow<'static, [A]>,
3336

3437
/// Unix timestamp when this transaction was last seen in the mempool.
3538
pub last_seen: Option<u64>,
@@ -39,9 +42,69 @@ pub struct TxTemplate<'a, A> {
3942
pub assume_canonical: bool,
4043
}
4144

45+
impl<A> Default for TxTemplate<A>
46+
where
47+
A: Clone + 'static,
48+
{
49+
fn default() -> Self {
50+
Self {
51+
tx_name: Cow::Borrowed(""),
52+
inputs: Cow::Borrowed(&[]),
53+
outputs: Cow::Borrowed(&[]),
54+
anchors: Cow::Borrowed(&[]),
55+
last_seen: None,
56+
assume_canonical: false,
57+
}
58+
}
59+
}
60+
61+
impl<A> TxTemplate<A>
62+
where
63+
A: Clone + 'static,
64+
{
65+
/// Create a new template with a name.
66+
pub fn new(name: impl Into<Cow<'static, str>>) -> Self {
67+
Self {
68+
tx_name: name.into(),
69+
..Default::default()
70+
}
71+
}
72+
73+
//// Set inputs. Accepts `&[TxInTemplate]`, `Vec<TxInTemplate>`, or a static slice.
74+
pub fn with_inputs(mut self, inputs: impl Into<Cow<'static, [TxInTemplate]>>) -> Self {
75+
self.inputs = inputs.into();
76+
self
77+
}
78+
79+
/// Set outputs with `Vec<TxOutTemplate>` or `&'static [TxOutTemplate]`.
80+
pub fn with_outputs(mut self, outputs: impl Into<Cow<'static, [TxOutTemplate]>>) -> Self {
81+
self.outputs = outputs.into();
82+
self
83+
}
84+
85+
/// Set anchors. Supports `Vec<A>` or `&'static [A]`.
86+
pub fn with_anchors(mut self, anchors: impl Into<Cow<'static, [A]>>) -> Self {
87+
self.anchors = anchors.into();
88+
self
89+
}
90+
91+
/// Mark this transaction as canonical.
92+
pub fn with_assume_canonical(mut self, assume: bool) -> Self {
93+
self.assume_canonical = assume;
94+
self
95+
}
96+
97+
/// Set the last-seen mempool timestamp.
98+
pub fn with_last_seen(mut self, last_seen: Option<u64>) -> Self {
99+
self.last_seen = last_seen;
100+
self
101+
}
102+
}
103+
42104
/// Describes how an input is created in a [`TxTemplate`].
105+
#[derive(Clone, Debug)]
43106
#[allow(dead_code)]
44-
pub enum TxInTemplate<'a> {
107+
pub enum TxInTemplate {
45108
/// A random (bogus) previous output. Useful when the actual prevout doesn't matter.
46109
Bogus,
47110

@@ -52,10 +115,11 @@ pub enum TxInTemplate<'a> {
52115
///
53116
/// The rule is that the referenced transaction (`prev_name`) must appear
54117
/// earlier in the list passed to [`init_graph`].
55-
PrevTx(&'a str, usize),
118+
PrevTx(Cow<'static, str>, usize),
56119
}
57120

58121
/// Describes an output in a [`TxTemplate`].
122+
#[derive(Clone, Debug)]
59123
pub struct TxOutTemplate {
60124
/// Value in satoshis.
61125
pub value: u64,
@@ -75,10 +139,10 @@ impl TxOutTemplate {
75139
/// Contains the built [`TxGraph`], the associated indexer, and a mapping from
76140
/// template names to their final txids.
77141
#[allow(dead_code)]
78-
pub struct TxTemplateEnv<'a, A> {
142+
pub struct TxTemplateEnv<A> {
79143
pub tx_graph: TxGraph<A>,
80144
pub indexer: SpkTxOutIndex<u32>,
81-
pub txid_to_name: HashMap<&'a str, Txid>,
145+
pub txid_to_name: HashMap<Cow<'static, str>, Txid>,
82146
pub canonicalization_params: CanonicalizationParams,
83147
}
84148

@@ -87,9 +151,9 @@ pub struct TxTemplateEnv<'a, A> {
87151
/// This is the main entry point for using transaction templates in tests.
88152
/// It handles txid generation, outpoint wiring, anchor insertion, and last-seen
89153
/// timestamps automatically.
90-
pub fn init_graph<'a, A: Anchor + Clone + 'a>(
91-
tx_templates: impl IntoIterator<Item = &'a TxTemplate<'a, A>>,
92-
) -> TxTemplateEnv<'a, A> {
154+
pub fn init_graph<A: Anchor + Clone + 'static>(
155+
tx_templates: impl IntoIterator<Item = TxTemplate<A>>,
156+
) -> TxTemplateEnv<A> {
93157
let (descriptor, _) =
94158
Descriptor::parse_descriptor(&Secp256k1::signing_only(), DESCRIPTORS[2]).unwrap();
95159

@@ -107,7 +171,7 @@ pub fn init_graph<'a, A: Anchor + Clone + 'a>(
107171
);
108172
});
109173

110-
let mut txid_to_name = HashMap::<&'a str, Txid>::new();
174+
let mut txid_to_name = HashMap::<Cow<'static, str>, Txid>::new();
111175
let mut canonicalization_params = CanonicalizationParams::default();
112176

113177
for (bogus_txin_vout, tx_tmp) in tx_templates.into_iter().enumerate() {

0 commit comments

Comments
 (0)