1use crate::merkle::cmr::Cmr;
4use elements::confidential;
5use elements::taproot::ControlBlock;
6use simplicity_sys::c_jets::c_env::elements as c_elements;
7use std::ops::Deref;
8
9use super::c_env;
10
11#[derive(Debug, Clone, Eq, PartialEq)]
15pub struct ElementsUtxo {
16 pub script_pubkey: elements::Script,
18 pub asset: confidential::Asset,
20 pub value: confidential::Value,
22}
23
24impl From<elements::TxOut> for ElementsUtxo {
25 fn from(txout: elements::TxOut) -> Self {
26 ElementsUtxo {
27 script_pubkey: txout.script_pubkey,
28 asset: txout.asset,
29 value: txout.value,
30 }
31 }
32}
33
34#[derive(Debug)]
40pub struct ElementsEnv<T: Deref<Target = elements::Transaction>> {
41 c_tx_env: c_elements::CTxEnv,
43 tx: T,
45 ix: u32,
47 control_block: ControlBlock,
49 annex: Option<Vec<u8>>,
51 genesis_hash: elements::BlockHash,
53}
54
55impl<T> ElementsEnv<T>
56where
57 T: Deref<Target = elements::Transaction>,
58{
59 pub fn new(
60 tx: T,
61 utxos: Vec<ElementsUtxo>,
62 ix: u32,
63 script_cmr: Cmr,
64 control_block: ControlBlock,
65 annex: Option<Vec<u8>>,
66 genesis_hash: elements::BlockHash,
67 ) -> Self {
68 let c_tx = c_env::new_tx(&tx, &utxos);
69 let c_tap_env = c_env::new_tap_env(&control_block, script_cmr);
70 let c_tx_env = c_env::new_tx_env(c_tx, c_tap_env, genesis_hash, ix);
71 ElementsEnv {
72 c_tx_env,
73 tx,
74 ix,
75 control_block,
76 annex,
77 genesis_hash,
78 }
79 }
80
81 pub fn c_tx_env(&self) -> &c_elements::CTxEnv {
83 &self.c_tx_env
84 }
85
86 pub fn tx(&self) -> &elements::Transaction {
88 &self.tx
89 }
90
91 pub fn ix(&self) -> u32 {
93 self.ix
94 }
95
96 pub fn control_block(&self) -> &ControlBlock {
98 &self.control_block
99 }
100
101 pub fn annex(&self) -> Option<&Vec<u8>> {
103 self.annex.as_ref()
104 }
105
106 pub fn genesis_hash(&self) -> elements::BlockHash {
108 self.genesis_hash
109 }
110}
111
112#[cfg(test)]
113impl ElementsEnv<std::sync::Arc<elements::Transaction>> {
114 pub fn dummy() -> Self {
116 Self::dummy_with(elements::LockTime::ZERO, elements::Sequence::MAX)
117 }
118
119 pub fn dummy_with(lock_time: elements::LockTime, sequence: elements::Sequence) -> Self {
121 use elements::AssetIssuance;
122 use hashes::Hash;
123
124 let ctrl_blk: [u8; 33] = [
125 0xc0, 0xeb, 0x04, 0xb6, 0x8e, 0x9a, 0x26, 0xd1, 0x16, 0x04, 0x6c, 0x76, 0xe8, 0xff,
126 0x47, 0x33, 0x2f, 0xb7, 0x1d, 0xda, 0x90, 0xff, 0x4b, 0xef, 0x53, 0x70, 0xf2, 0x52,
127 0x26, 0xd3, 0xbc, 0x09, 0xfc,
128 ];
129
130 ElementsEnv::new(
131 std::sync::Arc::new(elements::Transaction {
132 version: 2,
133 lock_time,
134 input: vec![elements::TxIn {
136 previous_output: elements::OutPoint::default(),
137 is_pegin: false,
138 script_sig: elements::Script::new(),
139 sequence,
140 asset_issuance: AssetIssuance::default(),
141 witness: elements::TxInWitness::default(),
142 }],
143 output: Vec::default(),
144 }),
145 vec![ElementsUtxo {
146 script_pubkey: elements::Script::new(),
147 asset: confidential::Asset::Null,
148 value: confidential::Value::Null,
149 }],
150 0,
151 Cmr::from_byte_array([0; 32]),
152 ControlBlock::from_slice(&ctrl_blk).unwrap(),
153 None,
154 elements::BlockHash::all_zeros(),
155 )
156 }
157}