chore: use saturating sub with max_ttl computation#1792
Conversation
There was a problem hiding this comment.
Pull request overview
This PR makes Storage::max_ttl() more defensive and consistent by using saturating arithmetic when computing the maximum TTL from ledger values.
Changes:
- Switch
max_ttlcomputation frommax - seqtomax.saturating_sub(seq)to avoid underflow in edge/misconfigured cases.
There was a problem hiding this comment.
This is fine but the host guarantees that max ttl is greater than the current seq, so in practice this will have no impact.
Will this introduce instructions into the wasm guest side that are redundant? I think so. Although maybe it won't be meaningful difference since the minus will already be doing a check when compiled with checks on.
What's the motivation for doing this?
If we keep it the way it is we can add a comment explaining why the sub is safe.
Actually, this reduces size. Seems the WASM code for The test: #![no_std]
use soroban_sdk::{contract, contractimpl, Env, Symbol};
#[contract]
pub struct Contract;
#[contractimpl]
impl Contract {
pub fn put(e: Env, key: Symbol, val: Symbol) {
e.storage().persistent().set(&key, &val);
let max_ttl = e.storage().max_ttl();
e.storage().persistent().extend_ttl(&key, max_ttl, max_ttl);
}
pub fn get(e: Env, key: Symbol) -> Option<Symbol> {
let entry = e.storage().persistent().get(&key);
let max_ttl = e.storage().max_ttl();
if entry.is_some() {
e.storage().persistent().extend_ttl(&key, max_ttl, max_ttl);
}
entry
}
pub fn del(e: Env, key: Symbol) {
e.storage().persistent().remove(&key)
}
}Results
The host does prevent this from occurring. The SDK uses safe math functions in most locations outside of indexes/counters. This just brings this up to that standard. |
What
Use
saturating_subwhen computingmax_ttl.Why
Add another defense layer to potential misconfigurations, and improve consistency with math usage in the repository.
Closes #1791
Known limitations
None