@@ -42,6 +42,12 @@ use chain;
42
42
use util:: crypto:: sign;
43
43
44
44
pub ( crate ) const MAX_HTLCS : u16 = 483 ;
45
+ pub ( crate ) const OFFERED_HTLC_SCRIPT_WEIGHT : usize = 133 ;
46
+ pub ( crate ) const OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS : usize = 136 ;
47
+ // The weight of `accepted_htlc_script` can vary in function of its CLTV argument value. We define a
48
+ // range that encompasses both its non-anchors and anchors variants.
49
+ pub ( crate ) const MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT : usize = 136 ;
50
+ pub ( crate ) const MAX_ACCEPTED_HTLC_SCRIPT_WEIGHT : usize = 143 ;
45
51
46
52
/// Gets the weight for an HTLC-Success transaction.
47
53
#[ inline]
@@ -60,18 +66,72 @@ pub fn htlc_timeout_tx_weight(opt_anchors: bool) -> u64 {
60
66
}
61
67
62
68
#[ derive( PartialEq ) ]
63
- pub ( crate ) enum HTLCType {
64
- AcceptedHTLC ,
65
- OfferedHTLC
69
+ pub ( crate ) enum HTLCClaim {
70
+ OfferedTimeout ,
71
+ OfferedPreimage ,
72
+ AcceptedTimeout ,
73
+ AcceptedPreimage ,
74
+ Revocation ,
66
75
}
67
76
68
- impl HTLCType {
69
- /// Check if a given tx witnessScript len matchs one of a pre-signed HTLC
70
- pub ( crate ) fn scriptlen_to_htlctype ( witness_script_len : usize ) -> Option < HTLCType > {
71
- if witness_script_len == 133 {
72
- Some ( HTLCType :: OfferedHTLC )
73
- } else if witness_script_len >= 136 && witness_script_len <= 139 {
74
- Some ( HTLCType :: AcceptedHTLC )
77
+ impl HTLCClaim {
78
+ /// Check if a given input witness attempts to claim a HTLC.
79
+ pub ( crate ) fn from_witness ( witness : & Witness ) -> Option < Self > {
80
+ debug_assert_eq ! ( OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS , MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT ) ;
81
+ if witness. len ( ) < 2 {
82
+ return None ;
83
+ }
84
+ let witness_script = witness. last ( ) . unwrap ( ) ;
85
+ let second_to_last = witness. second_to_last ( ) . unwrap ( ) ;
86
+ if witness_script. len ( ) == OFFERED_HTLC_SCRIPT_WEIGHT {
87
+ if witness. len ( ) == 3 && second_to_last. len ( ) == 33 {
88
+ // <revocation sig> <revocationpubkey> <witness_script>
89
+ Some ( Self :: Revocation )
90
+ } else if witness. len ( ) == 3 && second_to_last. len ( ) == 32 {
91
+ // <remotehtlcsig> <payment_preimage> <witness_script>
92
+ Some ( Self :: OfferedPreimage )
93
+ } else if witness. len ( ) == 5 && second_to_last. len ( ) == 0 {
94
+ // 0 <remotehtlcsig> <localhtlcsig> <> <witness_script>
95
+ Some ( Self :: OfferedTimeout )
96
+ } else {
97
+ None
98
+ }
99
+ } else if witness_script. len ( ) == OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS {
100
+ // It's possible for the weight of `offered_htlc_script` and `accepted_htlc_script` to
101
+ // match so we check for both here.
102
+ if witness. len ( ) == 3 && second_to_last. len ( ) == 33 {
103
+ // <revocation sig> <revocationpubkey> <witness_script>
104
+ Some ( Self :: Revocation )
105
+ } else if witness. len ( ) == 3 && second_to_last. len ( ) == 32 {
106
+ // <remotehtlcsig> <payment_preimage> <witness_script>
107
+ Some ( Self :: OfferedPreimage )
108
+ } else if witness. len ( ) == 5 && second_to_last. len ( ) == 0 {
109
+ // 0 <remotehtlcsig> <localhtlcsig> <> <witness_script>
110
+ Some ( Self :: OfferedTimeout )
111
+ } else if witness. len ( ) == 3 && second_to_last. len ( ) == 0 {
112
+ // <remotehtlcsig> <> <witness_script>
113
+ Some ( Self :: AcceptedTimeout )
114
+ } else if witness. len ( ) == 5 && second_to_last. len ( ) == 32 {
115
+ // 0 <remotehtlcsig> <localhtlcsig> <payment_preimage> <witness_script>
116
+ Some ( Self :: AcceptedPreimage )
117
+ } else {
118
+ None
119
+ }
120
+ } else if witness_script. len ( ) > MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT &&
121
+ witness_script. len ( ) <= MAX_ACCEPTED_HTLC_SCRIPT_WEIGHT {
122
+ // Handle remaining range of ACCEPTED_HTLC_SCRIPT_WEIGHT.
123
+ if witness. len ( ) == 3 && second_to_last. len ( ) == 33 {
124
+ // <revocation sig> <revocationpubkey> <witness_script>
125
+ Some ( Self :: Revocation )
126
+ } else if witness. len ( ) == 3 && second_to_last. len ( ) == 0 {
127
+ // <remotehtlcsig> <> <witness_script>
128
+ Some ( Self :: AcceptedTimeout )
129
+ } else if witness. len ( ) == 5 && second_to_last. len ( ) == 32 {
130
+ // 0 <remotehtlcsig> <localhtlcsig> <payment_preimage> <witness_script>
131
+ Some ( Self :: AcceptedPreimage )
132
+ } else {
133
+ None
134
+ }
75
135
} else {
76
136
None
77
137
}
@@ -285,7 +345,7 @@ pub fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_com
285
345
286
346
/// Derives a per-commitment-transaction revocation key from its constituent parts.
287
347
///
288
- /// Only the cheating participant owns a valid witness to propagate a revoked
348
+ /// Only the cheating participant owns a valid witness to propagate a revoked
289
349
/// commitment transaction, thus per_commitment_secret always come from cheater
290
350
/// and revocation_base_secret always come from punisher, which is the broadcaster
291
351
/// of the transaction spending with this key knowledge.
@@ -320,7 +380,7 @@ pub fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1
320
380
/// the public equivalend of derive_private_revocation_key - using only public keys to derive a
321
381
/// public key instead of private keys.
322
382
///
323
- /// Only the cheating participant owns a valid witness to propagate a revoked
383
+ /// Only the cheating participant owns a valid witness to propagate a revoked
324
384
/// commitment transaction, thus per_commitment_point always come from cheater
325
385
/// and revocation_base_point always come from punisher, which is the broadcaster
326
386
/// of the transaction spending with this key knowledge.
0 commit comments