@@ -21,11 +21,10 @@ static void SimpleConstructionTest() {
21
21
}
22
22
23
23
class TestBroadcaster : BroadcasterInterfaceInterface {
24
- public bool broadcasted = false ;
24
+ public int broadcasted_len = 0 ;
25
25
public void broadcast_transactions ( byte [ ] [ ] txn ) {
26
26
Assert ( txn . Length == 1 , 1 ) ;
27
- Assert ( txn [ 0 ] . Length == 42 , 2 ) ;
28
- broadcasted = true ;
27
+ broadcasted_len = txn [ 0 ] . Length ;
29
28
}
30
29
}
31
30
@@ -35,7 +34,7 @@ static void SimpleTraitTest() {
35
34
byte [ ] [ ] txn = new byte [ 1 ] [ ] ;
36
35
txn [ 0 ] = new byte [ 42 ] ;
37
36
broadcaster . broadcast_transactions ( txn ) ;
38
- Assert ( impl . broadcasted == true , 3 ) ;
37
+ Assert ( impl . broadcasted_len == 42 , 3 ) ;
39
38
}
40
39
41
40
class TestEstimator : FeeEstimatorInterface {
@@ -61,6 +60,7 @@ public ChannelMonitorUpdateStatus persist_new_channel(OutPoint channel_id, Chann
61
60
public ChannelMonitorUpdateStatus update_persisted_channel ( OutPoint channel_id , ChannelMonitorUpdate update , ChannelMonitor data , MonitorUpdateId update_id ) {
62
61
return ChannelMonitorUpdateStatus . LDKChannelMonitorUpdateStatus_Completed ;
63
62
}
63
+ public void archive_persisted_channel ( OutPoint channel_id ) { }
64
64
}
65
65
66
66
class TestEventHandler : EventHandlerInterface {
@@ -77,31 +77,75 @@ static Event get_event(ChannelManager manager) {
77
77
return impl . events [ 0 ] ;
78
78
}
79
79
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
+
80
113
class Node {
81
- public BroadcasterInterface broadcaster = BroadcasterInterface . new_impl ( new TestBroadcaster ( ) ) ;
114
+ public TestBroadcaster broadcaster = new TestBroadcaster ( ) ;
82
115
public FeeEstimator estimator = FeeEstimator . new_impl ( new TestEstimator ( ) ) ;
83
116
public Logger logger = Logger . new_impl ( new TestLogger ( ) ) ;
84
117
public Persist persister = Persist . new_impl ( new TestPersister ( ) ) ;
85
118
public ChainParameters chain_params = ChainParameters . of ( Network . LDKNetwork_Bitcoin , BestBlock . from_network ( Network . LDKNetwork_Bitcoin ) ) ;
86
119
120
+ public BroadcasterInterface ldk_broadcaster ;
87
121
public ChainMonitor chain_monitor ;
88
122
public NetworkGraph graph ;
89
123
public MultiThreadedLockableScore scorer ;
90
- public DefaultRouter router ;
124
+ public Router router ;
91
125
public KeysManager keys ;
92
126
public ChannelManager manager ;
127
+ public OnionMessenger messenger ;
93
128
94
129
public Node ( byte seed ) {
95
130
byte [ ] seed_bytes = new byte [ 32 ] ;
96
131
for ( int i = 0 ; i < 32 ; i ++ ) seed_bytes [ i ] = seed ;
97
132
keys = KeysManager . of ( seed_bytes , 42 , 43 ) ;
98
133
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 ) ;
100
136
graph = NetworkGraph . of ( Network . LDKNetwork_Bitcoin , logger ) ;
101
137
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 ( ) ) ;
103
138
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 ( ) ) ;
105
149
}
106
150
}
107
151
@@ -110,29 +154,38 @@ static void NodeTest() {
110
154
Node node_b = new Node ( 2 ) ;
111
155
112
156
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 ( ) ;
113
158
Init init_msg = Init . of ( init_features , Option_CVec_ThirtyTwoBytesZZ . none ( ) , Option_SocketAddressZ . none ( ) ) ;
114
159
node_a . manager . as_ChannelMessageHandler ( ) . peer_connected ( node_b . manager . get_our_node_id ( ) , init_msg , false ) ;
115
160
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 ) ;
116
163
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 ) ;
118
165
Assert ( res . is_ok ( ) , 4 ) ;
119
166
120
167
MessageSendEvent [ ] msgs = node_a . manager . as_MessageSendEventsProvider ( ) . get_and_clear_pending_msg_events ( ) ;
121
168
Assert ( msgs . Length == 1 , 5 ) ;
122
169
Assert ( msgs [ 0 ] is MessageSendEvent . MessageSendEvent_SendOpenChannel , 6 ) ;
123
170
node_b . manager . as_ChannelMessageHandler ( ) . handle_open_channel ( node_a . manager . get_our_node_id ( ) , ( ( MessageSendEvent . MessageSendEvent_SendOpenChannel ) msgs [ 0 ] ) . msg ) ;
124
171
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
+
125
178
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 ) ;
128
181
node_a . manager . as_ChannelMessageHandler ( ) . handle_accept_channel ( node_b . manager . get_our_node_id ( ) , ( ( MessageSendEvent . MessageSendEvent_SendAcceptChannel ) response_msgs [ 0 ] ) . msg ) ;
129
182
130
183
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 ) ;
132
185
133
186
// 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 ) ;
136
189
137
190
// Hand-crafted transaction which has a dummy witness and can pay to our script
138
191
byte [ ] transaction = new byte [ 99 ] ;
@@ -185,17 +238,17 @@ static void NodeTest() {
185
238
transaction [ 46 ] = 255 ;
186
239
transaction [ 47 ] = 255 ;
187
240
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 ;
191
244
transaction [ 52 ] = 0 ;
192
245
transaction [ 53 ] = 0 ;
193
246
transaction [ 54 ] = 0 ;
194
247
transaction [ 55 ] = 0 ;
195
248
transaction [ 56 ] = 0 ;
196
249
transaction [ 57 ] = 34 ;
197
250
198
- Assert ( ( ( Event . Event_FundingGenerationReady ) funding_ready ) . output_script . Length == 34 , 10 ) ;
251
+ Assert ( ( ( Event . Event_FundingGenerationReady ) funding_ready ) . output_script . Length == 34 , 12 ) ;
199
252
for ( int i = 0 ; i < 34 ; i ++ ) {
200
253
transaction [ 58 + i ] = ( ( Event . Event_FundingGenerationReady ) funding_ready ) . output_script [ i ] ;
201
254
}
@@ -209,6 +262,68 @@ static void NodeTest() {
209
262
transaction [ 98 ] = 0 ;
210
263
211
264
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 ) ;
212
327
}
213
328
214
329
static void Main ( string [ ] args ) {
0 commit comments