@@ -582,6 +582,11 @@ impl Simulation {
582
582
}
583
583
584
584
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
+ }
585
590
// We need every source node that is configured to execute some activity to be included in our set of
586
591
// nodes so that we can execute events on it.
587
592
self . nodes
@@ -1459,10 +1464,18 @@ async fn track_payment_result(
1459
1464
1460
1465
#[ cfg( test) ]
1461
1466
mod 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 ;
1463
1473
use mockall:: mock;
1474
+ use std:: collections:: HashMap ;
1464
1475
use std:: fmt;
1476
+ use std:: sync:: Arc ;
1465
1477
use std:: time:: Duration ;
1478
+ use tokio:: sync:: Mutex ;
1466
1479
1467
1480
#[ test]
1468
1481
fn create_seeded_mut_rng ( ) {
@@ -1505,6 +1518,27 @@ mod tests {
1505
1518
}
1506
1519
}
1507
1520
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
+
1508
1542
#[ test]
1509
1543
fn test_no_payment_delay ( ) {
1510
1544
let node = test_utils:: create_nodes ( 1 , 100_000 )
@@ -1559,4 +1593,33 @@ mod tests {
1559
1593
payment_interval
1560
1594
) ;
1561
1595
}
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
+ }
1562
1625
}
0 commit comments