@@ -12,12 +12,12 @@ use primitives::{
12
12
adapter:: Adapter ,
13
13
sentry:: {
14
14
channel_list:: { ChannelListQuery , LastApprovedQuery } ,
15
- LastApproved , LastApprovedResponse , SuccessResponse , SpenderLeaf , SpenderResponse
15
+ LastApproved , LastApprovedResponse , MessageResponse , SuccessResponse , SpenderLeaf , SpenderResponse , AllSpendersResponse
16
16
} ,
17
17
spender:: { Spendable , Deposit } ,
18
- validator:: MessageTypes ,
18
+ validator:: { MessageTypes , NewState } ,
19
19
channel_v5:: Channel as ChannelV5 ,
20
- Address , Channel , ChannelId , UnifiedNum
20
+ Address , BigNum , Channel , ChannelId , UnifiedNum
21
21
} ;
22
22
use slog:: error;
23
23
use std:: {
@@ -273,25 +273,7 @@ pub async fn get_spender_limits<A: Adapter + 'static>(
273
273
let channel_id = ChannelId :: from_hex ( route_params. index ( 0 ) ) ?;
274
274
let spender = Address :: from_str ( & route_params. index ( 1 ) ) ?;
275
275
276
- let default_response = Response :: builder ( )
277
- . header ( "Content-type" , "application/json" )
278
- . body (
279
- serde_json:: to_string ( & SpenderResponse {
280
- total_deposited : None ,
281
- spender_leaf : None ,
282
- } ) ?
283
- . into ( ) ,
284
- )
285
- . expect ( "should build response" ) ;
286
-
287
- let approve_state = match latest_approve_state_v5 ( & app. pool , & channel) . await ? {
288
- Some ( approve_state) => approve_state,
289
- None => return Ok ( default_response) ,
290
- } ;
291
-
292
- let state_root = approve_state. msg . state_root . clone ( ) ;
293
-
294
- let new_state = latest_new_state_v5 ( & app. pool , & channel, & state_root) . await ?. ok_or ( ResponseError :: BadRequest ( "non-existing NewState" . to_string ( ) ) ) ?;
276
+ let new_state = get_corresponding_new_state ( & app. pool , & channel) . await . ok_or_else ( || ResponseError :: NotFound ) ?;
295
277
296
278
let latest_spendable = fetch_spendable ( app. pool . clone ( ) , & spender, & channel_id)
297
279
. await ?;
@@ -306,54 +288,98 @@ pub async fn get_spender_limits<A: Adapter + 'static>(
306
288
// Calculate total_spent
307
289
let spender_balance = new_state. msg . balances . get ( & spender) . ok_or_else ( || ResponseError :: BadRequest ( "No balance for this spender" . to_string ( ) ) ) ?;
308
290
309
- let spender_balance = UnifiedNum :: from_u64 ( spender_balance. to_u64 ( ) . expect ( "Consider replacing this in a way that uses UnifiedMap" ) ) ;
310
- let total_spent = total_deposited. checked_sub ( & spender_balance) . ok_or_else ( || ResponseError :: BadRequest ( "Total spent is too large" . to_string ( ) ) ) ?;
311
-
312
- let spender_leaf = SpenderLeaf {
313
- total_spent,
314
- // merkle_proof: [u8; 32], // TODO
315
- } ;
291
+ // TODO: Maybe throw error if None?
292
+ let spender_leaf = get_spender_leaf_for_spender ( spender_balance, & total_deposited) ;
316
293
317
294
// Return
318
295
let res = SpenderResponse {
319
296
total_deposited : Some ( total_deposited) ,
320
- spender_leaf : Some ( spender_leaf ) ,
297
+ spender_leaf,
321
298
} ;
322
299
Ok ( success_response ( serde_json:: to_string ( & res) ?) )
323
300
}
301
+
324
302
pub async fn get_all_spender_limits < A : Adapter + ' static > (
325
303
req : Request < Body > ,
326
304
app : & Application < A > ,
327
305
) -> Result < Response < Body > , ResponseError > {
328
- let route_params = req
329
- . extensions ( )
330
- . get :: < RouteParams > ( )
331
- . expect ( "request should have route params" ) ;
332
-
333
306
let channel = req
334
307
. extensions ( )
335
308
. get :: < ChannelV5 > ( )
336
309
. expect ( "Request should have Channel" )
337
310
. to_owned ( ) ;
338
311
339
- // Get all spenders for this channel
312
+ let new_state = get_corresponding_new_state ( & app. pool , & channel) . await . ok_or_else ( || ResponseError :: NotFound ) ?;
313
+
314
+ let mut all_spender_limits: HashMap < Address , SpenderResponse > = HashMap :: new ( ) ;
315
+
316
+ // Using for loop to avoid async closures
317
+ for ( spender, balance) in new_state. msg . balances . iter ( ) {
318
+ let latest_spendable = fetch_spendable ( app. pool . clone ( ) , & spender, & channel. id ( ) ) . await . expect ( "todo: fix" ) ;
319
+
320
+ let latest_spendable = match latest_spendable {
321
+ Some ( spendable) => spendable,
322
+ None => create_spendable_document ( & app. adapter , app. pool . clone ( ) , & channel, & spender) . await . expect ( "todo" ) ,
323
+ } ;
324
+
325
+ let total_deposited = latest_spendable. deposit . total . checked_add ( & latest_spendable. deposit . still_on_create2 ) . ok_or_else ( || ResponseError :: BadRequest ( "Total Deposited is too large" . to_string ( ) ) ) . expect ( "todo" ) ;
326
+
327
+ // TODO: Maybe throw error if None?
328
+ let spender_leaf = get_spender_leaf_for_spender ( balance, & total_deposited) ;
329
+
330
+ let spender_response = SpenderResponse {
331
+ total_deposited : Some ( total_deposited) ,
332
+ spender_leaf,
333
+ } ;
340
334
341
- // Calculate spender limits for every spender
335
+ all_spender_limits. insert ( spender. clone ( ) , spender_response) ;
336
+ }
342
337
343
338
// Format and return output
344
339
345
- let default_response = Response :: builder ( )
346
- . header ( "Content-type" , "application/json" )
347
- . body (
348
- serde_json:: to_string ( & LastApprovedResponse {
349
- last_approved : None ,
350
- heartbeats : None ,
351
- } ) ?
352
- . into ( ) ,
353
- )
354
- . expect ( "should build response" ) ;
340
+ let res = AllSpendersResponse {
341
+ spenders : Some ( all_spender_limits) ,
342
+ } ;
343
+
344
+ Ok ( success_response ( serde_json:: to_string ( & res) ?) )
345
+ }
346
+
347
+ async fn get_corresponding_new_state ( pool : & DbPool , channel : & ChannelV5 ) -> Option < MessageResponse < NewState > > {
348
+ // Get all spenders for this channel
349
+ let approve_state = match latest_approve_state_v5 ( & pool, & channel) . await {
350
+ Ok ( Some ( approve_state) ) => approve_state,
351
+ _ => return None ,
352
+ } ;
353
+
354
+ let state_root = approve_state. msg . state_root . clone ( ) ;
355
+
356
+ let new_state = match latest_new_state_v5 ( & pool, & channel, & state_root) . await {
357
+ Ok ( Some ( new_state) ) => Some ( new_state) ,
358
+ _ => None ,
359
+ } ;
360
+
361
+ new_state
362
+ }
363
+
364
+ // TODO pass UnifiedNum instead
365
+ fn get_spender_leaf_for_spender ( spender_balance : & BigNum , total_deposited : & UnifiedNum ) -> Option < SpenderLeaf > {
366
+ let spender_balance = match spender_balance. to_u64 ( ) {
367
+ Some ( balance) => UnifiedNum :: from_u64 ( balance) ,
368
+ None => return None ,
369
+ } ;
370
+
371
+ let total_spent = match total_deposited. checked_sub ( & spender_balance) {
372
+ Some ( spent) => spent,
373
+ None => return None ,
374
+ } ;
375
+
376
+ // Return
377
+ let leaf = SpenderLeaf {
378
+ total_spent,
379
+ // merkle_proof: [u8; 32], // TODO
380
+ } ;
355
381
356
- Ok ( success_response ( serde_json :: to_string ( & default_response ) ? ) )
382
+ Some ( leaf )
357
383
}
358
384
359
385
#[ cfg( test) ]
0 commit comments