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
123 let ctrl_blk: [u8; 33] = [
124 0xc0, 0xeb, 0x04, 0xb6, 0x8e, 0x9a, 0x26, 0xd1, 0x16, 0x04, 0x6c, 0x76, 0xe8, 0xff,
125 0x47, 0x33, 0x2f, 0xb7, 0x1d, 0xda, 0x90, 0xff, 0x4b, 0xef, 0x53, 0x70, 0xf2, 0x52,
126 0x26, 0xd3, 0xbc, 0x09, 0xfc,
127 ];
128
129 ElementsEnv::new(
130 std::sync::Arc::new(elements::Transaction {
131 version: 2,
132 lock_time,
133 input: vec![elements::TxIn {
135 previous_output: elements::OutPoint::default(),
136 is_pegin: false,
137 script_sig: elements::Script::new(),
138 sequence,
139 asset_issuance: AssetIssuance::default(),
140 witness: elements::TxInWitness::default(),
141 }],
142 output: Vec::default(),
143 }),
144 vec![ElementsUtxo {
145 script_pubkey: elements::Script::new(),
146 asset: confidential::Asset::Null,
147 value: confidential::Value::Null,
148 }],
149 0,
150 Cmr::from_byte_array([0; 32]),
151 ControlBlock::from_slice(&ctrl_blk).unwrap(),
152 None,
153 elements::BlockHash::GENESIS_PREVIOUS_BLOCK_HASH,
154 )
155 }
156}