From 8a6a2d832b865549c26327273d165e2545f9e9a8 Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Thu, 12 Dec 2024 22:34:11 +0000 Subject: [PATCH 1/6] Include the total cycles topped up --- .../impl/src/queries/http_request.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/backend/canisters/local_user_index/impl/src/queries/http_request.rs b/backend/canisters/local_user_index/impl/src/queries/http_request.rs index 500b1b38f7..f606f633ac 100644 --- a/backend/canisters/local_user_index/impl/src/queries/http_request.rs +++ b/backend/canisters/local_user_index/impl/src/queries/http_request.rs @@ -4,7 +4,7 @@ use ic_cdk::query; use serde::Serialize; use std::collections::{BTreeMap, HashMap}; use std::str::FromStr; -use types::{BuildVersion, CanisterId, HttpRequest, HttpResponse, TimestampMillis, UserId}; +use types::{BuildVersion, CanisterId, Cycles, CyclesTopUp, HttpRequest, HttpResponse, TimestampMillis, UserId}; #[query] fn http_request(request: HttpRequest) -> HttpResponse { @@ -31,7 +31,12 @@ fn http_request(request: HttpRequest) -> HttpResponse { return HttpResponse::not_found(); }; - build_json_response(&user.cycle_top_ups) + let total = user.cycle_top_ups.iter().map(|c| c.amount).sum(); + + build_json_response(&TopUps { + total, + top_ups: &user.cycle_top_ups, + }) } fn get_user_canister_versions(state: &RuntimeState) -> HttpResponse { @@ -83,3 +88,9 @@ struct UserCanisterVersion { count: u32, users: Vec, } + +#[derive(Serialize)] +struct TopUps<'a> { + total: Cycles, + top_ups: &'a [CyclesTopUp], +} From 464a30124785057a063c55b7fd5badcb66a1ebde Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Thu, 12 Dec 2024 22:36:44 +0000 Subject: [PATCH 2/6] Update CHANGELOGs --- .../canisters/local_group_index/CHANGELOG.md | 4 +++ .../impl/src/queries/http_request.rs | 26 ++++++++++++++----- .../canisters/local_user_index/CHANGELOG.md | 1 + 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/backend/canisters/local_group_index/CHANGELOG.md b/backend/canisters/local_group_index/CHANGELOG.md index 9bfd8811fa..6138510a9b 100644 --- a/backend/canisters/local_group_index/CHANGELOG.md +++ b/backend/canisters/local_group_index/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Expose the cycles top-ups of Group/Community canisters ([#7053](https://github.com/open-chat-labs/open-chat/pull/7053)) +### Changed + +- Include the total cycles topped up ([#7056](https://github.com/open-chat-labs/open-chat/pull/7056)) + ## [[2.0.1505](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.1505-local_group_index)] - 2024-12-09 ### Changed diff --git a/backend/canisters/local_group_index/impl/src/queries/http_request.rs b/backend/canisters/local_group_index/impl/src/queries/http_request.rs index 2e2d864c94..ffd6f6b356 100644 --- a/backend/canisters/local_group_index/impl/src/queries/http_request.rs +++ b/backend/canisters/local_group_index/impl/src/queries/http_request.rs @@ -1,8 +1,9 @@ use crate::{read_state, RuntimeState}; use http_request::{build_json_response, encode_logs, extract_route, Route}; use ic_cdk::query; +use serde::Serialize; use std::collections::HashMap; -use types::{CanisterId, HttpRequest, HttpResponse, TimestampMillis}; +use types::{CanisterId, Cycles, CyclesTopUp, HttpRequest, HttpResponse, TimestampMillis}; #[query] fn http_request(request: HttpRequest) -> HttpResponse { @@ -25,13 +26,20 @@ fn http_request(request: HttpRequest) -> HttpResponse { fn get_top_ups(qs: HashMap, state: &RuntimeState) -> HttpResponse { let canister_id = CanisterId::from_text(qs.get("canister_id").unwrap()).unwrap(); - if let Some(group) = state.data.local_groups.get(&canister_id.into()) { - build_json_response(&group.cycle_top_ups) + let top_ups = if let Some(group) = state.data.local_groups.get(&canister_id.into()) { + &group.cycle_top_ups } else if let Some(community) = state.data.local_communities.get(&canister_id.into()) { - build_json_response(&community.cycle_top_ups) + &community.cycle_top_ups } else { - HttpResponse::not_found() - } + return HttpResponse::not_found(); + }; + + let total = top_ups.iter().map(|c| c.amount).sum(); + + build_json_response(&TopUps { + total, + top_ups: &top_ups, + }) } match extract_route(&request.url) { @@ -43,3 +51,9 @@ fn http_request(request: HttpRequest) -> HttpResponse { _ => HttpResponse::not_found(), } } + +#[derive(Serialize)] +struct TopUps<'a> { + total: Cycles, + top_ups: &'a [CyclesTopUp], +} diff --git a/backend/canisters/local_user_index/CHANGELOG.md b/backend/canisters/local_user_index/CHANGELOG.md index 0ee881feb0..c293329236 100644 --- a/backend/canisters/local_user_index/CHANGELOG.md +++ b/backend/canisters/local_user_index/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Switch to using `PrincipalToStableMemoryMap` ([#7023](https://github.com/open-chat-labs/open-chat/pull/7023)) - Make `MessageId` comparisons use their 64bit representation ([#7030](https://github.com/open-chat-labs/open-chat/pull/7030)) - Notify CHIT updates via LocalUserIndex ([#7033](https://github.com/open-chat-labs/open-chat/pull/7033)) +- Include the total cycles topped up ([#7056](https://github.com/open-chat-labs/open-chat/pull/7056)) ### Fixes From 4d7b9f3a4b20bef30e56254e3ba152f1548539cf Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Thu, 12 Dec 2024 22:43:08 +0000 Subject: [PATCH 3/6] clippy --- .../local_group_index/impl/src/queries/http_request.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/backend/canisters/local_group_index/impl/src/queries/http_request.rs b/backend/canisters/local_group_index/impl/src/queries/http_request.rs index ffd6f6b356..a2517a6708 100644 --- a/backend/canisters/local_group_index/impl/src/queries/http_request.rs +++ b/backend/canisters/local_group_index/impl/src/queries/http_request.rs @@ -36,10 +36,7 @@ fn http_request(request: HttpRequest) -> HttpResponse { let total = top_ups.iter().map(|c| c.amount).sum(); - build_json_response(&TopUps { - total, - top_ups: &top_ups, - }) + build_json_response(&TopUps { total, top_ups }) } match extract_route(&request.url) { From aecf0a5c4accd44e865b98af314dd0fecdad885d Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Thu, 12 Dec 2024 23:36:38 +0000 Subject: [PATCH 4/6] Format as T rather than cycles --- .../local_group_index/impl/src/queries/http_request.rs | 4 ++-- .../local_user_index/impl/src/queries/http_request.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/canisters/local_group_index/impl/src/queries/http_request.rs b/backend/canisters/local_group_index/impl/src/queries/http_request.rs index a2517a6708..b7f93f72dc 100644 --- a/backend/canisters/local_group_index/impl/src/queries/http_request.rs +++ b/backend/canisters/local_group_index/impl/src/queries/http_request.rs @@ -34,7 +34,7 @@ fn http_request(request: HttpRequest) -> HttpResponse { return HttpResponse::not_found(); }; - let total = top_ups.iter().map(|c| c.amount).sum(); + let total = top_ups.iter().map(|c| c.amount).sum::() as f64 / 1_000_000_000_000f64; build_json_response(&TopUps { total, top_ups }) } @@ -51,6 +51,6 @@ fn http_request(request: HttpRequest) -> HttpResponse { #[derive(Serialize)] struct TopUps<'a> { - total: Cycles, + total: f64, top_ups: &'a [CyclesTopUp], } diff --git a/backend/canisters/local_user_index/impl/src/queries/http_request.rs b/backend/canisters/local_user_index/impl/src/queries/http_request.rs index f606f633ac..30171bda23 100644 --- a/backend/canisters/local_user_index/impl/src/queries/http_request.rs +++ b/backend/canisters/local_user_index/impl/src/queries/http_request.rs @@ -4,7 +4,7 @@ use ic_cdk::query; use serde::Serialize; use std::collections::{BTreeMap, HashMap}; use std::str::FromStr; -use types::{BuildVersion, CanisterId, Cycles, CyclesTopUp, HttpRequest, HttpResponse, TimestampMillis, UserId}; +use types::{BuildVersion, CanisterId, CyclesTopUp, HttpRequest, HttpResponse, TimestampMillis, UserId}; #[query] fn http_request(request: HttpRequest) -> HttpResponse { @@ -31,7 +31,7 @@ fn http_request(request: HttpRequest) -> HttpResponse { return HttpResponse::not_found(); }; - let total = user.cycle_top_ups.iter().map(|c| c.amount).sum(); + let total = user.cycle_top_ups.iter().map(|c| c.amount).sum::() as f64 / 1_000_000_000_000f64; build_json_response(&TopUps { total, @@ -91,6 +91,6 @@ struct UserCanisterVersion { #[derive(Serialize)] struct TopUps<'a> { - total: Cycles, + total: f64, top_ups: &'a [CyclesTopUp], } From dbb14a64b26dba82827b1d67c2df7cfeb4f67aa2 Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Thu, 12 Dec 2024 23:48:41 +0000 Subject: [PATCH 5/6] Show each top up as T --- .../impl/src/queries/http_request.rs | 11 +++++++---- .../impl/src/queries/http_request.rs | 8 ++++---- backend/libraries/constants/src/lib.rs | 13 ------------- backend/libraries/types/src/cycles.rs | 15 +++++++++++++++ 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/backend/canisters/local_group_index/impl/src/queries/http_request.rs b/backend/canisters/local_group_index/impl/src/queries/http_request.rs index b7f93f72dc..0808577076 100644 --- a/backend/canisters/local_group_index/impl/src/queries/http_request.rs +++ b/backend/canisters/local_group_index/impl/src/queries/http_request.rs @@ -3,7 +3,7 @@ use http_request::{build_json_response, encode_logs, extract_route, Route}; use ic_cdk::query; use serde::Serialize; use std::collections::HashMap; -use types::{CanisterId, Cycles, CyclesTopUp, HttpRequest, HttpResponse, TimestampMillis}; +use types::{CanisterId, Cycles, CyclesTopUp, CyclesTopUpHumanReadable, HttpRequest, HttpResponse, TimestampMillis}; #[query] fn http_request(request: HttpRequest) -> HttpResponse { @@ -36,7 +36,10 @@ fn http_request(request: HttpRequest) -> HttpResponse { let total = top_ups.iter().map(|c| c.amount).sum::() as f64 / 1_000_000_000_000f64; - build_json_response(&TopUps { total, top_ups }) + build_json_response(&TopUps { + total, + top_ups: top_ups.iter().map(|c| c.into()).collect(), + }) } match extract_route(&request.url) { @@ -50,7 +53,7 @@ fn http_request(request: HttpRequest) -> HttpResponse { } #[derive(Serialize)] -struct TopUps<'a> { +struct TopUps { total: f64, - top_ups: &'a [CyclesTopUp], + top_ups: Vec, } diff --git a/backend/canisters/local_user_index/impl/src/queries/http_request.rs b/backend/canisters/local_user_index/impl/src/queries/http_request.rs index 30171bda23..8da1be42cc 100644 --- a/backend/canisters/local_user_index/impl/src/queries/http_request.rs +++ b/backend/canisters/local_user_index/impl/src/queries/http_request.rs @@ -4,7 +4,7 @@ use ic_cdk::query; use serde::Serialize; use std::collections::{BTreeMap, HashMap}; use std::str::FromStr; -use types::{BuildVersion, CanisterId, CyclesTopUp, HttpRequest, HttpResponse, TimestampMillis, UserId}; +use types::{BuildVersion, CanisterId, CyclesTopUpHumanReadable, HttpRequest, HttpResponse, TimestampMillis, UserId}; #[query] fn http_request(request: HttpRequest) -> HttpResponse { @@ -35,7 +35,7 @@ fn http_request(request: HttpRequest) -> HttpResponse { build_json_response(&TopUps { total, - top_ups: &user.cycle_top_ups, + top_ups: user.cycle_top_ups.iter().map(|c| c.into()).collect(), }) } @@ -90,7 +90,7 @@ struct UserCanisterVersion { } #[derive(Serialize)] -struct TopUps<'a> { +struct TopUps { total: f64, - top_ups: &'a [CyclesTopUp], + top_ups: Vec, } diff --git a/backend/libraries/constants/src/lib.rs b/backend/libraries/constants/src/lib.rs index 26e53c3e96..2543761c07 100644 --- a/backend/libraries/constants/src/lib.rs +++ b/backend/libraries/constants/src/lib.rs @@ -32,11 +32,6 @@ pub const SNS_ROOT_CANISTER_ID: CanisterId = Principal::from_slice(&[0, 0, 0, 0, pub const SNS_GOVERNANCE_CANISTER_ID: CanisterId = Principal::from_slice(&[0, 0, 0, 0, 2, 0, 0, 24, 1, 1]); pub const SNS_LEDGER_CANISTER_ID: CanisterId = Principal::from_slice(&[0, 0, 0, 0, 2, 0, 0, 25, 1, 1]); -pub const DEV_TEAM_DFX_PRINCIPAL: CanisterId = Principal::from_slice(&[ - 143, 216, 195, 195, 27, 134, 102, 49, 184, 154, 196, 117, 143, 40, 192, 164, 121, 209, 89, 30, 45, 18, 30, 32, 92, 106, - 138, 30, 2, -]); - pub const IC_ROOT_KEY: &[u8; 133] = b"\x30\x81\x82\x30\x1d\x06\x0d\x2b\x06\x01\x04\x01\x82\xdc\x7c\x05\x03\x01\x02\x01\x06\x0c\x2b\x06\x01\x04\x01\x82\xdc\x7c\x05\x03\x02\x01\x03\x61\x00\x81\x4c\x0e\x6e\xc7\x1f\xab\x58\x3b\x08\xbd\x81\x37\x3c\x25\x5c\x3c\x37\x1b\x2e\x84\x86\x3c\x98\xa4\xf1\xe0\x8b\x74\x23\x5d\x14\xfb\x5d\x9c\x0c\xd5\x46\xd9\x68\x5f\x91\x3a\x0c\x0b\x2c\xc5\x34\x15\x83\xbf\x4b\x43\x92\xe4\x67\xdb\x96\xd6\x5b\x9b\xb4\xcb\x71\x71\x12\xf8\x47\x2e\x0d\x5a\x4d\x14\x50\x5f\xfd\x74\x84\xb0\x12\x91\x09\x1c\x5f\x87\xb9\x88\x83\x46\x3f\x98\x09\x1a\x0b\xaa\xae"; pub const MEMO_MESSAGE: [u8; 6] = [0x4f, 0x43, 0x5f, 0x4d, 0x53, 0x47]; // OC_MSG @@ -113,14 +108,6 @@ mod tests { ); } - #[test] - fn dev_team_dfx_principal() { - assert_eq!( - DEV_TEAM_DFX_PRINCIPAL, - Principal::from_text("tu45y-p4p3d-b4gg4-gmyy3-rgweo-whsrq-fephi-vshrn-cipca-xdkri-pae").unwrap() - ); - } - #[test] fn openchat_treasury_canister_id() { assert_eq!( diff --git a/backend/libraries/types/src/cycles.rs b/backend/libraries/types/src/cycles.rs index 766cbac820..57c3c1c395 100644 --- a/backend/libraries/types/src/cycles.rs +++ b/backend/libraries/types/src/cycles.rs @@ -45,3 +45,18 @@ pub enum NotifyLowBalanceResponse { NotEnoughCyclesRemaining, FailedToDepositCycles, } + +#[derive(Serialize)] +pub struct CyclesTopUpHumanReadable { + date: TimestampMillis, + amount: f64, +} + +impl From<&CyclesTopUp> for CyclesTopUpHumanReadable { + fn from(value: &CyclesTopUp) -> Self { + CyclesTopUpHumanReadable { + date: value.date, + amount: value.amount as f64 / 1_000_000_000_000f64, + } + } +} From 13a76d0bb3e8003be562843fbea7a4a1f6968265 Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Fri, 13 Dec 2024 00:15:23 +0000 Subject: [PATCH 6/6] This is better --- .../impl/src/queries/http_request.rs | 2 +- backend/libraries/types/src/cycles.rs | 23 ++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/backend/canisters/local_group_index/impl/src/queries/http_request.rs b/backend/canisters/local_group_index/impl/src/queries/http_request.rs index 0808577076..429990042d 100644 --- a/backend/canisters/local_group_index/impl/src/queries/http_request.rs +++ b/backend/canisters/local_group_index/impl/src/queries/http_request.rs @@ -3,7 +3,7 @@ use http_request::{build_json_response, encode_logs, extract_route, Route}; use ic_cdk::query; use serde::Serialize; use std::collections::HashMap; -use types::{CanisterId, Cycles, CyclesTopUp, CyclesTopUpHumanReadable, HttpRequest, HttpResponse, TimestampMillis}; +use types::{CanisterId, CyclesTopUpHumanReadable, HttpRequest, HttpResponse, TimestampMillis}; #[query] fn http_request(request: HttpRequest) -> HttpResponse { diff --git a/backend/libraries/types/src/cycles.rs b/backend/libraries/types/src/cycles.rs index 57c3c1c395..03389c43a6 100644 --- a/backend/libraries/types/src/cycles.rs +++ b/backend/libraries/types/src/cycles.rs @@ -1,6 +1,6 @@ use crate::TimestampMillis; use candid::CandidType; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize, Serializer}; pub type Cycles = u128; @@ -46,17 +46,34 @@ pub enum NotifyLowBalanceResponse { FailedToDepositCycles, } +pub struct CyclesHumanReadable(Cycles); + #[derive(Serialize)] pub struct CyclesTopUpHumanReadable { date: TimestampMillis, - amount: f64, + amount: CyclesHumanReadable, } impl From<&CyclesTopUp> for CyclesTopUpHumanReadable { fn from(value: &CyclesTopUp) -> Self { CyclesTopUpHumanReadable { date: value.date, - amount: value.amount as f64 / 1_000_000_000_000f64, + amount: value.amount.into(), } } } + +impl From for CyclesHumanReadable { + fn from(value: Cycles) -> Self { + CyclesHumanReadable(value) + } +} + +impl Serialize for CyclesHumanReadable { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&format!("{}T", self.0 as f64 / 1_000_000_000_000.0)) + } +}