referrerpolicy=no-referrer-when-downgrade

sc_rpc/offchain/
mod.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Substrate offchain API.
20
21#[cfg(test)]
22mod tests;
23
24use self::error::Error;
25use jsonrpsee::{core::async_trait, Extensions};
26use parking_lot::RwLock;
27use sc_rpc_api::check_if_safe;
28/// Re-export the API for backward compatibility.
29pub use sc_rpc_api::offchain::*;
30use sp_core::{
31	offchain::{OffchainStorage, StorageKind},
32	Bytes,
33};
34use std::sync::Arc;
35
36/// Offchain API
37#[derive(Debug)]
38pub struct Offchain<T: OffchainStorage> {
39	/// Offchain storage
40	storage: Arc<RwLock<T>>,
41}
42
43impl<T: OffchainStorage> Offchain<T> {
44	/// Create new instance of Offchain API.
45	pub fn new(storage: T) -> Self {
46		Offchain { storage: Arc::new(RwLock::new(storage)) }
47	}
48}
49
50#[async_trait]
51impl<T: OffchainStorage + 'static> OffchainApiServer for Offchain<T> {
52	fn set_local_storage(
53		&self,
54		ext: &Extensions,
55		kind: StorageKind,
56		key: Bytes,
57		value: Bytes,
58	) -> Result<(), Error> {
59		check_if_safe(ext)?;
60
61		let prefix = match kind {
62			StorageKind::PERSISTENT => sp_offchain::STORAGE_PREFIX,
63			StorageKind::LOCAL => return Err(Error::UnavailableStorageKind),
64		};
65		self.storage.write().set(prefix, &key, &value);
66		Ok(())
67	}
68
69	fn clear_local_storage(
70		&self,
71		ext: &Extensions,
72		kind: StorageKind,
73		key: Bytes,
74	) -> Result<(), Error> {
75		check_if_safe(ext)?;
76
77		let prefix = match kind {
78			StorageKind::PERSISTENT => sp_offchain::STORAGE_PREFIX,
79			StorageKind::LOCAL => return Err(Error::UnavailableStorageKind),
80		};
81		self.storage.write().remove(prefix, &key);
82
83		Ok(())
84	}
85
86	fn get_local_storage(
87		&self,
88		ext: &Extensions,
89		kind: StorageKind,
90		key: Bytes,
91	) -> Result<Option<Bytes>, Error> {
92		check_if_safe(ext)?;
93
94		let prefix = match kind {
95			StorageKind::PERSISTENT => sp_offchain::STORAGE_PREFIX,
96			StorageKind::LOCAL => return Err(Error::UnavailableStorageKind),
97		};
98
99		Ok(self.storage.read().get(prefix, &key).map(Into::into))
100	}
101}