From 2b2f634090b7ad77523ae8d8503958578fb183a2 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Tue, 20 Aug 2024 11:42:49 +0300 Subject: [PATCH 1/2] adds TTL to the collections --- contracts/collections/src/contract.rs | 52 +++++++++++++++++++-------- contracts/collections/src/lib.rs | 10 ++++++ 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/contracts/collections/src/contract.rs b/contracts/collections/src/contract.rs index 57d7cbb8..ae730f96 100644 --- a/contracts/collections/src/contract.rs +++ b/contracts/collections/src/contract.rs @@ -9,6 +9,7 @@ use crate::{ }, Config, DataKey, OperatorApprovalKey, URIValue, }, + ttl::{BUMP_AMOUNT, LIFETIME_THRESHOLD}, }; #[contract] @@ -98,13 +99,15 @@ impl Collections { return Err(ContractError::CannotApproveSelf); } - env.storage().persistent().set( - &DataKey::OperatorApproval(OperatorApprovalKey { - owner: sender.clone(), - operator: operator.clone(), - }), - &approved, - ); + let data_key = DataKey::OperatorApproval(OperatorApprovalKey { + owner: sender.clone(), + operator: operator.clone(), + }); + + env.storage().persistent().set(&data_key, &approved); + env.storage() + .persistent() + .extend_ttl(&data_key, LIFETIME_THRESHOLD, BUMP_AMOUNT); env.events() .publish(("Set approval for", "Sender: "), sender); @@ -125,14 +128,15 @@ impl Collections { owner: Address, operator: Address, ) -> Result { - let result = env - .storage() - .persistent() - .get(&DataKey::OperatorApproval(OperatorApprovalKey { - owner, - operator, - })) - .unwrap_or(false); + let data_key = DataKey::OperatorApproval(OperatorApprovalKey { owner, operator }); + + let result = env.storage().persistent().get(&data_key).unwrap_or(false); + + env.storage().persistent().has(&data_key).then(|| { + env.storage() + .persistent() + .extend_ttl(&data_key, LIFETIME_THRESHOLD, BUMP_AMOUNT) + }); Ok(result) } @@ -363,6 +367,9 @@ impl Collections { env.storage() .persistent() .set(&DataKey::Uri(id), &URIValue { uri: uri.clone() }); + env.storage() + .persistent() + .extend_ttl(&DataKey::Uri(id), LIFETIME_THRESHOLD, BUMP_AMOUNT); env.events().publish(("set uri", "sender: "), sender); env.events().publish(("set uri", "id: "), id); @@ -379,6 +386,11 @@ impl Collections { env.storage() .persistent() .set(&DataKey::CollectionUri, &URIValue { uri: uri.clone() }); + env.storage().persistent().extend_ttl( + &DataKey::CollectionUri, + LIFETIME_THRESHOLD, + BUMP_AMOUNT, + ); env.events().publish(("set collection uri", "uri: "), uri); @@ -389,6 +401,11 @@ impl Collections { #[allow(dead_code)] pub fn uri(env: Env, id: u64) -> Result { if let Some(uri) = env.storage().persistent().get(&DataKey::Uri(id)) { + env.storage().persistent().extend_ttl( + &DataKey::Uri(id), + LIFETIME_THRESHOLD, + BUMP_AMOUNT, + ); Ok(uri) } else { log!(&env, "Collections: Uri: No uri set for the given id"); @@ -400,6 +417,11 @@ impl Collections { #[allow(dead_code)] pub fn collection_uri(env: Env) -> Result { if let Some(uri) = env.storage().persistent().get(&DataKey::CollectionUri) { + env.storage().persistent().extend_ttl( + &DataKey::CollectionUri, + LIFETIME_THRESHOLD, + BUMP_AMOUNT, + ); Ok(uri) } else { log!(&env, "Collections: Uri: No collection uri set"); diff --git a/contracts/collections/src/lib.rs b/contracts/collections/src/lib.rs index 6cb73305..f80dd8fe 100644 --- a/contracts/collections/src/lib.rs +++ b/contracts/collections/src/lib.rs @@ -4,5 +4,15 @@ mod contract; mod error; mod storage; +pub mod ttl { + pub const DAY_IN_LEDGERS: u32 = 17280; + + pub const BUMP_AMOUNT: u32 = 7 * DAY_IN_LEDGERS; + pub const LIFETIME_THRESHOLD: u32 = BUMP_AMOUNT - DAY_IN_LEDGERS; + + pub const BALANCE_BUMP_AMOUNT: u32 = 30 * DAY_IN_LEDGERS; + pub const BALANCE_LIFETIME_THRESHOLD: u32 = BALANCE_BUMP_AMOUNT - DAY_IN_LEDGERS; +} + #[cfg(test)] mod test; From a096b0e2d48cb3cdf98918830b05c77d0cf0c91e Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:23:33 +0300 Subject: [PATCH 2/2] adds TTL to collections and deployer storages --- contracts/collections/src/storage.rs | 7 --- contracts/deployer/src/lib.rs | 72 +++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/contracts/collections/src/storage.rs b/contracts/collections/src/storage.rs index d4a6ed96..68e3fc56 100644 --- a/contracts/collections/src/storage.rs +++ b/contracts/collections/src/storage.rs @@ -1,12 +1,5 @@ use soroban_sdk::{contracttype, symbol_short, Address, Bytes, String, Symbol}; -// Constants for storage bump amounts -//pub(crate) const DAY_IN_LEDGERS: u32 = 17280; -//pub(crate) const INSTANCE_BUMP_AMOUNT: u32 = 7 * DAY_IN_LEDGERS; -//pub(crate) const INSTANCE_LIFETIME_THRESHOLD: u32 = INSTANCE_BUMP_AMOUNT - DAY_IN_LEDGERS; -//pub(crate) const BALANCE_BUMP_AMOUNT: u32 = 30 * DAY_IN_LEDGERS; -//pub(crate) const BALANCE_LIFETIME_THRESHOLD: u32 = BALANCE_BUMP_AMOUNT - DAY_IN_LEDGERS; - type NftId = u64; type TokenId = u64; type Balance = u64; diff --git a/contracts/deployer/src/lib.rs b/contracts/deployer/src/lib.rs index e5ecd2f9..d703a516 100644 --- a/contracts/deployer/src/lib.rs +++ b/contracts/deployer/src/lib.rs @@ -5,6 +5,11 @@ use soroban_sdk::{ Env, IntoVal, String, Symbol, Val, Vec, }; +// Values used to extend the TTL of storage +pub const DAY_IN_LEDGERS: u32 = 17280; +pub const BUMP_AMOUNT: u32 = 7 * DAY_IN_LEDGERS; +pub const LIFETIME_THRESHOLD: u32 = BUMP_AMOUNT - DAY_IN_LEDGERS; + // Metadata that is added on to the WASM custom section contractmeta!( key = "Description", @@ -70,6 +75,17 @@ impl CollectionsDeployer { .get(&DataKey::AllCollections) .ok_or(ContractError::NoCollectionsSaved)?; + env.storage() + .persistent() + .has(&DataKey::AllCollections) + .then(|| { + env.storage().persistent().extend_ttl( + &DataKey::AllCollections, + LIFETIME_THRESHOLD, + BUMP_AMOUNT, + ) + }); + Ok(maybe_all) } @@ -77,12 +93,19 @@ impl CollectionsDeployer { env: &Env, creator: Address, ) -> Result, ContractError> { + let data_key = DataKey::Creator(creator); let maybe_collections = env .storage() .persistent() - .get(&DataKey::Creator(creator)) + .get(&data_key) .ok_or(ContractError::CreatorHasNoCollections)?; + env.storage().persistent().has(&data_key).then(|| { + env.storage() + .persistent() + .extend_ttl(&data_key, LIFETIME_THRESHOLD, BUMP_AMOUNT) + }); + Ok(maybe_collections) } } @@ -108,26 +131,50 @@ pub enum ContractError { pub fn set_initialized(env: &Env) { env.storage().instance().set(&DataKey::IsInitialized, &()); + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT); } pub fn is_initialized(env: &Env) -> bool { - env.storage() + let is_initialized = env + .storage() .instance() .get::<_, ()>(&DataKey::IsInitialized) - .is_some() + .is_some(); + + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT); + + is_initialized } pub fn set_wasm_hash(env: &Env, hash: &BytesN<32>) { env.storage() .instance() .set(&DataKey::CollectionsWasmHash, hash); + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT); } pub fn get_wasm_hash(env: &Env) -> BytesN<32> { - env.storage() + let wasm_hash = env + .storage() .instance() .get(&DataKey::CollectionsWasmHash) - .unwrap() + .unwrap(); + env.storage() + .instance() + .has(&DataKey::CollectionsWasmHash) + .then(|| { + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT) + }); + + wasm_hash } pub fn save_collection_with_generic_key(env: &Env, name: String) { @@ -142,20 +189,31 @@ pub fn save_collection_with_generic_key(env: &Env, name: String) { env.storage() .persistent() .set(&DataKey::AllCollections, &existent_collection); + + env.storage().persistent().extend_ttl( + &DataKey::AllCollections, + LIFETIME_THRESHOLD, + BUMP_AMOUNT, + ); } pub fn save_collection_with_admin_address_as_key(env: &Env, name: String, creator: Address) { + let data_key = DataKey::Creator(creator); + let mut existent_collection: Vec = env .storage() .persistent() - .get(&DataKey::Creator(creator.clone())) + .get(&data_key) .unwrap_or(vec![&env]); existent_collection.push_back(name); env.storage() .persistent() - .set(&DataKey::Creator(creator), &existent_collection); + .set(&data_key, &existent_collection); + env.storage() + .persistent() + .extend_ttl(&data_key, LIFETIME_THRESHOLD, BUMP_AMOUNT); } #[cfg(test)]