Skip to content

Commit

Permalink
chore: init all stable variable
Browse files Browse the repository at this point in the history
  • Loading branch information
IDX GitLab Automation committed Oct 11, 2024
1 parent 4a16572 commit 9c7347a
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 17 deletions.
5 changes: 5 additions & 0 deletions rs/boundary_node/rate_limits/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,8 @@ pub struct OutputRule {
pub description: Option<String>,
pub disclosed_at: Option<Timestamp>,
}

#[derive(CandidType, Deserialize, Debug)]
pub struct InitArg {
registry_polling_period_secs: u64,
}
22 changes: 12 additions & 10 deletions rs/boundary_node/rate_limits/canister/canister.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
use rate_limits_api::{GetConfigResponse, Version};
use storage::VERSION;
use rate_limits_api::{GetConfigResponse, InitArg, Version};
use storage::{get_stable_version, set_stable_version};
use types::{ConfigResponse, OutputConfig};
mod storage;
mod types;

#[ic_cdk::init]
fn init(_init_arg: InitArg) {
// Initialize version to 1
set_stable_version(1);
// TODO: init periodic timer for fetching API BNs principals.
}

#[ic_cdk_macros::update]
fn get_config(version: Option<Version>) -> GetConfigResponse {
let test_version_inc = VERSION.with(|v| {
let mut ver = v.borrow_mut();
let current_version = ver.get(&()).unwrap_or(0);
ver.insert((), current_version + 1);
current_version
});
fn get_config(_version: Option<Version>) -> GetConfigResponse {
let version = get_stable_version();

let response = ConfigResponse {
version: version.unwrap_or(test_version_inc),
version,
active_since: 1,
config: OutputConfig { rules: vec![] },
};
Expand Down
165 changes: 158 additions & 7 deletions rs/boundary_node/rate_limits/canister/storage.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,182 @@
use std::cell::RefCell;
use std::{borrow::Cow, cell::RefCell};

use ic_stable_structures::{
memory_manager::{MemoryId, MemoryManager, VirtualMemory},
DefaultMemoryImpl, StableBTreeMap,
storable::Bound,
DefaultMemoryImpl, StableBTreeMap, Storable,
};
use serde::{Deserialize, Serialize};

use crate::types::Version;
use crate::types::{RuleId, Timestamp, Version};

// Stable Memory
// Type aliases for stable memory
type Memory = VirtualMemory<DefaultMemoryImpl>;

type StableMap<K, V> = StableBTreeMap<K, V, Memory>;
type _StableSet<T> = StableMap<T, ()>;
type StableValue<T> = StableMap<(), T>;

// Memory IDs for stable memory management
const MEMORY_ID_VERSION: u8 = 0;
const _MEMORY_ID_CONFIGS: u8 = 1;
const _MEMORY_ID_RULES: u8 = 2;
const _MEMORY_ID_INCIDENTS: u8 = 3;

// Memory
// Storables
#[derive(Clone, Serialize, Deserialize, PartialOrd, Ord, PartialEq, Eq)]
pub struct StorableVersion(pub Version);

#[derive(Clone, Serialize, Deserialize, PartialOrd, Ord, PartialEq, Eq)]
pub struct StorableRuleId(pub String);

#[derive(Clone, Serialize, Deserialize, PartialOrd, Ord, PartialEq, Eq)]
pub struct StorableIncidentId(String);

#[derive(Serialize, Deserialize)]
pub struct StorableRuleMetadata {
pub rule_raw: Vec<u8>,
pub description: String,
pub disclosed_at: Option<Timestamp>,
pub added_in_version: Version,
pub removed_in_version: Option<Version>,
}

#[derive(Serialize, Deserialize)]
struct StorableConfig {
active_since: Timestamp,
rule_ids: Vec<RuleId>,
}

#[derive(Serialize, Deserialize)]
pub struct StorableRuleIds {
rule_ids: Vec<RuleId>,
}

impl Storable for StorableVersion {
fn to_bytes(&self) -> Cow<[u8]> {
self.0.to_bytes()
}

fn from_bytes(bytes: Cow<'_, [u8]>) -> Self {
Self(u64::from_bytes(bytes))
}

const BOUND: Bound = <Version as Storable>::BOUND;
}

impl Storable for StorableRuleId {
fn to_bytes(&self) -> Cow<[u8]> {
self.0.to_bytes()
}

fn from_bytes(bytes: Cow<'_, [u8]>) -> Self {
Self(String::from_bytes(bytes))
}

// TODO: make it bounded
const BOUND: Bound = Bound::Unbounded;
}

impl Storable for StorableIncidentId {
fn to_bytes(&self) -> Cow<[u8]> {
self.0.to_bytes()
}

fn from_bytes(bytes: Cow<'_, [u8]>) -> Self {
Self(String::from_bytes(bytes))
}

// TODO: make it bounded
const BOUND: Bound = Bound::Unbounded;
}

impl Storable for StorableConfig {
fn to_bytes(&self) -> Cow<[u8]> {
let mut buf = vec![];
ciborium::ser::into_writer(self, &mut buf).expect("failed to encode StorableConfig");
Cow::Owned(buf)
}

fn from_bytes(bytes: Cow<'_, [u8]>) -> Self {
ciborium::de::from_reader(&bytes[..]).expect("failed to decode StorableConfig")
}

// TODO: make it bounded
const BOUND: Bound = Bound::Unbounded;
}

impl Storable for StorableRuleIds {
fn to_bytes(&self) -> Cow<[u8]> {
let mut buf = vec![];
ciborium::ser::into_writer(self, &mut buf).expect("failed to encode StorableRuleIds");
Cow::Owned(buf)
}

fn from_bytes(bytes: Cow<'_, [u8]>) -> Self {
ciborium::de::from_reader(&bytes[..]).expect("failed to decode StorableRuleIds")
}

// TODO: make it bounded
const BOUND: Bound = Bound::Unbounded;
}

impl Storable for StorableRuleMetadata {
fn to_bytes(&self) -> Cow<[u8]> {
let mut buf = vec![];
ciborium::ser::into_writer(self, &mut buf).expect("failed to encode StorableRuleMetadata");
Cow::Owned(buf)
}

fn from_bytes(bytes: Cow<'_, [u8]>) -> Self {
ciborium::de::from_reader(&bytes[..]).expect("failed to decode StorableRuleMetadata")
}

// TODO: make it bounded
const BOUND: Bound = Bound::Unbounded;
}

pub fn set_stable_version(version: Version) {
VERSION.with(|v| {
let mut v = v.borrow_mut();
v.insert((), StorableVersion(version));
});
}

pub fn get_stable_version() -> Version {
let version = VERSION.with(|v| {
let v = v.borrow();
v.get(&()).expect("failed to get version")
});
version.0
}

// Declare storage, initialized lazily
thread_local! {
static MEMORY_MANAGER: RefCell<MemoryManager<DefaultMemoryImpl>> =
RefCell::new(MemoryManager::init(DefaultMemoryImpl::default()));
}

thread_local! {
pub static VERSION: RefCell<StableValue<Version>> = RefCell::new(
pub static VERSION: RefCell<StableValue<StorableVersion>> = RefCell::new(
StableValue::init(
MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(MEMORY_ID_VERSION))),
)
);

pub static CONFIGS: RefCell<StableMap<StorableVersion, StorableConfig>> = RefCell::new(
StableMap::init(
MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(_MEMORY_ID_CONFIGS))),
)
);

pub static RULES: RefCell<StableMap<StorableRuleId, StorableRuleMetadata>> = RefCell::new(
StableMap::init(
MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(_MEMORY_ID_RULES))),
)
);

pub static INCIDENTS: RefCell<StableMap<StorableIncidentId, StorableRuleIds>> = RefCell::new(
StableMap::init(
MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(_MEMORY_ID_INCIDENTS))),
)
);
}

0 comments on commit 9c7347a

Please sign in to comment.