1
1
#![ recursion_limit = "128" ]
2
2
3
3
use env_logger;
4
- use futures:: { future :: join_all , Future , Stream } ;
4
+ use futures:: { Future , Stream } ;
5
5
use interledger:: {
6
6
cli,
7
7
node:: { AccountDetails , InterledgerNode } ,
@@ -116,9 +116,10 @@ fn three_nodes() {
116
116
secret_seed : cli:: random_secret ( ) ,
117
117
route_broadcast_interval : Some ( 200 ) ,
118
118
} ;
119
+ let node2_clone = node2. clone ( ) ;
119
120
runtime. spawn (
120
- join_all ( vec ! [
121
- node2 . insert_account( AccountDetails {
121
+ node2_clone
122
+ . insert_account ( AccountDetails {
122
123
ilp_address : Address :: from_str ( "example.one" ) . unwrap ( ) ,
123
124
asset_code : "XYZ" . to_string ( ) ,
124
125
asset_scale : 9 ,
@@ -138,44 +139,45 @@ fn three_nodes() {
138
139
packets_per_minute_limit : None ,
139
140
amount_per_minute_limit : None ,
140
141
settlement_engine_url : None ,
141
- } ) ,
142
- node2. insert_account( AccountDetails {
143
- ilp_address: Address :: from_str( "example.two.three" ) . unwrap( ) ,
144
- asset_code: "ABC" . to_string( ) ,
145
- asset_scale: 6 ,
146
- btp_incoming_token: Some ( "three" . to_string( ) ) ,
147
- btp_uri: None ,
148
- http_endpoint: None ,
149
- http_incoming_token: None ,
150
- http_outgoing_token: None ,
151
- max_packet_amount: u64 :: max_value( ) ,
152
- min_balance: Some ( -1_000_000_000 ) ,
153
- settle_threshold: None ,
154
- settle_to: None ,
155
- send_routes: true ,
156
- receive_routes: false ,
157
- routing_relation: Some ( "Child" . to_string( ) ) ,
158
- round_trip_time: None ,
159
- packets_per_minute_limit: None ,
160
- amount_per_minute_limit: None ,
161
- settlement_engine_url: None ,
162
- } ) ,
163
- ] )
164
- . and_then ( move |_| node2. serve ( ) )
165
- . and_then ( move |_| {
166
- let client = reqwest:: r#async:: Client :: new ( ) ;
167
- client
168
- . put ( & format ! ( "http://localhost:{}/rates" , node2_http) )
169
- . header ( "Authorization" , "Bearer admin" )
170
- . json ( & json ! ( { "ABC" : 2 , "XYZ" : 1 } ) )
171
- . send ( )
172
- . map_err ( |err| panic ! ( err) )
173
- . and_then ( |res| {
174
- res. error_for_status ( )
175
- . expect ( "Error setting exchange rates" ) ;
176
- Ok ( ( ) )
142
+ } )
143
+ . and_then ( move |_| {
144
+ node2_clone. insert_account ( AccountDetails {
145
+ ilp_address : Address :: from_str ( "example.two.three" ) . unwrap ( ) ,
146
+ asset_code : "ABC" . to_string ( ) ,
147
+ asset_scale : 6 ,
148
+ btp_incoming_token : Some ( "three" . to_string ( ) ) ,
149
+ btp_uri : None ,
150
+ http_endpoint : None ,
151
+ http_incoming_token : Some ( "three" . to_string ( ) ) ,
152
+ http_outgoing_token : None ,
153
+ max_packet_amount : u64:: max_value ( ) ,
154
+ min_balance : Some ( -1_000_000_000 ) ,
155
+ settle_threshold : None ,
156
+ settle_to : None ,
157
+ send_routes : true ,
158
+ receive_routes : false ,
159
+ routing_relation : Some ( "Child" . to_string ( ) ) ,
160
+ round_trip_time : None ,
161
+ packets_per_minute_limit : None ,
162
+ amount_per_minute_limit : None ,
163
+ settlement_engine_url : None ,
177
164
} )
178
- } ) ,
165
+ } )
166
+ . and_then ( move |_| node2. serve ( ) )
167
+ . and_then ( move |_| {
168
+ let client = reqwest:: r#async:: Client :: new ( ) ;
169
+ client
170
+ . put ( & format ! ( "http://localhost:{}/rates" , node2_http) )
171
+ . header ( "Authorization" , "Bearer admin" )
172
+ . json ( & json ! ( { "ABC" : 2 , "XYZ" : 1 } ) )
173
+ . send ( )
174
+ . map_err ( |err| panic ! ( err) )
175
+ . and_then ( |res| {
176
+ res. error_for_status ( )
177
+ . expect ( "Error setting exchange rates" ) ;
178
+ Ok ( ( ) )
179
+ } )
180
+ } ) ,
179
181
) ;
180
182
181
183
let node3 = InterledgerNode {
@@ -193,8 +195,8 @@ fn three_nodes() {
193
195
runtime. spawn (
194
196
// Wait a bit to make sure the other node's BTP server is listening
195
197
delay ( 50 ) . map_err ( |err| panic ! ( err) ) . and_then ( move |_| {
196
- join_all ( vec ! [
197
- node3_clone . insert_account( AccountDetails {
198
+ node3_clone
199
+ . insert_account ( AccountDetails {
198
200
ilp_address : Address :: from_str ( "example.two.three" ) . unwrap ( ) ,
199
201
asset_code : "ABC" . to_string ( ) ,
200
202
asset_scale : 6 ,
@@ -214,30 +216,31 @@ fn three_nodes() {
214
216
packets_per_minute_limit : None ,
215
217
amount_per_minute_limit : None ,
216
218
settlement_engine_url : None ,
217
- } ) ,
218
- node3_clone. insert_account( AccountDetails {
219
- ilp_address: Address :: from_str( "example.two" ) . unwrap( ) ,
220
- asset_code: "ABC" . to_string( ) ,
221
- asset_scale: 6 ,
222
- btp_incoming_token: None ,
223
- btp_uri: Some ( format!( "btp+ws://:three@localhost:{}" , node2_btp) ) ,
224
- http_endpoint: None ,
225
- http_incoming_token: None ,
226
- http_outgoing_token: None ,
227
- max_packet_amount: u64 :: max_value( ) ,
228
- min_balance: Some ( -1_000_000_000 ) ,
229
- settle_threshold: None ,
230
- settle_to: None ,
231
- send_routes: false ,
232
- receive_routes: true ,
233
- routing_relation: Some ( "Parent" . to_string( ) ) ,
234
- round_trip_time: None ,
235
- packets_per_minute_limit: None ,
236
- amount_per_minute_limit: None ,
237
- settlement_engine_url: None ,
238
- } ) ,
239
- ] )
240
- . and_then ( move |_| node3. serve ( ) )
219
+ } )
220
+ . and_then ( move |_| {
221
+ node3_clone. insert_account ( AccountDetails {
222
+ ilp_address : Address :: from_str ( "example.two" ) . unwrap ( ) ,
223
+ asset_code : "ABC" . to_string ( ) ,
224
+ asset_scale : 6 ,
225
+ btp_incoming_token : None ,
226
+ btp_uri : Some ( format ! ( "btp+ws://:three@localhost:{}" , node2_btp) ) ,
227
+ http_endpoint : None ,
228
+ http_incoming_token : None ,
229
+ http_outgoing_token : None ,
230
+ max_packet_amount : u64:: max_value ( ) ,
231
+ min_balance : Some ( -1_000_000_000 ) ,
232
+ settle_threshold : None ,
233
+ settle_to : None ,
234
+ send_routes : false ,
235
+ receive_routes : true ,
236
+ routing_relation : Some ( "Parent" . to_string ( ) ) ,
237
+ round_trip_time : None ,
238
+ packets_per_minute_limit : None ,
239
+ amount_per_minute_limit : None ,
240
+ settlement_engine_url : None ,
241
+ } )
242
+ } )
243
+ . and_then ( move |_| node3. serve ( ) )
241
244
} ) ,
242
245
) ;
243
246
@@ -278,16 +281,82 @@ fn three_nodes() {
278
281
Ok ( ( ) )
279
282
} ) ;
280
283
284
+ let get_balance = |account_id, node_port, admin_token| {
285
+ let client = reqwest:: r#async:: Client :: new ( ) ;
286
+ client
287
+ . get ( & format ! (
288
+ "http://localhost:{}/accounts/{}/balance" ,
289
+ node_port, account_id
290
+ ) )
291
+ . header ( "Authorization" , format ! ( "Bearer {}" , admin_token) )
292
+ . send ( )
293
+ . map_err ( |err| {
294
+ eprintln ! ( "Error getting account data: {:?}" , err) ;
295
+ err
296
+ } )
297
+ . and_then ( |res| res. error_for_status ( ) )
298
+ . and_then ( |res| res. into_body ( ) . concat2 ( ) )
299
+ } ;
300
+
301
+ // Node 1 sends 1000 to Node 3. However, Node1's scale is 9,
302
+ // while Node 3's scale is 6. This means that Node 3 will
303
+ // see 1000x less. In addition, the conversion rate is 2:1
304
+ // for 3's asset, so he will receive 2 total.
281
305
send_1_to_3
282
306
. map_err ( |err| {
283
307
eprintln ! ( "Error sending from node 1 to node 3: {:?}" , err) ;
284
308
err
285
309
} )
286
- . and_then ( |_| send_3_to_1
310
+ . and_then ( move |_| {
311
+ get_balance ( 0 , node1_http, "default account holder" )
312
+ . and_then ( move |ret| {
313
+ let ret = str:: from_utf8 ( & ret) . unwrap ( ) ;
314
+ assert_eq ! ( ret, "{\" balance\" :\" -1000\" }" ) ;
315
+ Ok ( ( ) )
316
+ } ) . and_then ( move |_| {
317
+ // Node 2 updates Node 3's balance properly.
318
+ get_balance ( 1 , node2_http, "three" ) . and_then ( move |ret| {
319
+ let ret = str:: from_utf8 ( & ret) . unwrap ( ) ;
320
+ assert_eq ! ( ret, "{\" balance\" :\" 2\" }" ) ;
321
+ Ok ( ( ) )
322
+ } )
323
+ } ) . and_then ( move |_| {
324
+ // Node 3's balance is properly adjusted after
325
+ // it's received the message from node 2
326
+ get_balance ( 0 , node3_http, "default account holder" ) . and_then ( move |ret| {
327
+ let ret = str:: from_utf8 ( & ret) . unwrap ( ) ;
328
+ assert_eq ! ( ret, "{\" balance\" :\" 2\" }" ) ;
329
+ Ok ( ( ) )
330
+ } )
331
+ } )
332
+ } )
333
+ . and_then ( move |_| send_3_to_1
287
334
. map_err ( |err| {
288
335
eprintln ! ( "Error sending from node 3 to node 1: {:?}" , err) ;
289
336
err
290
337
} ) )
338
+ . and_then ( move |_| {
339
+ get_balance ( 0 , node1_http, "default account holder" ) . and_then ( move |ret| {
340
+ let ret = str:: from_utf8 ( & ret) . unwrap ( ) ;
341
+ assert_eq ! ( ret, "{\" balance\" :\" 499000\" }" ) ;
342
+ Ok ( ( ) )
343
+ } ) . and_then ( move |_| {
344
+ // Node 2 updates Node 3's balance properly.
345
+ get_balance ( 1 , node2_http, "three" ) . and_then ( move |ret| {
346
+ let ret = str:: from_utf8 ( & ret) . unwrap ( ) ;
347
+ assert_eq ! ( ret, "{\" balance\" :\" -998\" }" ) ;
348
+ Ok ( ( ) )
349
+ } )
350
+ } ) . and_then ( move |_| {
351
+ // Node 3's balance is properly adjusted after
352
+ // it's received the message from node 2
353
+ get_balance ( 0 , node3_http, "default account holder" ) . and_then ( move |ret| {
354
+ let ret = str:: from_utf8 ( & ret) . unwrap ( ) ;
355
+ assert_eq ! ( ret, "{\" balance\" :\" -998\" }" ) ;
356
+ Ok ( ( ) )
357
+ } )
358
+ } )
359
+ } )
291
360
} ) ,
292
361
)
293
362
. unwrap ( ) ;
0 commit comments