tet_io/
lib.rs

1// This file is part of Tetcore.
2
3// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! I/O host interface for tetcore runtime.
19
20#![warn(missing_docs)]
21
22#![cfg_attr(not(feature = "std"), no_std)]
23#![cfg_attr(not(feature = "std"), feature(alloc_error_handler))]
24
25#![cfg_attr(feature = "std",
26   doc = "Tetcore runtime standard library as compiled when linked with Rust's standard library.")]
27#![cfg_attr(not(feature = "std"),
28   doc = "Tetcore's runtime standard library as compiled without Rust's standard library.")]
29
30use tetcore_std::vec::Vec;
31
32#[cfg(feature = "std")]
33use tetcore_std::ops::Deref;
34
35#[cfg(feature = "std")]
36use tracing;
37
38#[cfg(feature = "std")]
39use tet_core::{
40	crypto::Pair,
41	traits::{CallInWasmExt, TaskExecutorExt, RuntimeSpawnExt},
42	offchain::{OffchainExt, TransactionPoolExt},
43	hexdisplay::HexDisplay,
44	storage::ChildInfo,
45};
46#[cfg(feature = "std")]
47use tp_keystore::{KeystoreExt, SyncCryptoStore};
48
49use tet_core::{
50	OpaquePeerId, crypto::KeyTypeId, ed25519, sr25519, ecdsa, H256, LogLevel,
51	offchain::{
52		Timestamp, HttpRequestId, HttpRequestStatus, HttpError, StorageKind, OpaqueNetworkState,
53	},
54};
55
56#[cfg(feature = "std")]
57use tp_trie::{TrieConfiguration, trie_types::Layout};
58
59use tp_runtime_interface::{runtime_interface, Pointer};
60use tp_runtime_interface::pass_by::PassBy;
61
62use codec::{Encode, Decode};
63
64#[cfg(feature = "std")]
65use externalities::{ExternalitiesExt, Externalities};
66
67#[cfg(feature = "std")]
68mod batch_verifier;
69
70#[cfg(feature = "std")]
71use batch_verifier::BatchVerifier;
72
73/// Error verifying ECDSA signature
74#[derive(Encode, Decode)]
75pub enum EcdsaVerifyError {
76	/// Incorrect value of R or S
77	BadRS,
78	/// Incorrect value of V
79	BadV,
80	/// Invalid signature
81	BadSignature,
82}
83
84/// Interface for accessing the storage from within the runtime.
85#[runtime_interface]
86pub trait Storage {
87	/// Returns the data for `key` in the storage or `None` if the key can not be found.
88	fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
89		self.storage(key).map(|s| s.to_vec())
90	}
91
92	/// Get `key` from storage, placing the value into `value_out` and return the number of
93	/// bytes that the entry in storage has beyond the offset or `None` if the storage entry
94	/// doesn't exist at all.
95	/// If `value_out` length is smaller than the returned length, only `value_out` length bytes
96	/// are copied into `value_out`.
97	fn read(&self, key: &[u8], value_out: &mut [u8], value_offset: u32) -> Option<u32> {
98		self.storage(key).map(|value| {
99			let value_offset = value_offset as usize;
100			let data = &value[value_offset.min(value.len())..];
101			let written = std::cmp::min(data.len(), value_out.len());
102			value_out[..written].copy_from_slice(&data[..written]);
103			data.len() as u32
104		})
105	}
106
107	/// Set `key` to `value` in the storage.
108	fn set(&mut self, key: &[u8], value: &[u8]) {
109		self.set_storage(key.to_vec(), value.to_vec());
110	}
111
112	/// Clear the storage of the given `key` and its value.
113	fn clear(&mut self, key: &[u8]) {
114		self.clear_storage(key)
115	}
116
117	/// Check whether the given `key` exists in storage.
118	fn exists(&self, key: &[u8]) -> bool {
119		self.exists_storage(key)
120	}
121
122	/// Clear the storage of each key-value pair where the key starts with the given `prefix`.
123	fn clear_prefix(&mut self, prefix: &[u8]) {
124		Externalities::clear_prefix(*self, prefix)
125	}
126
127	/// Append the encoded `value` to the storage item at `key`.
128	///
129	/// The storage item needs to implement [`EncodeAppend`](codec::EncodeAppend).
130	///
131	/// # Warning
132	///
133	/// If the storage item does not support [`EncodeAppend`](codec::EncodeAppend) or
134	/// something else fails at appending, the storage item will be set to `[value]`.
135	fn append(&mut self, key: &[u8], value: Vec<u8>) {
136		self.storage_append(key.to_vec(), value);
137	}
138
139	/// "Commit" all existing operations and compute the resulting storage root.
140	///
141	/// The hashing algorithm is defined by the `Block`.
142	///
143	/// Returns a `Vec<u8>` that holds the SCALE encoded hash.
144	fn root(&mut self) -> Vec<u8> {
145		self.storage_root()
146	}
147
148	/// "Commit" all existing operations and get the resulting storage change root.
149	/// `parent_hash` is a SCALE encoded hash.
150	///
151	/// The hashing algorithm is defined by the `Block`.
152	///
153	/// Returns `Some(Vec<u8>)` which holds the SCALE encoded hash or `None` when
154	/// changes trie is disabled.
155	fn changes_root(&mut self, parent_hash: &[u8]) -> Option<Vec<u8>> {
156		self.storage_changes_root(parent_hash)
157			.expect("Invalid `parent_hash` given to `changes_root`.")
158	}
159
160	/// Get the next key in storage after the given one in lexicographic order.
161	fn next_key(&mut self, key: &[u8]) -> Option<Vec<u8>> {
162		self.next_storage_key(&key)
163	}
164
165	/// Start a new nested transaction.
166	///
167	/// This allows to either commit or roll back all changes that are made after this call.
168	/// For every transaction there must be a matching call to either `rollback_transaction`
169	/// or `commit_transaction`. This is also effective for all values manipulated using the
170	/// `DefaultChildStorage` API.
171	///
172	/// # Warning
173	///
174	/// This is a low level API that is potentially dangerous as it can easily result
175	/// in unbalanced transactions. For example, FABRIC users should use high level storage
176	/// abstractions.
177	fn start_transaction(&mut self) {
178		self.storage_start_transaction();
179	}
180
181	/// Rollback the last transaction started by `start_transaction`.
182	///
183	/// Any changes made during that transaction are discarded.
184	///
185	/// # Panics
186	///
187	/// Will panic if there is no open transaction.
188	fn rollback_transaction(&mut self) {
189		self.storage_rollback_transaction()
190			.expect("No open transaction that can be rolled back.");
191	}
192
193	/// Commit the last transaction started by `start_transaction`.
194	///
195	/// Any changes made during that transaction are committed.
196	///
197	/// # Panics
198	///
199	/// Will panic if there is no open transaction.
200	fn commit_transaction(&mut self) {
201		self.storage_commit_transaction()
202			.expect("No open transaction that can be committed.");
203	}
204}
205
206/// Interface for accessing the child storage for default child trie,
207/// from within the runtime.
208#[runtime_interface]
209pub trait DefaultChildStorage {
210	/// Get a default child storage value for a given key.
211	///
212	/// Parameter `storage_key` is the unprefixed location of the root of the child trie in the parent trie.
213	/// Result is `None` if the value for `key` in the child storage can not be found.
214	fn get(
215		&self,
216		storage_key: &[u8],
217		key: &[u8],
218	) -> Option<Vec<u8>> {
219		let child_info = ChildInfo::new_default(storage_key);
220		self.child_storage(&child_info, key).map(|s| s.to_vec())
221	}
222
223	/// Allocation efficient variant of `get`.
224	///
225	/// Get `key` from child storage, placing the value into `value_out` and return the number
226	/// of bytes that the entry in storage has beyond the offset or `None` if the storage entry
227	/// doesn't exist at all.
228	/// If `value_out` length is smaller than the returned length, only `value_out` length bytes
229	/// are copied into `value_out`.
230	fn read(
231		&self,
232		storage_key: &[u8],
233		key: &[u8],
234		value_out: &mut [u8],
235		value_offset: u32,
236	) -> Option<u32> {
237		let child_info = ChildInfo::new_default(storage_key);
238		self.child_storage(&child_info, key)
239			.map(|value| {
240				let value_offset = value_offset as usize;
241				let data = &value[value_offset.min(value.len())..];
242				let written = std::cmp::min(data.len(), value_out.len());
243				value_out[..written].copy_from_slice(&data[..written]);
244				data.len() as u32
245			})
246	}
247
248	/// Set a child storage value.
249	///
250	/// Set `key` to `value` in the child storage denoted by `storage_key`.
251	fn set(
252		&mut self,
253		storage_key: &[u8],
254		key: &[u8],
255		value: &[u8],
256	) {
257		let child_info = ChildInfo::new_default(storage_key);
258		self.set_child_storage(&child_info, key.to_vec(), value.to_vec());
259	}
260
261	/// Clear a child storage key.
262	///
263	/// For the default child storage at `storage_key`, clear value at `key`.
264	fn clear(
265		&mut self,
266		storage_key: &[u8],
267		key: &[u8],
268	) {
269		let child_info = ChildInfo::new_default(storage_key);
270		self.clear_child_storage(&child_info, key);
271	}
272
273	/// Clear an entire child storage.
274	///
275	/// If it exists, the child storage for `storage_key`
276	/// is removed.
277	fn storage_kill(
278		&mut self,
279		storage_key: &[u8],
280	) {
281		let child_info = ChildInfo::new_default(storage_key);
282		self.kill_child_storage(&child_info, None);
283	}
284
285	/// Clear a child storage key.
286	///
287	/// Deletes all keys from the overlay and up to `limit` keys from the backend if
288	/// it is set to `Some`. No limit is applied when `limit` is set to `None`.
289	///
290	/// The limit can be used to partially delete a child trie in case it is too large
291	/// to delete in one go (block).
292	///
293	/// It returns false iff some keys are remaining in
294	/// the child trie after the functions returns.
295	///
296	/// # Note
297	///
298	/// Please note that keys that are residing in the overlay for that child trie when
299	/// issuing this call are all deleted without counting towards the `limit`. Only keys
300	/// written during the current block are part of the overlay. Deleting with a `limit`
301	/// mostly makes sense with an empty overlay for that child trie.
302	///
303	/// Calling this function multiple times per block for the same `storage_key` does
304	/// not make much sense because it is not cumulative when called inside the same block.
305	/// Use this function to distribute the deletion of a single child trie across multiple
306	/// blocks.
307	#[version(2)]
308	fn storage_kill(&mut self, storage_key: &[u8], limit: Option<u32>) -> bool {
309		let child_info = ChildInfo::new_default(storage_key);
310		self.kill_child_storage(&child_info, limit)
311	}
312
313	/// Check a child storage key.
314	///
315	/// Check whether the given `key` exists in default child defined at `storage_key`.
316	fn exists(
317		&self,
318		storage_key: &[u8],
319		key: &[u8],
320	) -> bool {
321		let child_info = ChildInfo::new_default(storage_key);
322		self.exists_child_storage(&child_info, key)
323	}
324
325	/// Clear child default key by prefix.
326	///
327	/// Clear the child storage of each key-value pair where the key starts with the given `prefix`.
328	fn clear_prefix(
329		&mut self,
330		storage_key: &[u8],
331		prefix: &[u8],
332	) {
333		let child_info = ChildInfo::new_default(storage_key);
334		self.clear_child_prefix(&child_info, prefix);
335	}
336
337	/// Default child root calculation.
338	///
339	/// "Commit" all existing operations and compute the resulting child storage root.
340	/// The hashing algorithm is defined by the `Block`.
341	///
342	/// Returns a `Vec<u8>` that holds the SCALE encoded hash.
343	fn root(
344		&mut self,
345		storage_key: &[u8],
346	) -> Vec<u8> {
347		let child_info = ChildInfo::new_default(storage_key);
348		self.child_storage_root(&child_info)
349	}
350
351	/// Child storage key iteration.
352	///
353	/// Get the next key in storage after the given one in lexicographic order in child storage.
354	fn next_key(
355		&mut self,
356		storage_key: &[u8],
357		key: &[u8],
358	) -> Option<Vec<u8>> {
359		let child_info = ChildInfo::new_default(storage_key);
360		self.next_child_storage_key(&child_info, key)
361	}
362}
363
364/// Interface that provides trie related functionality.
365#[runtime_interface]
366pub trait Trie {
367	/// A trie root formed from the iterated items.
368	fn blake2_256_root(input: Vec<(Vec<u8>, Vec<u8>)>) -> H256 {
369		Layout::<tet_core::Blake2Hasher>::tetsy_trie_root(input)
370	}
371
372	/// A trie root formed from the enumerated items.
373	fn blake2_256_ordered_root(input: Vec<Vec<u8>>) -> H256 {
374		Layout::<tet_core::Blake2Hasher>::ordered_tetsy_trie_root(input)
375	}
376
377	/// A trie root formed from the iterated items.
378	fn keccak_256_root(input: Vec<(Vec<u8>, Vec<u8>)>) -> H256 {
379		Layout::<tet_core::KeccakHasher>::tetsy_trie_root(input)
380	}
381
382	/// A trie root formed from the enumerated items.
383	fn keccak_256_ordered_root(input: Vec<Vec<u8>>) -> H256 {
384		Layout::<tet_core::KeccakHasher>::ordered_tetsy_trie_root(input)
385	}
386}
387
388/// Interface that provides miscellaneous functions for communicating between the runtime and the node.
389#[runtime_interface]
390pub trait Misc {
391	/// Print a number.
392	fn print_num(val: u64) {
393		log::debug!(target: "runtime", "{}", val);
394	}
395
396	/// Print any valid `utf8` buffer.
397	fn print_utf8(utf8: &[u8]) {
398		if let Ok(data) = std::str::from_utf8(utf8) {
399			log::debug!(target: "runtime", "{}", data)
400		}
401	}
402
403	/// Print any `u8` slice as hex.
404	fn print_hex(data: &[u8]) {
405		log::debug!(target: "runtime", "{}", HexDisplay::from(&data));
406	}
407
408	/// Extract the runtime version of the given wasm blob by calling `Core_version`.
409	///
410	/// Returns `None` if calling the function failed for any reason or `Some(Vec<u8>)` where
411	/// the `Vec<u8>` holds the SCALE encoded runtime version.
412	///
413	/// # Performance
414	///
415	/// Calling this function is very expensive and should only be done very occasionally.
416	/// For getting the runtime version, it requires instantiating the wasm blob and calling a
417	/// function in this blob.
418	fn runtime_version(&mut self, wasm: &[u8]) -> Option<Vec<u8>> {
419		// Create some dummy externalities, `Core_version` should not write data anyway.
420		let mut ext = tp_state_machine::BasicExternalities::default();
421
422		self.extension::<CallInWasmExt>()
423			.expect("No `CallInWasmExt` associated for the current context!")
424			.call_in_wasm(
425				wasm,
426				None,
427				"Core_version",
428				&[],
429				&mut ext,
430				// If a runtime upgrade introduces new host functions that are not provided by
431				// the node, we should not fail at instantiation. Otherwise nodes that are
432				// updated could run this successfully and it could lead to a storage root
433				// mismatch when importing this block.
434				tet_core::traits::MissingHostFunctions::Allow,
435			)
436			.ok()
437	}
438}
439
440/// Interfaces for working with crypto related types from within the runtime.
441#[runtime_interface]
442pub trait Crypto {
443	/// Returns all `ed25519` public keys for the given key id from the keystore.
444	fn ed25519_public_keys(&mut self, id: KeyTypeId) -> Vec<ed25519::Public> {
445		let keystore = &***self.extension::<KeystoreExt>()
446			.expect("No `keystore` associated for the current context!");
447		SyncCryptoStore::ed25519_public_keys(keystore, id)
448	}
449
450	/// Generate an `ed22519` key for the given key type using an optional `seed` and
451	/// store it in the keystore.
452	///
453	/// The `seed` needs to be a valid utf8.
454	///
455	/// Returns the public key.
456	fn ed25519_generate(&mut self, id: KeyTypeId, seed: Option<Vec<u8>>) -> ed25519::Public {
457		let seed = seed.as_ref().map(|s| std::str::from_utf8(&s).expect("Seed is valid utf8!"));
458		let keystore = &***self.extension::<KeystoreExt>()
459			.expect("No `keystore` associated for the current context!");
460		SyncCryptoStore::ed25519_generate_new(keystore, id, seed)
461			.expect("`ed25519_generate` failed")
462	}
463
464	/// Sign the given `msg` with the `ed25519` key that corresponds to the given public key and
465	/// key type in the keystore.
466	///
467	/// Returns the signature.
468	fn ed25519_sign(
469		&mut self,
470		id: KeyTypeId,
471		pub_key: &ed25519::Public,
472		msg: &[u8],
473	) -> Option<ed25519::Signature> {
474		let keystore = &***self.extension::<KeystoreExt>()
475			.expect("No `keystore` associated for the current context!");
476		SyncCryptoStore::sign_with(keystore, id, &pub_key.into(), msg)
477			.map(|sig| ed25519::Signature::from_slice(sig.as_slice()))
478			.ok()
479	}
480
481	/// Verify `ed25519` signature.
482	///
483	/// Returns `true` when the verification was successful.
484	fn ed25519_verify(
485		sig: &ed25519::Signature,
486		msg: &[u8],
487		pub_key: &ed25519::Public,
488	) -> bool {
489		ed25519::Pair::verify(sig, msg, pub_key)
490	}
491
492	/// Register a `ed25519` signature for batch verification.
493	///
494	/// Batch verification must be enabled by calling [`start_batch_verify`].
495	/// If batch verification is not enabled, the signature will be verified immediatley.
496	/// To get the result of the batch verification, [`finish_batch_verify`]
497	/// needs to be called.
498	///
499	/// Returns `true` when the verification is either successful or batched.
500	fn ed25519_batch_verify(
501		&mut self,
502		sig: &ed25519::Signature,
503		msg: &[u8],
504		pub_key: &ed25519::Public,
505	) -> bool {
506		self.extension::<VerificationExt>().map(
507			|extension| extension.push_ed25519(sig.clone(), pub_key.clone(), msg.to_vec())
508		).unwrap_or_else(|| ed25519_verify(sig, msg, pub_key))
509	}
510
511	/// Verify `sr25519` signature.
512	///
513	/// Returns `true` when the verification was successful.
514	#[version(2)]
515	fn sr25519_verify(
516		sig: &sr25519::Signature,
517		msg: &[u8],
518		pub_key: &sr25519::Public,
519	) -> bool {
520		sr25519::Pair::verify(sig, msg, pub_key)
521	}
522
523	/// Register a `sr25519` signature for batch verification.
524	///
525	/// Batch verification must be enabled by calling [`start_batch_verify`].
526	/// If batch verification is not enabled, the signature will be verified immediatley.
527	/// To get the result of the batch verification, [`finish_batch_verify`]
528	/// needs to be called.
529	///
530	/// Returns `true` when the verification is either successful or batched.
531	fn sr25519_batch_verify(
532		&mut self,
533		sig: &sr25519::Signature,
534		msg: &[u8],
535		pub_key: &sr25519::Public,
536	) -> bool {
537		self.extension::<VerificationExt>().map(
538			|extension| extension.push_sr25519(sig.clone(), pub_key.clone(), msg.to_vec())
539		).unwrap_or_else(|| sr25519_verify(sig, msg, pub_key))
540	}
541
542	/// Start verification extension.
543	fn start_batch_verify(&mut self) {
544		let scheduler = self.extension::<TaskExecutorExt>()
545			.expect("No task executor associated with the current context!")
546			.clone();
547
548		self.register_extension(VerificationExt(BatchVerifier::new(scheduler)))
549			.expect("Failed to register required extension: `VerificationExt`");
550	}
551
552	/// Finish batch-verification of signatures.
553	///
554	/// Verify or wait for verification to finish for all signatures which were previously
555	/// deferred by `sr25519_verify`/`ed25519_verify`.
556	///
557	/// Will panic if no `VerificationExt` is registered (`start_batch_verify` was not called).
558	fn finish_batch_verify(&mut self) -> bool {
559		let result = self.extension::<VerificationExt>()
560			.expect("`finish_batch_verify` should only be called after `start_batch_verify`")
561			.verify_and_clear();
562
563		self.deregister_extension::<VerificationExt>()
564			.expect("No verification extension in current context!");
565
566		result
567	}
568
569	/// Returns all `sr25519` public keys for the given key id from the keystore.
570	fn sr25519_public_keys(&mut self, id: KeyTypeId) -> Vec<sr25519::Public> {
571		let keystore = &*** self.extension::<KeystoreExt>()
572			.expect("No `keystore` associated for the current context!");
573		SyncCryptoStore::sr25519_public_keys(keystore, id)
574	}
575
576	/// Generate an `sr22519` key for the given key type using an optional seed and
577	/// store it in the keystore.
578	///
579	/// The `seed` needs to be a valid utf8.
580	///
581	/// Returns the public key.
582	fn sr25519_generate(&mut self, id: KeyTypeId, seed: Option<Vec<u8>>) -> sr25519::Public {
583		let seed = seed.as_ref().map(|s| std::str::from_utf8(&s).expect("Seed is valid utf8!"));
584		let keystore = &***self.extension::<KeystoreExt>()
585			.expect("No `keystore` associated for the current context!");
586		SyncCryptoStore::sr25519_generate_new(keystore, id, seed)
587			.expect("`sr25519_generate` failed")
588	}
589
590	/// Sign the given `msg` with the `sr25519` key that corresponds to the given public key and
591	/// key type in the keystore.
592	///
593	/// Returns the signature.
594	fn sr25519_sign(
595		&mut self,
596		id: KeyTypeId,
597		pub_key: &sr25519::Public,
598		msg: &[u8],
599	) -> Option<sr25519::Signature> {
600		let keystore = &***self.extension::<KeystoreExt>()
601			.expect("No `keystore` associated for the current context!");
602		SyncCryptoStore::sign_with(keystore, id, &pub_key.into(), msg)
603			.map(|sig| sr25519::Signature::from_slice(sig.as_slice()))
604			.ok()
605	}
606
607	/// Verify an `sr25519` signature.
608	///
609	/// Returns `true` when the verification in successful regardless of
610	/// signature version.
611	fn sr25519_verify(sig: &sr25519::Signature, msg: &[u8], pubkey: &sr25519::Public) -> bool {
612		sr25519::Pair::verify_deprecated(sig, msg, pubkey)
613	}
614
615	/// Returns all `ecdsa` public keys for the given key id from the keystore.
616	fn ecdsa_public_keys(&mut self, id: KeyTypeId) -> Vec<ecdsa::Public> {
617		let keystore = &***self.extension::<KeystoreExt>()
618			.expect("No `keystore` associated for the current context!");
619		SyncCryptoStore::ecdsa_public_keys(keystore, id)
620	}
621
622	/// Generate an `ecdsa` key for the given key type using an optional `seed` and
623	/// store it in the keystore.
624	///
625	/// The `seed` needs to be a valid utf8.
626	///
627	/// Returns the public key.
628	fn ecdsa_generate(&mut self, id: KeyTypeId, seed: Option<Vec<u8>>) -> ecdsa::Public {
629		let seed = seed.as_ref().map(|s| std::str::from_utf8(&s).expect("Seed is valid utf8!"));
630		let keystore = &***self.extension::<KeystoreExt>()
631			.expect("No `keystore` associated for the current context!");
632		SyncCryptoStore::ecdsa_generate_new(keystore, id, seed)
633			.expect("`ecdsa_generate` failed")
634	}
635
636	/// Sign the given `msg` with the `ecdsa` key that corresponds to the given public key and
637	/// key type in the keystore.
638	///
639	/// Returns the signature.
640	fn ecdsa_sign(
641		&mut self,
642		id: KeyTypeId,
643		pub_key: &ecdsa::Public,
644		msg: &[u8],
645	) -> Option<ecdsa::Signature> {
646		let keystore = &***self.extension::<KeystoreExt>()
647			.expect("No `keystore` associated for the current context!");
648		SyncCryptoStore::sign_with(keystore, id, &pub_key.into(), msg)
649			.map(|sig| ecdsa::Signature::from_slice(sig.as_slice()))
650			.ok()
651	}
652
653	/// Verify `ecdsa` signature.
654	///
655	/// Returns `true` when the verification was successful.
656	fn ecdsa_verify(
657		sig: &ecdsa::Signature,
658		msg: &[u8],
659		pub_key: &ecdsa::Public,
660	) -> bool {
661		ecdsa::Pair::verify(sig, msg, pub_key)
662	}
663
664	/// Register a `ecdsa` signature for batch verification.
665	///
666	/// Batch verification must be enabled by calling [`start_batch_verify`].
667	/// If batch verification is not enabled, the signature will be verified immediatley.
668	/// To get the result of the batch verification, [`finish_batch_verify`]
669	/// needs to be called.
670	///
671	/// Returns `true` when the verification is either successful or batched.
672	fn ecdsa_batch_verify(
673		&mut self,
674		sig: &ecdsa::Signature,
675		msg: &[u8],
676		pub_key: &ecdsa::Public,
677	) -> bool {
678		self.extension::<VerificationExt>().map(
679			|extension| extension.push_ecdsa(sig.clone(), pub_key.clone(), msg.to_vec())
680		).unwrap_or_else(|| ecdsa_verify(sig, msg, pub_key))
681	}
682
683	/// Verify and recover a SECP256k1 ECDSA signature.
684	///
685	/// - `sig` is passed in RSV format. V should be either `0/1` or `27/28`.
686	/// - `msg` is the blake2-256 hash of the message.
687	///
688	/// Returns `Err` if the signature is bad, otherwise the 64-byte pubkey
689	/// (doesn't include the 0x04 prefix).
690	fn secp256k1_ecdsa_recover(
691		sig: &[u8; 65],
692		msg: &[u8; 32],
693	) -> Result<[u8; 64], EcdsaVerifyError> {
694		let rs = secp256k1::Signature::parse_slice(&sig[0..64])
695			.map_err(|_| EcdsaVerifyError::BadRS)?;
696		let v = secp256k1::RecoveryId::parse(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8)
697			.map_err(|_| EcdsaVerifyError::BadV)?;
698		let pubkey = secp256k1::recover(&secp256k1::Message::parse(msg), &rs, &v)
699			.map_err(|_| EcdsaVerifyError::BadSignature)?;
700		let mut res = [0u8; 64];
701		res.copy_from_slice(&pubkey.serialize()[1..65]);
702		Ok(res)
703	}
704
705	/// Verify and recover a SECP256k1 ECDSA signature.
706	///
707	/// - `sig` is passed in RSV format. V should be either `0/1` or `27/28`.
708	/// - `msg` is the blake2-256 hash of the message.
709	///
710	/// Returns `Err` if the signature is bad, otherwise the 33-byte compressed pubkey.
711	fn secp256k1_ecdsa_recover_compressed(
712		sig: &[u8; 65],
713		msg: &[u8; 32],
714	) -> Result<[u8; 33], EcdsaVerifyError> {
715		let rs = secp256k1::Signature::parse_slice(&sig[0..64])
716			.map_err(|_| EcdsaVerifyError::BadRS)?;
717		let v = secp256k1::RecoveryId::parse(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8)
718			.map_err(|_| EcdsaVerifyError::BadV)?;
719		let pubkey = secp256k1::recover(&secp256k1::Message::parse(msg), &rs, &v)
720			.map_err(|_| EcdsaVerifyError::BadSignature)?;
721		Ok(pubkey.serialize_compressed())
722	}
723}
724
725/// Interface that provides functions for hashing with different algorithms.
726#[runtime_interface]
727pub trait Hashing {
728	/// Conduct a 256-bit Keccak hash.
729	fn keccak_256(data: &[u8]) -> [u8; 32] {
730		tet_core::hashing::keccak_256(data)
731	}
732
733	/// Conduct a 512-bit Keccak hash.
734	fn keccak_512(data: &[u8]) -> [u8; 64] {
735		tet_core::hashing::keccak_512(data)
736	}
737
738	/// Conduct a 256-bit Sha2 hash.
739	fn sha2_256(data: &[u8]) -> [u8; 32] {
740		tet_core::hashing::sha2_256(data)
741	}
742
743	/// Conduct a 128-bit Blake2 hash.
744	fn blake2_128(data: &[u8]) -> [u8; 16] {
745		tet_core::hashing::blake2_128(data)
746	}
747
748	/// Conduct a 256-bit Blake2 hash.
749	fn blake2_256(data: &[u8]) -> [u8; 32] {
750		tet_core::hashing::blake2_256(data)
751	}
752
753	/// Conduct four XX hashes to give a 256-bit result.
754	fn twox_256(data: &[u8]) -> [u8; 32] {
755		tet_core::hashing::twox_256(data)
756	}
757
758	/// Conduct two XX hashes to give a 128-bit result.
759	fn twox_128(data: &[u8]) -> [u8; 16] {
760		tet_core::hashing::twox_128(data)
761	}
762
763	/// Conduct two XX hashes to give a 64-bit result.
764	fn twox_64(data: &[u8]) -> [u8; 8] {
765		tet_core::hashing::twox_64(data)
766	}
767}
768
769/// Interface that provides functions to access the Offchain DB.
770#[runtime_interface]
771pub trait OffchainIndex {
772	/// Write a key value pair to the Offchain DB database in a buffered fashion.
773	fn set(&mut self, key: &[u8], value: &[u8]) {
774		self.set_offchain_storage(key, Some(value));
775	}
776
777	/// Remove a key and its associated value from the Offchain DB.
778	fn clear(&mut self, key: &[u8]) {
779		self.set_offchain_storage(key, None);
780	}
781}
782
783#[cfg(feature = "std")]
784externalities::decl_extension! {
785	/// Batch verification extension to register/retrieve from the externalities.
786	pub struct VerificationExt(BatchVerifier);
787}
788
789/// Interface that provides functions to access the offchain functionality.
790///
791/// These functions are being made available to the runtime and are called by the runtime.
792#[runtime_interface]
793pub trait Offchain {
794	/// Returns if the local node is a potential validator.
795	///
796	/// Even if this function returns `true`, it does not mean that any keys are configured
797	/// and that the validator is registered in the chain.
798	fn is_validator(&mut self) -> bool {
799		self.extension::<OffchainExt>()
800			.expect("is_validator can be called only in the offchain worker context")
801			.is_validator()
802	}
803
804	/// Submit an encoded transaction to the pool.
805	///
806	/// The transaction will end up in the pool.
807	fn submit_transaction(&mut self, data: Vec<u8>) -> Result<(), ()> {
808		self.extension::<TransactionPoolExt>()
809			.expect("submit_transaction can be called only in the offchain call context with
810				TransactionPool capabilities enabled")
811			.submit_transaction(data)
812	}
813
814	/// Returns information about the local node's network state.
815	fn network_state(&mut self) -> Result<OpaqueNetworkState, ()> {
816		self.extension::<OffchainExt>()
817			.expect("network_state can be called only in the offchain worker context")
818			.network_state()
819	}
820
821	/// Returns current UNIX timestamp (in millis)
822	fn timestamp(&mut self) -> Timestamp {
823		self.extension::<OffchainExt>()
824			.expect("timestamp can be called only in the offchain worker context")
825			.timestamp()
826	}
827
828	/// Pause the execution until `deadline` is reached.
829	fn sleep_until(&mut self, deadline: Timestamp) {
830		self.extension::<OffchainExt>()
831			.expect("sleep_until can be called only in the offchain worker context")
832			.sleep_until(deadline)
833	}
834
835	/// Returns a random seed.
836	///
837	/// This is a truly random, non-deterministic seed generated by host environment.
838	/// Obviously fine in the off-chain worker context.
839	fn random_seed(&mut self) -> [u8; 32] {
840		self.extension::<OffchainExt>()
841			.expect("random_seed can be called only in the offchain worker context")
842			.random_seed()
843	}
844
845	/// Sets a value in the local storage.
846	///
847	/// Note this storage is not part of the consensus, it's only accessible by
848	/// offchain worker tasks running on the same machine. It IS persisted between runs.
849	fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) {
850		self.extension::<OffchainExt>()
851			.expect("local_storage_set can be called only in the offchain worker context")
852			.local_storage_set(kind, key, value)
853	}
854
855	/// Remove a value from the local storage.
856	///
857	/// Note this storage is not part of the consensus, it's only accessible by
858	/// offchain worker tasks running on the same machine. It IS persisted between runs.
859	fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) {
860		self.extension::<OffchainExt>()
861			.expect("local_storage_clear can be called only in the offchain worker context")
862			.local_storage_clear(kind, key)
863	}
864
865	/// Sets a value in the local storage if it matches current value.
866	///
867	/// Since multiple offchain workers may be running concurrently, to prevent
868	/// data races use CAS to coordinate between them.
869	///
870	/// Returns `true` if the value has been set, `false` otherwise.
871	///
872	/// Note this storage is not part of the consensus, it's only accessible by
873	/// offchain worker tasks running on the same machine. It IS persisted between runs.
874	fn local_storage_compare_and_set(
875		&mut self,
876		kind: StorageKind,
877		key: &[u8],
878		old_value: Option<Vec<u8>>,
879		new_value: &[u8],
880	) -> bool {
881		self.extension::<OffchainExt>()
882			.expect("local_storage_compare_and_set can be called only in the offchain worker context")
883			.local_storage_compare_and_set(kind, key, old_value.as_ref().map(|v| v.deref()), new_value)
884	}
885
886	/// Gets a value from the local storage.
887	///
888	/// If the value does not exist in the storage `None` will be returned.
889	/// Note this storage is not part of the consensus, it's only accessible by
890	/// offchain worker tasks running on the same machine. It IS persisted between runs.
891	fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option<Vec<u8>> {
892		self.extension::<OffchainExt>()
893			.expect("local_storage_get can be called only in the offchain worker context")
894			.local_storage_get(kind, key)
895	}
896
897	/// Initiates a http request given HTTP verb and the URL.
898	///
899	/// Meta is a future-reserved field containing additional, tetsy-scale-codec encoded parameters.
900	/// Returns the id of newly started request.
901	fn http_request_start(
902		&mut self,
903		method: &str,
904		uri: &str,
905		meta: &[u8],
906	) -> Result<HttpRequestId, ()> {
907		self.extension::<OffchainExt>()
908			.expect("http_request_start can be called only in the offchain worker context")
909			.http_request_start(method, uri, meta)
910	}
911
912	/// Append header to the request.
913	fn http_request_add_header(
914		&mut self,
915		request_id: HttpRequestId,
916		name: &str,
917		value: &str,
918	) -> Result<(), ()> {
919		self.extension::<OffchainExt>()
920			.expect("http_request_add_header can be called only in the offchain worker context")
921			.http_request_add_header(request_id, name, value)
922	}
923
924	/// Write a chunk of request body.
925	///
926	/// Writing an empty chunks finalizes the request.
927	/// Passing `None` as deadline blocks forever.
928	///
929	/// Returns an error in case deadline is reached or the chunk couldn't be written.
930	fn http_request_write_body(
931		&mut self,
932		request_id: HttpRequestId,
933		chunk: &[u8],
934		deadline: Option<Timestamp>,
935	) -> Result<(), HttpError> {
936		self.extension::<OffchainExt>()
937			.expect("http_request_write_body can be called only in the offchain worker context")
938			.http_request_write_body(request_id, chunk, deadline)
939	}
940
941	/// Block and wait for the responses for given requests.
942	///
943	/// Returns a vector of request statuses (the len is the same as ids).
944	/// Note that if deadline is not provided the method will block indefinitely,
945	/// otherwise unready responses will produce `DeadlineReached` status.
946	///
947	/// Passing `None` as deadline blocks forever.
948	fn http_response_wait(
949		&mut self,
950		ids: &[HttpRequestId],
951		deadline: Option<Timestamp>,
952	) -> Vec<HttpRequestStatus> {
953		self.extension::<OffchainExt>()
954			.expect("http_response_wait can be called only in the offchain worker context")
955			.http_response_wait(ids, deadline)
956	}
957
958	/// Read all response headers.
959	///
960	/// Returns a vector of pairs `(HeaderKey, HeaderValue)`.
961	/// NOTE response headers have to be read before response body.
962	fn http_response_headers(&mut self, request_id: HttpRequestId) -> Vec<(Vec<u8>, Vec<u8>)> {
963		self.extension::<OffchainExt>()
964			.expect("http_response_headers can be called only in the offchain worker context")
965			.http_response_headers(request_id)
966	}
967
968	/// Read a chunk of body response to given buffer.
969	///
970	/// Returns the number of bytes written or an error in case a deadline
971	/// is reached or server closed the connection.
972	/// If `0` is returned it means that the response has been fully consumed
973	/// and the `request_id` is now invalid.
974	/// NOTE this implies that response headers must be read before draining the body.
975	/// Passing `None` as a deadline blocks forever.
976	fn http_response_read_body(
977		&mut self,
978		request_id: HttpRequestId,
979		buffer: &mut [u8],
980		deadline: Option<Timestamp>,
981	) -> Result<u32, HttpError> {
982		self.extension::<OffchainExt>()
983			.expect("http_response_read_body can be called only in the offchain worker context")
984			.http_response_read_body(request_id, buffer, deadline)
985			.map(|r| r as u32)
986	}
987
988	/// Set the authorized nodes and authorized_only flag.
989	fn set_authorized_nodes(&mut self, nodes: Vec<OpaquePeerId>, authorized_only: bool) {
990		self.extension::<OffchainExt>()
991			.expect("set_authorized_nodes can be called only in the offchain worker context")
992			.set_authorized_nodes(nodes, authorized_only)
993	}
994}
995
996/// Wasm only interface that provides functions for calling into the allocator.
997#[runtime_interface(wasm_only)]
998trait Allocator {
999	/// Malloc the given number of bytes and return the pointer to the allocated memory location.
1000	fn malloc(&mut self, size: u32) -> Pointer<u8> {
1001		self.allocate_memory(size).expect("Failed to allocate memory")
1002	}
1003
1004	/// Free the given pointer.
1005	fn free(&mut self, ptr: Pointer<u8>) {
1006		self.deallocate_memory(ptr).expect("Failed to deallocate memory")
1007	}
1008}
1009
1010/// Interface that provides functions for logging from within the runtime.
1011#[runtime_interface]
1012pub trait Logging {
1013	/// Request to print a log message on the host.
1014	///
1015	/// Note that this will be only displayed if the host is enabled to display log messages with
1016	/// given level and target.
1017	///
1018	/// Instead of using directly, prefer setting up `RuntimeLogger` and using `log` macros.
1019	fn log(level: LogLevel, target: &str, message: &[u8]) {
1020		if let Ok(message) = std::str::from_utf8(message) {
1021			log::log!(
1022				target: target,
1023				log::Level::from(level),
1024				"{}",
1025				message,
1026			)
1027		}
1028	}
1029}
1030
1031#[derive(Encode, Decode)]
1032/// Crossing is a helper wrapping any Encode-Decodeable type
1033/// for transferring over the wasm barrier.
1034pub struct Crossing<T: Encode + Decode>(T);
1035
1036impl<T: Encode + Decode> PassBy for Crossing<T> {
1037	type PassBy = tp_runtime_interface::pass_by::Codec<Self>;
1038}
1039
1040impl<T: Encode + Decode> Crossing<T> {
1041
1042	/// Convert into the inner type
1043	pub fn into_inner(self) -> T {
1044		self.0
1045	}
1046}
1047
1048// useful for testing
1049impl<T> core::default::Default for Crossing<T>
1050	where T: core::default::Default + Encode + Decode
1051{
1052	fn default() -> Self {
1053		Self(Default::default())
1054	}
1055
1056}
1057
1058/// Interface to provide tracing facilities for wasm. Modelled after tokios `tracing`-crate
1059/// interfaces. See `tetcore-tracing` for more information.
1060#[runtime_interface(wasm_only, no_tracing)]
1061pub trait WasmTracing {
1062	/// Whether the span described in `WasmMetadata` should be traced wasm-side
1063	/// On the host converts into a static Metadata and checks against the global `tracing` dispatcher.
1064	///
1065	/// When returning false the calling code should skip any tracing-related execution. In general
1066	/// within the same block execution this is not expected to change and it doesn't have to be
1067	/// checked more than once per metadata. This exists for optimisation purposes but is still not
1068	/// cheap as it will jump the wasm-native-barrier every time it is called. So an implementation might
1069	/// chose to cache the result for the execution of the entire block.
1070	fn enabled(&mut self, metadata: Crossing<tetcore_tracing::WasmMetadata>) -> bool {
1071		let metadata: &tracing_core::metadata::Metadata<'static> = (&metadata.into_inner()).into();
1072		tracing::dispatcher::get_default(|d| {
1073			d.enabled(metadata)
1074		})
1075	}
1076
1077	/// Open a new span with the given attributes. Return the u64 Id of the span.
1078	///
1079	/// On the native side this goes through the default `tracing` dispatcher to register the span
1080	/// and then calls `clone_span` with the ID to signal that we are keeping it around on the wasm-
1081	/// side even after the local span is dropped. The resulting ID is then handed over to the wasm-
1082	/// side.
1083	fn enter_span(&mut self, span: Crossing<tetcore_tracing::WasmEntryAttributes>) -> u64 {
1084		let span: tracing::Span = span.into_inner().into();
1085		match span.id() {
1086			Some(id) => tracing::dispatcher::get_default(|d| {
1087				// inform dispatch that we'll keep the ID around
1088				// then enter it immediately
1089				let final_id = d.clone_span(&id);
1090				d.enter(&final_id);
1091				final_id.into_u64()
1092			}),
1093			_ => {
1094				0
1095			}
1096		}
1097	}
1098
1099	/// Emit the given event to the global tracer on the native side
1100	fn event(&mut self, event: Crossing<tetcore_tracing::WasmEntryAttributes>) {
1101		event.into_inner().emit();
1102	}
1103
1104	/// Signal that a given span-id has been exited. On native, this directly
1105	/// proxies the span to the global dispatcher.
1106	fn exit(&mut self, span: u64) {
1107		tracing::dispatcher::get_default(|d| {
1108			let id = tracing_core::span::Id::from_u64(span);
1109			d.exit(&id);
1110		});
1111	}
1112}
1113
1114#[cfg(all(not(feature="std"), feature="with-tracing"))]
1115mod tracing_setup {
1116	use core::sync::atomic::{AtomicBool, Ordering};
1117	use tracing_core::{
1118		dispatcher::{Dispatch, set_global_default},
1119		span::{Id, Record, Attributes},
1120		Metadata, Event,
1121	};
1122	use super::{wasm_tracing, Crossing};
1123
1124	static TRACING_SET: AtomicBool = AtomicBool::new(false);
1125
1126
1127	/// The PassingTracingSubscriber implements `tracing_core::Subscriber`
1128	/// and pushes the information across the runtime interface to the host
1129	struct PassingTracingSubsciber;
1130
1131	impl tracing_core::Subscriber for PassingTracingSubsciber {
1132		fn enabled(&self, metadata: &Metadata<'_>) -> bool {
1133			wasm_tracing::enabled(Crossing(metadata.into()))
1134		}
1135		fn new_span(&self, attrs: &Attributes<'_>) -> Id {
1136			Id::from_u64(wasm_tracing::enter_span(Crossing(attrs.into())))
1137		}
1138		fn enter(&self, span: &Id) {
1139			// Do nothing, we already entered the span previously
1140		}
1141		/// Not implemented! We do not support recording values later
1142		/// Will panic when used.
1143		fn record(&self, span: &Id, values: &Record<'_>) {
1144			unimplemented!{} // this usage is not supported
1145		}
1146		/// Not implemented! We do not support recording values later
1147		/// Will panic when used.
1148		fn record_follows_from(&self, span: &Id, follows: &Id) {
1149			unimplemented!{ } // this usage is not supported
1150		}
1151		fn event(&self, event: &Event<'_>) {
1152			wasm_tracing::event(Crossing(event.into()))
1153		}
1154		fn exit(&self, span: &Id) {
1155			wasm_tracing::exit(span.into_u64())
1156		}
1157	}
1158
1159
1160	/// Initialize tracing of tetcore_tracing on wasm with `with-tracing` enabled.
1161	/// Can be called multiple times from within the same process and will only
1162	/// set the global bridging subscriber once.
1163	pub fn init_tracing() {
1164		if TRACING_SET.load(Ordering::Relaxed) == false {
1165			set_global_default(Dispatch::new(PassingTracingSubsciber {}))
1166				.expect("We only ever call this once");
1167			TRACING_SET.store(true, Ordering::Relaxed);
1168		}
1169	}
1170}
1171
1172#[cfg(not(all(not(feature="std"), feature="with-tracing")))]
1173mod tracing_setup {
1174	/// Initialize tracing of tetcore_tracing not necessary – noop. To enable build
1175	/// without std and with the `with-tracing`-feature.
1176	pub fn init_tracing() { }
1177}
1178
1179pub use tracing_setup::init_tracing;
1180
1181/// Wasm-only interface that provides functions for interacting with the sandbox.
1182#[runtime_interface(wasm_only)]
1183pub trait Sandbox {
1184	/// Instantiate a new sandbox instance with the given `wasm_code`.
1185	fn instantiate(
1186		&mut self,
1187		dispatch_thunk: u32,
1188		wasm_code: &[u8],
1189		env_def: &[u8],
1190		state_ptr: Pointer<u8>,
1191	) -> u32 {
1192		self.sandbox()
1193			.instance_new(dispatch_thunk, wasm_code, env_def, state_ptr.into())
1194			.expect("Failed to instantiate a new sandbox")
1195	}
1196
1197	/// Invoke `function` in the sandbox with `sandbox_idx`.
1198	fn invoke(
1199		&mut self,
1200		instance_idx: u32,
1201		function: &str,
1202		args: &[u8],
1203		return_val_ptr: Pointer<u8>,
1204		return_val_len: u32,
1205		state_ptr: Pointer<u8>,
1206	) -> u32 {
1207		self.sandbox().invoke(
1208			instance_idx,
1209			&function,
1210			&args,
1211			return_val_ptr,
1212			return_val_len,
1213			state_ptr.into(),
1214		).expect("Failed to invoke function with sandbox")
1215	}
1216
1217	/// Create a new memory instance with the given `initial` and `maximum` size.
1218	fn memory_new(&mut self, initial: u32, maximum: u32) -> u32 {
1219		self.sandbox()
1220			.memory_new(initial, maximum)
1221			.expect("Failed to create new memory with sandbox")
1222	}
1223
1224	/// Get the memory starting at `offset` from the instance with `memory_idx` into the buffer.
1225	fn memory_get(
1226		&mut self,
1227		memory_idx: u32,
1228		offset: u32,
1229		buf_ptr: Pointer<u8>,
1230		buf_len: u32,
1231	) -> u32 {
1232		self.sandbox()
1233			.memory_get(memory_idx, offset, buf_ptr, buf_len)
1234			.expect("Failed to get memory with sandbox")
1235	}
1236
1237	/// Set the memory in the given `memory_idx` to the given value at `offset`.
1238	fn memory_set(
1239		&mut self,
1240		memory_idx: u32,
1241		offset: u32,
1242		val_ptr: Pointer<u8>,
1243		val_len: u32,
1244	) -> u32 {
1245		self.sandbox()
1246			.memory_set(memory_idx, offset, val_ptr, val_len)
1247			.expect("Failed to set memory with sandbox")
1248	}
1249
1250	/// Teardown the memory instance with the given `memory_idx`.
1251	fn memory_teardown(&mut self, memory_idx: u32) {
1252		self.sandbox().memory_teardown(memory_idx).expect("Failed to teardown memory with sandbox")
1253	}
1254
1255	/// Teardown the sandbox instance with the given `instance_idx`.
1256	fn instance_teardown(&mut self, instance_idx: u32) {
1257		self.sandbox().instance_teardown(instance_idx).expect("Failed to teardown sandbox instance")
1258	}
1259
1260	/// Get the value from a global with the given `name`. The sandbox is determined by the given
1261	/// `instance_idx`.
1262	///
1263	/// Returns `Some(_)` when the requested global variable could be found.
1264	fn get_global_val(&mut self, instance_idx: u32, name: &str) -> Option<tetcore_wasm_interface::Value> {
1265		self.sandbox().get_global_val(instance_idx, name).expect("Failed to get global from sandbox")
1266	}
1267}
1268
1269/// Wasm host functions for managing tasks.
1270///
1271/// This should not be used directly. Use `tp_tasks` for running parallel tasks instead.
1272#[runtime_interface(wasm_only)]
1273pub trait RuntimeTasks {
1274	/// Wasm host function for spawning task.
1275	///
1276	/// This should not be used directly. Use `tp_tasks::spawn` instead.
1277	fn spawn(dispatcher_ref: u32, entry: u32, payload: Vec<u8>) -> u64 {
1278		externalities::with_externalities(|mut ext|{
1279			let runtime_spawn = ext.extension::<RuntimeSpawnExt>()
1280				.expect("Cannot spawn without dynamic runtime dispatcher (RuntimeSpawnExt)");
1281			runtime_spawn.spawn_call(dispatcher_ref, entry, payload)
1282		}).expect("`RuntimeTasks::spawn`: called outside of externalities context")
1283	}
1284
1285	/// Wasm host function for joining a task.
1286	///
1287	/// This should not be used directly. Use `join` of `tp_tasks::spawn` result instead.
1288	fn join(handle: u64) -> Vec<u8> {
1289		externalities::with_externalities(|mut ext| {
1290			let runtime_spawn = ext.extension::<RuntimeSpawnExt>()
1291				.expect("Cannot join without dynamic runtime dispatcher (RuntimeSpawnExt)");
1292			runtime_spawn.join(handle)
1293		}).expect("`RuntimeTasks::join`: called outside of externalities context")
1294	}
1295 }
1296
1297/// Allocator used by Tetcore when executing the Wasm runtime.
1298#[cfg(not(feature = "std"))]
1299struct WasmAllocator;
1300
1301#[cfg(all(not(feature = "disable_allocator"), not(feature = "std")))]
1302#[global_allocator]
1303static ALLOCATOR: WasmAllocator = WasmAllocator;
1304
1305#[cfg(not(feature = "std"))]
1306mod allocator_impl {
1307	use super::*;
1308	use core::alloc::{GlobalAlloc, Layout};
1309
1310	unsafe impl GlobalAlloc for WasmAllocator {
1311		unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
1312			allocator::malloc(layout.size() as u32)
1313		}
1314
1315		unsafe fn dealloc(&self, ptr: *mut u8, _: Layout) {
1316			allocator::free(ptr)
1317		}
1318	}
1319}
1320
1321/// A default panic handler for WASM environment.
1322#[cfg(all(not(feature = "disable_panic_handler"), not(feature = "std")))]
1323#[panic_handler]
1324#[no_mangle]
1325pub fn panic(info: &core::panic::PanicInfo) -> ! {
1326	unsafe {
1327		let message = tetcore_std::alloc::format!("{}", info);
1328		logging::log(LogLevel::Error, "runtime", message.as_bytes());
1329		core::arch::wasm32::unreachable();
1330	}
1331}
1332
1333/// A default OOM handler for WASM environment.
1334#[cfg(all(not(feature = "disable_oom"), not(feature = "std")))]
1335#[alloc_error_handler]
1336pub fn oom(_: core::alloc::Layout) -> ! {
1337	unsafe {
1338		logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting");
1339		core::arch::wasm32::unreachable();
1340	}
1341}
1342
1343/// Type alias for Externalities implementation used in tests.
1344#[cfg(feature = "std")]
1345pub type TestExternalities = tp_state_machine::TestExternalities<tet_core::Blake2Hasher, u64>;
1346
1347/// The host functions Tetcore provides for the Wasm runtime environment.
1348///
1349/// All these host functions will be callable from inside the Wasm environment.
1350#[cfg(feature = "std")]
1351pub type TetcoreHostFunctions = (
1352	storage::HostFunctions,
1353	default_child_storage::HostFunctions,
1354	misc::HostFunctions,
1355	wasm_tracing::HostFunctions,
1356	offchain::HostFunctions,
1357	crypto::HostFunctions,
1358	hashing::HostFunctions,
1359	allocator::HostFunctions,
1360	logging::HostFunctions,
1361	sandbox::HostFunctions,
1362	crate::trie::HostFunctions,
1363	offchain_index::HostFunctions,
1364	runtime_tasks::HostFunctions,
1365);
1366
1367#[cfg(test)]
1368mod tests {
1369	use super::*;
1370	use tp_state_machine::BasicExternalities;
1371	use tet_core::{
1372		storage::Storage, map, traits::TaskExecutorExt, testing::TaskExecutor,
1373	};
1374	use std::any::TypeId;
1375
1376	#[test]
1377	fn storage_works() {
1378		let mut t = BasicExternalities::default();
1379		t.execute_with(|| {
1380			assert_eq!(storage::get(b"hello"), None);
1381			storage::set(b"hello", b"world");
1382			assert_eq!(storage::get(b"hello"), Some(b"world".to_vec()));
1383			assert_eq!(storage::get(b"foo"), None);
1384			storage::set(b"foo", &[1, 2, 3][..]);
1385		});
1386
1387		t = BasicExternalities::new(Storage {
1388			top: map![b"foo".to_vec() => b"bar".to_vec()],
1389			children_default: map![],
1390		});
1391
1392		t.execute_with(|| {
1393			assert_eq!(storage::get(b"hello"), None);
1394			assert_eq!(storage::get(b"foo"), Some(b"bar".to_vec()));
1395		});
1396	}
1397
1398	#[test]
1399	fn read_storage_works() {
1400		let value = b"\x0b\0\0\0Hello world".to_vec();
1401		let mut t = BasicExternalities::new(Storage {
1402			top: map![b":test".to_vec() => value.clone()],
1403			children_default: map![],
1404		});
1405
1406		t.execute_with(|| {
1407			let mut v = [0u8; 4];
1408			assert_eq!(storage::read(b":test", &mut v[..], 0).unwrap(), value.len() as u32);
1409			assert_eq!(v, [11u8, 0, 0, 0]);
1410			let mut w = [0u8; 11];
1411			assert_eq!(storage::read(b":test", &mut w[..], 4).unwrap(), value.len() as u32 - 4);
1412			assert_eq!(&w, b"Hello world");
1413		});
1414	}
1415
1416	#[test]
1417	fn clear_prefix_works() {
1418		let mut t = BasicExternalities::new(Storage {
1419			top: map![
1420				b":a".to_vec() => b"\x0b\0\0\0Hello world".to_vec(),
1421				b":abcd".to_vec() => b"\x0b\0\0\0Hello world".to_vec(),
1422				b":abc".to_vec() => b"\x0b\0\0\0Hello world".to_vec(),
1423				b":abdd".to_vec() => b"\x0b\0\0\0Hello world".to_vec()
1424			],
1425			children_default: map![],
1426		});
1427
1428		t.execute_with(|| {
1429			storage::clear_prefix(b":abc");
1430
1431			assert!(storage::get(b":a").is_some());
1432			assert!(storage::get(b":abdd").is_some());
1433			assert!(storage::get(b":abcd").is_none());
1434			assert!(storage::get(b":abc").is_none());
1435		});
1436	}
1437
1438	#[test]
1439	fn batch_verify_start_finish_works() {
1440		let mut ext = BasicExternalities::default();
1441		ext.register_extension(TaskExecutorExt::new(TaskExecutor::new()));
1442
1443		ext.execute_with(|| {
1444			crypto::start_batch_verify();
1445		});
1446
1447		assert!(ext.extensions().get_mut(TypeId::of::<VerificationExt>()).is_some());
1448
1449		ext.execute_with(|| {
1450			assert!(crypto::finish_batch_verify());
1451		});
1452
1453		assert!(ext.extensions().get_mut(TypeId::of::<VerificationExt>()).is_none());
1454	}
1455
1456	#[test]
1457	fn long_sr25519_batching() {
1458		let mut ext = BasicExternalities::default();
1459		ext.register_extension(TaskExecutorExt::new(TaskExecutor::new()));
1460		ext.execute_with(|| {
1461			let pair = sr25519::Pair::generate_with_phrase(None).0;
1462			crypto::start_batch_verify();
1463			for it in 0..70 {
1464				let msg = format!("Schnorrkel {}!", it);
1465				let signature = pair.sign(msg.as_bytes());
1466				crypto::sr25519_batch_verify(&signature, msg.as_bytes(), &pair.public());
1467			}
1468
1469			// push invlaid
1470			crypto::sr25519_batch_verify(
1471				&Default::default(),
1472				&Vec::new(),
1473				&Default::default(),
1474			);
1475			assert!(!crypto::finish_batch_verify());
1476
1477			crypto::start_batch_verify();
1478			for it in 0..70 {
1479				let msg = format!("Schnorrkel {}!", it);
1480				let signature = pair.sign(msg.as_bytes());
1481				crypto::sr25519_batch_verify(&signature, msg.as_bytes(), &pair.public());
1482			}
1483			assert!(crypto::finish_batch_verify());
1484		});
1485	}
1486
1487	#[test]
1488	fn batching_works() {
1489		let mut ext = BasicExternalities::default();
1490		ext.register_extension(TaskExecutorExt::new(TaskExecutor::new()));
1491		ext.execute_with(|| {
1492			// invalid ed25519 signature
1493			crypto::start_batch_verify();
1494			crypto::ed25519_batch_verify(
1495				&Default::default(),
1496				&Vec::new(),
1497				&Default::default(),
1498			);
1499			assert!(!crypto::finish_batch_verify());
1500
1501			// 2 valid ed25519 signatures
1502			crypto::start_batch_verify();
1503
1504			let pair = ed25519::Pair::generate_with_phrase(None).0;
1505			let msg = b"Important message";
1506			let signature = pair.sign(msg);
1507			crypto::ed25519_batch_verify(&signature, msg, &pair.public());
1508
1509			let pair = ed25519::Pair::generate_with_phrase(None).0;
1510			let msg = b"Even more important message";
1511			let signature = pair.sign(msg);
1512			crypto::ed25519_batch_verify(&signature, msg, &pair.public());
1513
1514			assert!(crypto::finish_batch_verify());
1515
1516			// 1 valid, 1 invalid ed25519 signature
1517			crypto::start_batch_verify();
1518
1519			let pair = ed25519::Pair::generate_with_phrase(None).0;
1520			let msg = b"Important message";
1521			let signature = pair.sign(msg);
1522			crypto::ed25519_batch_verify(&signature, msg, &pair.public());
1523
1524			crypto::ed25519_batch_verify(
1525				&Default::default(),
1526				&Vec::new(),
1527				&Default::default(),
1528			);
1529
1530			assert!(!crypto::finish_batch_verify());
1531
1532			// 1 valid ed25519, 2 valid sr25519
1533			crypto::start_batch_verify();
1534
1535			let pair = ed25519::Pair::generate_with_phrase(None).0;
1536			let msg = b"Ed25519 batching";
1537			let signature = pair.sign(msg);
1538			crypto::ed25519_batch_verify(&signature, msg, &pair.public());
1539
1540			let pair = sr25519::Pair::generate_with_phrase(None).0;
1541			let msg = b"Schnorrkel rules";
1542			let signature = pair.sign(msg);
1543			crypto::sr25519_batch_verify(&signature, msg, &pair.public());
1544
1545			let pair = sr25519::Pair::generate_with_phrase(None).0;
1546			let msg = b"Schnorrkel batches!";
1547			let signature = pair.sign(msg);
1548			crypto::sr25519_batch_verify(&signature, msg, &pair.public());
1549
1550			assert!(crypto::finish_batch_verify());
1551
1552			// 1 valid sr25519, 1 invalid sr25519
1553			crypto::start_batch_verify();
1554
1555			let pair = sr25519::Pair::generate_with_phrase(None).0;
1556			let msg = b"Schnorrkcel!";
1557			let signature = pair.sign(msg);
1558			crypto::sr25519_batch_verify(&signature, msg, &pair.public());
1559
1560			crypto::sr25519_batch_verify(
1561				&Default::default(),
1562				&Vec::new(),
1563				&Default::default(),
1564			);
1565
1566			assert!(!crypto::finish_batch_verify());
1567		});
1568	}
1569}