Skip to content

Commit 41e66bc

Browse files
committed
adding some test
1 parent cf6d0ab commit 41e66bc

File tree

10 files changed

+252
-44
lines changed

10 files changed

+252
-44
lines changed

common/primitives/src/offchain.rs

Lines changed: 87 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::msa::MessageSourceId;
22
use numtoa::NumToA;
3-
use parity_scale_codec::{Decode, Encode};
4-
use sp_io::offchain_index;
3+
use parity_scale_codec::Decode;
54
use sp_runtime::offchain::storage::{StorageRetrievalError, StorageValueRef};
65
use sp_std::{fmt::Debug, vec, vec::Vec};
76

@@ -36,25 +35,6 @@ pub fn get_index_value<V: Decode + Debug>(key: &[u8]) -> Result<Option<V>, Stora
3635
get_impl::<V>(key)
3736
}
3837

39-
/// Wrapper for offchain_index remove operations
40-
pub fn remove_offchain_index_value(key: &[u8]) {
41-
offchain_index::clear(key);
42-
}
43-
44-
/// Wrapper for offchain_index set operations
45-
pub fn set_offchain_index_value(key: &[u8], value: &[u8]) {
46-
offchain_index::set(key, value);
47-
}
48-
49-
/// Sets a value by the key to offchain index
50-
pub fn set_index_value<V>(key: &[u8], value: V)
51-
where
52-
V: Encode + Debug,
53-
{
54-
let oci_mem = StorageValueRef::persistent(key);
55-
oci_mem.set(&value);
56-
}
57-
5838
/// Gets a value by the key from persistent storage
5939
fn get_impl<V: Decode + Debug>(key: &[u8]) -> Result<Option<V>, StorageRetrievalError> {
6040
let oci_mem = StorageValueRef::persistent(key);
@@ -64,3 +44,89 @@ fn get_impl<V: Decode + Debug>(key: &[u8]) -> Result<Option<V>, StorageRetrieval
6444
Err(_) => Err(StorageRetrievalError::Undecodable),
6545
}
6646
}
47+
48+
#[cfg(test)]
49+
mod tests {
50+
use super::*;
51+
use sp_core::offchain::{testing, OffchainDbExt, OffchainWorkerExt};
52+
use sp_io::TestExternalities;
53+
54+
#[test]
55+
fn get_msa_account_lock_name_should_return_expected_value() {
56+
let msa_id: MessageSourceId = 2_000_000;
57+
let result = get_msa_account_lock_name(msa_id);
58+
assert_eq!(result, b"Msa::ofw::lock::2000000".to_vec());
59+
}
60+
61+
#[test]
62+
fn get_msa_account_storage_name_should_return_expected_value() {
63+
let msa_id: MessageSourceId = 2_000_000;
64+
let result = get_msa_account_storage_key_name(msa_id);
65+
assert_eq!(result, b"Msa::ofw::keys::2000000".to_vec());
66+
}
67+
68+
#[test]
69+
fn get_index_for_not_set_should_return_none() {
70+
let (offchain, _state) = testing::TestOffchainExt::new();
71+
let mut t = TestExternalities::default();
72+
t.register_extension(OffchainDbExt::new(offchain.clone()));
73+
t.register_extension(OffchainWorkerExt::new(offchain));
74+
75+
t.execute_with(|| {
76+
let key = b"my_key";
77+
let result = get_index_value::<MessageSourceId>(key);
78+
assert_eq!(result, Ok(None));
79+
});
80+
}
81+
82+
#[test]
83+
fn get_index_for_set_should_return_expected() {
84+
// arrange
85+
let (offchain, _state) = testing::TestOffchainExt::new();
86+
let mut t = TestExternalities::default();
87+
t.register_extension(OffchainDbExt::new(offchain.clone()));
88+
t.register_extension(OffchainWorkerExt::new(offchain));
89+
90+
t.execute_with(|| {
91+
let key = b"my_key1";
92+
let msa_id: MessageSourceId = 1000000;
93+
let oci_mem = StorageValueRef::persistent(key);
94+
oci_mem.set(&msa_id);
95+
96+
// act
97+
let result = get_index_value::<MessageSourceId>(key);
98+
99+
// assert
100+
assert_eq!(result, Ok(Some(msa_id)));
101+
});
102+
}
103+
104+
#[test]
105+
fn get_index_for_not_decodable_should_return_error() {
106+
let (offchain, _state) = testing::TestOffchainExt::new();
107+
let mut t = TestExternalities::default();
108+
t.register_extension(OffchainDbExt::new(offchain.clone()));
109+
t.register_extension(OffchainWorkerExt::new(offchain));
110+
111+
#[derive(Debug, Decode, PartialEq)]
112+
struct Testing {
113+
pub a: u64,
114+
pub b: u32,
115+
pub c: u16,
116+
}
117+
118+
t.execute_with(|| {
119+
// arrange
120+
let key = b"my_key2";
121+
let msa_id: MessageSourceId = 1000000;
122+
let oci_mem = StorageValueRef::persistent(key);
123+
oci_mem.set(&msa_id);
124+
125+
// act
126+
let result = get_index_value::<Testing>(key);
127+
128+
// assert
129+
assert_eq!(result, Err(StorageRetrievalError::Undecodable));
130+
});
131+
}
132+
}

node/service/src/block_sealing.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,10 @@ pub fn frequency_dev_sealing(
181181
let rpc_extensions_builder = {
182182
let client = client.clone();
183183
let transaction_pool = transaction_pool.clone();
184-
let backend = backend.offchain_storage();
184+
let backend = match config.offchain_worker.enabled {
185+
true => backend.offchain_storage(),
186+
false => None,
187+
};
185188

186189
move |deny_unsafe, _| {
187190
let deps = crate::rpc::FullDeps {

node/service/src/service.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,10 @@ async fn start_node_impl(
295295
let rpc_builder = {
296296
let client = client.clone();
297297
let transaction_pool = transaction_pool.clone();
298-
let backend = backend.offchain_storage();
298+
let backend = match parachain_config.offchain_worker.enabled {
299+
true => backend.offchain_storage(),
300+
false => None,
301+
};
299302

300303
Box::new(move |deny_unsafe, _| {
301304
let deps = crate::rpc::FullDeps {

pallets/msa/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,8 @@ pub mod pallet {
263263
/// At the start of the next block this storage is set to 0
264264
#[pallet::storage]
265265
#[pallet::whitelist_storage]
266-
#[pallet::getter(fn get_msa_event_count)]
267-
pub(super) type MSAEventCount<T: Config> = StorageValue<_, u16, ValueQuery>;
266+
#[pallet::getter(fn get_offchain_index_event_count)]
267+
pub(super) type OffchainIndexEventCount<T: Config> = StorageValue<_, u16, ValueQuery>;
268268

269269
#[pallet::event]
270270
#[pallet::generate_deposit(pub (super) fn deposit_event)]
@@ -427,7 +427,7 @@ pub mod pallet {
427427
#[pallet::hooks]
428428
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
429429
fn on_initialize(_block_number: BlockNumberFor<T>) -> Weight {
430-
<MSAEventCount<T>>::set(0u16);
430+
<OffchainIndexEventCount<T>>::set(0u16);
431431
// allocates 1 read and 1 write for any access of `MSAEventCount` in every block
432432
T::DbWeight::get().reads_writes(1u64, 1u64)
433433
}

pallets/msa/src/offchain_storage.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{pallet::MSAEventCount, Config, Event, Pallet, PublicKeyToMsaId};
1+
use crate::{pallet::OffchainIndexEventCount, Config, Event, Pallet, PublicKeyToMsaId};
22
pub use common_primitives::msa::MessageSourceId;
33
/// Offchain Storage for MSA
44
use common_primitives::offchain::{
@@ -8,9 +8,10 @@ use common_primitives::offchain::{
88
use frame_support::RuntimeDebugNoBound;
99
use frame_system::pallet_prelude::BlockNumberFor;
1010
use parity_scale_codec::{Decode, Encode};
11-
use sp_core::serde::Deserialize;
11+
use sp_core::serde::{Deserialize, Serialize};
1212
extern crate alloc;
1313
use alloc::string::String;
14+
use sp_io::offchain_index;
1415
use sp_runtime::{
1516
offchain::{
1617
storage::StorageValueRef,
@@ -59,19 +60,21 @@ const NUMBER_OF_PREVIOUS_BLOCKS_TO_CHECK: u32 = 5u32;
5960
const NUMBER_OF_BLOCKS_TO_EXPLORE: u32 = 1000;
6061

6162
/// HTTP request deadline in milliseconds
62-
const HTTP_REQUEST_DEADLINE_MILLISECONDS: u64 = 2000;
63+
pub const HTTP_REQUEST_DEADLINE_MILLISECONDS: u64 = 2000;
6364

6465
/// LOCAL RPC URL and port
6566
/// warning: this should be updated if rpc port is set to anything different from 9944
66-
const RPC_REQUEST_URL: &'static str = "http://localhost:9944";
67+
pub const RPC_FINALIZED_BLOCK_REQUEST_URL: &'static str = "http://localhost:9944";
68+
/// request body for getting last finalized block from rpc
69+
pub const RPC_FINALIZED_BLOCK_REQUEST_BODY: &[u8; 78] = b"{\"id\": 10, \"jsonrpc\": \"2.0\", \"method\": \"chain_getFinalizedHead\", \"params\": []}";
6770

6871
/// stores the event into offchain DB using offchain indexing
6972
pub fn offchain_index_event<T: Config>(event: &Event<T>, msa_id: MessageSourceId) {
7073
if let Some(event) = IndexedEvent::map(event, msa_id) {
7174
let block_number: u32 =
7275
<frame_system::Pallet<T>>::block_number().try_into().unwrap_or_default();
73-
let current_event_count: u16 = <MSAEventCount<T>>::get().saturating_add(1);
74-
<MSAEventCount<T>>::put(current_event_count);
76+
let current_event_count: u16 = <OffchainIndexEventCount<T>>::get().saturating_add(1);
77+
<OffchainIndexEventCount<T>>::put(current_event_count);
7578
let event_key = [
7679
BLOCK_EVENT_KEY,
7780
block_number.encode().as_slice(),
@@ -173,7 +176,7 @@ fn set_offchain_index<V>(key: &[u8], value: V)
173176
where
174177
V: Encode + Clone + Decode + Eq + Debug,
175178
{
176-
offchain_common::set_offchain_index_value(key, value.encode().as_slice());
179+
offchain_index::set(key, value.encode().as_slice());
177180
}
178181

179182
/// Get offchain index value, used to store MSA Events to be process by offchain worker
@@ -302,9 +305,9 @@ fn clean_offchain_events<T: Config>(block_number: BlockNumberFor<T>) {
302305
let key =
303306
[BLOCK_EVENT_KEY, block_number.encode().as_slice(), i.encode().as_slice()].concat();
304307

305-
offchain_common::remove_offchain_index_value(key.encode().as_slice());
308+
offchain_index::clear(key.encode().as_slice());
306309
}
307-
offchain_common::remove_offchain_index_value(count_key.encode().as_slice());
310+
offchain_index::clear(count_key.encode().as_slice());
308311
}
309312

310313
/// offchain worker callback for indexing msa keys
@@ -385,9 +388,9 @@ fn process_offchain_events<T: Config>(msa_id: MessageSourceId, events: Vec<Index
385388
msa_storage.set(&msa_keys);
386389
}
387390

388-
#[derive(Deserialize, Encode, Decode, Default, Debug)]
389-
struct FinalizedResult {
390-
result: String,
391+
#[derive(Serialize, Deserialize, Encode, Decode, Default, Debug)]
392+
pub struct FinalizedBlockResponse {
393+
pub result: String,
391394
}
392395

393396
/// get finalized
@@ -398,8 +401,8 @@ pub fn fetch_finalized<T: Config>() -> Result<T::Hash, sp_runtime::offchain::htt
398401
// coming from the host machine.
399402
let deadline =
400403
sp_io::offchain::timestamp().add(Duration::from_millis(HTTP_REQUEST_DEADLINE_MILLISECONDS));
401-
let body = vec![b"{\"id\": 10, \"jsonrpc\": \"2.0\", \"method\": \"chain_getFinalizedHead\", \"params\": []}"];
402-
let request = sp_runtime::offchain::http::Request::post(RPC_REQUEST_URL, body);
404+
let body = vec![RPC_FINALIZED_BLOCK_REQUEST_BODY];
405+
let request = sp_runtime::offchain::http::Request::post(RPC_FINALIZED_BLOCK_REQUEST_URL, body);
403406
let pending = request
404407
.add_header("Content-Type", "application/json")
405408
.deadline(deadline)
@@ -427,7 +430,7 @@ pub fn fetch_finalized<T: Config>() -> Result<T::Hash, sp_runtime::offchain::htt
427430
})?;
428431

429432
log::debug!("{}", body_str);
430-
let gh_info: FinalizedResult =
433+
let gh_info: FinalizedBlockResponse =
431434
serde_json::from_str(body_str).map_err(|_| sp_runtime::offchain::http::Error::Unknown)?;
432435

433436
let decoded_from_hex = hex::decode(&gh_info.result[2..])

pallets/msa/src/rpc/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ pub enum MsaOffchainRpcError {
8888
ErrorAcquiringLLock,
8989
/// Error decoding data
9090
ErrorDecodingData,
91+
/// Offchain indexing is not enabled
92+
OffchainIndexingNotEnabled,
9193
}
9294

9395
impl From<MsaOffchainRpcError> for JsonRpseeError {
@@ -161,7 +163,7 @@ where
161163
let reader = self.offchain.try_read().ok_or(MsaOffchainRpcError::ErrorAcquiringLLock)?;
162164
let raw: Option<Bytes> = reader
163165
.as_ref()
164-
.ok_or(MsaOffchainRpcError::ErrorAcquiringLLock)?
166+
.ok_or(MsaOffchainRpcError::OffchainIndexingNotEnabled)?
165167
.get(sp_offchain::STORAGE_PREFIX, &msa_key)
166168
.map(Into::into);
167169
if let Some(rr) = raw {
@@ -173,8 +175,8 @@ where
173175
.map(|account_id| KeyInfoResponse { msa_id, key: account_id })
174176
.collect();
175177

176-
return RpcResult::Ok(Some(res))
178+
return Ok(Some(res))
177179
}
178-
RpcResult::Ok(None)
180+
Ok(None)
179181
}
180182
}

pallets/msa/src/rpc/src/tests/mod.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use rpc_mock::*;
55

66
use common_primitives::node::BlockNumber;
77
use pallet_msa_runtime_api::MsaRuntimeApi;
8+
use parity_scale_codec::Encode;
89
use sp_api::offchain::testing::TestPersistentOffchainDB;
10+
use sp_core::{offchain::OffchainStorage, sr25519::Public};
911
use sp_runtime::traits::Zero;
1012
use std::{sync::Arc, vec};
1113
use substrate_test_runtime_client::runtime::{AccountId, Block};
@@ -184,3 +186,50 @@ async fn get_granted_schemas_by_msa_id_with_bad_provider_id() {
184186
let response = result.unwrap();
185187
assert!(response.is_none());
186188
}
189+
190+
#[tokio::test]
191+
async fn get_keys_by_msa_id_with_disabled_offchain_should_fail() {
192+
let client = Arc::new(TestApi {});
193+
let api = MsaHandler::<TestApi, Block, TestPersistentOffchainDB>::new(client, None);
194+
195+
let result = api.get_keys_by_msa_id(NOT_EXIST_MSA);
196+
197+
assert_eq!(true, result.is_err());
198+
assert_eq!("Custom error: OffchainIndexingNotEnabled", result.unwrap_err().to_string());
199+
}
200+
201+
#[tokio::test]
202+
async fn get_keys_by_msa_id_with_empty_value_should_work() {
203+
let client = Arc::new(TestApi {});
204+
let api = MsaHandler::<TestApi, Block, TestPersistentOffchainDB>::new(
205+
client,
206+
Some(TestPersistentOffchainDB::new()),
207+
);
208+
209+
let result = api.get_keys_by_msa_id(NOT_EXIST_MSA);
210+
211+
assert_eq!(true, result.is_ok());
212+
let response = result.unwrap();
213+
assert_eq!(None, response);
214+
}
215+
216+
#[tokio::test]
217+
async fn get_keys_by_msa_id_with_value_should_work() {
218+
let msa_id: MessageSourceId = 10;
219+
let accounts = vec![Public([1u8; 32])];
220+
let client = Arc::new(TestApi {});
221+
let mut db = TestPersistentOffchainDB::new();
222+
db.set(
223+
sp_offchain::STORAGE_PREFIX,
224+
&get_msa_account_storage_key_name(msa_id),
225+
&accounts.encode(),
226+
);
227+
let api = MsaHandler::<TestApi, Block, TestPersistentOffchainDB>::new(client, Some(db));
228+
229+
let result = api.get_keys_by_msa_id(msa_id);
230+
231+
assert_eq!(true, result.is_ok());
232+
let response = result.unwrap();
233+
assert_eq!(true, response.is_some());
234+
assert_eq!(vec![KeyInfoResponse { msa_id, key: accounts[0] }], response.unwrap());
235+
}

pallets/msa/src/tests/mock.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use frame_system::EnsureRoot;
1212
use pallet_collective;
1313
use parity_scale_codec::MaxEncodedLen;
1414
use sp_core::{sr25519, sr25519::Public, Encode, Pair, H256};
15+
use sp_core::offchain::{OffchainDbExt, OffchainWorkerExt, testing};
16+
use sp_io::TestExternalities;
1517
use sp_runtime::{
1618
traits::{BlakeTwo256, ConvertInto, IdentityLookup},
1719
AccountId32, BuildStorage, DispatchError, MultiSignature,
@@ -213,6 +215,18 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
213215
ext
214216
}
215217

218+
pub fn new_test_with_offchain_ext() -> sp_io::TestExternalities {
219+
set_max_signature_stored(8000);
220+
set_max_public_keys_per_msa(255);
221+
let t = frame_system::GenesisConfig::<Test>::default().build_storage().unwrap();
222+
let mut ext = sp_io::TestExternalities::new(t);
223+
let (offchain, _state) = testing::TestOffchainExt::new();
224+
ext.register_extension(OffchainDbExt::new(offchain.clone()));
225+
ext.register_extension(OffchainWorkerExt::new(offchain));
226+
ext.execute_with(|| System::set_block_number(1));
227+
ext
228+
}
229+
216230
pub fn run_to_block(n: u32) {
217231
while System::block_number() < n {
218232
if System::block_number() > 1 {

pallets/msa/src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ mod retirement_tests;
1010
mod schema_permission_tests;
1111
mod signature_registry_tests;
1212
mod signed_extension_tests;
13+
mod offchain_tests;

0 commit comments

Comments
 (0)