From b31130dd91a37cd58a699bdb4d3f5f0eeee54edd Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Fri, 13 Dec 2024 09:27:38 +0000 Subject: [PATCH 1/4] Disallow P2P swaps of disabled tokens --- Cargo.lock | 2 + .../escrow/api/src/lifecycle/init.rs | 1 + .../api/src/updates/c2c_set_token_enabled.rs | 14 ++++ .../canisters/escrow/api/src/updates/mod.rs | 1 + .../canisters/escrow/c2c_client/src/lib.rs | 1 + backend/canisters/escrow/impl/src/guards.rs | 9 +++ backend/canisters/escrow/impl/src/lib.rs | 19 ++++- .../escrow/impl/src/lifecycle/init.rs | 2 +- .../escrow/impl/src/lifecycle/post_upgrade.rs | 9 ++- .../impl/src/updates/c2c_set_token_enabled.rs | 20 ++++++ .../escrow/impl/src/updates/create_swap.rs | 16 +++-- .../canisters/escrow/impl/src/updates/mod.rs | 1 + .../registry/api/src/lifecycle/init.rs | 1 + backend/canisters/registry/impl/Cargo.toml | 2 + backend/canisters/registry/impl/src/lib.rs | 6 ++ .../registry/impl/src/lifecycle/init.rs | 1 + .../impl/src/lifecycle/post_upgrade.rs | 40 ++++++++++- .../impl/src/updates/set_token_enabled.rs | 20 +++++- .../integration_tests/src/client/registry.rs | 3 +- .../integration_tests/src/p2p_swap_tests.rs | 71 +++++++++++++++++++ backend/integration_tests/src/setup.rs | 2 + backend/tools/canister_installer/src/lib.rs | 2 + 22 files changed, 229 insertions(+), 14 deletions(-) create mode 100644 backend/canisters/escrow/api/src/updates/c2c_set_token_enabled.rs create mode 100644 backend/canisters/escrow/impl/src/guards.rs create mode 100644 backend/canisters/escrow/impl/src/updates/c2c_set_token_enabled.rs diff --git a/Cargo.lock b/Cargo.lock index 4303bad03d..1c71c7f997 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6233,6 +6233,8 @@ dependencies = [ "canister_tracing_macros", "constants", "dataurl", + "escrow_canister", + "escrow_canister_c2c_client", "futures", "hex", "http_request", diff --git a/backend/canisters/escrow/api/src/lifecycle/init.rs b/backend/canisters/escrow/api/src/lifecycle/init.rs index bf6aebaba6..1cbcd518a3 100644 --- a/backend/canisters/escrow/api/src/lifecycle/init.rs +++ b/backend/canisters/escrow/api/src/lifecycle/init.rs @@ -4,6 +4,7 @@ use types::{BuildVersion, CanisterId}; #[derive(CandidType, Serialize, Deserialize, Debug)] pub struct Args { + pub registry_canister_id: CanisterId, pub cycles_dispenser_canister_id: CanisterId, pub wasm_version: BuildVersion, pub test_mode: bool, diff --git a/backend/canisters/escrow/api/src/updates/c2c_set_token_enabled.rs b/backend/canisters/escrow/api/src/updates/c2c_set_token_enabled.rs new file mode 100644 index 0000000000..2f02f61f26 --- /dev/null +++ b/backend/canisters/escrow/api/src/updates/c2c_set_token_enabled.rs @@ -0,0 +1,14 @@ +use candid::CandidType; +use serde::{Deserialize, Serialize}; +use types::CanisterId; + +#[derive(CandidType, Serialize, Deserialize, Debug)] +pub struct Args { + pub ledger_canister_id: CanisterId, + pub enabled: bool, +} + +#[derive(CandidType, Serialize, Deserialize, Debug)] +pub enum Response { + Success, +} diff --git a/backend/canisters/escrow/api/src/updates/mod.rs b/backend/canisters/escrow/api/src/updates/mod.rs index 59e944bd01..c59725f456 100644 --- a/backend/canisters/escrow/api/src/updates/mod.rs +++ b/backend/canisters/escrow/api/src/updates/mod.rs @@ -1,3 +1,4 @@ +pub mod c2c_set_token_enabled; pub mod cancel_swap; pub mod create_swap; pub mod notify_deposit; diff --git a/backend/canisters/escrow/c2c_client/src/lib.rs b/backend/canisters/escrow/c2c_client/src/lib.rs index f0ff84f758..ccbfb951d8 100644 --- a/backend/canisters/escrow/c2c_client/src/lib.rs +++ b/backend/canisters/escrow/c2c_client/src/lib.rs @@ -4,6 +4,7 @@ use escrow_canister::*; // Queries // Updates +generate_c2c_call!(c2c_set_token_enabled); generate_c2c_call!(create_swap); generate_c2c_call!(cancel_swap); generate_c2c_call!(notify_deposit); diff --git a/backend/canisters/escrow/impl/src/guards.rs b/backend/canisters/escrow/impl/src/guards.rs new file mode 100644 index 0000000000..849ad8e293 --- /dev/null +++ b/backend/canisters/escrow/impl/src/guards.rs @@ -0,0 +1,9 @@ +use crate::read_state; + +pub fn caller_is_registry_canister() -> Result<(), String> { + if read_state(|state| state.is_caller_registry_canister()) { + Ok(()) + } else { + Err("Caller is not the registry canister".to_string()) + } +} diff --git a/backend/canisters/escrow/impl/src/lib.rs b/backend/canisters/escrow/impl/src/lib.rs index dd3049b52c..a3c4f1b619 100644 --- a/backend/canisters/escrow/impl/src/lib.rs +++ b/backend/canisters/escrow/impl/src/lib.rs @@ -6,10 +6,11 @@ use canister_state_macros::canister_state; use canister_timer_jobs::TimerJobs; use serde::{Deserialize, Serialize}; use std::cell::RefCell; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use types::{BuildVersion, CanisterId, Cycles, TimestampMillis, Timestamped}; use utils::env::Environment; +mod guards; mod jobs; mod lifecycle; mod memory; @@ -34,6 +35,10 @@ impl RuntimeState { RuntimeState { env, data } } + pub fn is_caller_registry_canister(&self) -> bool { + self.env.caller() == self.data.registry_canister_id + } + pub fn metrics(&self) -> Metrics { let now = self.env.now(); @@ -46,7 +51,9 @@ impl RuntimeState { git_commit_id: utils::git::git_commit_id().to_string(), swaps: self.data.swaps.metrics(now), stable_memory_sizes: memory::memory_sizes(), + disabled_tokens: self.data.disabled_tokens.iter().copied().collect(), canister_ids: CanisterIds { + registry: self.data.registry_canister_id, cycles_dispenser: self.data.cycles_dispenser_canister_id, }, } @@ -59,19 +66,25 @@ struct Data { pub pending_payments_queue: PendingPaymentsQueue, pub notify_status_change_queue: NotifyStatusChangeQueue, timer_jobs: TimerJobs, + #[serde(default = "CanisterId::anonymous")] + pub registry_canister_id: CanisterId, pub cycles_dispenser_canister_id: CanisterId, + #[serde(default)] + pub disabled_tokens: BTreeSet, pub rng_seed: [u8; 32], pub test_mode: bool, } impl Data { - pub fn new(cycles_dispenser_canister_id: CanisterId, test_mode: bool) -> Data { + pub fn new(registry_canister_id: CanisterId, cycles_dispenser_canister_id: CanisterId, test_mode: bool) -> Data { Data { swaps: Swaps::default(), pending_payments_queue: PendingPaymentsQueue::default(), notify_status_change_queue: NotifyStatusChangeQueue::default(), timer_jobs: TimerJobs::default(), + registry_canister_id, cycles_dispenser_canister_id, + disabled_tokens: BTreeSet::new(), rng_seed: [0; 32], test_mode, } @@ -88,6 +101,7 @@ pub struct Metrics { pub git_commit_id: String, pub swaps: SwapMetrics, pub stable_memory_sizes: BTreeMap, + pub disabled_tokens: Vec, pub canister_ids: CanisterIds, } @@ -103,5 +117,6 @@ pub struct SwapMetrics { #[derive(Serialize, Debug)] pub struct CanisterIds { + pub registry: CanisterId, pub cycles_dispenser: CanisterId, } diff --git a/backend/canisters/escrow/impl/src/lifecycle/init.rs b/backend/canisters/escrow/impl/src/lifecycle/init.rs index b76dcd16f9..0ffd876187 100644 --- a/backend/canisters/escrow/impl/src/lifecycle/init.rs +++ b/backend/canisters/escrow/impl/src/lifecycle/init.rs @@ -13,7 +13,7 @@ fn init(args: Args) { init_cycles_dispenser_client(args.cycles_dispenser_canister_id, args.test_mode); let env = init_env([0; 32]); - let data = Data::new(args.cycles_dispenser_canister_id, args.test_mode); + let data = Data::new(args.registry_canister_id, args.cycles_dispenser_canister_id, args.test_mode); init_state(env, data, args.wasm_version); diff --git a/backend/canisters/escrow/impl/src/lifecycle/post_upgrade.rs b/backend/canisters/escrow/impl/src/lifecycle/post_upgrade.rs index 2e48d58761..c552ce97a7 100644 --- a/backend/canisters/escrow/impl/src/lifecycle/post_upgrade.rs +++ b/backend/canisters/escrow/impl/src/lifecycle/post_upgrade.rs @@ -7,6 +7,7 @@ use escrow_canister::post_upgrade::Args; use ic_cdk::post_upgrade; use stable_memory::get_reader; use tracing::info; +use types::CanisterId; use utils::cycles::init_cycles_dispenser_client; #[post_upgrade] @@ -15,7 +16,13 @@ fn post_upgrade(args: Args) { let memory = get_upgrades_memory(); let reader = get_reader(&memory); - let (data, logs, traces): (Data, Vec, Vec) = msgpack::deserialize(reader).unwrap(); + let (mut data, logs, traces): (Data, Vec, Vec) = msgpack::deserialize(reader).unwrap(); + + if data.test_mode { + data.registry_canister_id = CanisterId::from_text("cglwi-oaaaa-aaaar-aqw4q-cai").unwrap(); + } else { + data.registry_canister_id = CanisterId::from_text("cpi5u-yiaaa-aaaar-aqw5a-cai").unwrap(); + } // TODO: After release change this to // let (data, errors, logs, traces): (Data, Vec, Vec, Vec) = msgpack::deserialize(reader).unwrap(); diff --git a/backend/canisters/escrow/impl/src/updates/c2c_set_token_enabled.rs b/backend/canisters/escrow/impl/src/updates/c2c_set_token_enabled.rs new file mode 100644 index 0000000000..74e1aceeff --- /dev/null +++ b/backend/canisters/escrow/impl/src/updates/c2c_set_token_enabled.rs @@ -0,0 +1,20 @@ +use crate::guards::caller_is_registry_canister; +use crate::{mutate_state, RuntimeState}; +use canister_api_macros::update; +use canister_tracing_macros::trace; +use escrow_canister::c2c_set_token_enabled::{Response::*, *}; + +#[update(guard = "caller_is_registry_canister", msgpack = true)] +#[trace] +fn c2c_set_token_enabled(args: Args) -> Response { + mutate_state(|state| c2c_set_token_enabled_impl(args, state)) +} + +fn c2c_set_token_enabled_impl(args: Args, state: &mut RuntimeState) -> Response { + if args.enabled { + state.data.disabled_tokens.remove(&args.ledger_canister_id); + } else { + state.data.disabled_tokens.insert(args.ledger_canister_id); + } + Success +} diff --git a/backend/canisters/escrow/impl/src/updates/create_swap.rs b/backend/canisters/escrow/impl/src/updates/create_swap.rs index fa5bf8477d..c0b7a9d8fc 100644 --- a/backend/canisters/escrow/impl/src/updates/create_swap.rs +++ b/backend/canisters/escrow/impl/src/updates/create_swap.rs @@ -1,5 +1,5 @@ use crate::timer_job_types::{ExpireSwapJob, TimerJob}; -use crate::{mutate_state, RuntimeState}; +use crate::{mutate_state, Data, RuntimeState}; use canister_api_macros::update; use canister_tracing_macros::trace; use escrow_canister::create_swap::{Response::*, *}; @@ -13,7 +13,7 @@ fn create_swap(args: Args) -> Response { fn create_swap_impl(args: Args, state: &mut RuntimeState) -> Response { let now = state.env.now(); - if let Err(error) = validate_swap(&args, now) { + if let Err(error) = validate_swap(&args, now, &state.data) { InvalidSwap(error) } else { let caller = state.env.caller().into(); @@ -28,15 +28,19 @@ fn create_swap_impl(args: Args, state: &mut RuntimeState) -> Response { } } -fn validate_swap(args: &Args, now: TimestampMillis) -> Result<(), String> { +fn validate_swap(args: &Args, now: TimestampMillis, data: &Data) -> Result<(), String> { if args.token0.ledger == args.token1.ledger { - Err("Token0 must be different to token1".to_string()) + Err("Input token must be different to output token".to_string()) } else if args.token0_amount == 0 { - Err("Token0 amount cannot be 0".to_string()) + Err("Input amount cannot be 0".to_string()) } else if args.token1_amount == 0 { - Err("Token1 amount cannot be 0".to_string()) + Err("Output amount cannot be 0".to_string()) } else if args.expires_at < now { Err("Expiry cannot be in the past".to_string()) + } else if data.disabled_tokens.contains(&args.token0.ledger) { + Err("Input token is disabled for swaps".to_string()) + } else if data.disabled_tokens.contains(&args.token1.ledger) { + Err("Output token is disabled for swaps".to_string()) } else { Ok(()) } diff --git a/backend/canisters/escrow/impl/src/updates/mod.rs b/backend/canisters/escrow/impl/src/updates/mod.rs index 3f0d805d8c..cb356adaaa 100644 --- a/backend/canisters/escrow/impl/src/updates/mod.rs +++ b/backend/canisters/escrow/impl/src/updates/mod.rs @@ -1,3 +1,4 @@ +pub mod c2c_set_token_enabled; pub mod cancel_swap; pub mod create_swap; pub mod notify_deposit; diff --git a/backend/canisters/registry/api/src/lifecycle/init.rs b/backend/canisters/registry/api/src/lifecycle/init.rs index 49a9836c7c..0fe06906b4 100644 --- a/backend/canisters/registry/api/src/lifecycle/init.rs +++ b/backend/canisters/registry/api/src/lifecycle/init.rs @@ -12,6 +12,7 @@ pub struct Args { pub nns_root_canister_id: CanisterId, pub sns_wasm_canister_id: CanisterId, pub nns_index_canister_id: CanisterId, + pub escrow_canister_id: CanisterId, pub cycles_dispenser_canister_id: CanisterId, pub wasm_version: BuildVersion, pub test_mode: bool, diff --git a/backend/canisters/registry/impl/Cargo.toml b/backend/canisters/registry/impl/Cargo.toml index 11edeccff2..14a73569f3 100644 --- a/backend/canisters/registry/impl/Cargo.toml +++ b/backend/canisters/registry/impl/Cargo.toml @@ -17,6 +17,8 @@ canister_state_macros = { path = "../../../libraries/canister_state_macros" } canister_tracing_macros = { path = "../../../libraries/canister_tracing_macros" } constants = { path = "../../../libraries/constants" } dataurl = { workspace = true } +escrow_canister = { path = "../../escrow/api" } +escrow_canister_c2c_client = { path = "../../escrow/c2c_client" } futures = { workspace = true } hex = { workspace = true } http_request = { path = "../../../libraries/http_request" } diff --git a/backend/canisters/registry/impl/src/lib.rs b/backend/canisters/registry/impl/src/lib.rs index a782f0cca4..593d317cb4 100644 --- a/backend/canisters/registry/impl/src/lib.rs +++ b/backend/canisters/registry/impl/src/lib.rs @@ -63,6 +63,7 @@ impl RuntimeState { canister_ids: CanisterIds { proposals_bot: self.data.proposals_bot_canister_id, sns_wasm: self.data.sns_wasm_canister_id, + escrow: self.data.escrow_canister_id, cycles_dispenser: self.data.cycles_dispenser_canister_id, }, } @@ -75,6 +76,8 @@ struct Data { proposals_bot_canister_id: CanisterId, user_index_canister_id: CanisterId, sns_wasm_canister_id: CanisterId, + #[serde(default = "CanisterId::anonymous")] + escrow_canister_id: CanisterId, cycles_dispenser_canister_id: CanisterId, tokens: Tokens, nervous_systems: NervousSystems, @@ -94,6 +97,7 @@ impl Data { proposals_bot_canister_id: CanisterId, user_index_canister_id: CanisterId, sns_wasm_canister_id: CanisterId, + escrow_canister_id: CanisterId, cycles_dispenser_canister_id: CanisterId, test_mode: bool, ) -> Data { @@ -102,6 +106,7 @@ impl Data { proposals_bot_canister_id, user_index_canister_id, sns_wasm_canister_id, + escrow_canister_id, cycles_dispenser_canister_id, tokens: Tokens::default(), nervous_systems: NervousSystems::default(), @@ -184,5 +189,6 @@ pub struct Metrics { pub struct CanisterIds { pub proposals_bot: CanisterId, pub sns_wasm: CanisterId, + pub escrow: CanisterId, pub cycles_dispenser: CanisterId, } diff --git a/backend/canisters/registry/impl/src/lifecycle/init.rs b/backend/canisters/registry/impl/src/lifecycle/init.rs index ced8f72874..84a5105316 100644 --- a/backend/canisters/registry/impl/src/lifecycle/init.rs +++ b/backend/canisters/registry/impl/src/lifecycle/init.rs @@ -19,6 +19,7 @@ fn init(args: Args) { args.proposals_bot_canister_id, args.user_index_canister_id, args.sns_wasm_canister_id, + args.escrow_canister_id, args.cycles_dispenser_canister_id, args.test_mode, ); diff --git a/backend/canisters/registry/impl/src/lifecycle/post_upgrade.rs b/backend/canisters/registry/impl/src/lifecycle/post_upgrade.rs index 2b1c02e4ab..83d8c932f2 100644 --- a/backend/canisters/registry/impl/src/lifecycle/post_upgrade.rs +++ b/backend/canisters/registry/impl/src/lifecycle/post_upgrade.rs @@ -1,12 +1,14 @@ use crate::lifecycle::{init_env, init_state}; use crate::memory::get_upgrades_memory; -use crate::Data; +use crate::{read_state, Data}; use canister_logger::LogEntry; use canister_tracing_macros::trace; use ic_cdk::post_upgrade; use registry_canister::post_upgrade::Args; use stable_memory::get_reader; +use std::time::Duration; use tracing::info; +use types::CanisterId; use utils::cycles::init_cycles_dispenser_client; #[post_upgrade] @@ -15,9 +17,15 @@ fn post_upgrade(args: Args) { let memory = get_upgrades_memory(); let reader = get_reader(&memory); - let (data, errors, logs, traces): (Data, Vec, Vec, Vec) = + let (mut data, errors, logs, traces): (Data, Vec, Vec, Vec) = msgpack::deserialize(reader).unwrap(); + if data.test_mode { + data.escrow_canister_id = CanisterId::from_text("tspqt-xaaaa-aaaal-qcnna-cai").unwrap(); + } else { + data.escrow_canister_id = CanisterId::from_text("s4yi7-yiaaa-aaaar-qacpq-cai").unwrap(); + } + canister_logger::init_with_logs(data.test_mode, errors, logs, traces); let env = init_env(data.rng_seed); @@ -25,4 +33,32 @@ fn post_upgrade(args: Args) { init_state(env, data, args.wasm_version); info!(version = %args.wasm_version, "Post-upgrade complete"); + + ic_cdk_timers::set_timer(Duration::ZERO, || ic_cdk::spawn(set_disabled_tokens_in_escrow_canister())); +} + +async fn set_disabled_tokens_in_escrow_canister() { + let (disabled_tokens, escrow_canister_id) = read_state(|state| { + let disabled_tokens: Vec<_> = state + .data + .tokens + .iter() + .filter(|t| !t.enabled) + .map(|t| t.ledger_canister_id) + .collect(); + + (disabled_tokens, state.data.escrow_canister_id) + }); + + for ledger_canister_id in disabled_tokens { + escrow_canister_c2c_client::c2c_set_token_enabled( + escrow_canister_id, + &escrow_canister::c2c_set_token_enabled::Args { + ledger_canister_id, + enabled: false, + }, + ) + .await + .unwrap(); + } } diff --git a/backend/canisters/registry/impl/src/updates/set_token_enabled.rs b/backend/canisters/registry/impl/src/updates/set_token_enabled.rs index e36bfcf800..e37439fd0e 100644 --- a/backend/canisters/registry/impl/src/updates/set_token_enabled.rs +++ b/backend/canisters/registry/impl/src/updates/set_token_enabled.rs @@ -7,7 +7,13 @@ use user_index_canister_c2c_client::{lookup_user, LookupUserError}; #[update(msgpack = true)] #[trace] async fn set_token_enabled(args: Args) -> Response { - let (caller, user_index_canister_id) = read_state(|state| (state.env.caller(), state.data.user_index_canister_id)); + let (caller, user_index_canister_id, escrow_canister_id) = read_state(|state| { + ( + state.env.caller(), + state.data.user_index_canister_id, + state.data.escrow_canister_id, + ) + }); match lookup_user(caller, user_index_canister_id).await { Ok(user) if user.is_platform_operator => {} @@ -15,6 +21,18 @@ async fn set_token_enabled(args: Args) -> Response { Err(LookupUserError::InternalError(error)) => return InternalError(error), } + if let Err(error) = escrow_canister_c2c_client::c2c_set_token_enabled( + escrow_canister_id, + &escrow_canister::c2c_set_token_enabled::Args { + ledger_canister_id: args.ledger_canister_id, + enabled: args.enabled, + }, + ) + .await + { + return InternalError(format!("Failed to update Escrow canister: {error:?}")); + } + mutate_state(|state| { state .data diff --git a/backend/integration_tests/src/client/registry.rs b/backend/integration_tests/src/client/registry.rs index d7b5c1b239..3dfa893b52 100644 --- a/backend/integration_tests/src/client/registry.rs +++ b/backend/integration_tests/src/client/registry.rs @@ -1,4 +1,4 @@ -use crate::{generate_msgpack_query_call, generate_update_call}; +use crate::{generate_msgpack_query_call, generate_msgpack_update_call, generate_update_call}; use registry_canister::*; // Queries @@ -7,3 +7,4 @@ generate_msgpack_query_call!(updates); // Updates generate_update_call!(add_token); generate_update_call!(update_token); +generate_msgpack_update_call!(set_token_enabled); diff --git a/backend/integration_tests/src/p2p_swap_tests.rs b/backend/integration_tests/src/p2p_swap_tests.rs index a01d27fc92..d28dc91bf3 100644 --- a/backend/integration_tests/src/p2p_swap_tests.rs +++ b/backend/integration_tests/src/p2p_swap_tests.rs @@ -560,6 +560,77 @@ fn deposit_refunded_if_swap_expires() { ); } +#[test_case(false)] +#[test_case(true)] +fn p2p_swap_blocked_if_token_disabled(input_token: bool) { + let mut wrapper = ENV.deref().get(); + let TestEnv { + env, + canister_ids, + controller, + .. + } = wrapper.env(); + + let user = client::register_diamond_user(env, canister_ids, *controller); + client::user_index::happy_path::add_platform_operator(env, *controller, canister_ids.user_index, user.user_id); + + let group_id = client::user::happy_path::create_group(env, &user, &random_string(), true, true); + + client::ledger::happy_path::transfer( + env, + *controller, + canister_ids.icp_ledger, + Principal::from(user.user_id), + 1_100_000_000, + ); + + let message_id = random_from_u128(); + + client::registry::set_token_enabled( + env, + user.principal, + canister_ids.registry, + ®istry_canister::set_token_enabled::Args { + ledger_canister_id: if input_token { canister_ids.icp_ledger } else { canister_ids.chat_ledger }, + enabled: false, + }, + ); + + let send_message_response = client::user::send_message_with_transfer_to_group( + env, + user.principal, + user.canister(), + &user_canister::send_message_with_transfer_to_group::Args { + group_id, + thread_root_message_index: None, + message_id, + content: MessageContentInitial::P2PSwap(P2PSwapContentInitial { + token0: Cryptocurrency::InternetComputer.try_into().unwrap(), + token0_amount: 1_000_000_000, + token1: Cryptocurrency::CHAT.try_into().unwrap(), + token1_amount: 10_000_000_000, + expires_in: DAY_IN_MS, + caption: None, + }), + sender_name: user.username(), + sender_display_name: None, + replies_to: None, + mentioned: Vec::new(), + block_level_markdown: false, + correlation_id: 0, + rules_accepted: None, + message_filter_failed: None, + pin: None, + }, + ); + + if let user_canister::send_message_with_transfer_to_group::Response::InvalidRequest(error) = send_message_response { + assert!(error.contains(if input_token { "Input" } else { "Output" })) + } else { + panic!("Unexpected response: {:?}", send_message_response); + } +} + pub(crate) fn verify_swap_status bool>(event: ChatEvent, predicate: F) { let ChatEvent::Message(m) = event else { panic!("Event is not a message. Event: {event:?}") diff --git a/backend/integration_tests/src/setup.rs b/backend/integration_tests/src/setup.rs index f8c4d82136..4cf17ca539 100644 --- a/backend/integration_tests/src/setup.rs +++ b/backend/integration_tests/src/setup.rs @@ -339,6 +339,7 @@ fn install_canisters(env: &mut PocketIc, controller: Principal) -> CanisterIds { nns_governance_canister_id, nns_index_canister_id, sns_wasm_canister_id, + escrow_canister_id, cycles_dispenser_canister_id, wasm_version, test_mode, @@ -352,6 +353,7 @@ fn install_canisters(env: &mut PocketIc, controller: Principal) -> CanisterIds { ); let escrow_init_args = escrow_canister::init::Args { + registry_canister_id, cycles_dispenser_canister_id, wasm_version, test_mode, diff --git a/backend/tools/canister_installer/src/lib.rs b/backend/tools/canister_installer/src/lib.rs index 4a45c17fa9..ef563b5ed0 100644 --- a/backend/tools/canister_installer/src/lib.rs +++ b/backend/tools/canister_installer/src/lib.rs @@ -222,6 +222,7 @@ async fn install_service_canisters_impl( nns_root_canister_id: canister_ids.nns_root, sns_wasm_canister_id: canister_ids.nns_sns_wasm, nns_index_canister_id: canister_ids.nns_index, + escrow_canister_id: canister_ids.escrow, cycles_dispenser_canister_id: canister_ids.cycles_dispenser, wasm_version: version, test_mode, @@ -250,6 +251,7 @@ async fn install_service_canisters_impl( let escrow_canister_wasm = get_canister_wasm(CanisterName::Escrow, version); let escrow_init_args = escrow_canister::init::Args { + registry_canister_id: canister_ids.registry, cycles_dispenser_canister_id: canister_ids.cycles_dispenser, wasm_version: version, test_mode, From 6d3683ca7e740028a5fa35f7f93fa51308d6bff8 Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Fri, 13 Dec 2024 10:06:34 +0000 Subject: [PATCH 2/4] Update CHANGELOGs --- backend/canisters/escrow/CHANGELOG.md | 6 ++++++ backend/canisters/registry/CHANGELOG.md | 1 + 2 files changed, 7 insertions(+) diff --git a/backend/canisters/escrow/CHANGELOG.md b/backend/canisters/escrow/CHANGELOG.md index 005586a58a..2d661aa294 100644 --- a/backend/canisters/escrow/CHANGELOG.md +++ b/backend/canisters/escrow/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [unreleased] +### Changed + +- Disallow P2P swaps of disabled tokens ([#7057](https://github.com/open-chat-labs/open-chat/pull/7057)) + +## [[2.0.1512](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.1512-escrow)] - 2024-12-13 + ### Added - Add an error log with http endpoint ([#6608](https://github.com/open-chat-labs/open-chat/pull/6608)) diff --git a/backend/canisters/registry/CHANGELOG.md b/backend/canisters/registry/CHANGELOG.md index 3fccdeac24..5af5e38002 100644 --- a/backend/canisters/registry/CHANGELOG.md +++ b/backend/canisters/registry/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Expose size of each virtual stable memory in metrics ([#6981](https://github.com/open-chat-labs/open-chat/pull/6981)) - Include the ledger canister Id in transfer failed error logs ([#7011](https://github.com/open-chat-labs/open-chat/pull/7011)) +- Disallow P2P swaps of disabled tokens ([#7057](https://github.com/open-chat-labs/open-chat/pull/7057)) ## [[2.0.1490](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.1490-registry)] - 2024-12-03 From 6007ba47af6faff2c5b506690472e01250224f48 Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Fri, 13 Dec 2024 10:07:54 +0000 Subject: [PATCH 3/4] Clean up post release --- .../canisters/escrow/impl/src/lifecycle/post_upgrade.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/backend/canisters/escrow/impl/src/lifecycle/post_upgrade.rs b/backend/canisters/escrow/impl/src/lifecycle/post_upgrade.rs index c552ce97a7..37844b04b4 100644 --- a/backend/canisters/escrow/impl/src/lifecycle/post_upgrade.rs +++ b/backend/canisters/escrow/impl/src/lifecycle/post_upgrade.rs @@ -16,7 +16,8 @@ fn post_upgrade(args: Args) { let memory = get_upgrades_memory(); let reader = get_reader(&memory); - let (mut data, logs, traces): (Data, Vec, Vec) = msgpack::deserialize(reader).unwrap(); + let (mut data, errors, logs, traces): (Data, Vec, Vec, Vec) = + msgpack::deserialize(reader).unwrap(); if data.test_mode { data.registry_canister_id = CanisterId::from_text("cglwi-oaaaa-aaaar-aqw4q-cai").unwrap(); @@ -24,9 +25,7 @@ fn post_upgrade(args: Args) { data.registry_canister_id = CanisterId::from_text("cpi5u-yiaaa-aaaar-aqw5a-cai").unwrap(); } - // TODO: After release change this to - // let (data, errors, logs, traces): (Data, Vec, Vec, Vec) = msgpack::deserialize(reader).unwrap(); - canister_logger::init_with_logs(data.test_mode, Vec::new(), logs, traces); + canister_logger::init_with_logs(data.test_mode, errors, logs, traces); let env = init_env(data.rng_seed); init_cycles_dispenser_client(data.cycles_dispenser_canister_id, data.test_mode); From 655b078d2de690b7332cfbf71b3679f238e7a102 Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Fri, 13 Dec 2024 12:14:21 +0000 Subject: [PATCH 4/4] Re-enable token at end of test --- backend/integration_tests/src/p2p_swap_tests.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/backend/integration_tests/src/p2p_swap_tests.rs b/backend/integration_tests/src/p2p_swap_tests.rs index d28dc91bf3..9bef462c78 100644 --- a/backend/integration_tests/src/p2p_swap_tests.rs +++ b/backend/integration_tests/src/p2p_swap_tests.rs @@ -624,6 +624,17 @@ fn p2p_swap_blocked_if_token_disabled(input_token: bool) { }, ); + // Re-enable token so that other tests aren't affected + client::registry::set_token_enabled( + env, + user.principal, + canister_ids.registry, + ®istry_canister::set_token_enabled::Args { + ledger_canister_id: if input_token { canister_ids.icp_ledger } else { canister_ids.chat_ledger }, + enabled: true, + }, + ); + if let user_canister::send_message_with_transfer_to_group::Response::InvalidRequest(error) = send_message_response { assert!(error.contains(if input_token { "Input" } else { "Output" })) } else {