+impl HTLCClaim {
+ /// Check if a given input witness attempts to claim a HTLC.
+ pub(crate) fn from_witness(witness: &Witness) -> Option<Self> {
+ debug_assert_eq!(OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS, MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT);
+ if witness.len() < 2 {
+ return None;
+ }
+ let witness_script = witness.last().unwrap();
+ let second_to_last = witness.second_to_last().unwrap();
+ if witness_script.len() == OFFERED_HTLC_SCRIPT_WEIGHT {
+ if witness.len() == 3 && second_to_last.len() == 33 {
+ // <revocation sig> <revocationpubkey> <witness_script>
+ Some(Self::Revocation)
+ } else if witness.len() == 3 && second_to_last.len() == 32 {
+ // <remotehtlcsig> <payment_preimage> <witness_script>
+ Some(Self::OfferedPreimage)
+ } else if witness.len() == 5 && second_to_last.len() == 0 {
+ // 0 <remotehtlcsig> <localhtlcsig> <> <witness_script>
+ Some(Self::OfferedTimeout)
+ } else {
+ None
+ }
+ } else if witness_script.len() == OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS {
+ // It's possible for the weight of `offered_htlc_script` and `accepted_htlc_script` to
+ // match so we check for both here.
+ if witness.len() == 3 && second_to_last.len() == 33 {
+ // <revocation sig> <revocationpubkey> <witness_script>
+ Some(Self::Revocation)
+ } else if witness.len() == 3 && second_to_last.len() == 32 {
+ // <remotehtlcsig> <payment_preimage> <witness_script>
+ Some(Self::OfferedPreimage)
+ } else if witness.len() == 5 && second_to_last.len() == 0 {
+ // 0 <remotehtlcsig> <localhtlcsig> <> <witness_script>
+ Some(Self::OfferedTimeout)
+ } else if witness.len() == 3 && second_to_last.len() == 0 {
+ // <remotehtlcsig> <> <witness_script>
+ Some(Self::AcceptedTimeout)
+ } else if witness.len() == 5 && second_to_last.len() == 32 {
+ // 0 <remotehtlcsig> <localhtlcsig> <payment_preimage> <witness_script>
+ Some(Self::AcceptedPreimage)
+ } else {
+ None
+ }
+ } else if witness_script.len() > MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT &&
+ witness_script.len() <= MAX_ACCEPTED_HTLC_SCRIPT_WEIGHT {
+ // Handle remaining range of ACCEPTED_HTLC_SCRIPT_WEIGHT.
+ if witness.len() == 3 && second_to_last.len() == 33 {
+ // <revocation sig> <revocationpubkey> <witness_script>
+ Some(Self::Revocation)
+ } else if witness.len() == 3 && second_to_last.len() == 0 {
+ // <remotehtlcsig> <> <witness_script>
+ Some(Self::AcceptedTimeout)
+ } else if witness.len() == 5 && second_to_last.len() == 32 {
+ // 0 <remotehtlcsig> <localhtlcsig> <payment_preimage> <witness_script>
+ Some(Self::AcceptedPreimage)
+ } else {
+ None
+ }