@@ -582,6 +582,11 @@ impl Simulation {
582582 }
583583
584584 for payment_flow in self . activity . iter ( ) {
585+ if payment_flow. amount_msat . value ( ) == 0 {
586+ return Err ( LightningError :: ValidationError (
587+ "We do not allow defined activity amount_msat with zero values" . to_string ( ) ,
588+ ) ) ;
589+ }
585590 // We need every source node that is configured to execute some activity to be included in our set of
586591 // nodes so that we can execute events on it.
587592 self . nodes
@@ -1459,10 +1464,18 @@ async fn track_payment_result(
14591464
14601465#[ cfg( test) ]
14611466mod tests {
1462- use crate :: { get_payment_delay, test_utils, MutRng , PaymentGenerationError , PaymentGenerator } ;
1467+ use crate :: {
1468+ get_payment_delay, test_utils, LightningError , LightningNode , MutRng , NodeInfo ,
1469+ PaymentGenerationError , PaymentGenerator , Simulation ,
1470+ } ;
1471+ use async_trait:: async_trait;
1472+ use bitcoin:: secp256k1:: PublicKey ;
14631473 use mockall:: mock;
1474+ use std:: collections:: HashMap ;
14641475 use std:: fmt;
1476+ use std:: sync:: Arc ;
14651477 use std:: time:: Duration ;
1478+ use tokio:: sync:: Mutex ;
14661479
14671480 #[ test]
14681481 fn create_seeded_mut_rng ( ) {
@@ -1505,6 +1518,27 @@ mod tests {
15051518 }
15061519 }
15071520
1521+ mock ! {
1522+ pub LightningNode { }
1523+ #[ async_trait]
1524+ impl crate :: LightningNode for LightningNode {
1525+ fn get_info( & self ) -> & NodeInfo ;
1526+ async fn get_network( & mut self ) -> Result <bitcoin:: Network , LightningError >;
1527+ async fn send_payment(
1528+ & mut self ,
1529+ dest: bitcoin:: secp256k1:: PublicKey ,
1530+ amount_msat: u64 ,
1531+ ) -> Result <lightning:: ln:: PaymentHash , LightningError >;
1532+ async fn track_payment(
1533+ & mut self ,
1534+ hash: & lightning:: ln:: PaymentHash ,
1535+ shutdown: triggered:: Listener ,
1536+ ) -> Result <crate :: PaymentResult , LightningError >;
1537+ async fn get_node_info( & mut self , node_id: & PublicKey ) -> Result <NodeInfo , LightningError >;
1538+ async fn list_channels( & mut self ) -> Result <Vec <u64 >, LightningError >;
1539+ }
1540+ }
1541+
15081542 #[ test]
15091543 fn test_no_payment_delay ( ) {
15101544 let node = test_utils:: create_nodes ( 1 , 100_000 )
@@ -1559,4 +1593,33 @@ mod tests {
15591593 payment_interval
15601594 ) ;
15611595 }
1596+
1597+ #[ tokio:: test]
1598+ async fn test_validate_zero_amount_no_valid ( ) {
1599+ let nodes = test_utils:: create_nodes ( 2 , 100_000 ) ;
1600+ let mut node_1 = nodes. first ( ) . unwrap ( ) . 0 . clone ( ) ;
1601+ let mut node_2 = nodes. get ( 1 ) . unwrap ( ) . 0 . clone ( ) ;
1602+ node_1. features . set_keysend_optional ( ) ;
1603+ node_2. features . set_keysend_optional ( ) ;
1604+
1605+ let mock_node_1 = MockLightningNode :: new ( ) ;
1606+ let mock_node_2 = MockLightningNode :: new ( ) ;
1607+ let mut clients: HashMap < PublicKey , Arc < Mutex < dyn LightningNode > > > = HashMap :: new ( ) ;
1608+ clients. insert ( node_1. pubkey , Arc :: new ( Mutex :: new ( mock_node_1) ) ) ;
1609+ clients. insert ( node_2. pubkey , Arc :: new ( Mutex :: new ( mock_node_2) ) ) ;
1610+ let activity_definition = crate :: ActivityDefinition {
1611+ source : node_1,
1612+ destination : node_2,
1613+ start_secs : None ,
1614+ count : None ,
1615+ interval_secs : crate :: ValueOrRange :: Value ( 0 ) ,
1616+ amount_msat : crate :: ValueOrRange :: Value ( 0 ) ,
1617+ } ;
1618+ let simulation = Simulation :: new (
1619+ crate :: SimulationCfg :: new ( Some ( 0 ) , 0 , 0.0 , None , None ) ,
1620+ clients,
1621+ vec ! [ activity_definition] ,
1622+ ) ;
1623+ assert ! ( simulation. validate_activity( ) . await . is_err( ) ) ;
1624+ }
15621625}
0 commit comments