Offchain-worker APIs stubs (#2615)

* WiP: HTTP Apis.

* Working on the API.

* Add docs, clean up the API.

* Expose ext_ stuff as well.

* Implement HTTP helpers for offchain sr-io.

* Remove HTTP stuff.

* Revert "Remove HTTP stuff."

This reverts commit 7cca029d6ae93c5849b50edfcc6d2c313ba3e5bf.

* HTTP apis.

* Additional offchain methods.

* Make it compile.

* Implement wasm-ext boundary of offchain methods.

* Add stubs for offchain stuff to prevent panics.

* Fix tests.

* Addres some more issues.

* Introduce typedef, use unsafe from_utf8

* Bump runtime version.

* Introduce error to distinguish deadline and io errors.

* Add local_storage_cas

* Some tests for offchain stuff.

* Address more grumbles.

* Fix tests compilation.

* Fix borked merge.

* Improve docs for expected return values from ext functions.

* Adding new sign/enrypt/decrypt APIs.
This commit is contained in:
Tomasz Drwięga
2019-05-31 09:33:44 +02:00
committed by Gavin Wood
parent 80b18c8531
commit 308ab4f269
26 changed files with 2648 additions and 120 deletions
+4 -3
View File
@@ -20,6 +20,7 @@ use std::collections::HashMap;
use std::iter::FromIterator;
use hash_db::Hasher;
use trie::trie_root;
use primitives::offchain;
use primitives::storage::well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES};
use parity_codec::Encode;
use super::{ChildStorageKey, Externalities, OverlayedChanges};
@@ -155,9 +156,9 @@ impl<H: Hasher> Externalities<H> for BasicExternalities where H::Out: Ord {
Ok(None)
}
fn submit_extrinsic(&mut self, _extrinsic: Vec<u8>) -> Result<(), ()> {
warn!("Call to submit_extrinsic without offchain externalities set.");
Err(())
fn offchain(&mut self) -> Option<&mut offchain::Externalities> {
warn!("Call to non-existent out offchain externalities set.");
None
}
}
+7 -13
View File
@@ -20,8 +20,9 @@ use std::{error, fmt, cmp::Ord};
use log::warn;
use crate::backend::Backend;
use crate::changes_trie::{Storage as ChangesTrieStorage, compute_changes_trie_root};
use crate::{Externalities, OverlayedChanges, OffchainExt, ChildStorageKey};
use crate::{Externalities, OverlayedChanges, ChildStorageKey};
use hash_db::Hasher;
use primitives::offchain;
use primitives::storage::well_known_keys::is_child_storage_key;
use trie::{MemoryDB, TrieDBMut, TrieMut, default_child_trie_root};
@@ -91,7 +92,7 @@ where
H: Hasher,
B: 'a + Backend<H>,
T: 'a + ChangesTrieStorage<H, N>,
O: 'a + OffchainExt,
O: 'a + offchain::Externalities,
H::Out: Ord + 'static,
N: crate::changes_trie::BlockNumber,
{
@@ -145,7 +146,7 @@ where
H: Hasher,
B: 'a + Backend<H>,
T: 'a + ChangesTrieStorage<H, N>,
O: 'a + OffchainExt,
O: 'a + offchain::Externalities,
N: crate::changes_trie::BlockNumber,
{
pub fn storage_pairs(&self) -> Vec<(Vec<u8>, Vec<u8>)> {
@@ -167,7 +168,7 @@ where
H: Hasher,
B: 'a + Backend<H>,
T: 'a + ChangesTrieStorage<H, N>,
O: 'a + OffchainExt,
O: 'a + offchain::Externalities,
H::Out: Ord + 'static,
N: crate::changes_trie::BlockNumber,
{
@@ -342,15 +343,8 @@ where
Ok(root)
}
fn submit_extrinsic(&mut self, extrinsic: Vec<u8>) -> Result<(), ()> {
let _guard = panic_handler::AbortGuard::new(true);
if let Some(ext) = self.offchain_externalities.as_mut() {
ext.submit_extrinsic(extrinsic);
Ok(())
} else {
warn!("Call to submit_extrinsic without offchain externalities set.");
Err(())
}
fn offchain(&mut self) -> Option<&mut offchain::Externalities> {
self.offchain_externalities.as_mut().map(|x| &mut **x as _)
}
}
+120 -10
View File
@@ -24,7 +24,7 @@ use log::warn;
use hash_db::Hasher;
use parity_codec::{Decode, Encode};
use primitives::{
storage::well_known_keys, NativeOrEncoded, NeverNativeValue, OffchainExt
storage::well_known_keys, NativeOrEncoded, NeverNativeValue, offchain
};
pub mod backend;
@@ -221,10 +221,8 @@ pub trait Externalities<H: Hasher> {
/// Get the change trie root of the current storage overlay at a block with given parent.
fn storage_changes_root(&mut self, parent: H::Out) -> Result<Option<H::Out>, ()> where H::Out: Ord;
/// Submit extrinsic.
///
/// Returns an error in case the API is not available.
fn submit_extrinsic(&mut self, extrinsic: Vec<u8>) -> Result<(), ()>;
/// Returns offchain externalities extension if present.
fn offchain(&mut self) -> Option<&mut offchain::Externalities>;
}
/// An implementation of offchain extensions that should never be triggered.
@@ -237,8 +235,121 @@ impl NeverOffchainExt {
}
}
impl OffchainExt for NeverOffchainExt {
fn submit_extrinsic(&mut self, _extrinsic: Vec<u8>) { unreachable!() }
impl offchain::Externalities for NeverOffchainExt {
fn submit_transaction(&mut self, _extrinsic: Vec<u8>) -> Result<(), ()> {
unreachable!()
}
fn new_crypto_key(
&mut self,
_crypto: offchain::CryptoKind,
) -> Result<offchain::CryptoKeyId, ()> {
unreachable!()
}
fn encrypt(
&mut self,
_key: Option<offchain::CryptoKeyId>,
_data: &[u8],
) -> Result<Vec<u8>, ()> {
unreachable!()
}
fn decrypt(
&mut self,
_key: Option<offchain::CryptoKeyId>,
_data: &[u8],
) -> Result<Vec<u8>, ()> {
unreachable!()
}
fn sign(&mut self, _key: Option<offchain::CryptoKeyId>, _data: &[u8]) -> Result<Vec<u8>, ()> {
unreachable!()
}
fn verify(
&mut self,
_key: Option<offchain::CryptoKeyId>,
_msg: &[u8],
_signature: &[u8],
) -> Result<bool, ()> {
unreachable!()
}
fn timestamp(&mut self) -> offchain::Timestamp {
unreachable!()
}
fn sleep_until(&mut self, _deadline: offchain::Timestamp) {
unreachable!()
}
fn random_seed(&mut self) -> [u8; 32] {
unreachable!()
}
fn local_storage_set(&mut self, _key: &[u8], _value: &[u8]) {
unreachable!()
}
fn local_storage_compare_and_set(&mut self, _key: &[u8], _old_value: &[u8], _new_value: &[u8]) {
unreachable!()
}
fn local_storage_get(&mut self, _key: &[u8]) -> Option<Vec<u8>> {
unreachable!()
}
fn http_request_start(
&mut self,
_method: &str,
_uri: &str,
_meta: &[u8]
) -> Result<offchain::HttpRequestId, ()> {
unreachable!()
}
fn http_request_add_header(
&mut self,
_request_id: offchain::HttpRequestId,
_name: &str,
_value: &str
) -> Result<(), ()> {
unreachable!()
}
fn http_request_write_body(
&mut self,
_request_id: offchain::HttpRequestId,
_chunk: &[u8],
_deadline: Option<offchain::Timestamp>
) -> Result<(), offchain::HttpError> {
unreachable!()
}
fn http_response_wait(
&mut self,
_ids: &[offchain::HttpRequestId],
_deadline: Option<offchain::Timestamp>
) -> Vec<offchain::HttpRequestStatus> {
unreachable!()
}
fn http_response_headers(
&mut self,
_request_id: offchain::HttpRequestId
) -> Vec<(Vec<u8>, Vec<u8>)> {
unreachable!()
}
fn http_response_read_body(
&mut self,
_request_id: offchain::HttpRequestId,
_buffer: &mut [u8],
_deadline: Option<offchain::Timestamp>
) -> Result<usize, offchain::HttpError> {
unreachable!()
}
}
/// Code execution engine.
@@ -376,7 +487,7 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where
Exec: CodeExecutor<H>,
B: Backend<H>,
T: ChangesTrieStorage<H, N>,
O: OffchainExt,
O: offchain::Externalities,
H::Out: Ord + 'static,
N: crate::changes_trie::BlockNumber,
{
@@ -415,12 +526,11 @@ impl<'a, H, N, B, T, O, Exec> StateMachine<'a, H, N, B, T, O, Exec> where
R: Decode + Encode + PartialEq,
NC: FnOnce() -> result::Result<R, &'static str> + UnwindSafe,
{
let offchain = self.offchain_ext.as_mut();
let mut externalities = ext::Ext::new(
self.overlay,
self.backend,
self.changes_trie_storage,
offchain.map(|x| &mut **x),
self.offchain_ext.as_mut().map(|x| &mut **x),
);
let (result, was_native) = self.exec.call(
&mut externalities,
+12 -2
View File
@@ -25,6 +25,7 @@ use crate::changes_trie::{
compute_changes_trie_root, InMemoryStorage as ChangesTrieInMemoryStorage,
BlockNumber as ChangesTrieBlockNumber,
};
use primitives::offchain;
use primitives::storage::well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES};
use parity_codec::Encode;
use super::{ChildStorageKey, Externalities, OverlayedChanges};
@@ -36,6 +37,7 @@ pub struct TestExternalities<H: Hasher, N: ChangesTrieBlockNumber> {
overlay: OverlayedChanges,
backend: InMemory<H>,
changes_trie_storage: ChangesTrieInMemoryStorage<H, N>,
offchain: Option<Box<offchain::Externalities>>,
}
impl<H: Hasher, N: ChangesTrieBlockNumber> TestExternalities<H, N> {
@@ -61,6 +63,7 @@ impl<H: Hasher, N: ChangesTrieBlockNumber> TestExternalities<H, N> {
overlay,
changes_trie_storage: ChangesTrieInMemoryStorage::new(),
backend: inner.into(),
offchain: None,
}
}
@@ -80,6 +83,11 @@ impl<H: Hasher, N: ChangesTrieBlockNumber> TestExternalities<H, N> {
.filter_map(|(k, maybe_val)| maybe_val.map(|val| (k, val)))
}
/// Set offchain externaltiies.
pub fn set_offchain_externalities(&mut self, offchain: impl offchain::Externalities + 'static) {
self.offchain = Some(Box::new(offchain));
}
/// Get mutable reference to changes trie storage.
pub fn changes_trie_storage(&mut self) -> &mut ChangesTrieInMemoryStorage<H, N> {
&mut self.changes_trie_storage
@@ -226,8 +234,10 @@ impl<H, N> Externalities<H> for TestExternalities<H, N>
)?.map(|(root, _)| root.clone()))
}
fn submit_extrinsic(&mut self, _extrinsic: Vec<u8>) -> Result<(), ()> {
unimplemented!()
fn offchain(&mut self) -> Option<&mut offchain::Externalities> {
self.offchain
.as_mut()
.map(|x| &mut **x as _)
}
}