@@ -230,16 +230,22 @@ fn complexity_score(tx: &Transaction, signals: &ScriptSignals) -> u32 {
230230mod tests {
231231 use super :: * ;
232232
233+ const SAMPLE_TX_HEX : & str = "02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff02e80300000000000016001400000000000000000000000000000000000000006400000000000000160014111111111111111111111111111111111111111100000000" ;
234+
235+ fn sample_tx ( ) -> Transaction {
236+ deserialize ( & hex:: decode ( SAMPLE_TX_HEX ) . unwrap ( ) ) . unwrap ( )
237+ }
238+
233239 #[ test]
234240 fn estimates_fee_when_prevouts_are_present ( ) {
235241 let input = TransactionInputFile {
236- hex : "02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff02e80300000000000016001400000000000000000000000000000000000000006400000000000000160014111111111111111111111111111111111111111100000000" . to_owned ( ) ,
242+ hex : SAMPLE_TX_HEX . to_owned ( ) ,
237243 prevouts : vec ! [ PrevoutInput {
238244 value_sats: 2_000 ,
239245 script_pubkey: None ,
240246 } ] ,
241247 } ;
242- let tx = deserialize :: < Transaction > ( & hex :: decode ( input . hex ) . unwrap ( ) ) . unwrap ( ) ;
248+ let tx = sample_tx ( ) ;
243249
244250 let report = analyze_transaction ( & tx, & input. prevouts , None ) ;
245251
@@ -249,15 +255,54 @@ mod tests {
249255
250256 #[ test]
251257 fn direct_hex_reports_fee_unavailable_without_prevouts ( ) {
252- let report = analyze_transaction_hex (
253- "02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff02e80300000000000016001400000000000000000000000000000000000000006400000000000000160014111111111111111111111111111111111111111100000000" ,
254- )
255- . unwrap ( ) ;
258+ let report = analyze_transaction_hex ( SAMPLE_TX_HEX ) . unwrap ( ) ;
256259
257260 let tx = report. transaction . unwrap ( ) ;
258261 assert_eq ! ( tx. estimated_fee_sats, None ) ;
259262 assert ! ( report
260263 . missing_data
261264 . contains( & "prevout values for every input" . to_owned( ) ) ) ;
262265 }
266+
267+ #[ test]
268+ fn warns_when_prevouts_imply_negative_fee ( ) {
269+ let tx = sample_tx ( ) ;
270+ let prevouts = vec ! [ PrevoutInput {
271+ value_sats: 1_000 ,
272+ script_pubkey: None ,
273+ } ] ;
274+
275+ let report = analyze_transaction ( & tx, & prevouts, None ) ;
276+
277+ assert_eq ! ( report. transaction. unwrap( ) . estimated_fee_sats, Some ( -100 ) ) ;
278+ assert_eq ! ( report. risk, RiskLevel :: High ) ;
279+ assert ! ( report
280+ . warnings
281+ . iter( )
282+ . any( |warning| warning. code == "negative-fee" ) ) ;
283+ }
284+
285+ #[ test]
286+ fn detects_multisig_and_timelock_from_prevout_script_pubkeys ( ) {
287+ let tx = sample_tx ( ) ;
288+ let prevouts = vec ! [ PrevoutInput {
289+ value_sats: 2_000 ,
290+ script_pubkey: Some ( "52aeb2" . to_owned( ) ) ,
291+ } ] ;
292+
293+ let report = analyze_transaction ( & tx, & prevouts, None ) ;
294+ let analysis = report. transaction . unwrap ( ) ;
295+
296+ assert ! ( analysis. signals. multisig) ;
297+ assert ! ( analysis. signals. relative_timelock) ;
298+ assert_eq ! ( report. risk, RiskLevel :: Medium ) ;
299+ assert ! ( report
300+ . warnings
301+ . iter( )
302+ . any( |warning| warning. code == "multisig-signal" ) ) ;
303+ assert ! ( report
304+ . warnings
305+ . iter( )
306+ . any( |warning| warning. code == "timelock-signal" ) ) ;
307+ }
263308}
0 commit comments