mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-29 20:31:04 +00:00
Persistent Local Storage for offchain workers. (#2894)
* WiP. * Implement offchain storage APIs. * Change compare_and_set to return bool. * Add offchain http test. * Fix tests. * Bump spec version. * Fix warnings and test. * Fix compilation. * Remove unused code. * Introduce Local (fork-aware) and Persistent storage. * Fix borked merge. * Prevent warning on depreacated client.backend * Fix long lines. * Clean up dependencies. * Update core/primitives/src/offchain.rs Co-Authored-By: André Silva <andre.beat@gmail.com> * Update core/primitives/src/offchain.rs Co-Authored-By: André Silva <andre.beat@gmail.com>
This commit is contained in:
committed by
Gavin Wood
parent
24aa882ebc
commit
2217c1e9a1
@@ -857,24 +857,28 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
||||
.map_err(|_| "Invalid attempt to set value in ext_random_seed")?;
|
||||
Ok(())
|
||||
},
|
||||
ext_local_storage_set(key: *const u8, key_len: u32, value: *const u8, value_len: u32) => {
|
||||
ext_local_storage_set(kind: u32, key: *const u8, key_len: u32, value: *const u8, value_len: u32) => {
|
||||
let kind = offchain::StorageKind::try_from(kind)
|
||||
.map_err(|_| "storage kind OOB while ext_local_storage_set: wasm")?;
|
||||
let key = this.memory.get(key, key_len as usize)
|
||||
.map_err(|_| "OOB while ext_local_storage_set: wasm")?;
|
||||
let value = this.memory.get(value, value_len as usize)
|
||||
.map_err(|_| "OOB while ext_local_storage_set: wasm")?;
|
||||
|
||||
this.ext.offchain()
|
||||
.map(|api| api.local_storage_set(&key, &value))
|
||||
.map(|api| api.local_storage_set(kind, &key, &value))
|
||||
.ok_or_else(|| "Calling unavailable API ext_local_storage_set: wasm")?;
|
||||
|
||||
Ok(())
|
||||
},
|
||||
ext_local_storage_get(key: *const u8, key_len: u32, value_len: *mut u32) -> *mut u8 => {
|
||||
ext_local_storage_get(kind: u32, key: *const u8, key_len: u32, value_len: *mut u32) -> *mut u8 => {
|
||||
let kind = offchain::StorageKind::try_from(kind)
|
||||
.map_err(|_| "storage kind OOB while ext_local_storage_get: wasm")?;
|
||||
let key = this.memory.get(key, key_len as usize)
|
||||
.map_err(|_| "OOB while ext_local_storage_get: wasm")?;
|
||||
|
||||
let maybe_value = this.ext.offchain()
|
||||
.map(|api| api.local_storage_get(&key))
|
||||
.map(|api| api.local_storage_get(kind, &key))
|
||||
.ok_or_else(|| "Calling unavailable API ext_local_storage_get: wasm")?;
|
||||
|
||||
let (offset, len) = if let Some(value) = maybe_value {
|
||||
@@ -891,6 +895,31 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
||||
|
||||
Ok(offset)
|
||||
},
|
||||
ext_local_storage_compare_and_set(
|
||||
kind: u32,
|
||||
key: *const u8,
|
||||
key_len: u32,
|
||||
old_value: *const u8,
|
||||
old_value_len: u32,
|
||||
new_value: *const u8,
|
||||
new_value_len: u32
|
||||
) -> u32 => {
|
||||
let kind = offchain::StorageKind::try_from(kind)
|
||||
.map_err(|_| "storage kind OOB while ext_local_storage_compare_and_set: wasm")?;
|
||||
let key = this.memory.get(key, key_len as usize)
|
||||
.map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?;
|
||||
let old_value = this.memory.get(old_value, old_value_len as usize)
|
||||
.map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?;
|
||||
let new_value = this.memory.get(new_value, new_value_len as usize)
|
||||
.map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?;
|
||||
|
||||
let res = this.ext.offchain()
|
||||
.map(|api| api.local_storage_compare_and_set(kind, &key, &old_value, &new_value))
|
||||
.ok_or_else(|| "Calling unavailable API ext_local_storage_compare_andset: wasm")?;
|
||||
|
||||
Ok(if res { 0 } else { 1 })
|
||||
|
||||
},
|
||||
ext_http_request_start(
|
||||
method: *const u8,
|
||||
method_len: u32,
|
||||
@@ -1365,6 +1394,7 @@ mod tests {
|
||||
use state_machine::TestExternalities as CoreTestExternalities;
|
||||
use hex_literal::hex;
|
||||
use primitives::map;
|
||||
use substrate_offchain::testing;
|
||||
|
||||
type TestExternalities<H> = CoreTestExternalities<H, u64>;
|
||||
|
||||
@@ -1550,4 +1580,45 @@ mod tests {
|
||||
ordered_trie_root::<Blake2Hasher, _, _>(vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()].iter()).as_fixed_bytes().encode()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn offchain_local_storage_should_work() {
|
||||
use substrate_client::backend::OffchainStorage;
|
||||
|
||||
let mut ext = TestExternalities::<Blake2Hasher>::default();
|
||||
let (offchain, state) = testing::TestOffchainExt::new();
|
||||
ext.set_offchain_externalities(offchain);
|
||||
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||
assert_eq!(
|
||||
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_offchain_local_storage", &[]).unwrap(),
|
||||
vec![0]
|
||||
);
|
||||
assert_eq!(state.read().persistent_storage.get(b"", b"test"), Some(vec![]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn offchain_http_should_work() {
|
||||
let mut ext = TestExternalities::<Blake2Hasher>::default();
|
||||
let (offchain, state) = testing::TestOffchainExt::new();
|
||||
ext.set_offchain_externalities(offchain);
|
||||
state.write().expect_request(
|
||||
0,
|
||||
testing::PendingRequest {
|
||||
method: "POST".into(),
|
||||
uri: "http://localhost:12345".into(),
|
||||
body: vec![1, 2, 3, 4],
|
||||
headers: vec![("X-Auth".to_owned(), "test".to_owned())],
|
||||
sent: true,
|
||||
response: vec![1, 2, 3],
|
||||
response_headers: vec![("X-Auth".to_owned(), "hello".to_owned())],
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||
assert_eq!(
|
||||
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_offchain_http", &[]).unwrap(),
|
||||
vec![0]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user