From b1aa94a3bc4d3dee52c7c4af118d2af287ad6677 Mon Sep 17 00:00:00 2001 From: Kaloyan Gangov <6922910+gangov@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:00:36 +0300 Subject: [PATCH] adds TTL to multisig --- contracts/deployer/src/lib.rs | 43 ++++++++- contracts/multisig/src/lib.rs | 7 ++ contracts/multisig/src/storage.rs | 149 +++++++++++++++++++++++++++--- 3 files changed, 181 insertions(+), 18 deletions(-) diff --git a/contracts/deployer/src/lib.rs b/contracts/deployer/src/lib.rs index ade1a0e..180562c 100644 --- a/contracts/deployer/src/lib.rs +++ b/contracts/deployer/src/lib.rs @@ -5,6 +5,11 @@ use soroban_sdk::{ 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", @@ -73,26 +78,56 @@ pub enum DataKey { 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() + .has(&DataKey::IsInitialized) + .then(|| { + 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::MultisigWasmHash, 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::MultisigWasmHash) - .unwrap() + .unwrap(); + + env.storage() + .instance() + .has(&DataKey::MultisigWasmHash) + .then(|| { + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT) + }); + + wasm_hash } #[cfg(test)] diff --git a/contracts/multisig/src/lib.rs b/contracts/multisig/src/lib.rs index aaf839c..05be24f 100644 --- a/contracts/multisig/src/lib.rs +++ b/contracts/multisig/src/lib.rs @@ -13,5 +13,12 @@ pub mod token_contract { ); } +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; +} + #[cfg(test)] mod tests; diff --git a/contracts/multisig/src/storage.rs b/contracts/multisig/src/storage.rs index f41fef5..1ae4bdb 100644 --- a/contracts/multisig/src/storage.rs +++ b/contracts/multisig/src/storage.rs @@ -1,5 +1,7 @@ use soroban_sdk::{contracttype, map, Address, BytesN, Env, Map, String, Vec}; +use crate::ttl::{BUMP_AMOUNT, LIFETIME_THRESHOLD}; + #[contracttype] #[derive(Clone, Debug, PartialEq, Eq)] pub struct Proposal { @@ -68,13 +70,28 @@ pub enum DataKey { 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() + .has(&DataKey::IsInitialized) + .then(|| { + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT) + }); + + is_initialized } // ------------- @@ -83,36 +100,71 @@ pub fn set_name(env: &Env, name: String, description: String) { env.storage() .instance() .set(&DataKey::NameDescription, &(name, description)); + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT); } pub fn get_name(env: &Env) -> (String, String) { - env.storage() + let name = env + .storage() .instance() .get(&DataKey::NameDescription) - .unwrap() + .unwrap(); + + env.storage() + .instance() + .has(&DataKey::NameDescription) + .then(|| { + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT) + }); + + name } // ------------- pub fn get_quorum_bps(env: &Env) -> u32 { - env.storage().instance().get(&DataKey::QuorumBps).unwrap() + let quorum_bps = env.storage().instance().get(&DataKey::QuorumBps).unwrap(); + env.storage().instance().has(&DataKey::QuorumBps).then(|| { + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT); + }); + + quorum_bps } pub fn save_quorum_bps(env: &Env, quorum_bps: u32) { env.storage() .instance() .set(&DataKey::QuorumBps, &quorum_bps); + + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT); } // ------------- pub fn get_multisig_members(env: &Env) -> Map
{ - env.storage() + let members = env + .storage() .instance() .get(&DataKey::Multisig) // This vector is set during initialization // if it fails to load, it's a critical error - .unwrap() + .unwrap(); + + env.storage().instance().has(&DataKey::Multisig).then(|| { + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT) + }); + + members } #[allow(dead_code)] @@ -121,6 +173,9 @@ pub fn add_multisig_member(env: &Env, member: Address) { multisig.set(member, ()); env.storage().instance().set(&DataKey::Multisig, &multisig); + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT); } pub fn save_new_multisig(env: &Env, members: &Vec) { @@ -130,6 +185,9 @@ pub fn save_new_multisig(env: &Env, members: &Vec) { } env.storage().instance().set(&DataKey::Multisig, &multisig); + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT); } // ------------- @@ -143,14 +201,31 @@ pub fn increment_last_proposal_id(env: &Env) -> u32 { .unwrap_or_default() + 1u32; env.storage().instance().set(&DataKey::LastProposalId, &id); + + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT); + id } pub fn get_last_proposal_id(env: &Env) -> u32 { - env.storage() + let last_proposal_id = env + .storage() .instance() .get(&DataKey::LastProposalId) - .unwrap_or_default() + .unwrap_or_default(); + + env.storage() + .instance() + .has(&DataKey::LastProposalId) + .then(|| { + env.storage() + .instance() + .extend_ttl(LIFETIME_THRESHOLD, BUMP_AMOUNT) + }); + + last_proposal_id } // ------------- @@ -159,12 +234,32 @@ pub fn save_proposal(env: &Env, proposal: &Proposal) { env.storage() .persistent() .set(&DataKey::Proposal(proposal.id), proposal); + + env.storage().persistent().extend_ttl( + &DataKey::Proposal(proposal.id), + LIFETIME_THRESHOLD, + BUMP_AMOUNT, + ); } pub fn get_proposal(env: &Env, proposal_id: u32) -> Option