Expand description

Off-chain Storage Lock

A storage-based lock with a defined expiry time.

The lock is using Local Storage and allows synchronizing access to critical section of your code for concurrently running Off-chain Workers. Usage of PERSISTENT variant of the storage persists the lock value across a full node restart or re-orgs.

A use case for the lock is to make sure that a particular section of the code is only run by one Off-chain Worker at a time. This may include performing a side-effect (i.e. an HTTP call) or alteration of single or multiple Local Storage entries.

One use case would be collective updates of multiple data items or append / remove of i.e. sets, vectors which are stored in the off-chain storage DB.

Example:

// in your off-chain worker code
use sp_runtime::offchain::{
		storage::StorageValueRef,
		storage_lock::{StorageLock, Time},
};

fn append_to_in_storage_vec<'a, T>(key: &'a [u8], _: T) where T: Codec {
   // `access::lock` defines the storage entry which is used for
   // persisting the lock in the underlying database.
   // The entry name _must_ be unique and can be interpreted as a
   // unique mutex instance reference tag.
   let mut lock = StorageLock::<Time>::new(b"access::lock");
   {
        let _guard = lock.lock();
        let acc = StorageValueRef::persistent(key);
        let v: Vec<T> = acc.get::<Vec<T>>().unwrap().unwrap();
        // modify `v` as desired
        // i.e. perform some heavy computation with
        // side effects that should only be done once.
        acc.set(&v);
        // drop `_guard` implicitly at end of scope
   }
}

Structs

Traits

  • Lockable item for use with a persisted storage lock.