From 1d96f68e0b940a5a4b9bde449b1774dffd382a1b Mon Sep 17 00:00:00 2001 From: NicolasCantu Date: Fri, 17 Jan 2025 18:08:18 +0100 Subject: [PATCH] Add check_tx_for_process_updates --- src/process.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/process.rs b/src/process.rs index a555792..a49bf51 100644 --- a/src/process.rs +++ b/src/process.rs @@ -5,7 +5,7 @@ use std::{ use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; -use sp_client::bitcoin::{hex::{DisplayHex, FromHex}, OutPoint}; +use sp_client::bitcoin::{hex::{DisplayHex, FromHex}, OutPoint, Transaction}; use tsify::Tsify; use crate::{ @@ -502,6 +502,49 @@ pub fn lock_processes() -> Result .lock_anyhow() } +pub fn check_tx_for_process_updates(tx: &Transaction) -> anyhow::Result { + let mut processes = lock_processes()?; + for (outpoint, process) in &mut *processes { + let process_tip = if let Ok(tip) = process.get_process_tip() { tip } else { continue }; + for input in &tx.input { + if process_tip == input.previous_output { + log::debug!("Find a match for process tip {}", process_tip); + // This transaction commits a new state + let last_output = &tx.output.get(tx.output.len()-1).unwrap().script_pubkey; + let state_id: String; + if last_output.is_op_return() { + if last_output.as_bytes().len() != 34 { + return Err(anyhow::Error::msg("commited data is not 32B long")); + } + state_id = last_output.as_bytes()[2..].to_lower_hex_string(); + } else { + return Err(anyhow::Error::msg("last output must be op_return")); + } + // Check if we know about the commited state + let new_state: ProcessState; + if let Ok(commited_state) = process.get_state_for_id(&state_id) { + new_state = commited_state.clone(); + } else { + new_state = ProcessState { + commited_in: process_tip, + state_id, + ..Default::default() + }; + } + + // We update the process in place + process.remove_all_concurrent_states()?; + process.insert_concurrent_state(new_state)?; + process.update_states_tip(OutPoint::new(tx.txid(), 0))?; + + return Ok(*outpoint) + } + } + } + + Err(anyhow::Error::msg("Transaction doesn't spend any known commitment")) +} + #[cfg(test)] mod tests { use std::str::FromStr;