@@ -21,11 +21,10 @@ static void SimpleConstructionTest() {
2121 }
2222
2323 class TestBroadcaster : BroadcasterInterfaceInterface {
24- public bool broadcasted = false ;
24+ public int broadcasted_len = 0 ;
2525 public void broadcast_transactions ( byte [ ] [ ] txn ) {
2626 Assert ( txn . Length == 1 , 1 ) ;
27- Assert ( txn [ 0 ] . Length == 42 , 2 ) ;
28- broadcasted = true ;
27+ broadcasted_len = txn [ 0 ] . Length ;
2928 }
3029 }
3130
@@ -35,7 +34,7 @@ static void SimpleTraitTest() {
3534 byte [ ] [ ] txn = new byte [ 1 ] [ ] ;
3635 txn [ 0 ] = new byte [ 42 ] ;
3736 broadcaster . broadcast_transactions ( txn ) ;
38- Assert ( impl . broadcasted == true , 3 ) ;
37+ Assert ( impl . broadcasted_len == 42 , 3 ) ;
3938 }
4039
4140 class TestEstimator : FeeEstimatorInterface {
@@ -61,6 +60,7 @@ public ChannelMonitorUpdateStatus persist_new_channel(OutPoint channel_id, Chann
6160 public ChannelMonitorUpdateStatus update_persisted_channel ( OutPoint channel_id , ChannelMonitorUpdate update , ChannelMonitor data , MonitorUpdateId update_id ) {
6261 return ChannelMonitorUpdateStatus . LDKChannelMonitorUpdateStatus_Completed ;
6362 }
63+ public void archive_persisted_channel ( OutPoint channel_id ) { }
6464 }
6565
6666 class TestEventHandler : EventHandlerInterface {
@@ -77,31 +77,75 @@ static Event get_event(ChannelManager manager) {
7777 return impl . events [ 0 ] ;
7878 }
7979
80+ class TestRouter : RouterInterface , MessageRouterInterface {
81+ DefaultRouter inner ;
82+ EntropySource entropy ;
83+ public TestRouter ( DefaultRouter inner , EntropySource entropy ) {
84+ this . inner = inner ;
85+ this . entropy = entropy ;
86+ }
87+ public Result_RouteLightningErrorZ find_route ( byte [ ] payer , RouteParameters param , ChannelDetails [ ] chans , InFlightHtlcs htlcs ) {
88+ return inner . as_Router ( ) . find_route ( payer , param , chans , htlcs ) ;
89+ }
90+ public Result_RouteLightningErrorZ find_route_with_id ( byte [ ] payer , RouteParameters param , ChannelDetails [ ] chans , InFlightHtlcs htlcs , byte [ ] payment_hash , byte [ ] payment_id ) {
91+ return inner . as_Router ( ) . find_route_with_id ( payer , param , chans , htlcs , payment_hash , payment_id ) ;
92+ }
93+ public Result_CVec_C2Tuple_BlindedPayInfoBlindedPathZZNoneZ create_blinded_payment_paths ( byte [ ] recipient , ChannelDetails [ ] first_hops , ReceiveTlvs tlvs , long amount_msats ) {
94+ Result_C2Tuple_BlindedPayInfoBlindedPathZNoneZ info_path = UtilMethods . BlindedPath_one_hop_for_payment ( recipient , tlvs , 40 , entropy ) ;
95+ TwoTuple_BlindedPayInfoBlindedPathZ hop = ( ( Result_C2Tuple_BlindedPayInfoBlindedPathZNoneZ . Result_C2Tuple_BlindedPayInfoBlindedPathZNoneZ_OK ) info_path ) . res ;
96+ TwoTuple_BlindedPayInfoBlindedPathZ [ ] hops = new TwoTuple_BlindedPayInfoBlindedPathZ [ 1 ] ;
97+ hops [ 0 ] = hop ;
98+ return Result_CVec_C2Tuple_BlindedPayInfoBlindedPathZZNoneZ . ok ( hops ) ;
99+ }
100+
101+ public Result_OnionMessagePathNoneZ find_path ( byte [ ] sender , byte [ ] [ ] peers , Destination dest ) {
102+ return inner . as_MessageRouter ( ) . find_path ( sender , peers , dest ) ;
103+ }
104+ public Result_CVec_BlindedPathZNoneZ create_blinded_paths ( byte [ ] recipient , byte [ ] [ ] peers ) {
105+ Result_BlindedPathNoneZ path = BlindedPath . one_hop_for_message ( recipient , entropy ) ;
106+ Assert ( path . is_ok ( ) , 2 ) ;
107+ BlindedPath [ ] paths = new BlindedPath [ 1 ] ;
108+ paths [ 0 ] = ( ( Result_BlindedPathNoneZ . Result_BlindedPathNoneZ_OK ) path ) . res ;
109+ return Result_CVec_BlindedPathZNoneZ . ok ( paths ) ;
110+ }
111+ }
112+
80113 class Node {
81- public BroadcasterInterface broadcaster = BroadcasterInterface . new_impl ( new TestBroadcaster ( ) ) ;
114+ public TestBroadcaster broadcaster = new TestBroadcaster ( ) ;
82115 public FeeEstimator estimator = FeeEstimator . new_impl ( new TestEstimator ( ) ) ;
83116 public Logger logger = Logger . new_impl ( new TestLogger ( ) ) ;
84117 public Persist persister = Persist . new_impl ( new TestPersister ( ) ) ;
85118 public ChainParameters chain_params = ChainParameters . of ( Network . LDKNetwork_Bitcoin , BestBlock . from_network ( Network . LDKNetwork_Bitcoin ) ) ;
86119
120+ public BroadcasterInterface ldk_broadcaster ;
87121 public ChainMonitor chain_monitor ;
88122 public NetworkGraph graph ;
89123 public MultiThreadedLockableScore scorer ;
90- public DefaultRouter router ;
124+ public Router router ;
91125 public KeysManager keys ;
92126 public ChannelManager manager ;
127+ public OnionMessenger messenger ;
93128
94129 public Node ( byte seed ) {
95130 byte [ ] seed_bytes = new byte [ 32 ] ;
96131 for ( int i = 0 ; i < 32 ; i ++ ) seed_bytes [ i ] = seed ;
97132 keys = KeysManager . of ( seed_bytes , 42 , 43 ) ;
98133
99- chain_monitor = ChainMonitor . of ( Option_FilterZ . none ( ) , broadcaster , logger , estimator , persister ) ;
134+ ldk_broadcaster = BroadcasterInterface . new_impl ( broadcaster ) ;
135+ chain_monitor = ChainMonitor . of ( Option_FilterZ . none ( ) , ldk_broadcaster , logger , estimator , persister ) ;
100136 graph = NetworkGraph . of ( Network . LDKNetwork_Bitcoin , logger ) ;
101137 scorer = MultiThreadedLockableScore . of ( ProbabilisticScorer . of ( ProbabilisticScoringDecayParameters . with_default ( ) , graph , logger ) . as_Score ( ) ) ;
102- router = DefaultRouter . of ( graph , logger , keys . as_EntropySource ( ) , scorer . as_LockableScore ( ) , ProbabilisticScoringFeeParameters . with_default ( ) ) ;
103138
104- manager = ChannelManager . of ( estimator , chain_monitor . as_Watch ( ) , broadcaster , router . as_Router ( ) , logger , keys . as_EntropySource ( ) , keys . as_NodeSigner ( ) , keys . as_SignerProvider ( ) , UserConfig . with_default ( ) , chain_params , 42 ) ;
139+ DefaultRouter router_impl = DefaultRouter . of ( graph , logger , keys . as_EntropySource ( ) , scorer . as_LockableScore ( ) , ProbabilisticScoringFeeParameters . with_default ( ) ) ;
140+ TestRouter router_wrapper = new TestRouter ( router_impl , keys . as_EntropySource ( ) ) ;
141+ router = Router . new_impl ( router_wrapper , router_wrapper ) ;
142+
143+ UserConfig config = UserConfig . with_default ( ) ;
144+ config . set_manually_accept_inbound_channels ( true ) ;
145+
146+ manager = ChannelManager . of ( estimator , chain_monitor . as_Watch ( ) , ldk_broadcaster , router , logger , keys . as_EntropySource ( ) , keys . as_NodeSigner ( ) , keys . as_SignerProvider ( ) , config , chain_params , 42 ) ;
147+
148+ messenger = OnionMessenger . of ( keys . as_EntropySource ( ) , keys . as_NodeSigner ( ) , logger , manager . as_NodeIdLookUp ( ) , MessageRouter . new_impl ( router_wrapper ) , manager . as_OffersMessageHandler ( ) , IgnoringMessageHandler . of ( ) . as_CustomOnionMessageHandler ( ) ) ;
105149 }
106150 }
107151
@@ -110,29 +154,38 @@ static void NodeTest() {
110154 Node node_b = new Node ( 2 ) ;
111155
112156 InitFeatures init_features = node_a . manager . as_ChannelMessageHandler ( ) . provided_init_features ( node_b . manager . get_our_node_id ( ) ) ;
157+ init_features . set_onion_messages_optional ( ) ;
113158 Init init_msg = Init . of ( init_features , Option_CVec_ThirtyTwoBytesZZ . none ( ) , Option_SocketAddressZ . none ( ) ) ;
114159 node_a . manager . as_ChannelMessageHandler ( ) . peer_connected ( node_b . manager . get_our_node_id ( ) , init_msg , false ) ;
115160 node_b . manager . as_ChannelMessageHandler ( ) . peer_connected ( node_a . manager . get_our_node_id ( ) , init_msg , false ) ;
161+ node_a . messenger . as_OnionMessageHandler ( ) . peer_connected ( node_b . manager . get_our_node_id ( ) , init_msg , false ) ;
162+ node_b . messenger . as_OnionMessageHandler ( ) . peer_connected ( node_a . manager . get_our_node_id ( ) , init_msg , false ) ;
116163
117- Result_ThirtyTwoBytesAPIErrorZ res = node_a . manager . create_channel ( node_b . manager . get_our_node_id ( ) , 100000 , 42 , new UInt128 ( 43 ) , Option_ThirtyTwoBytesZ . none ( ) , null ) ;
164+ Result_ChannelIdAPIErrorZ res = node_a . manager . create_channel ( node_b . manager . get_our_node_id ( ) , 100000 , 42 , new UInt128 ( 43 ) , null , null ) ;
118165 Assert ( res . is_ok ( ) , 4 ) ;
119166
120167 MessageSendEvent [ ] msgs = node_a . manager . as_MessageSendEventsProvider ( ) . get_and_clear_pending_msg_events ( ) ;
121168 Assert ( msgs . Length == 1 , 5 ) ;
122169 Assert ( msgs [ 0 ] is MessageSendEvent . MessageSendEvent_SendOpenChannel , 6 ) ;
123170 node_b . manager . as_ChannelMessageHandler ( ) . handle_open_channel ( node_a . manager . get_our_node_id ( ) , ( ( MessageSendEvent . MessageSendEvent_SendOpenChannel ) msgs [ 0 ] ) . msg ) ;
124171
172+ Event inbound_chan = get_event ( node_b . manager ) ;
173+ Assert ( inbound_chan is Event . Event_OpenChannelRequest , 7 ) ;
174+ Event . Event_OpenChannelRequest chan_request = ( Event . Event_OpenChannelRequest ) inbound_chan ;
175+ Result_NoneAPIErrorZ accept_res = node_b . manager . accept_inbound_channel_from_trusted_peer_0conf ( chan_request . temporary_channel_id , chan_request . counterparty_node_id , new UInt128 ( 42 ) ) ;
176+ Assert ( accept_res . is_ok ( ) , 8 ) ;
177+
125178 MessageSendEvent [ ] response_msgs = node_b . manager . as_MessageSendEventsProvider ( ) . get_and_clear_pending_msg_events ( ) ;
126- Assert ( response_msgs . Length == 1 , 7 ) ;
127- Assert ( response_msgs [ 0 ] is MessageSendEvent . MessageSendEvent_SendAcceptChannel , 8 ) ;
179+ Assert ( response_msgs . Length == 1 , 9 ) ;
180+ Assert ( response_msgs [ 0 ] is MessageSendEvent . MessageSendEvent_SendAcceptChannel , 10 ) ;
128181 node_a . manager . as_ChannelMessageHandler ( ) . handle_accept_channel ( node_b . manager . get_our_node_id ( ) , ( ( MessageSendEvent . MessageSendEvent_SendAcceptChannel ) response_msgs [ 0 ] ) . msg ) ;
129182
130183 Event funding_ready = get_event ( node_a . manager ) ;
131- Assert ( funding_ready is Event . Event_FundingGenerationReady , 9 ) ;
184+ Assert ( funding_ready is Event . Event_FundingGenerationReady , 11 ) ;
132185
133186 // We could use funding_transaction_generated here, but test batching
134- TwoTuple_ThirtyTwoBytesPublicKeyZ [ ] channel = new TwoTuple_ThirtyTwoBytesPublicKeyZ [ 1 ] ;
135- channel [ 0 ] = TwoTuple_ThirtyTwoBytesPublicKeyZ . of ( ( ( Event . Event_FundingGenerationReady ) funding_ready ) . temporary_channel_id , ( ( Event . Event_FundingGenerationReady ) funding_ready ) . counterparty_node_id ) ;
187+ TwoTuple_ChannelIdPublicKeyZ [ ] channel = new TwoTuple_ChannelIdPublicKeyZ [ 1 ] ;
188+ channel [ 0 ] = TwoTuple_ChannelIdPublicKeyZ . of ( ( ( Event . Event_FundingGenerationReady ) funding_ready ) . temporary_channel_id , ( ( Event . Event_FundingGenerationReady ) funding_ready ) . counterparty_node_id ) ;
136189
137190 // Hand-crafted transaction which has a dummy witness and can pay to our script
138191 byte [ ] transaction = new byte [ 99 ] ;
@@ -185,17 +238,17 @@ static void NodeTest() {
185238 transaction [ 46 ] = 255 ;
186239 transaction [ 47 ] = 255 ;
187240 transaction [ 48 ] = 1 ;
188- transaction [ 49 ] = 34 ;
189- transaction [ 50 ] = 2 ;
190- transaction [ 51 ] = 0 ;
241+ transaction [ 49 ] = 160 ;
242+ transaction [ 50 ] = 134 ;
243+ transaction [ 51 ] = 1 ;
191244 transaction [ 52 ] = 0 ;
192245 transaction [ 53 ] = 0 ;
193246 transaction [ 54 ] = 0 ;
194247 transaction [ 55 ] = 0 ;
195248 transaction [ 56 ] = 0 ;
196249 transaction [ 57 ] = 34 ;
197250
198- Assert ( ( ( Event . Event_FundingGenerationReady ) funding_ready ) . output_script . Length == 34 , 10 ) ;
251+ Assert ( ( ( Event . Event_FundingGenerationReady ) funding_ready ) . output_script . Length == 34 , 12 ) ;
199252 for ( int i = 0 ; i < 34 ; i ++ ) {
200253 transaction [ 58 + i ] = ( ( Event . Event_FundingGenerationReady ) funding_ready ) . output_script [ i ] ;
201254 }
@@ -209,6 +262,68 @@ static void NodeTest() {
209262 transaction [ 98 ] = 0 ;
210263
211264 node_a . manager . batch_funding_transaction_generated ( channel , transaction ) ;
265+
266+ MessageSendEvent [ ] funding_msg = node_a . manager . as_MessageSendEventsProvider ( ) . get_and_clear_pending_msg_events ( ) ;
267+ Assert ( funding_msg . Length == 1 , 13 ) ;
268+ Assert ( funding_msg [ 0 ] is MessageSendEvent . MessageSendEvent_SendFundingCreated , 14 ) ;
269+ node_b . manager . as_ChannelMessageHandler ( ) . handle_funding_created ( node_a . manager . get_our_node_id ( ) , ( ( MessageSendEvent . MessageSendEvent_SendFundingCreated ) funding_msg [ 0 ] ) . msg ) ;
270+
271+ Event bs_chan_pending = get_event ( node_b . manager ) ;
272+ Assert ( bs_chan_pending is Event . Event_ChannelPending , 15 ) ;
273+
274+ MessageSendEvent [ ] signed_ready_msgs = node_b . manager . as_MessageSendEventsProvider ( ) . get_and_clear_pending_msg_events ( ) ;
275+ Assert ( signed_ready_msgs . Length == 2 , 16 ) ;
276+ Assert ( signed_ready_msgs [ 0 ] is MessageSendEvent . MessageSendEvent_SendFundingSigned , 17 ) ;
277+ node_a . manager . as_ChannelMessageHandler ( ) . handle_funding_signed ( node_b . manager . get_our_node_id ( ) , ( ( MessageSendEvent . MessageSendEvent_SendFundingSigned ) signed_ready_msgs [ 0 ] ) . msg ) ;
278+ Assert ( node_a . broadcaster . broadcasted_len == 99 , 18 ) ;
279+
280+ Event as_chan_pending = get_event ( node_a . manager ) ;
281+ Assert ( as_chan_pending is Event . Event_ChannelPending , 19 ) ;
282+
283+ MessageSendEvent [ ] as_ready = node_a . manager . as_MessageSendEventsProvider ( ) . get_and_clear_pending_msg_events ( ) ;
284+ Assert ( as_ready . Length == 1 , 20 ) ;
285+ Assert ( as_ready [ 0 ] is MessageSendEvent . MessageSendEvent_SendChannelReady , 21 ) ;
286+
287+ Assert ( signed_ready_msgs [ 1 ] is MessageSendEvent . MessageSendEvent_SendChannelReady , 22 ) ;
288+ node_a . manager . as_ChannelMessageHandler ( ) . handle_channel_ready ( node_b . manager . get_our_node_id ( ) , ( ( MessageSendEvent . MessageSendEvent_SendChannelReady ) signed_ready_msgs [ 1 ] ) . msg ) ;
289+
290+ MessageSendEvent [ ] as_chan_update = node_a . manager . as_MessageSendEventsProvider ( ) . get_and_clear_pending_msg_events ( ) ;
291+ Assert ( as_chan_update . Length == 1 , 23 ) ;
292+ Assert ( as_chan_update [ 0 ] is MessageSendEvent . MessageSendEvent_SendChannelUpdate , 24 ) ;
293+
294+ node_b . manager . as_ChannelMessageHandler ( ) . handle_channel_ready ( node_a . manager . get_our_node_id ( ) , ( ( MessageSendEvent . MessageSendEvent_SendChannelReady ) as_ready [ 0 ] ) . msg ) ;
295+
296+ Event as_chan_ready = get_event ( node_a . manager ) ;
297+ Assert ( as_chan_ready is Event . Event_ChannelReady , 25 ) ;
298+
299+ Event bs_chan_ready = get_event ( node_b . manager ) ;
300+ Assert ( bs_chan_ready is Event . Event_ChannelReady , 26 ) ;
301+
302+ MessageSendEvent [ ] bs_chan_update = node_b . manager . as_MessageSendEventsProvider ( ) . get_and_clear_pending_msg_events ( ) ;
303+ Assert ( bs_chan_update . Length == 1 , 27 ) ;
304+ Assert ( bs_chan_update [ 0 ] is MessageSendEvent . MessageSendEvent_SendChannelUpdate , 28 ) ;
305+
306+ // Now that we have a channel, pay using a BOLT12 offer!
307+
308+ Result_OfferWithDerivedMetadataBuilderBolt12SemanticErrorZ builder_res = node_b . manager . create_offer_builder ( ) ;
309+ Assert ( builder_res . is_ok ( ) , 29 ) ;
310+ Result_OfferBolt12SemanticErrorZ offer_res = ( ( Result_OfferWithDerivedMetadataBuilderBolt12SemanticErrorZ . Result_OfferWithDerivedMetadataBuilderBolt12SemanticErrorZ_OK ) builder_res ) . res . build ( ) ;
311+ Assert ( offer_res . is_ok ( ) , 30 ) ;
312+ Offer offer = ( ( Result_OfferBolt12SemanticErrorZ . Result_OfferBolt12SemanticErrorZ_OK ) offer_res ) . res ;
313+
314+ Result_NoneBolt12SemanticErrorZ pay_res = node_a . manager . pay_for_offer ( offer , Option_u64Z . none ( ) , Option_u64Z . some ( 42000 ) , Option_StrZ . none ( ) , new byte [ 32 ] , Retry . attempts ( 0 ) , Option_u64Z . none ( ) ) ;
315+ Assert ( pay_res . is_ok ( ) , 31 ) ;
316+
317+ OnionMessage as_invreq = node_a . messenger . as_OnionMessageHandler ( ) . next_onion_message_for_peer ( node_b . manager . get_our_node_id ( ) ) ;
318+ node_b . messenger . as_OnionMessageHandler ( ) . handle_onion_message ( node_a . manager . get_our_node_id ( ) , as_invreq ) ;
319+
320+ OnionMessage bs_inv = node_b . messenger . as_OnionMessageHandler ( ) . next_onion_message_for_peer ( node_a . manager . get_our_node_id ( ) ) ;
321+ node_a . messenger . as_OnionMessageHandler ( ) . handle_onion_message ( node_b . manager . get_our_node_id ( ) , bs_inv ) ;
322+
323+ // At this point node_a will generate a commitment update for node_b, which we check exists but don't bother to handle:
324+ MessageSendEvent [ ] as_commit = node_a . manager . as_MessageSendEventsProvider ( ) . get_and_clear_pending_msg_events ( ) ;
325+ Assert ( as_commit . Length == 1 , 32 ) ;
326+ Assert ( as_commit [ 0 ] is MessageSendEvent . MessageSendEvent_UpdateHTLCs , 33 ) ;
212327 }
213328
214329 static void Main ( string [ ] args ) {
0 commit comments