| 196 | } |
| 197 | |
| 198 | pub(crate) fn partial_scripts_from_segments(segments: &[Segment]) -> Vec<ScriptBuf> { |
| 199 | fn serialize_element_types(elems: &[ElementType]) -> String { |
| 200 | // 1. Convert each variant to its string representation. |
| 201 | let joined = elems |
| 202 | .iter() |
| 203 | .map(|elem| format!("{:?}", elem)) // uses #[derive(Debug)] |
| 204 | .collect::<Vec<String>>() |
| 205 | .join("_"); |
| 206 | |
| 207 | // 2. Compute a simple 64-bit hash of that string |
| 208 | let mut hasher = DefaultHasher::new(); |
| 209 | joined.hash(&mut hasher); |
| 210 | let unique_hash = hasher.finish(); |
| 211 | |
| 212 | // 3. Concatenate final result as "ENUM1-ENUM2-ENUM3|hash" |
| 213 | format!("{}|{}", joined, unique_hash) |
| 214 | } |
| 215 | |
| 216 | let mut op_scripts: Vec<ScriptBuf> = vec![]; |
| 217 | |
| 218 | // cache hashing script as it is repititive |
| 219 | let mut hashing_script_cache: HashMap<String, Script> = HashMap::new(); |
| 220 | for s in segments { |
| 221 | if s.scr_type.is_final_script() || s.scr_type == ScriptType::NonDeterministic { |
| 222 | continue; |
| 223 | } |
| 224 | let mut elem_types_to_hash: Vec<ElementType> = |
| 225 | s.parameter_ids.iter().rev().map(|f| f.1).collect(); |
| 226 | elem_types_to_hash.push(s.result.1); |
| 227 | let elem_types_str_as_key = serialize_element_types(&elem_types_to_hash); |
| 228 | hashing_script_cache |
| 229 | .entry(elem_types_str_as_key) |
| 230 | .or_insert_with(|| { |
| 231 | let hash_scr = script! { |
| 232 | {hash_messages(elem_types_to_hash)} |
| 233 | OP_TRUE |
| 234 | }; |
| 235 | hash_scr |
| 236 | }); |
| 237 | } |
| 238 | |
| 239 | for seg in segments { |
| 240 | let scr_type = seg.scr_type.clone(); |
| 241 | if scr_type == ScriptType::NonDeterministic { |
| 242 | continue; |
| 243 | } |
| 244 | |
| 245 | let op_scr = seg.scr.clone(); |
| 246 | |
| 247 | if seg.scr_type.is_final_script() { |
| 248 | // validating segments do not have output hash, so don't add hashing layer; they are self sufficient |
| 249 | op_scripts.push(op_scr); |
| 250 | } else { |
| 251 | // fetch hashing script from cache for these element types |
| 252 | let mut elem_types_to_hash: Vec<ElementType> = seg |
| 253 | .parameter_ids |
| 254 | .iter() |
| 255 | .rev() |