@@ -3,7 +3,7 @@ use crate::{
3
3
accounting:: { get_accounting, Side } ,
4
4
campaign:: { get_campaigns_by_channel, update_campaign} ,
5
5
insert_campaign, insert_channel,
6
- spendable:: { fetch_spendable , update_spendable} ,
6
+ spendable:: update_spendable,
7
7
CampaignRemaining , DbPool , RedisError ,
8
8
} ,
9
9
success_response, Application , Auth , ResponseError ,
@@ -25,7 +25,7 @@ use thiserror::Error;
25
25
use tokio_postgres:: error:: SqlState ;
26
26
27
27
#[ derive( Debug , Error ) ]
28
- pub enum Error {
28
+ pub enum Error < AE : AdapterErrorKind + ' static > {
29
29
#[ error( "Error while updating campaign: {0}" ) ]
30
30
FailedUpdate ( String ) ,
31
31
#[ error( "Error while performing calculations" ) ]
@@ -36,8 +36,12 @@ pub enum Error {
36
36
NewBudget ( String ) ,
37
37
#[ error( "Spendable amount for campaign creator {0} not found" ) ]
38
38
SpenderNotFound ( Address ) ,
39
+ #[ error( "Channel token is not whitelisted" ) ]
40
+ ChannelTokenNotWhitelisted ,
39
41
#[ error( "Campaign was not modified because of spending constraints" ) ]
40
42
CampaignNotModified ,
43
+ #[ error( "Error while updating spendable for creator: {0}" ) ]
44
+ LatestSpendable ( #[ from] LatestSpendableError < AE > ) ,
41
45
#[ error( "Redis error: {0}" ) ]
42
46
Redis ( #[ from] RedisError ) ,
43
47
#[ error( "DB Pool error: {0}" ) ]
@@ -159,10 +163,10 @@ pub async fn create_campaign<A: Adapter>(
159
163
. await ?
160
164
. iter ( )
161
165
. sum :: < Option < UnifiedNum > > ( )
162
- . ok_or ( Error :: Calculation ) ?
166
+ . ok_or ( Error :: < A :: AdapterError > :: Calculation ) ?
163
167
// DO NOT FORGET to add the Campaign being created right now!
164
168
. checked_add ( & campaign. budget )
165
- . ok_or ( Error :: Calculation ) ?;
169
+ . ok_or ( Error :: < A :: AdapterError > :: Calculation ) ?;
166
170
167
171
// `new_campaigns_remaining <= total_remaining` should be upheld
168
172
// `campaign.budget < total_remaining` should also be upheld!
@@ -215,11 +219,13 @@ pub async fn create_campaign<A: Adapter>(
215
219
}
216
220
217
221
pub mod update_campaign {
222
+ use primitives:: Config ;
223
+
218
224
use crate :: db:: { accounting:: Side , CampaignRemaining } ;
219
225
220
226
use super :: * ;
221
227
222
- pub async fn handle_route < A : Adapter > (
228
+ pub async fn handle_route < A : Adapter + ' static > (
223
229
req : Request < Body > ,
224
230
app : & Application < A > ,
225
231
) -> Result < Response < Body > , ResponseError > {
@@ -236,7 +242,9 @@ pub mod update_campaign {
236
242
237
243
// modify Campaign
238
244
let modified_campaign = modify_campaign (
245
+ app. adapter . clone ( ) ,
239
246
& app. pool ,
247
+ & app. config ,
240
248
& app. campaign_remaining ,
241
249
campaign_being_mutated,
242
250
modify_campaign_fields,
@@ -247,18 +255,20 @@ pub mod update_campaign {
247
255
Ok ( success_response ( serde_json:: to_string ( & modified_campaign) ?) )
248
256
}
249
257
250
- pub async fn modify_campaign (
258
+ pub async fn modify_campaign < A : Adapter + ' static > (
259
+ adapter : A ,
251
260
pool : & DbPool ,
261
+ config : & Config ,
252
262
campaign_remaining : & CampaignRemaining ,
253
263
campaign : Campaign ,
254
264
modify_campaign : ModifyCampaign ,
255
- ) -> Result < Campaign , Error > {
256
- // *NOTE*: When updating campaigns make sure sum(campaigns.map(getRemaining)) <= totalDepoisted - totalspent
265
+ ) -> Result < Campaign , Error < A :: AdapterError > > {
266
+ // *NOTE*: When updating campaigns make sure sum(campaigns.map(getRemaining)) <= totalDeposited - totalSpent
257
267
// !WARNING!: totalSpent != sum(campaign.map(c => c.spending)) therefore we must always calculate remaining funds based on total_deposit - lastApprovedNewState.spenders[user]
258
268
// *NOTE*: To close a campaign set campaignBudget to campaignSpent so that spendable == 0
259
269
260
270
let delta_budget = if let Some ( new_budget) = modify_campaign. budget {
261
- get_delta_budget ( campaign_remaining, & campaign, new_budget) . await ?
271
+ get_delta_budget :: < A > ( campaign_remaining, & campaign, new_budget) . await ?
262
272
} else {
263
273
None
264
274
} ;
@@ -278,10 +288,14 @@ pub mod update_campaign {
278
288
. map ( |accounting| accounting. amount )
279
289
. unwrap_or_default ( ) ;
280
290
291
+ let token = config
292
+ . token_address_whitelist
293
+ . get ( & campaign. channel . token )
294
+ . ok_or ( Error :: ChannelTokenNotWhitelisted ) ?;
295
+
281
296
let latest_spendable =
282
- fetch_spendable ( pool. clone ( ) , & campaign. creator , & campaign. channel . id ( ) )
283
- . await ?
284
- . ok_or ( Error :: SpenderNotFound ( campaign. creator ) ) ?;
297
+ update_latest_spendable ( & adapter, & pool, campaign. channel , token, campaign. creator )
298
+ . await ?;
285
299
286
300
// Gets the latest Spendable for this (spender, channelId) pair
287
301
let total_deposited = latest_spendable. deposit . total ;
@@ -352,11 +366,12 @@ pub mod update_campaign {
352
366
Decrease ( T ) ,
353
367
}
354
368
355
- async fn get_delta_budget (
369
+ // TODO: Figure out a way to simplify Errors and remove the Adapter from here
370
+ async fn get_delta_budget < A : Adapter + ' static > (
356
371
campaign_remaining : & CampaignRemaining ,
357
372
campaign : & Campaign ,
358
373
new_budget : UnifiedNum ,
359
- ) -> Result < Option < DeltaBudget < UnifiedNum > > , Error > {
374
+ ) -> Result < Option < DeltaBudget < UnifiedNum > > , Error < A :: AdapterError > > {
360
375
let current_budget = campaign. budget ;
361
376
362
377
let budget_action = match new_budget. cmp ( & current_budget) {
@@ -913,10 +928,16 @@ mod test {
913
928
campaign. channel . token ,
914
929
) ;
915
930
916
- let modified_campaign =
917
- modify_campaign ( & app. pool , & app. campaign_remaining , campaign. clone ( ) , modify)
918
- . await
919
- . expect ( "Should modify campaign" ) ;
931
+ let modified_campaign = modify_campaign (
932
+ app. adapter . clone ( ) ,
933
+ & app. pool ,
934
+ & app. config ,
935
+ & app. campaign_remaining ,
936
+ campaign. clone ( ) ,
937
+ modify,
938
+ )
939
+ . await
940
+ . expect ( "Should modify campaign" ) ;
920
941
921
942
assert_eq ! ( new_budget, modified_campaign. budget) ;
922
943
assert_eq ! ( Some ( "Updated title" . to_string( ) ) , modified_campaign. title) ;
@@ -997,10 +1018,16 @@ mod test {
997
1018
modified. channel . token ,
998
1019
) ;
999
1020
1000
- let modified_campaign =
1001
- modify_campaign ( & app. pool , & app. campaign_remaining , modified, modify)
1002
- . await
1003
- . expect ( "Should modify campaign" ) ;
1021
+ let modified_campaign = modify_campaign (
1022
+ app. adapter . clone ( ) ,
1023
+ & app. pool ,
1024
+ & app. config ,
1025
+ & app. campaign_remaining ,
1026
+ modified,
1027
+ modify,
1028
+ )
1029
+ . await
1030
+ . expect ( "Should modify campaign" ) ;
1004
1031
1005
1032
assert_eq ! ( lower_budget, modified_campaign. budget) ;
1006
1033
@@ -1054,9 +1081,16 @@ mod test {
1054
1081
modified. channel . token ,
1055
1082
) ;
1056
1083
1057
- let modify_err = modify_campaign ( & app. pool , & app. campaign_remaining , modified, modify)
1058
- . await
1059
- . expect_err ( "Should return Error response" ) ;
1084
+ let modify_err = modify_campaign (
1085
+ app. adapter . clone ( ) ,
1086
+ & app. pool ,
1087
+ & app. config ,
1088
+ & app. campaign_remaining ,
1089
+ modified,
1090
+ modify,
1091
+ )
1092
+ . await
1093
+ . expect_err ( "Should return Error response" ) ;
1060
1094
1061
1095
assert ! (
1062
1096
matches!( modify_err, Error :: NewBudget ( string) if string == "Not enough deposit left for the campaign's new budget" )
0 commit comments