Skip to content

Commit e063aef

Browse files
authored
Merge pull request #434 from AdExNetwork/issue-409-update-spendable-on-modify-campaign
Issue #409 update spendable on modify campaign
2 parents add7568 + 3690552 commit e063aef

File tree

2 files changed

+62
-26
lines changed

2 files changed

+62
-26
lines changed

sentry/src/db/channel.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ pub async fn get_channel_by_id(
1212
let client = pool.get().await?;
1313

1414
let select = client
15-
.prepare("SELECT leader, follower, guardian, token, nonce FROM channels WHERE id = $1 LIMIT 1")
15+
.prepare(
16+
"SELECT leader, follower, guardian, token, nonce FROM channels WHERE id = $1 LIMIT 1",
17+
)
1618
.await?;
1719

1820
let row = client.query_opt(&select, &[&id]).await?;

sentry/src/routes/campaign.rs

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
accounting::{get_accounting, Side},
44
campaign::{get_campaigns_by_channel, update_campaign},
55
insert_campaign, insert_channel,
6-
spendable::{fetch_spendable, update_spendable},
6+
spendable::update_spendable,
77
CampaignRemaining, DbPool, RedisError,
88
},
99
success_response, Application, Auth, ResponseError,
@@ -25,7 +25,7 @@ use thiserror::Error;
2525
use tokio_postgres::error::SqlState;
2626

2727
#[derive(Debug, Error)]
28-
pub enum Error {
28+
pub enum Error<AE: AdapterErrorKind + 'static> {
2929
#[error("Error while updating campaign: {0}")]
3030
FailedUpdate(String),
3131
#[error("Error while performing calculations")]
@@ -36,8 +36,12 @@ pub enum Error {
3636
NewBudget(String),
3737
#[error("Spendable amount for campaign creator {0} not found")]
3838
SpenderNotFound(Address),
39+
#[error("Channel token is not whitelisted")]
40+
ChannelTokenNotWhitelisted,
3941
#[error("Campaign was not modified because of spending constraints")]
4042
CampaignNotModified,
43+
#[error("Error while updating spendable for creator: {0}")]
44+
LatestSpendable(#[from] LatestSpendableError<AE>),
4145
#[error("Redis error: {0}")]
4246
Redis(#[from] RedisError),
4347
#[error("DB Pool error: {0}")]
@@ -159,10 +163,10 @@ pub async fn create_campaign<A: Adapter>(
159163
.await?
160164
.iter()
161165
.sum::<Option<UnifiedNum>>()
162-
.ok_or(Error::Calculation)?
166+
.ok_or(Error::<A::AdapterError>::Calculation)?
163167
// DO NOT FORGET to add the Campaign being created right now!
164168
.checked_add(&campaign.budget)
165-
.ok_or(Error::Calculation)?;
169+
.ok_or(Error::<A::AdapterError>::Calculation)?;
166170

167171
// `new_campaigns_remaining <= total_remaining` should be upheld
168172
// `campaign.budget < total_remaining` should also be upheld!
@@ -215,11 +219,13 @@ pub async fn create_campaign<A: Adapter>(
215219
}
216220

217221
pub mod update_campaign {
222+
use primitives::Config;
223+
218224
use crate::db::{accounting::Side, CampaignRemaining};
219225

220226
use super::*;
221227

222-
pub async fn handle_route<A: Adapter>(
228+
pub async fn handle_route<A: Adapter + 'static>(
223229
req: Request<Body>,
224230
app: &Application<A>,
225231
) -> Result<Response<Body>, ResponseError> {
@@ -236,7 +242,9 @@ pub mod update_campaign {
236242

237243
// modify Campaign
238244
let modified_campaign = modify_campaign(
245+
app.adapter.clone(),
239246
&app.pool,
247+
&app.config,
240248
&app.campaign_remaining,
241249
campaign_being_mutated,
242250
modify_campaign_fields,
@@ -247,18 +255,20 @@ pub mod update_campaign {
247255
Ok(success_response(serde_json::to_string(&modified_campaign)?))
248256
}
249257

250-
pub async fn modify_campaign(
258+
pub async fn modify_campaign<A: Adapter + 'static>(
259+
adapter: A,
251260
pool: &DbPool,
261+
config: &Config,
252262
campaign_remaining: &CampaignRemaining,
253263
campaign: Campaign,
254264
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
257267
// !WARNING!: totalSpent != sum(campaign.map(c => c.spending)) therefore we must always calculate remaining funds based on total_deposit - lastApprovedNewState.spenders[user]
258268
// *NOTE*: To close a campaign set campaignBudget to campaignSpent so that spendable == 0
259269

260270
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?
262272
} else {
263273
None
264274
};
@@ -278,10 +288,14 @@ pub mod update_campaign {
278288
.map(|accounting| accounting.amount)
279289
.unwrap_or_default();
280290

291+
let token = config
292+
.token_address_whitelist
293+
.get(&campaign.channel.token)
294+
.ok_or(Error::ChannelTokenNotWhitelisted)?;
295+
281296
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?;
285299

286300
// Gets the latest Spendable for this (spender, channelId) pair
287301
let total_deposited = latest_spendable.deposit.total;
@@ -352,11 +366,12 @@ pub mod update_campaign {
352366
Decrease(T),
353367
}
354368

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>(
356371
campaign_remaining: &CampaignRemaining,
357372
campaign: &Campaign,
358373
new_budget: UnifiedNum,
359-
) -> Result<Option<DeltaBudget<UnifiedNum>>, Error> {
374+
) -> Result<Option<DeltaBudget<UnifiedNum>>, Error<A::AdapterError>> {
360375
let current_budget = campaign.budget;
361376

362377
let budget_action = match new_budget.cmp(&current_budget) {
@@ -913,10 +928,16 @@ mod test {
913928
campaign.channel.token,
914929
);
915930

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");
920941

921942
assert_eq!(new_budget, modified_campaign.budget);
922943
assert_eq!(Some("Updated title".to_string()), modified_campaign.title);
@@ -997,10 +1018,16 @@ mod test {
9971018
modified.channel.token,
9981019
);
9991020

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");
10041031

10051032
assert_eq!(lower_budget, modified_campaign.budget);
10061033

@@ -1054,9 +1081,16 @@ mod test {
10541081
modified.channel.token,
10551082
);
10561083

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");
10601094

10611095
assert!(
10621096
matches!(modify_err, Error::NewBudget(string) if string == "Not enough deposit left for the campaign's new budget")

0 commit comments

Comments
 (0)