From f3844696a450a4001703fb7b2b93c09c0eb22ddb Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Thu, 8 Feb 2024 08:50:24 +0000 Subject: [PATCH] Introduce the EventRelay canister (#5334) --- Cargo.lock | 35 ++++++++ Cargo.toml | 2 + backend/canister_installer/Cargo.toml | 1 + backend/canister_installer/src/lib.rs | 17 +++- backend/canister_installer/src/main.rs | 4 + backend/canister_upgrader/Cargo.toml | 1 + backend/canister_upgrader/src/lib.rs | 19 +++++ backend/canister_upgrader/src/main.rs | 4 + backend/canisters/event_relay/api/Cargo.toml | 12 +++ backend/canisters/event_relay/api/can.did | 2 + backend/canisters/event_relay/api/src/lib.rs | 9 +++ .../event_relay/api/src/lifecycle/init.rs | 11 +++ .../event_relay/api/src/lifecycle/mod.rs | 2 + .../api/src/lifecycle/post_upgrade.rs | 8 ++ backend/canisters/event_relay/api/src/main.rs | 4 + .../event_relay/api/src/queries/mod.rs | 1 + .../event_relay/api/src/updates/mod.rs | 1 + backend/canisters/event_relay/impl/Cargo.toml | 29 +++++++ backend/canisters/event_relay/impl/src/lib.rs | 79 +++++++++++++++++++ .../event_relay/impl/src/lifecycle/init.rs | 25 ++++++ .../event_relay/impl/src/lifecycle/mod.rs | 39 +++++++++ .../impl/src/lifecycle/post_upgrade.rs | 27 +++++++ .../impl/src/lifecycle/pre_upgrade.rs | 26 ++++++ .../canisters/event_relay/impl/src/memory.rs | 21 +++++ .../event_relay/impl/src/model/mod.rs | 1 + .../impl/src/queries/http_request.rs | 26 ++++++ .../event_relay/impl/src/queries/mod.rs | 1 + .../event_relay/impl/src/updates/mod.rs | 1 + .../impl/src/updates/wallet_receive.rs | 9 +++ .../libraries/canister_agent_utils/src/lib.rs | 4 + canister_ids.json | 4 + dfx.json | 6 ++ scripts/deploy-local.sh | 1 + scripts/deploy-testnet.sh | 1 + scripts/deploy.sh | 4 +- scripts/download-all-canister-wasms.sh | 1 + scripts/generate-all-canister-wasms.sh | 1 + scripts/proposals/upgrade_event_relay.sh | 17 ++++ scripts/upgrade-canister.sh | 2 + .../event_relay.ini | 5 ++ 40 files changed, 461 insertions(+), 2 deletions(-) create mode 100644 backend/canisters/event_relay/api/Cargo.toml create mode 100644 backend/canisters/event_relay/api/can.did create mode 100644 backend/canisters/event_relay/api/src/lib.rs create mode 100644 backend/canisters/event_relay/api/src/lifecycle/init.rs create mode 100644 backend/canisters/event_relay/api/src/lifecycle/mod.rs create mode 100644 backend/canisters/event_relay/api/src/lifecycle/post_upgrade.rs create mode 100644 backend/canisters/event_relay/api/src/main.rs create mode 100644 backend/canisters/event_relay/api/src/queries/mod.rs create mode 100644 backend/canisters/event_relay/api/src/updates/mod.rs create mode 100644 backend/canisters/event_relay/impl/Cargo.toml create mode 100644 backend/canisters/event_relay/impl/src/lib.rs create mode 100644 backend/canisters/event_relay/impl/src/lifecycle/init.rs create mode 100644 backend/canisters/event_relay/impl/src/lifecycle/mod.rs create mode 100644 backend/canisters/event_relay/impl/src/lifecycle/post_upgrade.rs create mode 100644 backend/canisters/event_relay/impl/src/lifecycle/pre_upgrade.rs create mode 100644 backend/canisters/event_relay/impl/src/memory.rs create mode 100644 backend/canisters/event_relay/impl/src/model/mod.rs create mode 100644 backend/canisters/event_relay/impl/src/queries/http_request.rs create mode 100644 backend/canisters/event_relay/impl/src/queries/mod.rs create mode 100644 backend/canisters/event_relay/impl/src/updates/mod.rs create mode 100644 backend/canisters/event_relay/impl/src/updates/wallet_receive.rs create mode 100755 scripts/proposals/upgrade_event_relay.sh create mode 100644 sns/scripts/proposals/register_canisters_with_sns/event_relay.ini diff --git a/Cargo.lock b/Cargo.lock index c4d7351a0a..7b96952b0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -978,6 +978,7 @@ dependencies = [ "clap", "cycles_dispenser_canister", "escrow_canister", + "event_relay_canister", "futures", "group_index_canister", "group_index_canister_client", @@ -1076,6 +1077,7 @@ dependencies = [ "clap", "cycles_dispenser_canister", "escrow_canister", + "event_relay_canister", "group_index_canister", "group_index_canister_client", "ic-agent", @@ -2059,6 +2061,39 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "event_relay_canister" +version = "0.1.0" +dependencies = [ + "candid", + "candid_gen", + "serde", + "types", +] + +[[package]] +name = "event_relay_canister_impl" +version = "0.1.0" +dependencies = [ + "candid", + "canister_logger", + "canister_state_macros", + "canister_tracing_macros", + "event_relay_canister", + "http_request", + "ic-cdk", + "ic-cdk-macros", + "ic-cdk-timers", + "ic-stable-structures", + "rand", + "serde", + "serializer", + "stable_memory", + "tracing", + "types", + "utils", +] + [[package]] name = "fastrand" version = "1.9.0" diff --git a/Cargo.toml b/Cargo.toml index 34e7e1dd05..f2347ecad6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,8 @@ members = [ "backend/canisters/escrow/api", "backend/canisters/escrow/c2c_client", "backend/canisters/escrow/impl", + "backend/canisters/event_relay/api", + "backend/canisters/event_relay/impl", "backend/canisters/group/api", "backend/canisters/group/c2c_client", "backend/canisters/group/client", diff --git a/backend/canister_installer/Cargo.toml b/backend/canister_installer/Cargo.toml index 377b2f7998..8459e2a8d2 100644 --- a/backend/canister_installer/Cargo.toml +++ b/backend/canister_installer/Cargo.toml @@ -11,6 +11,7 @@ canister_agent_utils = { path = "../libraries/canister_agent_utils" } clap = { workspace = true, features = ["derive"] } cycles_dispenser_canister = { path = "../canisters/cycles_dispenser/api" } escrow_canister = { path = "../canisters/escrow/api" } +event_relay_canister = { path = "../canisters/event_relay/api" } futures = { workspace = true } group_index_canister = { path = "../canisters/group_index/api" } group_index_canister_client = { path = "../canisters/group_index/client" } diff --git a/backend/canister_installer/src/lib.rs b/backend/canister_installer/src/lib.rs index a4e3148702..322c8c7d93 100644 --- a/backend/canister_installer/src/lib.rs +++ b/backend/canister_installer/src/lib.rs @@ -36,6 +36,7 @@ async fn install_service_canisters_impl( set_controllers(management_canister, &canister_ids.neuron_controller, controllers.clone()), set_controllers(management_canister, &canister_ids.escrow, controllers.clone()), set_controllers(management_canister, &canister_ids.translations, controllers.clone()), + set_controllers(management_canister, &canister_ids.event_relay, controllers.clone()), set_controllers( management_canister, &canister_ids.local_user_index, @@ -220,6 +221,14 @@ async fn install_service_canisters_impl( test_mode, }; + let event_relay_canister_wasm = get_canister_wasm(CanisterName::EventRelay, version); + let event_relay_init_args = event_relay_canister::init::Args { + push_events_whitelist: vec![canister_ids.user_index, canister_ids.online_users], + cycles_dispenser_canister_id: canister_ids.cycles_dispenser, + wasm_version: version, + test_mode, + }; + futures::future::join5( install_wasm( management_canister, @@ -288,7 +297,7 @@ async fn install_service_canisters_impl( ) .await; - futures::future::join3( + futures::future::join4( install_wasm( management_canister, &canister_ids.neuron_controller, @@ -307,6 +316,12 @@ async fn install_service_canisters_impl( &translations_canister_wasm.module, translations_init_args, ), + install_wasm( + management_canister, + &canister_ids.event_relay, + &event_relay_canister_wasm.module, + event_relay_init_args, + ), ) .await; diff --git a/backend/canister_installer/src/main.rs b/backend/canister_installer/src/main.rs index 36e4f18fcb..c1fa10f653 100644 --- a/backend/canister_installer/src/main.rs +++ b/backend/canister_installer/src/main.rs @@ -24,6 +24,7 @@ async fn main() { neuron_controller: opts.neuron_controller, escrow: opts.escrow, translations: opts.translations, + event_relay: opts.event_relay, nns_root: opts.nns_root, nns_governance: opts.nns_governance, nns_internet_identity: opts.nns_internet_identity, @@ -97,6 +98,9 @@ struct Opts { #[arg(long)] translations: CanisterId, + #[arg(long)] + event_relay: CanisterId, + #[arg(long)] nns_root: CanisterId, diff --git a/backend/canister_upgrader/Cargo.toml b/backend/canister_upgrader/Cargo.toml index 868c769d93..7692e600f5 100644 --- a/backend/canister_upgrader/Cargo.toml +++ b/backend/canister_upgrader/Cargo.toml @@ -11,6 +11,7 @@ canister_agent_utils = { path = "../libraries/canister_agent_utils" } clap = { workspace = true, features = ["derive"] } cycles_dispenser_canister = { path = "../canisters/cycles_dispenser/api" } escrow_canister = { path = "../canisters/escrow/api" } +event_relay_canister = { path = "../canisters/event_relay/api" } group_index_canister = { path = "../canisters/group_index/api" } group_index_canister_client = { path = "../canisters/group_index/client" } ic-agent = { workspace = true } diff --git a/backend/canister_upgrader/src/lib.rs b/backend/canister_upgrader/src/lib.rs index 9301c18a62..862035b4e2 100644 --- a/backend/canister_upgrader/src/lib.rs +++ b/backend/canister_upgrader/src/lib.rs @@ -254,6 +254,25 @@ pub async fn upgrade_escrow_canister( println!("Escrow canister upgraded"); } +pub async fn upgrade_event_relay_canister( + identity: Box, + url: String, + event_relay_canister_id: CanisterId, + version: BuildVersion, +) { + upgrade_top_level_canister( + identity, + url, + event_relay_canister_id, + version, + event_relay_canister::post_upgrade::Args { wasm_version: version }, + CanisterName::EventRelay, + ) + .await; + + println!("Event relay canister upgraded"); +} + pub async fn upgrade_local_group_index_canister( identity: Box, url: String, diff --git a/backend/canister_upgrader/src/main.rs b/backend/canister_upgrader/src/main.rs index 5a966ee9b4..5a6b3dfb49 100644 --- a/backend/canister_upgrader/src/main.rs +++ b/backend/canister_upgrader/src/main.rs @@ -15,6 +15,7 @@ async fn main() { upgrade_cycles_dispenser_canister(identity, opts.url, opts.cycles_dispenser, opts.version).await } CanisterName::Escrow => upgrade_escrow_canister(identity, opts.url, opts.escrow, opts.version).await, + CanisterName::EventRelay => upgrade_event_relay_canister(identity, opts.url, opts.event_relay, opts.version).await, CanisterName::Group => upgrade_group_canister(identity, opts.url, opts.group_index, opts.version).await, CanisterName::LocalGroupIndex => { upgrade_local_group_index_canister(identity, opts.url, opts.group_index, opts.version).await @@ -98,6 +99,9 @@ struct Opts { #[arg(long)] escrow: CanisterId, + #[arg(long)] + event_relay: CanisterId, + #[arg(long)] canister_to_upgrade: CanisterName, diff --git a/backend/canisters/event_relay/api/Cargo.toml b/backend/canisters/event_relay/api/Cargo.toml new file mode 100644 index 0000000000..edb2e1234c --- /dev/null +++ b/backend/canisters/event_relay/api/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "event_relay_canister" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +candid = { workspace = true } +candid_gen = { path = "../../../libraries/candid_gen" } +serde = { workspace = true } +types = { path = "../../../libraries/types" } \ No newline at end of file diff --git a/backend/canisters/event_relay/api/can.did b/backend/canisters/event_relay/api/can.did new file mode 100644 index 0000000000..22da1208bd --- /dev/null +++ b/backend/canisters/event_relay/api/can.did @@ -0,0 +1,2 @@ +service : { +}; diff --git a/backend/canisters/event_relay/api/src/lib.rs b/backend/canisters/event_relay/api/src/lib.rs new file mode 100644 index 0000000000..862369ef41 --- /dev/null +++ b/backend/canisters/event_relay/api/src/lib.rs @@ -0,0 +1,9 @@ +#![allow(unused_imports)] + +mod lifecycle; +mod queries; +mod updates; + +pub use lifecycle::*; +pub use queries::*; +pub use updates::*; diff --git a/backend/canisters/event_relay/api/src/lifecycle/init.rs b/backend/canisters/event_relay/api/src/lifecycle/init.rs new file mode 100644 index 0000000000..ae7e98964f --- /dev/null +++ b/backend/canisters/event_relay/api/src/lifecycle/init.rs @@ -0,0 +1,11 @@ +use candid::{CandidType, Principal}; +use serde::{Deserialize, Serialize}; +use types::{BuildVersion, CanisterId}; + +#[derive(CandidType, Serialize, Deserialize, Debug)] +pub struct Args { + pub push_events_whitelist: Vec, + pub cycles_dispenser_canister_id: CanisterId, + pub wasm_version: BuildVersion, + pub test_mode: bool, +} diff --git a/backend/canisters/event_relay/api/src/lifecycle/mod.rs b/backend/canisters/event_relay/api/src/lifecycle/mod.rs new file mode 100644 index 0000000000..70bd4f5a23 --- /dev/null +++ b/backend/canisters/event_relay/api/src/lifecycle/mod.rs @@ -0,0 +1,2 @@ +pub mod init; +pub mod post_upgrade; diff --git a/backend/canisters/event_relay/api/src/lifecycle/post_upgrade.rs b/backend/canisters/event_relay/api/src/lifecycle/post_upgrade.rs new file mode 100644 index 0000000000..470a25ac40 --- /dev/null +++ b/backend/canisters/event_relay/api/src/lifecycle/post_upgrade.rs @@ -0,0 +1,8 @@ +use candid::CandidType; +use serde::{Deserialize, Serialize}; +use types::BuildVersion; + +#[derive(CandidType, Serialize, Deserialize, Debug)] +pub struct Args { + pub wasm_version: BuildVersion, +} diff --git a/backend/canisters/event_relay/api/src/main.rs b/backend/canisters/event_relay/api/src/main.rs new file mode 100644 index 0000000000..f39a15551f --- /dev/null +++ b/backend/canisters/event_relay/api/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + candid::export_service!(); + std::print!("{}", __export_service()); +} diff --git a/backend/canisters/event_relay/api/src/queries/mod.rs b/backend/canisters/event_relay/api/src/queries/mod.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/backend/canisters/event_relay/api/src/queries/mod.rs @@ -0,0 +1 @@ + diff --git a/backend/canisters/event_relay/api/src/updates/mod.rs b/backend/canisters/event_relay/api/src/updates/mod.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/backend/canisters/event_relay/api/src/updates/mod.rs @@ -0,0 +1 @@ + diff --git a/backend/canisters/event_relay/impl/Cargo.toml b/backend/canisters/event_relay/impl/Cargo.toml new file mode 100644 index 0000000000..870b80875d --- /dev/null +++ b/backend/canisters/event_relay/impl/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "event_relay_canister_impl" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +path = "src/lib.rs" +crate-type = ["cdylib"] + +[dependencies] +candid = { workspace = true } +canister_logger = { path = "../../../libraries/canister_logger" } +canister_state_macros = { path = "../../../libraries/canister_state_macros" } +canister_tracing_macros = { path = "../../../libraries/canister_tracing_macros" } +event_relay_canister = { path = "../api" } +http_request = { path = "../../../libraries/http_request" } +ic-cdk = { workspace = true } +ic-cdk-macros = { workspace = true } +ic-cdk-timers = { workspace = true } +ic-stable-structures = { workspace = true } +rand = { workspace = true } +serde = { workspace = true } +serializer = { path = "../../../libraries/serializer" } +stable_memory = { path = "../../../libraries/stable_memory" } +tracing = { workspace = true } +types = { path = "../../../libraries/types" } +utils = { path = "../../../libraries/utils" } diff --git a/backend/canisters/event_relay/impl/src/lib.rs b/backend/canisters/event_relay/impl/src/lib.rs new file mode 100644 index 0000000000..6461e8be4e --- /dev/null +++ b/backend/canisters/event_relay/impl/src/lib.rs @@ -0,0 +1,79 @@ +use candid::Principal; +use canister_state_macros::canister_state; +use serde::{Deserialize, Serialize}; +use std::cell::RefCell; +use std::collections::HashSet; +use types::{BuildVersion, CanisterId, Cycles, TimestampMillis, Timestamped}; +use utils::env::Environment; + +mod lifecycle; +mod memory; +mod model; +mod queries; +mod updates; + +thread_local! { + static WASM_VERSION: RefCell> = RefCell::default(); +} + +canister_state!(RuntimeState); + +struct RuntimeState { + pub env: Box, + pub data: Data, +} + +impl RuntimeState { + pub fn new(env: Box, data: Data) -> RuntimeState { + RuntimeState { env, data } + } + + pub fn metrics(&self) -> Metrics { + Metrics { + memory_used: utils::memory::used(), + now: self.env.now(), + cycles_balance: self.env.cycles_balance(), + wasm_version: WASM_VERSION.with_borrow(|v| **v), + git_commit_id: utils::git::git_commit_id().to_string(), + push_events_whitelist: self.data.push_events_whitelist.iter().copied().collect(), + canister_ids: CanisterIds { + cycles_dispenser: self.data.cycles_dispenser_canister_id, + }, + } + } +} + +#[derive(Serialize, Deserialize)] +struct Data { + pub push_events_whitelist: HashSet, + pub cycles_dispenser_canister_id: CanisterId, + pub rng_seed: [u8; 32], + pub test_mode: bool, +} + +impl Data { + pub fn new(push_events_whitelist: HashSet, cycles_dispenser_canister_id: CanisterId, test_mode: bool) -> Data { + Data { + push_events_whitelist, + cycles_dispenser_canister_id, + rng_seed: [0; 32], + test_mode, + } + } +} + +#[derive(Serialize, Debug)] +pub struct Metrics { + pub now: TimestampMillis, + pub memory_used: u64, + pub cycles_balance: Cycles, + pub wasm_version: BuildVersion, + pub git_commit_id: String, + pub push_events_whitelist: Vec, + pub canister_ids: CanisterIds, +} + +#[derive(Serialize, Debug)] +pub struct CanisterIds { + pub cycles_dispenser: CanisterId, +} diff --git a/backend/canisters/event_relay/impl/src/lifecycle/init.rs b/backend/canisters/event_relay/impl/src/lifecycle/init.rs new file mode 100644 index 0000000000..be22a36e23 --- /dev/null +++ b/backend/canisters/event_relay/impl/src/lifecycle/init.rs @@ -0,0 +1,25 @@ +use crate::lifecycle::{init_env, init_state}; +use crate::Data; +use canister_tracing_macros::trace; +use event_relay_canister::init::Args; +use ic_cdk_macros::init; +use tracing::info; +use utils::cycles::init_cycles_dispenser_client; + +#[init] +#[trace] +fn init(args: Args) { + canister_logger::init(args.test_mode); + init_cycles_dispenser_client(args.cycles_dispenser_canister_id, args.test_mode); + + let env = init_env([0; 32]); + let data = Data::new( + args.push_events_whitelist.into_iter().collect(), + args.cycles_dispenser_canister_id, + args.test_mode, + ); + + init_state(env, data, args.wasm_version); + + info!(version = %args.wasm_version, "Initialization complete"); +} diff --git a/backend/canisters/event_relay/impl/src/lifecycle/mod.rs b/backend/canisters/event_relay/impl/src/lifecycle/mod.rs new file mode 100644 index 0000000000..aaf9b1d99f --- /dev/null +++ b/backend/canisters/event_relay/impl/src/lifecycle/mod.rs @@ -0,0 +1,39 @@ +use crate::{mutate_state, Data, RuntimeState, WASM_VERSION}; +use std::time::Duration; +use tracing::trace; +use types::{BuildVersion, Timestamped}; +use utils::canister::get_random_seed; +use utils::env::canister::CanisterEnv; +use utils::env::Environment; + +mod init; +mod post_upgrade; +mod pre_upgrade; + +fn init_env(rng_seed: [u8; 32]) -> Box { + if rng_seed == [0; 32] { + ic_cdk_timers::set_timer(Duration::ZERO, reseed_rng); + } + Box::new(CanisterEnv::new(rng_seed)) +} + +fn init_state(env: Box, data: Data, wasm_version: BuildVersion) { + let now = env.now(); + let state = RuntimeState::new(env, data); + + crate::init_state(state); + WASM_VERSION.set(Timestamped::new(wasm_version, now)); +} + +fn reseed_rng() { + ic_cdk::spawn(reseed_rng_inner()); + + async fn reseed_rng_inner() { + let seed = get_random_seed().await; + mutate_state(|state| { + state.data.rng_seed = seed; + state.env = Box::new(CanisterEnv::new(seed)) + }); + trace!("Successfully reseeded rng"); + } +} diff --git a/backend/canisters/event_relay/impl/src/lifecycle/post_upgrade.rs b/backend/canisters/event_relay/impl/src/lifecycle/post_upgrade.rs new file mode 100644 index 0000000000..abb01184e2 --- /dev/null +++ b/backend/canisters/event_relay/impl/src/lifecycle/post_upgrade.rs @@ -0,0 +1,27 @@ +use crate::lifecycle::{init_env, init_state}; +use crate::memory::get_upgrades_memory; +use crate::Data; +use canister_logger::LogEntry; +use canister_tracing_macros::trace; +use event_relay_canister::post_upgrade::Args; +use ic_cdk_macros::post_upgrade; +use stable_memory::get_reader; +use tracing::info; +use utils::cycles::init_cycles_dispenser_client; + +#[post_upgrade] +#[trace] +fn post_upgrade(args: Args) { + let memory = get_upgrades_memory(); + let reader = get_reader(&memory); + + let (data, logs, traces): (Data, Vec, Vec) = serializer::deserialize(reader).unwrap(); + + canister_logger::init_with_logs(data.test_mode, logs, traces); + + let env = init_env(data.rng_seed); + init_cycles_dispenser_client(data.cycles_dispenser_canister_id, data.test_mode); + init_state(env, data, args.wasm_version); + + info!(version = %args.wasm_version, "Post-upgrade complete"); +} diff --git a/backend/canisters/event_relay/impl/src/lifecycle/pre_upgrade.rs b/backend/canisters/event_relay/impl/src/lifecycle/pre_upgrade.rs new file mode 100644 index 0000000000..220192443f --- /dev/null +++ b/backend/canisters/event_relay/impl/src/lifecycle/pre_upgrade.rs @@ -0,0 +1,26 @@ +use crate::memory::get_upgrades_memory; +use crate::take_state; +use canister_tracing_macros::trace; +use ic_cdk_macros::pre_upgrade; +use rand::Rng; +use stable_memory::get_writer; +use tracing::info; + +#[pre_upgrade] +#[trace] +fn pre_upgrade() { + info!("Pre-upgrade starting"); + + let mut state = take_state(); + state.data.rng_seed = state.env.rng().gen(); + + let logs = canister_logger::export_logs(); + let traces = canister_logger::export_traces(); + + let stable_state = (state.data, logs, traces); + + let mut memory = get_upgrades_memory(); + let writer = get_writer(&mut memory); + + serializer::serialize(stable_state, writer).unwrap(); +} diff --git a/backend/canisters/event_relay/impl/src/memory.rs b/backend/canisters/event_relay/impl/src/memory.rs new file mode 100644 index 0000000000..430afd5c57 --- /dev/null +++ b/backend/canisters/event_relay/impl/src/memory.rs @@ -0,0 +1,21 @@ +use ic_stable_structures::{ + memory_manager::{MemoryId, MemoryManager, VirtualMemory}, + DefaultMemoryImpl, +}; + +const UPGRADES: MemoryId = MemoryId::new(0); + +pub type Memory = VirtualMemory; + +thread_local! { + static MEMORY_MANAGER: MemoryManager + = MemoryManager::init_with_bucket_size(DefaultMemoryImpl::default(), 16); +} + +pub fn get_upgrades_memory() -> Memory { + get_memory(UPGRADES) +} + +fn get_memory(id: MemoryId) -> Memory { + MEMORY_MANAGER.with(|m| m.get(id)) +} diff --git a/backend/canisters/event_relay/impl/src/model/mod.rs b/backend/canisters/event_relay/impl/src/model/mod.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/backend/canisters/event_relay/impl/src/model/mod.rs @@ -0,0 +1 @@ + diff --git a/backend/canisters/event_relay/impl/src/queries/http_request.rs b/backend/canisters/event_relay/impl/src/queries/http_request.rs new file mode 100644 index 0000000000..fea6d8d402 --- /dev/null +++ b/backend/canisters/event_relay/impl/src/queries/http_request.rs @@ -0,0 +1,26 @@ +use crate::{read_state, RuntimeState}; +use http_request::{build_json_response, encode_logs, extract_route, Route}; +use ic_cdk_macros::query; +use types::{HttpRequest, HttpResponse, TimestampMillis}; + +#[query] +fn http_request(request: HttpRequest) -> HttpResponse { + fn get_logs_impl(since: Option) -> HttpResponse { + encode_logs(canister_logger::export_logs(), since.unwrap_or(0)) + } + + fn get_traces_impl(since: Option) -> HttpResponse { + encode_logs(canister_logger::export_traces(), since.unwrap_or(0)) + } + + fn get_metrics_impl(state: &RuntimeState) -> HttpResponse { + build_json_response(&state.metrics()) + } + + match extract_route(&request.url) { + Route::Logs(since) => get_logs_impl(since), + Route::Traces(since) => get_traces_impl(since), + Route::Metrics => read_state(get_metrics_impl), + _ => HttpResponse::not_found(), + } +} diff --git a/backend/canisters/event_relay/impl/src/queries/mod.rs b/backend/canisters/event_relay/impl/src/queries/mod.rs new file mode 100644 index 0000000000..1cfa1ad736 --- /dev/null +++ b/backend/canisters/event_relay/impl/src/queries/mod.rs @@ -0,0 +1 @@ +mod http_request; diff --git a/backend/canisters/event_relay/impl/src/updates/mod.rs b/backend/canisters/event_relay/impl/src/updates/mod.rs new file mode 100644 index 0000000000..f77132607f --- /dev/null +++ b/backend/canisters/event_relay/impl/src/updates/mod.rs @@ -0,0 +1 @@ +mod wallet_receive; diff --git a/backend/canisters/event_relay/impl/src/updates/wallet_receive.rs b/backend/canisters/event_relay/impl/src/updates/wallet_receive.rs new file mode 100644 index 0000000000..d08987204c --- /dev/null +++ b/backend/canisters/event_relay/impl/src/updates/wallet_receive.rs @@ -0,0 +1,9 @@ +use canister_tracing_macros::trace; +use ic_cdk_macros::update; +use utils::cycles::accept_cycles; + +#[update] +#[trace] +fn wallet_receive() { + accept_cycles(); +} diff --git a/backend/libraries/canister_agent_utils/src/lib.rs b/backend/libraries/canister_agent_utils/src/lib.rs index 0cb3b8d007..b186d2e264 100644 --- a/backend/libraries/canister_agent_utils/src/lib.rs +++ b/backend/libraries/canister_agent_utils/src/lib.rs @@ -15,6 +15,7 @@ pub enum CanisterName { Community, CyclesDispenser, Escrow, + EventRelay, Group, GroupIndex, Identity, @@ -42,6 +43,7 @@ impl FromStr for CanisterName { "community" => Ok(CanisterName::Community), "cycles_dispenser" => Ok(CanisterName::CyclesDispenser), "escrow" => Ok(CanisterName::Escrow), + "event_relay" => Ok(CanisterName::EventRelay), "group" => Ok(CanisterName::Group), "group_index" => Ok(CanisterName::GroupIndex), "identity" => Ok(CanisterName::Identity), @@ -70,6 +72,7 @@ impl Display for CanisterName { CanisterName::Community => "community", CanisterName::CyclesDispenser => "cycles_dispenser", CanisterName::Escrow => "escrow", + CanisterName::EventRelay => "event_relay", CanisterName::Group => "group", CanisterName::GroupIndex => "group_index", CanisterName::Identity => "identity", @@ -111,6 +114,7 @@ pub struct CanisterIds { pub neuron_controller: CanisterId, pub escrow: CanisterId, pub translations: CanisterId, + pub event_relay: CanisterId, pub nns_root: CanisterId, pub nns_governance: CanisterId, pub nns_internet_identity: CanisterId, diff --git a/canister_ids.json b/canister_ids.json index 6a8015b55d..f537d4579c 100644 --- a/canister_ids.json +++ b/canister_ids.json @@ -12,6 +12,10 @@ "ic": "s4yi7-yiaaa-aaaar-qacpq-cai", "ic_test": "tspqt-xaaaa-aaaal-qcnna-cai" }, + "event_relay": { + "ic": "6ofpc-2aaaa-aaaaf-biibq-cai", + "ic_test": "6jejw-xyaaa-aaaaf-biiba-cai" + }, "group_index": { "ic": "4ijyc-kiaaa-aaaaf-aaaja-cai", "ic_test": "7kifq-3yaaa-aaaaf-ab2cq-cai" diff --git a/dfx.json b/dfx.json index 73b1fedf44..f651511819 100644 --- a/dfx.json +++ b/dfx.json @@ -115,6 +115,12 @@ "wasm": "wasms/translations.wasm.gz", "build": "./scripts/generate-wasm.sh translations" }, + "event_relay": { + "type": "custom", + "candid": "backend/canisters/event_relay/api/can.did", + "wasm": "wasms/event_relay.wasm.gz", + "build": "./scripts/generate-wasm.sh event_relay" + }, "website": { "source": [ "frontend/app/build", diff --git a/scripts/deploy-local.sh b/scripts/deploy-local.sh index f5c43fdc97..6812655925 100755 --- a/scripts/deploy-local.sh +++ b/scripts/deploy-local.sh @@ -38,6 +38,7 @@ dfx --identity $IDENTITY canister create --no-wallet --with-cycles 1000000000000 dfx --identity $IDENTITY canister create --no-wallet --with-cycles 100000000000000 neuron_controller dfx --identity $IDENTITY canister create --no-wallet --with-cycles 100000000000000 escrow dfx --identity $IDENTITY canister create --no-wallet --with-cycles 100000000000000 translations +dfx --identity $IDENTITY canister create --no-wallet --with-cycles 100000000000000 event_relay # Install the OpenChat canisters ./scripts/deploy.sh local \ diff --git a/scripts/deploy-testnet.sh b/scripts/deploy-testnet.sh index 5a1d5d9db8..2d6cd61e96 100755 --- a/scripts/deploy-testnet.sh +++ b/scripts/deploy-testnet.sh @@ -34,6 +34,7 @@ dfx --identity $IDENTITY canister create --provisional-create-canister-effective dfx --identity $IDENTITY canister create --provisional-create-canister-effective-canister-id jrlun-jiaaa-aaaab-aaaaa-cai --network $NETWORK --no-wallet --with-cycles 100000000000000 neuron_controller dfx --identity $IDENTITY canister create --provisional-create-canister-effective-canister-id jrlun-jiaaa-aaaab-aaaaa-cai --network $NETWORK --no-wallet --with-cycles 100000000000000 escrow dfx --identity $IDENTITY canister create --provisional-create-canister-effective-canister-id jrlun-jiaaa-aaaab-aaaaa-cai --network $NETWORK --no-wallet --with-cycles 100000000000000 translations +dfx --identity $IDENTITY canister create --provisional-create-canister-effective-canister-id jrlun-jiaaa-aaaab-aaaaa-cai --network $NETWORK --no-wallet --with-cycles 100000000000000 event_relay # Install the OpenChat canisters ./scripts/deploy.sh $NETWORK \ diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 4b7026c82d..f81d683a29 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -44,6 +44,7 @@ MARKET_MAKER_CANISTER_ID=$(dfx canister --network $NETWORK id market_maker) NEURON_CONTROLLER_CANISTER_ID=$(dfx canister --network $NETWORK id neuron_controller) ESCROW_CANISTER_ID=$(dfx canister --network $NETWORK id escrow) TRANSLATIONS_CANISTER_ID=$(dfx canister --network $NETWORK id translations) +EVENT_RELAY_CANISTER_ID=$(dfx canister --network $NETWORK id event_relay) cargo run \ --manifest-path backend/canister_installer/Cargo.toml -- \ @@ -65,6 +66,8 @@ cargo run \ --market-maker $MARKET_MAKER_CANISTER_ID \ --neuron-controller $NEURON_CONTROLLER_CANISTER_ID \ --escrow $ESCROW_CANISTER_ID \ + --translations $TRANSLATIONS_CANISTER_ID \ + --event-relay $EVENT_RELAY_CANISTER_ID \ --nns-root $NNS_ROOT_CANISTER_ID \ --nns-governance $NNS_GOVERNANCE_CANISTER_ID \ --nns-internet-identity $NNS_INTERNET_IDENTITY_CANISTER_ID \ @@ -72,5 +75,4 @@ cargo run \ --nns-cmc $NNS_CMC_CANISTER_ID \ --nns-sns-wasm $NNS_SNS_WASM_CANISTER_ID \ --nns-index $NNS_INDEX_CANISTER_ID \ - --translations $TRANSLATIONS_CANISTER_ID diff --git a/scripts/download-all-canister-wasms.sh b/scripts/download-all-canister-wasms.sh index de2ae6863b..d20e0e7844 100755 --- a/scripts/download-all-canister-wasms.sh +++ b/scripts/download-all-canister-wasms.sh @@ -16,6 +16,7 @@ echo "Downloading wasms" ./download-canister-wasm.sh community $WASM_SRC || exit 1 ./download-canister-wasm.sh cycles_dispenser $WASM_SRC || exit 1 ./download-canister-wasm.sh escrow $WASM_SRC || exit 1 +./download-canister-wasm.sh event_relay $WASM_SRC || exit 1 ./download-canister-wasm.sh group $WASM_SRC || exit 1 ./download-canister-wasm.sh group_index $WASM_SRC || exit 1 ./download-canister-wasm.sh identity $WASM_SRC || exit 1 diff --git a/scripts/generate-all-canister-wasms.sh b/scripts/generate-all-canister-wasms.sh index 9aa174530e..2e146abd7e 100755 --- a/scripts/generate-all-canister-wasms.sh +++ b/scripts/generate-all-canister-wasms.sh @@ -7,6 +7,7 @@ cd $SCRIPT_DIR/.. ./scripts/generate-wasm.sh community ./scripts/generate-wasm.sh cycles_dispenser ./scripts/generate-wasm.sh escrow +./scripts/generate-wasm.sh event_relay ./scripts/generate-wasm.sh group ./scripts/generate-wasm.sh group_index ./scripts/generate-wasm.sh identity diff --git a/scripts/proposals/upgrade_event_relay.sh b/scripts/proposals/upgrade_event_relay.sh new file mode 100755 index 0000000000..d3f84f3ed9 --- /dev/null +++ b/scripts/proposals/upgrade_event_relay.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +VERSION=$1 +CHANGELOG_PATH=$2 + +TITLE="Upgrade EventRelay canister to $VERSION" +CHANGELOG=`cat $CHANGELOG_PATH` +FUNCTION_ID=3 +CANISTER_NAME=event_relay + +# Set current directory to the scripts root +SCRIPT=$(readlink -f "$0") +SCRIPT_DIR=$(dirname "$SCRIPT") +cd $SCRIPT_DIR/.. + +# Submit the proposal +./make_upgrade_canister_proposal.sh $FUNCTION_ID $CANISTER_NAME "$VERSION" "$TITLE" "$CHANGELOG" diff --git a/scripts/upgrade-canister.sh b/scripts/upgrade-canister.sh index 113a1118ec..c78c53ff81 100755 --- a/scripts/upgrade-canister.sh +++ b/scripts/upgrade-canister.sh @@ -35,6 +35,7 @@ MARKET_MAKER_CANISTER_ID=$(dfx canister --network $NETWORK id market_maker) NEURON_CONTROLLER_CANISTER_ID=$(dfx canister --network $NETWORK id neuron_controller) ESCROW_CANISTER_ID=$(dfx canister --network $NETWORK id escrow) TRANSLATIONS_CANISTER_ID=$(dfx canister --network $NETWORK id translations) +EVENT_RELAY_CANISTER_ID=$(dfx canister --network $NETWORK id event_relay) cargo run \ --manifest-path backend/canister_upgrader/Cargo.toml -- \ @@ -53,5 +54,6 @@ cargo run \ --neuron-controller $NEURON_CONTROLLER_CANISTER_ID \ --escrow $ESCROW_CANISTER_ID \ --translations $TRANSLATIONS_CANISTER_ID \ + --event-relay $EVENT_RELAY_CANISTER_ID \ --canister-to-upgrade $CANISTER_NAME \ --version $VERSION \ diff --git a/sns/scripts/proposals/register_canisters_with_sns/event_relay.ini b/sns/scripts/proposals/register_canisters_with_sns/event_relay.ini new file mode 100644 index 0000000000..3240dab5e2 --- /dev/null +++ b/sns/scripts/proposals/register_canisters_with_sns/event_relay.ini @@ -0,0 +1,5 @@ +TITLE="Register 'EventRelay' as an SNS controlled canister" +URL="https://github.com/open-chat-labs/open-chat/blob/master/backend/canisters/event_relay/impl/src/lib.rs" +SUMMARY="This canister will receive events from other OpenChat canisters then forward them on to the upcoming events / metrics system. + +This will allow for the creation of dashboards showcasing the activity taking place on OpenChat." \ No newline at end of file