From a6799b216ee92aa9dde15c20e2565ce5f6e12d9f Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Mon, 2 Oct 2023 14:36:16 +0100 Subject: [PATCH] Support prize messages in any token by getting fee from original transfer (#4470) --- backend/canisters/community/CHANGELOG.md | 1 + .../community/impl/src/updates/claim_prize.rs | 8 ++--- backend/canisters/group/CHANGELOG.md | 1 + .../group/impl/src/updates/claim_prize.rs | 8 ++--- backend/canisters/user/CHANGELOG.md | 1 + .../src/updates/send_message_with_transfer.rs | 2 +- .../libraries/chat_events/src/chat_events.rs | 5 +-- backend/libraries/types/src/cryptocurrency.rs | 33 ++++++++++++++++++- 8 files changed, 45 insertions(+), 14 deletions(-) diff --git a/backend/canisters/community/CHANGELOG.md b/backend/canisters/community/CHANGELOG.md index 343b1a43a4..7082af3b6f 100644 --- a/backend/canisters/community/CHANGELOG.md +++ b/backend/canisters/community/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - All members can mention @everyone by default in private communities ([#4458](https://github.com/open-chat-labs/open-chat/pull/4458)) - Notifications for custom messages should use the sub-type ([#4465](https://github.com/open-chat-labs/open-chat/pull/4465)) - Join all community members to channels that are made public ([#4469](https://github.com/open-chat-labs/open-chat/pull/4469)) +- Support prize messages in any token by getting fee from original transfer ([#4470](https://github.com/open-chat-labs/open-chat/pull/4470)) ## [[2.0.864](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.864-community)] - 2023-09-27 diff --git a/backend/canisters/community/impl/src/updates/claim_prize.rs b/backend/canisters/community/impl/src/updates/claim_prize.rs index c5f75c05b5..298f9a760c 100644 --- a/backend/canisters/community/impl/src/updates/claim_prize.rs +++ b/backend/canisters/community/impl/src/updates/claim_prize.rs @@ -82,22 +82,20 @@ fn prepare(args: &Args, state: &mut RuntimeState) -> Result return Err(Box::new(AlreadyClaimed)), - ReservePrizeResult::Success(t, l, a) => (t, l, a), + ReservePrizeResult::Success(t, l, a, f) => (t, l, a, f), ReservePrizeResult::MessageNotFound => return Err(Box::new(MessageNotFound)), ReservePrizeResult::PrizeFullyClaimed => return Err(Box::new(PrizeFullyClaimed)), ReservePrizeResult::PrizeEnded => return Err(Box::new(PrizeEnded)), }; - let fee = token.fee().unwrap(); // TODO send up the transaction fee when creating the prize message - - let transaction = create_pending_transaction(token, ledger, amount.e8s() as u128, fee, user_id, now_nanos); + let transaction = create_pending_transaction(token, ledger, amount, fee, user_id, now_nanos); Ok(PrepareResult { group: state.env.canister_id(), diff --git a/backend/canisters/group/CHANGELOG.md b/backend/canisters/group/CHANGELOG.md index 19dfa2e35c..c8927f6a47 100644 --- a/backend/canisters/group/CHANGELOG.md +++ b/backend/canisters/group/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - Notifications for custom messages should use the sub-type ([#4465](https://github.com/open-chat-labs/open-chat/pull/4465)) +- Support prize messages in any token by getting fee from original transfer ([#4470](https://github.com/open-chat-labs/open-chat/pull/4470)) ## [[2.0.865](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.865-group)] - 2023-09-27 diff --git a/backend/canisters/group/impl/src/updates/claim_prize.rs b/backend/canisters/group/impl/src/updates/claim_prize.rs index e3a1c9edef..d782c95d79 100644 --- a/backend/canisters/group/impl/src/updates/claim_prize.rs +++ b/backend/canisters/group/impl/src/updates/claim_prize.rs @@ -66,7 +66,7 @@ fn prepare(args: &Args, state: &mut RuntimeState) -> Result Result return Err(Box::new(AlreadyClaimed)), - ReservePrizeResult::Success(t, l, a) => (t, l, a), + ReservePrizeResult::Success(t, l, a, f) => (t, l, a, f), ReservePrizeResult::MessageNotFound => return Err(Box::new(MessageNotFound)), ReservePrizeResult::PrizeFullyClaimed => return Err(Box::new(PrizeFullyClaimed)), ReservePrizeResult::PrizeEnded => return Err(Box::new(PrizeEnded)), }; - let fee = token.fee().unwrap(); // TODO send up the transaction fee when creating the prize message - - let transaction = create_pending_transaction(token, ledger, amount.e8s() as u128, fee, user_id, now_nanos); + let transaction = create_pending_transaction(token, ledger, amount, fee, user_id, now_nanos); Ok(PrepareResult { group: state.env.canister_id(), diff --git a/backend/canisters/user/CHANGELOG.md b/backend/canisters/user/CHANGELOG.md index 149fe1fac5..a580708740 100644 --- a/backend/canisters/user/CHANGELOG.md +++ b/backend/canisters/user/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - Notifications for custom messages should use the sub-type ([#4465](https://github.com/open-chat-labs/open-chat/pull/4465)) +- Support prize messages in any token by getting fee from original transfer ([#4470](https://github.com/open-chat-labs/open-chat/pull/4470)) - Prevent transfers to yourself ([#4471](https://github.com/open-chat-labs/open-chat/pull/4471)) ## [[2.0.867](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.867-user)] - 2023-09-27 diff --git a/backend/canisters/user/impl/src/updates/send_message_with_transfer.rs b/backend/canisters/user/impl/src/updates/send_message_with_transfer.rs index cb58e6df6b..454c71adb1 100644 --- a/backend/canisters/user/impl/src/updates/send_message_with_transfer.rs +++ b/backend/canisters/user/impl/src/updates/send_message_with_transfer.rs @@ -206,7 +206,7 @@ fn prepare(content: &MessageContentInitial, state: &RuntimeState) -> PrepareResu match &c.transfer { CryptoTransaction::Pending(t) => { let total_prize = c.prizes.iter().map(|t| t.e8s()).sum::() as u128; - let prize_fees = c.prizes.len() as u128 * t.token().fee().unwrap(); + let prize_fees = c.prizes.len() as u128 * t.fee(); let total_amount_to_send = total_prize + prize_fees; if t.units() != total_amount_to_send { diff --git a/backend/libraries/chat_events/src/chat_events.rs b/backend/libraries/chat_events/src/chat_events.rs index 46e40f9b27..a2685f0e1e 100644 --- a/backend/libraries/chat_events/src/chat_events.rs +++ b/backend/libraries/chat_events/src/chat_events.rs @@ -601,12 +601,13 @@ impl ChatEvents { let amount = content.prizes_remaining.pop().expect("some prizes_remaining"); let token = content.transaction.token(); let ledger_canister_id = content.transaction.ledger_canister_id(); + let fee = content.transaction.fee(); content.reservations.insert(user_id); message.last_updated = Some(now); self.last_updated_timestamps.mark_updated(None, event_index, now); - return ReservePrizeResult::Success(token, ledger_canister_id, amount); + return ReservePrizeResult::Success(token, ledger_canister_id, amount.e8s() as u128, fee); } } @@ -1454,7 +1455,7 @@ pub enum TipMessageResult { } pub enum ReservePrizeResult { - Success(Cryptocurrency, CanisterId, Tokens), + Success(Cryptocurrency, CanisterId, u128, u128), MessageNotFound, AlreadyClaimed, PrizeFullyClaimed, diff --git a/backend/libraries/types/src/cryptocurrency.rs b/backend/libraries/types/src/cryptocurrency.rs index ca6871e3ed..2e97607cdd 100644 --- a/backend/libraries/types/src/cryptocurrency.rs +++ b/backend/libraries/types/src/cryptocurrency.rs @@ -4,6 +4,8 @@ use candid::{CandidType, Principal}; use ic_ledger_types::{AccountIdentifier, Subaccount, DEFAULT_SUBACCOUNT}; use serde::{Deserialize, Serialize}; +const ICP_FEE: u128 = 10_000; + #[derive(CandidType, Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Hash)] pub enum Cryptocurrency { InternetComputer, @@ -39,7 +41,7 @@ impl Cryptocurrency { pub fn fee(&self) -> Option { match self { - Cryptocurrency::InternetComputer => Some(10_000), + Cryptocurrency::InternetComputer => Some(ICP_FEE), Cryptocurrency::SNS1 => Some(1_000), Cryptocurrency::CKBTC => Some(10), Cryptocurrency::CHAT => Some(100_000), @@ -115,6 +117,14 @@ impl CryptoTransaction { CryptoTransaction::Failed(f) => f.units(), } } + + pub fn fee(&self) -> u128 { + match self { + CryptoTransaction::Pending(p) => p.fee(), + CryptoTransaction::Completed(c) => c.fee(), + CryptoTransaction::Failed(f) => f.fee(), + } + } } impl PendingCryptoTransaction { @@ -143,6 +153,13 @@ impl PendingCryptoTransaction { } } + pub fn fee(&self) -> u128 { + match self { + PendingCryptoTransaction::NNS(_) => ICP_FEE, + PendingCryptoTransaction::ICRC1(t) => t.fee, + } + } + pub fn user_id(&self) -> Option { match self { PendingCryptoTransaction::NNS(t) => { @@ -204,6 +221,13 @@ impl CompletedCryptoTransaction { CompletedCryptoTransaction::ICRC1(t) => t.amount, } } + + pub fn fee(&self) -> u128 { + match self { + CompletedCryptoTransaction::NNS(_) => ICP_FEE, + CompletedCryptoTransaction::ICRC1(t) => t.fee, + } + } } impl FailedCryptoTransaction { @@ -234,6 +258,13 @@ impl FailedCryptoTransaction { FailedCryptoTransaction::ICRC1(t) => t.amount, } } + + pub fn fee(&self) -> u128 { + match self { + FailedCryptoTransaction::NNS(_) => ICP_FEE, + FailedCryptoTransaction::ICRC1(t) => t.fee, + } + } } pub mod nns {