@@ -33,7 +33,6 @@ pub mod lnd;
3333mod random_activity;
3434pub mod serializers;
3535pub mod sim_node;
36- #[ cfg( test) ]
3736mod test_utils;
3837
3938#[ derive( Serialize , Debug , Clone ) ]
@@ -1418,18 +1417,17 @@ async fn track_payment_result(
14181417#[ cfg( test) ]
14191418mod tests {
14201419 use crate :: {
1421- get_payment_delay, test_utils, LightningError , LightningNode , MutRng , NodeInfo ,
1422- PaymentGenerationError , PaymentGenerator , Simulation ,
1420+ get_payment_delay, test_utils, test_utils :: LightningTestNodeBuilder , LightningError ,
1421+ LightningNode , MutRng , PaymentGenerationError , PaymentGenerator ,
14231422 } ;
1424- use async_trait:: async_trait;
14251423 use bitcoin:: secp256k1:: PublicKey ;
1424+ use bitcoin:: Network ;
14261425 use mockall:: mock;
14271426 use std:: collections:: HashMap ;
14281427 use std:: fmt;
14291428 use std:: sync:: Arc ;
14301429 use std:: time:: Duration ;
14311430 use tokio:: sync:: Mutex ;
1432- use tokio_util:: task:: TaskTracker ;
14331431
14341432 #[ test]
14351433 fn create_seeded_mut_rng ( ) {
@@ -1472,27 +1470,6 @@ mod tests {
14721470 }
14731471 }
14741472
1475- mock ! {
1476- pub LightningNode { }
1477- #[ async_trait]
1478- impl crate :: LightningNode for LightningNode {
1479- fn get_info( & self ) -> & NodeInfo ;
1480- async fn get_network( & mut self ) -> Result <bitcoin:: Network , LightningError >;
1481- async fn send_payment(
1482- & mut self ,
1483- dest: bitcoin:: secp256k1:: PublicKey ,
1484- amount_msat: u64 ,
1485- ) -> Result <lightning:: ln:: PaymentHash , LightningError >;
1486- async fn track_payment(
1487- & mut self ,
1488- hash: & lightning:: ln:: PaymentHash ,
1489- shutdown: triggered:: Listener ,
1490- ) -> Result <crate :: PaymentResult , LightningError >;
1491- async fn get_node_info( & mut self , node_id: & PublicKey ) -> Result <NodeInfo , LightningError >;
1492- async fn list_channels( & mut self ) -> Result <Vec <u64 >, LightningError >;
1493- }
1494- }
1495-
14961473 #[ test]
14971474 fn test_no_payment_delay ( ) {
14981475 let node = test_utils:: create_nodes ( 1 , 100_000 )
@@ -1548,33 +1525,178 @@ mod tests {
15481525 ) ;
15491526 }
15501527
1528+ /// Verifies that an empty activity (for random generation) is valid when two nodes with keysend
1529+ /// support are present, expecting an `Ok` result.
1530+ #[ tokio:: test]
1531+ async fn test_validate_activity_empty_with_sufficient_nodes ( ) {
1532+ let ( _, clients) = LightningTestNodeBuilder :: new ( 3 ) . build_full ( ) ;
1533+ let simulation = test_utils:: create_simulation ( clients, vec ! [ ] ) ;
1534+ let result = simulation. validate_activity ( ) . await ;
1535+ assert ! ( result. is_ok( ) ) ;
1536+ }
1537+
1538+ /// Verifies that an empty activity fails validation with only one keysend-enabled node,
1539+ /// expecting a `ValidationError` with "At least two nodes required".
1540+ #[ tokio:: test]
1541+ async fn test_validate_activity_empty_with_insufficient_nodes ( ) {
1542+ let ( _, clients) = LightningTestNodeBuilder :: new ( 1 ) . build_full ( ) ;
1543+ let simulation = test_utils:: create_simulation ( clients, vec ! [ ] ) ;
1544+ let result = simulation. validate_activity ( ) . await ;
1545+
1546+ assert ! ( result. is_err( ) ) ;
1547+ assert ! ( matches!( result,
1548+ Err ( LightningError :: ValidationError ( msg) ) if msg. contains( "At least two nodes required" ) ) ) ;
1549+ }
1550+
1551+ /// Verifies that an empty activity fails when one of two nodes doesn’t support keysend,
1552+ /// expecting a `ValidationError` with "must support keysend".
1553+ #[ tokio:: test]
1554+ async fn test_validate_activity_empty_with_non_keysend_node ( ) {
1555+ let ( _, clients) = LightningTestNodeBuilder :: new ( 2 )
1556+ . with_keysend_nodes ( vec ! [ 0 ] )
1557+ . build_full ( ) ;
1558+ let simulation = test_utils:: create_simulation ( clients, vec ! [ ] ) ;
1559+ let result = simulation. validate_activity ( ) . await ;
1560+
1561+ assert ! ( result. is_err( ) ) ;
1562+ assert ! ( matches!( result,
1563+ Err ( LightningError :: ValidationError ( msg) ) if msg. contains( "must support keysend" ) ) ) ;
1564+ }
1565+
1566+ /// Verifies that an activity fails when the source node isn’t in the clients map,
1567+ /// expecting a `ValidationError` with "Source node not found".
1568+ #[ tokio:: test]
1569+ async fn test_validate_activity_with_missing_source_node ( ) {
1570+ let ( nodes, clients) = LightningTestNodeBuilder :: new ( 1 ) . build_full ( ) ;
1571+ let missing_nodes = test_utils:: create_nodes ( 1 , 100_000 ) ;
1572+ let missing_node = missing_nodes. first ( ) . unwrap ( ) . 0 . clone ( ) ;
1573+ let dest_node = nodes[ 0 ] . clone ( ) ;
1574+
1575+ let activity = test_utils:: create_activity ( missing_node, dest_node, 1000 ) ;
1576+ let simulation = test_utils:: create_simulation ( clients, vec ! [ activity] ) ;
1577+ let result = simulation. validate_activity ( ) . await ;
1578+
1579+ assert ! ( result. is_err( ) ) ;
1580+ assert ! ( matches!( result,
1581+ Err ( LightningError :: ValidationError ( msg) ) if msg. contains( "Source node not found" ) ) ) ;
1582+ }
1583+
1584+ /// Verifies that an activity fails when the destination lacks keysend support,
1585+ /// expecting a `ValidationError` with "does not support keysend".
1586+ #[ tokio:: test]
1587+ async fn test_validate_activity_with_non_keysend_destination ( ) {
1588+ let ( nodes, clients) = LightningTestNodeBuilder :: new ( 1 ) . build_full ( ) ;
1589+ let dest_nodes = test_utils:: create_nodes ( 1 , 100_000 ) ;
1590+ let dest_node = dest_nodes. first ( ) . unwrap ( ) . 0 . clone ( ) ;
1591+
1592+ let activity = test_utils:: create_activity ( nodes[ 0 ] . clone ( ) , dest_node, 1000 ) ;
1593+ let simulation = test_utils:: create_simulation ( clients, vec ! [ activity] ) ;
1594+ let result = simulation. validate_activity ( ) . await ;
1595+
1596+ assert ! ( result. is_err( ) ) ;
1597+ assert ! ( matches!( result,
1598+ Err ( LightningError :: ValidationError ( msg) ) if msg. contains( "does not support keysend" ) ) ) ;
1599+ }
1600+
1601+ /// Verifies that an activity with a non-zero amount between two keysend-enabled nodes
1602+ /// passes validation, expecting an `Ok` result.
1603+ #[ tokio:: test]
1604+ async fn test_validate_activity_valid_payment_flow ( ) {
1605+ let ( nodes, clients) = LightningTestNodeBuilder :: new ( 1 ) . build_full ( ) ;
1606+ let dest_nodes = test_utils:: create_nodes ( 1 , 100_000 ) ;
1607+ let mut dest_node = dest_nodes. first ( ) . unwrap ( ) . 0 . clone ( ) ;
1608+ dest_node. features . set_keysend_optional ( ) ;
1609+
1610+ let activity = test_utils:: create_activity ( nodes[ 0 ] . clone ( ) , dest_node, 1000 ) ;
1611+ let simulation = test_utils:: create_simulation ( clients, vec ! [ activity] ) ;
1612+ let result = simulation. validate_activity ( ) . await ;
1613+
1614+ assert ! ( result. is_ok( ) ) ;
1615+ }
1616+
1617+ /// Verifies that an activity with a zero amount between two keysend-enabled nodes fails,
1618+ /// expecting a `ValidationError` with "zero values".
15511619 #[ tokio:: test]
15521620 async fn test_validate_zero_amount_no_valid ( ) {
1553- let nodes = test_utils:: create_nodes ( 2 , 100_000 ) ;
1554- let mut node_1 = nodes. first ( ) . unwrap ( ) . 0 . clone ( ) ;
1555- let mut node_2 = nodes. get ( 1 ) . unwrap ( ) . 0 . clone ( ) ;
1556- node_1. features . set_keysend_optional ( ) ;
1557- node_2. features . set_keysend_optional ( ) ;
1558-
1559- let mock_node_1 = MockLightningNode :: new ( ) ;
1560- let mock_node_2 = MockLightningNode :: new ( ) ;
1561- let mut clients: HashMap < PublicKey , Arc < Mutex < dyn LightningNode > > > = HashMap :: new ( ) ;
1562- clients. insert ( node_1. pubkey , Arc :: new ( Mutex :: new ( mock_node_1) ) ) ;
1563- clients. insert ( node_2. pubkey , Arc :: new ( Mutex :: new ( mock_node_2) ) ) ;
1564- let activity_definition = crate :: ActivityDefinition {
1565- source : node_1,
1566- destination : node_2,
1567- start_secs : None ,
1568- count : None ,
1569- interval_secs : crate :: ValueOrRange :: Value ( 0 ) ,
1570- amount_msat : crate :: ValueOrRange :: Value ( 0 ) ,
1571- } ;
1572- let simulation = Simulation :: new (
1573- crate :: SimulationCfg :: new ( Some ( 0 ) , 0 , 0.0 , None , None ) ,
1574- clients,
1575- vec ! [ activity_definition] ,
1576- TaskTracker :: new ( ) ,
1577- ) ;
1578- assert ! ( simulation. validate_activity( ) . await . is_err( ) ) ;
1621+ let ( nodes, clients) = LightningTestNodeBuilder :: new ( 2 ) . build_full ( ) ;
1622+
1623+ let activity = test_utils:: create_activity ( nodes[ 0 ] . clone ( ) , nodes[ 1 ] . clone ( ) , 0 ) ;
1624+ let simulation = test_utils:: create_simulation ( clients, vec ! [ activity] ) ;
1625+ let result = simulation. validate_activity ( ) . await ;
1626+
1627+ assert ! ( result. is_err( ) ) ;
1628+ assert ! ( matches!( result,
1629+ Err ( LightningError :: ValidationError ( msg) ) if msg. contains( "zero values" ) ) ) ;
1630+ }
1631+
1632+ /// Verifies that validation fails with no nodes, expecting a `ValidationError` with
1633+ /// "we don't control any nodes".
1634+ #[ tokio:: test]
1635+ async fn test_validate_node_network_empty_nodes ( ) {
1636+ let empty_nodes: HashMap < PublicKey , Arc < Mutex < dyn LightningNode > > > = HashMap :: new ( ) ;
1637+
1638+ let simulation = test_utils:: create_simulation ( empty_nodes, vec ! [ ] ) ;
1639+ let result = simulation. validate_node_network ( ) . await ;
1640+
1641+ assert ! ( result. is_err( ) ) ;
1642+ assert ! ( matches!( result,
1643+ Err ( LightningError :: ValidationError ( msg) ) if msg. contains( "we don't control any nodes" ) ) ) ;
1644+ }
1645+
1646+ /// Verifies that a node on Bitcoin mainnet fails validation, expecting a `ValidationError`
1647+ /// with "mainnet is not supported".
1648+ #[ tokio:: test]
1649+ async fn test_validate_node_network_mainnet_not_supported ( ) {
1650+ let clients = LightningTestNodeBuilder :: new ( 1 )
1651+ . with_networks ( vec ! [ Network :: Bitcoin ] )
1652+ . build_clients_only ( ) ;
1653+
1654+ let simulation = test_utils:: create_simulation ( clients, vec ! [ ] ) ;
1655+ let result = simulation. validate_node_network ( ) . await ;
1656+
1657+ assert ! ( result. is_err( ) ) ;
1658+ assert ! ( matches!( result,
1659+ Err ( LightningError :: ValidationError ( msg) ) if msg. contains( "mainnet is not supported" ) ) ) ;
1660+ }
1661+
1662+ /// Verifies that nodes on Testnet and Regtest fail validation, expecting a
1663+ /// `ValidationError` with "nodes are not on the same network".
1664+ #[ tokio:: test]
1665+ async fn test_validate_node_network_mixed_networks ( ) {
1666+ let clients = LightningTestNodeBuilder :: new ( 2 )
1667+ . with_networks ( vec ! [ Network :: Testnet , Network :: Regtest ] )
1668+ . build_clients_only ( ) ;
1669+
1670+ let simulation = test_utils:: create_simulation ( clients, vec ! [ ] ) ;
1671+ let result = simulation. validate_node_network ( ) . await ;
1672+
1673+ assert ! ( result. is_err( ) ) ;
1674+ assert ! ( matches!( result,
1675+ Err ( LightningError :: ValidationError ( msg) ) if msg. contains( "nodes are not on the same network" ) ) ) ;
1676+ }
1677+
1678+ /// Verifies that three Testnet nodes pass validation, expecting an `Ok` result.
1679+ #[ tokio:: test]
1680+ async fn test_validate_node_network_multiple_nodes_same_network ( ) {
1681+ let clients = LightningTestNodeBuilder :: new ( 3 )
1682+ . with_networks ( vec ! [ Network :: Testnet , Network :: Testnet , Network :: Testnet ] )
1683+ . build_clients_only ( ) ;
1684+
1685+ let simulation = test_utils:: create_simulation ( clients, vec ! [ ] ) ;
1686+ let result = simulation. validate_node_network ( ) . await ;
1687+
1688+ assert ! ( result. is_ok( ) ) ;
1689+ }
1690+
1691+ #[ tokio:: test]
1692+ async fn test_validate_node_network_single_node_valid_network ( ) {
1693+ let clients = LightningTestNodeBuilder :: new ( 1 )
1694+ . with_networks ( vec ! [ Network :: Testnet ] )
1695+ . build_clients_only ( ) ;
1696+
1697+ let simulation = test_utils:: create_simulation ( clients, vec ! [ ] ) ;
1698+ let result = simulation. validate_node_network ( ) . await ;
1699+
1700+ assert ! ( result. is_ok( ) ) ;
15791701 }
15801702}
0 commit comments