diff --git a/.changelog/unreleased/bug-fixes/1984-rm-redundant-writes.md b/.changelog/unreleased/bug-fixes/1984-rm-redundant-writes.md new file mode 100644 index 0000000000..f88ad5858f --- /dev/null +++ b/.changelog/unreleased/bug-fixes/1984-rm-redundant-writes.md @@ -0,0 +1,4 @@ +- Avoid redundant storage deletions in lazy collections that would incur + extra gas cause and appear in transaction result as changed keys even if not + changed occurred. This may have caused PoS transactions to run out of gas. + ([\#1984](https://github.com/anoma/namada/pull/1984)) \ No newline at end of file diff --git a/core/src/ledger/storage_api/collections/lazy_map.rs b/core/src/ledger/storage_api/collections/lazy_map.rs index 8d30e2052c..e17de83bef 100644 --- a/core/src/ledger/storage_api/collections/lazy_map.rs +++ b/core/src/ledger/storage_api/collections/lazy_map.rs @@ -585,16 +585,18 @@ where Ok(previous) } - /// Removes a key from the map, returning the value at the key if the key - /// was previously in the map. + /// Removes a key from the map if it's present, returning the value at the + /// key if the key was previously in the map. pub fn remove(&self, storage: &mut S, key: &K) -> Result> where S: StorageWrite + StorageRead, { let value = self.get(storage, key)?; - let data_key = self.get_data_key(key); - storage.delete(&data_key)?; + if value.is_some() { + let data_key = self.get_data_key(key); + storage.delete(&data_key)?; + } Ok(value) } diff --git a/core/src/ledger/storage_api/collections/lazy_set.rs b/core/src/ledger/storage_api/collections/lazy_set.rs index 038b7a87d0..9dc6747465 100644 --- a/core/src/ledger/storage_api/collections/lazy_set.rs +++ b/core/src/ledger/storage_api/collections/lazy_set.rs @@ -183,7 +183,7 @@ where storage.write(&key, ()) } - /// Removes a key from the set, returning `true` if the key + /// Removes a key from the set if it's present, returning `true` if the key /// was in the set. pub fn remove(&self, storage: &mut S, key: &K) -> Result where @@ -191,8 +191,10 @@ where { let present = self.contains(storage, key)?; - let key = self.get_key(key); - storage.delete(&key)?; + if present { + let key = self.get_key(key); + storage.delete(&key)?; + } Ok(present) }