@@ -35,10 +35,11 @@ use lightning::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr,
3535use lightning:: chain:: transaction:: OutPoint ;
3636use lightning:: chain:: chaininterface:: { BroadcasterInterface , ConfirmationTarget , FeeEstimator } ;
3737use lightning:: chain:: keysinterface:: { KeysInterface , InMemoryChannelKeys } ;
38- use lightning:: ln:: channelmanager:: { ChannelManager , PaymentHash , PaymentPreimage , PaymentSecret , ChannelManagerReadArgs } ;
38+ use lightning:: ln:: channelmanager:: { ChannelManager , PaymentHash , PaymentPreimage , PaymentSecret , PaymentSendFailure , ChannelManagerReadArgs } ;
3939use lightning:: ln:: features:: { ChannelFeatures , InitFeatures , NodeFeatures } ;
4040use lightning:: ln:: msgs:: { CommitmentUpdate , ChannelMessageHandler , ErrorAction , UpdateAddHTLC , Init } ;
4141use lightning:: util:: enforcing_trait_impls:: EnforcingChannelKeys ;
42+ use lightning:: util:: errors:: APIError ;
4243use lightning:: util:: events;
4344use lightning:: util:: logger:: Logger ;
4445use lightning:: util:: config:: UserConfig ;
@@ -185,6 +186,47 @@ impl KeysInterface for KeyProvider {
185186 }
186187}
187188
189+ #[ inline]
190+ fn check_api_err ( api_err : APIError ) {
191+ match api_err {
192+ APIError :: APIMisuseError { .. } => panic ! ( "We can't misuse the API" ) ,
193+ APIError :: FeeRateTooHigh { .. } => panic ! ( "We can't send too much fee?" ) ,
194+ APIError :: RouteError { .. } => panic ! ( "Our routes should work" ) ,
195+ APIError :: ChannelUnavailable { err } => {
196+ // Test the error against a list of errors we can hit, and reject
197+ // all others. If you hit this panic, the list of acceptable errors
198+ // is probably just stale and you should add new messages here.
199+ match err. as_str ( ) {
200+ "Peer for first hop currently disconnected/pending monitor update!" => { } ,
201+ _ if err. starts_with ( "Cannot push more than their max accepted HTLCs " ) => { } ,
202+ _ if err. starts_with ( "Cannot send value that would put us over the max HTLC value in flight our peer will accept " ) => { } ,
203+ _ if err. starts_with ( "Cannot send value that would put our balance under counterparty-announced channel reserve value" ) => { } ,
204+ _ if err. starts_with ( "Cannot send value that would overdraw remaining funds." ) => { } ,
205+ _ if err. starts_with ( "Cannot send value that would not leave enough to pay for fees." ) => { } ,
206+ _ => panic ! ( err) ,
207+ }
208+ } ,
209+ APIError :: MonitorUpdateFailed => {
210+ // We can (obviously) temp-fail a monitor update
211+ } ,
212+ }
213+ }
214+ #[ inline]
215+ fn check_payment_err ( send_err : PaymentSendFailure ) {
216+ match send_err {
217+ PaymentSendFailure :: ParameterError ( api_err) => check_api_err ( api_err) ,
218+ PaymentSendFailure :: PathParameterError ( per_path_results) => {
219+ for res in per_path_results { if let Err ( api_err) = res { check_api_err ( api_err) ; } }
220+ } ,
221+ PaymentSendFailure :: AllFailedRetrySafe ( per_path_results) => {
222+ for api_err in per_path_results { check_api_err ( api_err) ; }
223+ } ,
224+ PaymentSendFailure :: PartialFailure ( per_path_results) => {
225+ for res in per_path_results { if let Err ( api_err) = res { check_api_err ( api_err) ; } }
226+ } ,
227+ }
228+ }
229+
188230#[ inline]
189231pub fn do_test < Out : test_logger:: Output > ( data : & [ u8 ] , out : Out ) {
190232 let fee_est = Arc :: new ( FuzzEstimator { } ) ;
@@ -407,7 +449,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
407449 ( $source: expr, $dest: expr, $amt: expr) => { {
408450 let payment_hash = Sha256 :: hash( & [ payment_id; 1 ] ) ;
409451 payment_id = payment_id. wrapping_add( 1 ) ;
410- if let Err ( _ ) = $source. send_payment( & Route {
452+ if let Err ( err ) = $source. send_payment( & Route {
411453 paths: vec![ vec![ RouteHop {
412454 pubkey: $dest. 0 . get_our_node_id( ) ,
413455 node_features: NodeFeatures :: empty( ) ,
@@ -417,14 +459,13 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
417459 cltv_expiry_delta: 200 ,
418460 } ] ] ,
419461 } , PaymentHash ( payment_hash. into_inner( ) ) , & None ) {
420- // Probably ran out of funds
421- test_return!( ) ;
462+ check_payment_err( err) ;
422463 }
423464 } } ;
424465 ( $source: expr, $middle: expr, $dest: expr, $amt: expr) => { {
425466 let payment_hash = Sha256 :: hash( & [ payment_id; 1 ] ) ;
426467 payment_id = payment_id. wrapping_add( 1 ) ;
427- if let Err ( _ ) = $source. send_payment( & Route {
468+ if let Err ( err ) = $source. send_payment( & Route {
428469 paths: vec![ vec![ RouteHop {
429470 pubkey: $middle. 0 . get_our_node_id( ) ,
430471 node_features: NodeFeatures :: empty( ) ,
@@ -441,8 +482,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
441482 cltv_expiry_delta: 200 ,
442483 } ] ] ,
443484 } , PaymentHash ( payment_hash. into_inner( ) ) , & None ) {
444- // Probably ran out of funds
445- test_return!( ) ;
485+ check_payment_err( err) ;
446486 }
447487 } }
448488 }
@@ -452,7 +492,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
452492 payment_id = payment_id. wrapping_add( 1 ) ;
453493 let payment_secret = Sha256 :: hash( & [ payment_id; 1 ] ) ;
454494 payment_id = payment_id. wrapping_add( 1 ) ;
455- if let Err ( _ ) = $source. send_payment( & Route {
495+ if let Err ( err ) = $source. send_payment( & Route {
456496 paths: vec![ vec![ RouteHop {
457497 pubkey: $middle. 0 . get_our_node_id( ) ,
458498 node_features: NodeFeatures :: empty( ) ,
@@ -483,8 +523,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
483523 cltv_expiry_delta: 200 ,
484524 } ] ] ,
485525 } , PaymentHash ( payment_hash. into_inner( ) ) , & Some ( PaymentSecret ( payment_secret. into_inner( ) ) ) ) {
486- // Probably ran out of funds
487- test_return!( ) ;
526+ check_payment_err( err) ;
488527 }
489528 } }
490529 }
0 commit comments