hal_simplicity/actions/simplicity/pset/
finalize.rs1use crate::hal_simplicity::Program;
5use crate::simplicity::jet;
6
7use super::{execution_environment, PsetError, UpdatedPset};
8
9#[derive(Debug, thiserror::Error)]
10pub enum PsetFinalizeError {
11 #[error(transparent)]
12 SharedError(#[from] PsetError),
13
14 #[error("invalid PSET: {0}")]
15 PsetDecode(elements::pset::ParseError),
16
17 #[error("invalid input index: {0}")]
18 InputIndexParse(std::num::ParseIntError),
19
20 #[error("invalid program: {0}")]
21 ProgramParse(simplicity::ParseError),
22
23 #[error("program does not have a redeem node")]
24 NoRedeemNode,
25
26 #[error("failed to prune program: {0}")]
27 ProgramPrune(simplicity::bit_machine::ExecutionError),
28}
29
30pub fn pset_finalize(
32 pset_b64: &str,
33 input_idx: &str,
34 program: &str,
35 witness: &str,
36 genesis_hash: Option<&str>,
37) -> Result<UpdatedPset, PsetFinalizeError> {
38 let mut pset: elements::pset::PartiallySignedTransaction =
40 pset_b64.parse().map_err(PsetFinalizeError::PsetDecode)?;
41 let input_idx: u32 = input_idx.parse().map_err(PsetFinalizeError::InputIndexParse)?;
42 let input_idx_usize = input_idx as usize; let program = Program::<jet::Elements>::from_str(program, Some(witness))
45 .map_err(PsetFinalizeError::ProgramParse)?;
46
47 let (tx_env, control_block, tap_leaf) =
49 execution_environment(&pset, input_idx_usize, program.cmr(), genesis_hash)?;
50 let cb_serialized = control_block.serialize();
51
52 let redeem_node = program.redeem_node().ok_or(PsetFinalizeError::NoRedeemNode)?;
54 let pruned = redeem_node.prune(&tx_env).map_err(PsetFinalizeError::ProgramPrune)?;
55
56 let (prog, witness) = pruned.to_vec_with_witness();
57 let input = &mut pset.inputs_mut()[input_idx_usize];
59 input.final_script_witness = Some(vec![witness, prog, tap_leaf.into_bytes(), cb_serialized]);
60
61 let updated_values = vec!["final_script_witness"];
62
63 Ok(UpdatedPset {
64 pset: pset.to_string(),
65 updated_values,
66 })
67}