use crate::merkle::cmr::Cmr;
use elements::confidential;
use elements::taproot::ControlBlock;
use simplicity_sys::c_jets::c_env::CElementsTxEnv;
use std::ops::Deref;
use super::c_env;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ElementsUtxo {
pub script_pubkey: elements::Script,
pub asset: confidential::Asset,
pub value: confidential::Value,
}
impl From<elements::TxOut> for ElementsUtxo {
fn from(txout: elements::TxOut) -> Self {
ElementsUtxo {
script_pubkey: txout.script_pubkey,
asset: txout.asset,
value: txout.value,
}
}
}
#[derive(Debug)]
pub struct ElementsEnv<T: Deref<Target = elements::Transaction>> {
c_tx_env: CElementsTxEnv,
tx: T,
ix: u32,
control_block: ControlBlock,
annex: Option<Vec<u8>>,
genesis_hash: elements::BlockHash,
}
impl<T> ElementsEnv<T>
where
T: Deref<Target = elements::Transaction>,
{
pub fn new(
tx: T,
utxos: Vec<ElementsUtxo>,
ix: u32,
script_cmr: Cmr,
control_block: ControlBlock,
annex: Option<Vec<u8>>,
genesis_hash: elements::BlockHash,
) -> Self {
let c_tx = c_env::new_tx(&tx, &utxos);
let c_tap_env = c_env::new_tap_env(&control_block, script_cmr);
let c_tx_env = c_env::new_tx_env(c_tx, c_tap_env, genesis_hash, ix);
ElementsEnv {
c_tx_env,
tx,
ix,
control_block,
annex,
genesis_hash,
}
}
pub fn c_tx_env(&self) -> &CElementsTxEnv {
&self.c_tx_env
}
pub fn tx(&self) -> &elements::Transaction {
&self.tx
}
pub fn ix(&self) -> u32 {
self.ix
}
pub fn control_block(&self) -> &ControlBlock {
&self.control_block
}
pub fn annex(&self) -> Option<&Vec<u8>> {
self.annex.as_ref()
}
pub fn genesis_hash(&self) -> elements::BlockHash {
self.genesis_hash
}
}
#[cfg(test)]
impl ElementsEnv<std::sync::Arc<elements::Transaction>> {
pub fn dummy() -> Self {
Self::dummy_with(elements::LockTime::ZERO, elements::Sequence::MAX)
}
pub fn dummy_with(lock_time: elements::LockTime, sequence: elements::Sequence) -> Self {
use elements::AssetIssuance;
use hashes::Hash;
let ctrl_blk: [u8; 33] = [
0xc0, 0xeb, 0x04, 0xb6, 0x8e, 0x9a, 0x26, 0xd1, 0x16, 0x04, 0x6c, 0x76, 0xe8, 0xff,
0x47, 0x33, 0x2f, 0xb7, 0x1d, 0xda, 0x90, 0xff, 0x4b, 0xef, 0x53, 0x70, 0xf2, 0x52,
0x26, 0xd3, 0xbc, 0x09, 0xfc,
];
ElementsEnv::new(
std::sync::Arc::new(elements::Transaction {
version: 2,
lock_time,
input: vec![elements::TxIn {
previous_output: elements::OutPoint::default(),
is_pegin: false,
script_sig: elements::Script::new(),
sequence,
asset_issuance: AssetIssuance::default(),
witness: elements::TxInWitness::default(),
}],
output: Vec::default(),
}),
vec![ElementsUtxo {
script_pubkey: elements::Script::new(),
asset: confidential::Asset::Null,
value: confidential::Value::Null,
}],
0,
Cmr::from_byte_array([0; 32]),
ControlBlock::from_slice(&ctrl_blk).unwrap(),
None,
elements::BlockHash::all_zeros(),
)
}
}