Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add offchain_localStorageClear RPC method #7266

Merged
merged 10 commits into from
Jan 23, 2025
13 changes: 13 additions & 0 deletions prdoc/pr_7266.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
title: Add `offchain_localStorageClear` RPC method
doc:
bkchr marked this conversation as resolved.
Show resolved Hide resolved
- audience: Node Operator
description: |-
Adds RPC method `offchain_localStorageClear` to clear the offchain local storage.
crates:
- name: sc-offchain
bump: minor
- name: sc-rpc-api
bump: minor
bkchr marked this conversation as resolved.
Show resolved Hide resolved
validate: false
- name: sc-rpc
bump: minor
8 changes: 7 additions & 1 deletion substrate/client/offchain/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ mod tests {
}

#[test]
fn should_set_and_get_local_storage() {
fn should_set_get_and_clear_local_storage() {
// given
let kind = StorageKind::PERSISTENT;
let mut api = offchain_db();
Expand All @@ -387,6 +387,12 @@ mod tests {

// then
assert_eq!(api.local_storage_get(kind, key), Some(b"value".to_vec()));

// when
api.local_storage_clear(kind, key);

// then
assert_eq!(api.local_storage_get(kind, key), None);
}

#[test]
Expand Down
4 changes: 4 additions & 0 deletions substrate/client/rpc-api/src/offchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ pub trait OffchainApi {
#[method(name = "offchain_localStorageSet", with_extensions)]
fn set_local_storage(&self, kind: StorageKind, key: Bytes, value: Bytes) -> Result<(), Error>;

/// Clear offchain local storage under given key and prefix.
#[method(name = "offchain_localStorageClear", with_extensions)]
fn clear_local_storage(&self, kind: StorageKind, key: Bytes) -> Result<(), Error>;

/// Get offchain local storage under given key and prefix.
#[method(name = "offchain_localStorageGet", with_extensions)]
fn get_local_storage(&self, kind: StorageKind, key: Bytes) -> Result<Option<Bytes>, Error>;
Expand Down
17 changes: 17 additions & 0 deletions substrate/client/rpc/src/offchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ impl<T: OffchainStorage + 'static> OffchainApiServer for Offchain<T> {
Ok(())
}

fn clear_local_storage(
&self,
ext: &Extensions,
kind: StorageKind,
key: Bytes,
) -> Result<(), Error> {
check_if_safe(ext)?;

let prefix = match kind {
StorageKind::PERSISTENT => sp_offchain::STORAGE_PREFIX,
StorageKind::LOCAL => return Err(Error::UnavailableStorageKind),
};
self.storage.write().remove(prefix, &key);

Ok(())
}

fn get_local_storage(
&self,
ext: &Extensions,
Expand Down
13 changes: 12 additions & 1 deletion substrate/client/rpc/src/offchain/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,14 @@ fn local_storage_should_work() {
Ok(())
);
assert_matches!(
offchain.get_local_storage(&ext, StorageKind::PERSISTENT, key),
offchain.get_local_storage(&ext, StorageKind::PERSISTENT, key.clone()),
Ok(Some(ref v)) if *v == value
);
assert_matches!(
offchain.clear_local_storage(&ext, StorageKind::PERSISTENT, key.clone()),
Ok(())
);
assert_matches!(offchain.get_local_storage(&ext, StorageKind::PERSISTENT, key), Ok(None));
}

#[test]
Expand All @@ -55,6 +60,12 @@ fn offchain_calls_considered_unsafe() {
assert_eq!(e.to_string(), "RPC call is unsafe to be called externally")
}
);
assert_matches!(
offchain.clear_local_storage(&ext, StorageKind::PERSISTENT, key.clone()),
Err(Error::UnsafeRpcCalled(e)) => {
assert_eq!(e.to_string(), "RPC call is unsafe to be called externally")
}
);
assert_matches!(
offchain.get_local_storage(&ext, StorageKind::PERSISTENT, key),
Err(Error::UnsafeRpcCalled(e)) => {
Expand Down
Loading