diff --git a/crates/subprotocols/bridge-v1/subprotocol/src/state/bridge.rs b/crates/subprotocols/bridge-v1/subprotocol/src/state/bridge.rs index 5f569c5..319a7b7 100644 --- a/crates/subprotocols/bridge-v1/subprotocol/src/state/bridge.rs +++ b/crates/subprotocols/bridge-v1/subprotocol/src/state/bridge.rs @@ -1,5 +1,6 @@ use bitcoin_bosd::Descriptor; use ssz_derive::{Decode, Encode}; +use strata_asm_common::logging::info; use strata_asm_params::BridgeV1InitConfig; use strata_asm_proto_bridge_v1_txs::{deposit::DepositInfo, errors::Mismatch}; use strata_asm_proto_bridge_v1_types::{ @@ -187,15 +188,36 @@ impl BridgeV1State { } let selected_operator = withdrawal_output.selected_operator(); + let selected_operator_raw = selected_operator.raw(); + let deposit_idx = deposit.idx(); + let amount_sat = deposit.amt().to_sat(); let withdrawal_cmd = WithdrawalCommand::new(withdrawal_output.clone(), self.operator_fee); - self.assignments.add_new_assignment( + let result = self.assignments.add_new_assignment( deposit, withdrawal_cmd, self.operators.current_multisig(), l1_block, selected_operator, - ) + ); + + if result.is_ok() { + let assignment = self + .assignments + .get_assignment(deposit_idx) + .expect("assignment must exist after successful insertion"); + info!( + deposit_idx, + assignee = assignment.current_assignee(), + amount_sat, + fulfillment_deadline = assignment.fulfillment_deadline(), + selected_operator_raw, + selected_operator = %selected_operator, + "Created withdrawal assignment", + ); + } + + result } /// Decomposes a batch withdrawal into N individual assignments. @@ -258,8 +280,23 @@ impl BridgeV1State { &mut self, current_block: &L1BlockCommitment, ) -> Result, WithdrawalCommandError> { - self.assignments - .reassign_expired_assignments(self.operators.current_multisig(), current_block) + let reassigned_deposits = self + .assignments + .reassign_expired_assignments(self.operators.current_multisig(), current_block)?; + + for deposit_idx in &reassigned_deposits { + if let Some(assignment) = self.assignments.get_assignment(*deposit_idx) { + info!( + deposit_idx, + assignee = assignment.current_assignee(), + fulfillment_deadline = assignment.fulfillment_deadline(), + l1_height = current_block.height(), + "Reassigned expired withdrawal assignment", + ); + } + } + + Ok(reassigned_deposits) } /// Removes an assignment by its deposit index. diff --git a/crates/subprotocols/bridge-v1/types/src/operator.rs b/crates/subprotocols/bridge-v1/types/src/operator.rs index c015850..99cfc46 100644 --- a/crates/subprotocols/bridge-v1/types/src/operator.rs +++ b/crates/subprotocols/bridge-v1/types/src/operator.rs @@ -1,3 +1,5 @@ +use std::fmt::{self, Display, Formatter}; + use arbitrary::Arbitrary; use bitvec::prelude::*; use borsh::{BorshDeserialize, BorshSerialize}; @@ -70,6 +72,15 @@ impl OperatorSelection { } } +impl Display for OperatorSelection { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self.as_specific() { + Some(idx) => write!(f, "specific({idx})"), + None => f.write_str("any"), + } + } +} + /// Error type for OperatorBitmap operations. #[derive(Debug, Error, PartialEq)] pub enum OperatorBitmapError { @@ -365,6 +376,12 @@ mod tests { use super::*; + #[test] + fn test_operator_selection_display() { + assert_eq!(OperatorSelection::any().to_string(), "any"); + assert_eq!(OperatorSelection::specific(42).to_string(), "specific(42)"); + } + #[test] fn test_operator_bitmap_new_empty() { let bitmap = OperatorBitmap::new_empty();