@@ -546,6 +546,11 @@ impl Simulation {
546
546
}
547
547
548
548
for payment_flow in self . activity . iter ( ) {
549
+ if payment_flow. amount_msat . value ( ) == 0 {
550
+ return Err ( LightningError :: ValidationError (
551
+ "We do not allow defined activity amount_msat with zero values" . to_string ( ) ,
552
+ ) ) ;
553
+ }
549
554
// We need every source node that is configured to execute some activity to be included in our set of
550
555
// nodes so that we can execute events on it.
551
556
self . nodes
@@ -1423,10 +1428,18 @@ async fn track_payment_result(
1423
1428
1424
1429
#[ cfg( test) ]
1425
1430
mod tests {
1426
- use crate :: { get_payment_delay, test_utils, MutRng , PaymentGenerationError , PaymentGenerator } ;
1431
+ use crate :: {
1432
+ get_payment_delay, test_utils, LightningError , LightningNode , MutRng , NodeInfo ,
1433
+ PaymentGenerationError , PaymentGenerator , Simulation ,
1434
+ } ;
1435
+ use async_trait:: async_trait;
1436
+ use bitcoin:: secp256k1:: PublicKey ;
1427
1437
use mockall:: mock;
1438
+ use std:: collections:: HashMap ;
1428
1439
use std:: fmt;
1440
+ use std:: sync:: Arc ;
1429
1441
use std:: time:: Duration ;
1442
+ use tokio:: sync:: Mutex ;
1430
1443
1431
1444
#[ test]
1432
1445
fn create_seeded_mut_rng ( ) {
@@ -1469,6 +1482,27 @@ mod tests {
1469
1482
}
1470
1483
}
1471
1484
1485
+ mock ! {
1486
+ pub LightningNode { }
1487
+ #[ async_trait]
1488
+ impl crate :: LightningNode for LightningNode {
1489
+ fn get_info( & self ) -> & NodeInfo ;
1490
+ async fn get_network( & mut self ) -> Result <bitcoin:: Network , LightningError >;
1491
+ async fn send_payment(
1492
+ & mut self ,
1493
+ dest: bitcoin:: secp256k1:: PublicKey ,
1494
+ amount_msat: u64 ,
1495
+ ) -> Result <lightning:: ln:: PaymentHash , LightningError >;
1496
+ async fn track_payment(
1497
+ & mut self ,
1498
+ hash: & lightning:: ln:: PaymentHash ,
1499
+ shutdown: triggered:: Listener ,
1500
+ ) -> Result <crate :: PaymentResult , LightningError >;
1501
+ async fn get_node_info( & mut self , node_id: & PublicKey ) -> Result <NodeInfo , LightningError >;
1502
+ async fn list_channels( & mut self ) -> Result <Vec <u64 >, LightningError >;
1503
+ }
1504
+ }
1505
+
1472
1506
#[ test]
1473
1507
fn test_no_payment_delay ( ) {
1474
1508
let node = test_utils:: create_nodes ( 1 , 100_000 )
@@ -1523,4 +1557,33 @@ mod tests {
1523
1557
payment_interval
1524
1558
) ;
1525
1559
}
1560
+
1561
+ #[ tokio:: test]
1562
+ async fn test_validate_zero_amount_no_valid ( ) {
1563
+ let nodes = test_utils:: create_nodes ( 2 , 100_000 ) ;
1564
+ let mut node_1 = nodes. first ( ) . unwrap ( ) . 0 . clone ( ) ;
1565
+ let mut node_2 = nodes. get ( 1 ) . unwrap ( ) . 0 . clone ( ) ;
1566
+ node_1. features . set_keysend_optional ( ) ;
1567
+ node_2. features . set_keysend_optional ( ) ;
1568
+
1569
+ let mock_node_1 = MockLightningNode :: new ( ) ;
1570
+ let mock_node_2 = MockLightningNode :: new ( ) ;
1571
+ let mut clients: HashMap < PublicKey , Arc < Mutex < dyn LightningNode > > > = HashMap :: new ( ) ;
1572
+ clients. insert ( node_1. pubkey , Arc :: new ( Mutex :: new ( mock_node_1) ) ) ;
1573
+ clients. insert ( node_2. pubkey , Arc :: new ( Mutex :: new ( mock_node_2) ) ) ;
1574
+ let activity_definition = crate :: ActivityDefinition {
1575
+ source : node_1,
1576
+ destination : node_2,
1577
+ start_secs : None ,
1578
+ count : None ,
1579
+ interval_secs : crate :: ValueOrRange :: Value ( 0 ) ,
1580
+ amount_msat : crate :: ValueOrRange :: Value ( 0 ) ,
1581
+ } ;
1582
+ let simulation = Simulation :: new (
1583
+ crate :: SimulationCfg :: new ( Some ( 0 ) , 0 , 0.0 , None , None ) ,
1584
+ clients,
1585
+ vec ! [ activity_definition] ,
1586
+ ) ;
1587
+ assert ! ( simulation. validate_activity( ) . await . is_err( ) ) ;
1588
+ }
1526
1589
}
0 commit comments