Dry-runs a specific taproot input
(
tx: &Transaction,
input_index: usize,
prevouts: &[TxOut],
)
| 180 | |
| 181 | /// Dry-runs a specific taproot input |
| 182 | pub fn dry_run_taproot_input( |
| 183 | tx: &Transaction, |
| 184 | input_index: usize, |
| 185 | prevouts: &[TxOut], |
| 186 | ) -> ExecuteInfo { |
| 187 | let script = tx.input[input_index].witness.tapscript().unwrap(); |
| 188 | let stack = { |
| 189 | let witness_items = tx.input[input_index].witness.to_vec(); |
| 190 | let last = witness_items.last().unwrap(); |
| 191 | |
| 192 | // From BIP341: |
| 193 | // If there are at least two witness elements, and the first byte of |
| 194 | // the last element is 0x50, this last element is called annex a |
| 195 | // and is removed from the witness stack. |
| 196 | let script_index = |
| 197 | if witness_items.len() >= 3 && last.first() == Some(&TAPROOT_ANNEX_PREFIX) { |
| 198 | witness_items.len() - 3 |
| 199 | } else { |
| 200 | witness_items.len() - 2 |
| 201 | }; |
| 202 | |
| 203 | witness_items[0..script_index].to_vec() |
| 204 | }; |
| 205 | |
| 206 | let leaf_hash = TapLeafHash::from_script( |
| 207 | Script::from_bytes(script.as_bytes()), |
| 208 | LeafVersion::TapScript, |
| 209 | ); |
| 210 | |
| 211 | let mut exec = Exec::new( |
| 212 | ExecCtx::Tapscript, |
| 213 | Options::default(), |
| 214 | TxTemplate { |
| 215 | tx: tx.clone(), |
| 216 | prevouts: prevouts.into(), |
| 217 | input_idx: input_index, |
| 218 | taproot_annex_scriptleaf: Some((leaf_hash, None)), |
| 219 | }, |
| 220 | ScriptBuf::from_bytes(script.to_bytes()), |
| 221 | stack, |
| 222 | ) |
| 223 | .expect("error creating exec"); |
| 224 | |
| 225 | loop { |
| 226 | if exec.exec_next().is_err() { |
| 227 | break; |
| 228 | } |
| 229 | } |
| 230 | let res = exec.result().unwrap(); |
| 231 | let info = ExecuteInfo { |
| 232 | success: res.success, |
| 233 | error: res.error.clone(), |
| 234 | last_opcode: res.opcode, |
| 235 | final_stack: FmtStack(exec.stack().clone()), |
| 236 | remaining_script: exec.remaining_script().to_asm_string(), |
| 237 | stats: exec.stats().clone(), |
| 238 | }; |
| 239 |
no test coverage detected