pezsp_io/
lib.rs

1// This file is part of Bizinikiwi.
2
3// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
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//! # Bizinikiwi Primitives: IO
19//!
20//! This crate contains interfaces for the runtime to communicate with the outside world, ergo `io`.
21//! In other context, such interfaces are referred to as "**host functions**".
22//!
23//! Each set of host functions are defined with an instance of the
24//! [`pezsp_runtime_interface::runtime_interface`] macro.
25//!
26//! Most notably, this crate contains host functions for:
27//!
28//! - [`hashing`]
29//! - [`crypto`]
30//! - [`trie`]
31//! - [`offchain`]
32//! - [`storage`]
33//! - [`allocator`]
34//! - [`logging`]
35//!
36//! All of the default host functions provided by this crate, and by default contained in all
37//! bizinikiwi-based clients are amalgamated in [`BizinikiwiHostFunctions`].
38//!
39//! ## Externalities
40//!
41//! Host functions go hand in hand with the concept of externalities. Externalities are an
42//! environment in which host functions are provided, and thus can be accessed. Some host functions
43//! are only accessible in an externality environment that provides it.
44//!
45//! A typical error for bizinikiwi developers is the following:
46//!
47//! ```should_panic
48//! use pezsp_io::storage::get;
49//! # fn main() {
50//! let data = get(b"hello world");
51//! # }
52//! ```
53//!
54//! This code will panic with the following error:
55//!
56//! ```no_compile
57//! thread 'main' panicked at '`get_version_1` called outside of an Externalities-provided environment.'
58//! ```
59//!
60//! Such error messages should always be interpreted as "code accessing host functions accessed
61//! outside of externalities".
62//!
63//! An externality is any type that implements [`pezsp_externalities::Externalities`]. A simple
64//! example of which is [`TestExternalities`], which is commonly used in tests and is exported from
65//! this crate.
66//!
67//! ```
68//! use pezsp_io::{storage::get, TestExternalities};
69//! # fn main() {
70//! TestExternalities::default().execute_with(|| {
71//! 	let data = get(b"hello world");
72//! });
73//! # }
74//! ```
75
76#![warn(missing_docs)]
77#![cfg_attr(not(feature = "std"), no_std)]
78#![cfg_attr(enable_alloc_error_handler, feature(alloc_error_handler))]
79
80extern crate alloc;
81
82use alloc::vec::Vec;
83
84#[cfg(not(bizinikiwi_runtime))]
85use tracing;
86
87#[cfg(not(bizinikiwi_runtime))]
88use pezsp_core::{
89	crypto::Pair,
90	hexdisplay::HexDisplay,
91	offchain::{OffchainDbExt, OffchainWorkerExt, TransactionPoolExt},
92	storage::ChildInfo,
93};
94#[cfg(not(bizinikiwi_runtime))]
95use pezsp_keystore::KeystoreExt;
96
97#[cfg(feature = "bandersnatch-experimental")]
98use pezsp_core::bandersnatch;
99use pezsp_core::{
100	crypto::KeyTypeId,
101	ecdsa, ed25519,
102	offchain::{
103		HttpError, HttpRequestId, HttpRequestStatus, OpaqueNetworkState, StorageKind, Timestamp,
104	},
105	sr25519,
106	storage::StateVersion,
107	LogLevelFilter, OpaquePeerId, RuntimeInterfaceLogLevel, H256,
108};
109
110#[cfg(feature = "bls-experimental")]
111use pezsp_core::{bls381, ecdsa_bls381};
112
113#[cfg(not(bizinikiwi_runtime))]
114use pezsp_trie::{LayoutV0, LayoutV1, TrieConfiguration};
115
116use pezsp_runtime_interface::{
117	pass_by::{
118		AllocateAndReturnByCodec, AllocateAndReturnFatPointer, AllocateAndReturnPointer, PassAs,
119		PassFatPointerAndDecode, PassFatPointerAndDecodeSlice, PassFatPointerAndRead,
120		PassFatPointerAndReadWrite, PassPointerAndRead, PassPointerAndReadCopy, ReturnAs,
121	},
122	runtime_interface, Pointer,
123};
124
125use codec::{Decode, Encode};
126
127#[cfg(not(bizinikiwi_runtime))]
128use secp256k1::{
129	ecdsa::{RecoverableSignature, RecoveryId},
130	Message,
131};
132
133#[cfg(not(bizinikiwi_runtime))]
134use pezsp_externalities::{Externalities, ExternalitiesExt};
135
136pub use pezsp_externalities::MultiRemovalResults;
137
138#[cfg(all(not(feature = "disable_allocator"), bizinikiwi_runtime, target_family = "wasm"))]
139mod global_alloc_wasm;
140
141#[cfg(all(
142	not(feature = "disable_allocator"),
143	bizinikiwi_runtime,
144	any(target_arch = "riscv32", target_arch = "riscv64")
145))]
146mod global_alloc_riscv;
147
148#[cfg(not(bizinikiwi_runtime))]
149const LOG_TARGET: &str = "runtime::io";
150
151/// Error verifying ECDSA signature
152#[derive(Encode, Decode)]
153pub enum EcdsaVerifyError {
154	/// Incorrect value of R or S
155	BadRS,
156	/// Incorrect value of V
157	BadV,
158	/// Invalid signature
159	BadSignature,
160}
161
162/// The outcome of calling `storage_kill`. Returned value is the number of storage items
163/// removed from the backend from making the `storage_kill` call.
164#[derive(Encode, Decode)]
165pub enum KillStorageResult {
166	/// All keys to remove were removed, return number of iterations performed during the
167	/// operation.
168	AllRemoved(u32),
169	/// Not all key to remove were removed, return number of iterations performed during the
170	/// operation.
171	SomeRemaining(u32),
172}
173
174impl From<MultiRemovalResults> for KillStorageResult {
175	fn from(r: MultiRemovalResults) -> Self {
176		// We use `loops` here rather than `backend` because that's the same as the original
177		// functionality pre-#11490. This won't matter once we switch to the new host function
178		// since we won't be using the `KillStorageResult` type in the runtime any more.
179		match r.maybe_cursor {
180			None => Self::AllRemoved(r.loops),
181			Some(..) => Self::SomeRemaining(r.loops),
182		}
183	}
184}
185
186/// Interface for accessing the storage from within the runtime.
187#[runtime_interface]
188pub trait Storage {
189	/// Returns the data for `key` in the storage or `None` if the key can not be found.
190	fn get(
191		&mut self,
192		key: PassFatPointerAndRead<&[u8]>,
193	) -> AllocateAndReturnByCodec<Option<bytes::Bytes>> {
194		self.storage(key).map(|s| bytes::Bytes::from(s.to_vec()))
195	}
196
197	/// Get `key` from storage, placing the value into `value_out` and return the number of
198	/// bytes that the entry in storage has beyond the offset or `None` if the storage entry
199	/// doesn't exist at all.
200	/// If `value_out` length is smaller than the returned length, only `value_out` length bytes
201	/// are copied into `value_out`.
202	fn read(
203		&mut self,
204		key: PassFatPointerAndRead<&[u8]>,
205		value_out: PassFatPointerAndReadWrite<&mut [u8]>,
206		value_offset: u32,
207	) -> AllocateAndReturnByCodec<Option<u32>> {
208		self.storage(key).map(|value| {
209			let value_offset = value_offset as usize;
210			let data = &value[value_offset.min(value.len())..];
211			let written = core::cmp::min(data.len(), value_out.len());
212			value_out[..written].copy_from_slice(&data[..written]);
213			data.len() as u32
214		})
215	}
216
217	/// Set `key` to `value` in the storage.
218	fn set(&mut self, key: PassFatPointerAndRead<&[u8]>, value: PassFatPointerAndRead<&[u8]>) {
219		self.set_storage(key.to_vec(), value.to_vec());
220	}
221
222	/// Clear the storage of the given `key` and its value.
223	fn clear(&mut self, key: PassFatPointerAndRead<&[u8]>) {
224		self.clear_storage(key)
225	}
226
227	/// Check whether the given `key` exists in storage.
228	fn exists(&mut self, key: PassFatPointerAndRead<&[u8]>) -> bool {
229		self.exists_storage(key)
230	}
231
232	/// Clear the storage of each key-value pair where the key starts with the given `prefix`.
233	fn clear_prefix(&mut self, prefix: PassFatPointerAndRead<&[u8]>) {
234		let _ = Externalities::clear_prefix(*self, prefix, None, None);
235	}
236
237	/// Clear the storage of each key-value pair where the key starts with the given `prefix`.
238	///
239	/// # Limit
240	///
241	/// Deletes all keys from the overlay and up to `limit` keys from the backend if
242	/// it is set to `Some`. No limit is applied when `limit` is set to `None`.
243	///
244	/// The limit can be used to partially delete a prefix storage in case it is too large
245	/// to delete in one go (block).
246	///
247	/// Returns [`KillStorageResult`] to inform about the result.
248	///
249	/// # Note
250	///
251	/// Please note that keys that are residing in the overlay for that prefix when
252	/// issuing this call are all deleted without counting towards the `limit`. Only keys
253	/// written during the current block are part of the overlay. Deleting with a `limit`
254	/// mostly makes sense with an empty overlay for that prefix.
255	///
256	/// Calling this function multiple times per block for the same `prefix` does
257	/// not make much sense because it is not cumulative when called inside the same block.
258	/// The deletion would always start from `prefix` resulting in the same keys being deleted
259	/// every time this function is called with the exact same arguments per block. This happens
260	/// because the keys in the overlay are not taken into account when deleting keys in the
261	/// backend.
262	#[version(2)]
263	fn clear_prefix(
264		&mut self,
265		prefix: PassFatPointerAndRead<&[u8]>,
266		limit: PassFatPointerAndDecode<Option<u32>>,
267	) -> AllocateAndReturnByCodec<KillStorageResult> {
268		Externalities::clear_prefix(*self, prefix, limit, None).into()
269	}
270
271	/// Partially clear the storage of each key-value pair where the key starts with the given
272	/// prefix.
273	///
274	/// # Limit
275	///
276	/// A *limit* should always be provided through `maybe_limit`. This is one fewer than the
277	/// maximum number of backend iterations which may be done by this operation and as such
278	/// represents the maximum number of backend deletions which may happen. A *limit* of zero
279	/// implies that no keys will be deleted, though there may be a single iteration done.
280	///
281	/// The limit can be used to partially delete a prefix storage in case it is too large or costly
282	/// to delete in a single operation.
283	///
284	/// # Cursor
285	///
286	/// A *cursor* may be passed in to this operation with `maybe_cursor`. `None` should only be
287	/// passed once (in the initial call) for any given `maybe_prefix` value. Subsequent calls
288	/// operating on the same prefix should always pass `Some`, and this should be equal to the
289	/// previous call result's `maybe_cursor` field.
290	///
291	/// Returns [`MultiRemovalResults`](pezsp_io::MultiRemovalResults) to inform about the result.
292	/// Once the resultant `maybe_cursor` field is `None`, then no further items remain to be
293	/// deleted.
294	///
295	/// NOTE: After the initial call for any given prefix, it is important that no keys further
296	/// keys under the same prefix are inserted. If so, then they may or may not be deleted by
297	/// subsequent calls.
298	///
299	/// # Note
300	///
301	/// Please note that keys which are residing in the overlay for that prefix when
302	/// issuing this call are deleted without counting towards the `limit`.
303	#[version(3, register_only)]
304	fn clear_prefix(
305		&mut self,
306		maybe_prefix: PassFatPointerAndRead<&[u8]>,
307		maybe_limit: PassFatPointerAndDecode<Option<u32>>,
308		maybe_cursor: PassFatPointerAndDecode<Option<Vec<u8>>>, /* TODO Make work or just
309		                                                         * Option<Vec<u8>>? */
310	) -> AllocateAndReturnByCodec<MultiRemovalResults> {
311		Externalities::clear_prefix(
312			*self,
313			maybe_prefix,
314			maybe_limit,
315			maybe_cursor.as_ref().map(|x| &x[..]),
316		)
317		.into()
318	}
319
320	/// Append the encoded `value` to the storage item at `key`.
321	///
322	/// The storage item needs to implement [`EncodeAppend`](codec::EncodeAppend).
323	///
324	/// # Warning
325	///
326	/// If the storage item does not support [`EncodeAppend`](codec::EncodeAppend) or
327	/// something else fails at appending, the storage item will be set to `[value]`.
328	fn append(&mut self, key: PassFatPointerAndRead<&[u8]>, value: PassFatPointerAndRead<Vec<u8>>) {
329		self.storage_append(key.to_vec(), value);
330	}
331
332	/// "Commit" all existing operations and compute the resulting storage root.
333	///
334	/// The hashing algorithm is defined by the `Block`.
335	///
336	/// Returns a `Vec<u8>` that holds the SCALE encoded hash.
337	fn root(&mut self) -> AllocateAndReturnFatPointer<Vec<u8>> {
338		self.storage_root(StateVersion::V0)
339	}
340
341	/// "Commit" all existing operations and compute the resulting storage root.
342	///
343	/// The hashing algorithm is defined by the `Block`.
344	///
345	/// Returns a `Vec<u8>` that holds the SCALE encoded hash.
346	#[version(2)]
347	fn root(&mut self, version: PassAs<StateVersion, u8>) -> AllocateAndReturnFatPointer<Vec<u8>> {
348		self.storage_root(version)
349	}
350
351	/// Always returns `None`. This function exists for compatibility reasons.
352	fn changes_root(
353		&mut self,
354		_parent_hash: PassFatPointerAndRead<&[u8]>,
355	) -> AllocateAndReturnByCodec<Option<Vec<u8>>> {
356		None
357	}
358
359	/// Get the next key in storage after the given one in lexicographic order.
360	fn next_key(
361		&mut self,
362		key: PassFatPointerAndRead<&[u8]>,
363	) -> AllocateAndReturnByCodec<Option<Vec<u8>>> {
364		self.next_storage_key(key)
365	}
366
367	/// Start a new nested transaction.
368	///
369	/// This allows to either commit or roll back all changes that are made after this call.
370	/// For every transaction there must be a matching call to either `rollback_transaction`
371	/// or `commit_transaction`. This is also effective for all values manipulated using the
372	/// `DefaultChildStorage` API.
373	///
374	/// # Warning
375	///
376	/// This is a low level API that is potentially dangerous as it can easily result
377	/// in unbalanced transactions. For example, FRAME users should use high level storage
378	/// abstractions.
379	fn start_transaction(&mut self) {
380		self.storage_start_transaction();
381	}
382
383	/// Rollback the last transaction started by `start_transaction`.
384	///
385	/// Any changes made during that transaction are discarded.
386	///
387	/// # Panics
388	///
389	/// Will panic if there is no open transaction.
390	fn rollback_transaction(&mut self) {
391		self.storage_rollback_transaction()
392			.expect("No open transaction that can be rolled back.");
393	}
394
395	/// Commit the last transaction started by `start_transaction`.
396	///
397	/// Any changes made during that transaction are committed.
398	///
399	/// # Panics
400	///
401	/// Will panic if there is no open transaction.
402	fn commit_transaction(&mut self) {
403		self.storage_commit_transaction()
404			.expect("No open transaction that can be committed.");
405	}
406}
407
408/// Interface for accessing the child storage for default child trie,
409/// from within the runtime.
410#[runtime_interface]
411pub trait DefaultChildStorage {
412	/// Get a default child storage value for a given key.
413	///
414	/// Parameter `storage_key` is the unprefixed location of the root of the child trie in the
415	/// parent trie. Result is `None` if the value for `key` in the child storage can not be found.
416	fn get(
417		&mut self,
418		storage_key: PassFatPointerAndRead<&[u8]>,
419		key: PassFatPointerAndRead<&[u8]>,
420	) -> AllocateAndReturnByCodec<Option<Vec<u8>>> {
421		let child_info = ChildInfo::new_default(storage_key);
422		self.child_storage(&child_info, key).map(|s| s.to_vec())
423	}
424
425	/// Allocation efficient variant of `get`.
426	///
427	/// Get `key` from child storage, placing the value into `value_out` and return the number
428	/// of bytes that the entry in storage has beyond the offset or `None` if the storage entry
429	/// doesn't exist at all.
430	/// If `value_out` length is smaller than the returned length, only `value_out` length bytes
431	/// are copied into `value_out`.
432	fn read(
433		&mut self,
434		storage_key: PassFatPointerAndRead<&[u8]>,
435		key: PassFatPointerAndRead<&[u8]>,
436		value_out: PassFatPointerAndReadWrite<&mut [u8]>,
437		value_offset: u32,
438	) -> AllocateAndReturnByCodec<Option<u32>> {
439		let child_info = ChildInfo::new_default(storage_key);
440		self.child_storage(&child_info, key).map(|value| {
441			let value_offset = value_offset as usize;
442			let data = &value[value_offset.min(value.len())..];
443			let written = core::cmp::min(data.len(), value_out.len());
444			value_out[..written].copy_from_slice(&data[..written]);
445			data.len() as u32
446		})
447	}
448
449	/// Set a child storage value.
450	///
451	/// Set `key` to `value` in the child storage denoted by `storage_key`.
452	fn set(
453		&mut self,
454		storage_key: PassFatPointerAndRead<&[u8]>,
455		key: PassFatPointerAndRead<&[u8]>,
456		value: PassFatPointerAndRead<&[u8]>,
457	) {
458		let child_info = ChildInfo::new_default(storage_key);
459		self.set_child_storage(&child_info, key.to_vec(), value.to_vec());
460	}
461
462	/// Clear a child storage key.
463	///
464	/// For the default child storage at `storage_key`, clear value at `key`.
465	fn clear(
466		&mut self,
467		storage_key: PassFatPointerAndRead<&[u8]>,
468		key: PassFatPointerAndRead<&[u8]>,
469	) {
470		let child_info = ChildInfo::new_default(storage_key);
471		self.clear_child_storage(&child_info, key);
472	}
473
474	/// Clear an entire child storage.
475	///
476	/// If it exists, the child storage for `storage_key`
477	/// is removed.
478	fn storage_kill(&mut self, storage_key: PassFatPointerAndRead<&[u8]>) {
479		let child_info = ChildInfo::new_default(storage_key);
480		let _ = self.kill_child_storage(&child_info, None, None);
481	}
482
483	/// Clear a child storage key.
484	///
485	/// See `Storage` module `clear_prefix` documentation for `limit` usage.
486	#[version(2)]
487	fn storage_kill(
488		&mut self,
489		storage_key: PassFatPointerAndRead<&[u8]>,
490		limit: PassFatPointerAndDecode<Option<u32>>,
491	) -> bool {
492		let child_info = ChildInfo::new_default(storage_key);
493		let r = self.kill_child_storage(&child_info, limit, None);
494		r.maybe_cursor.is_none()
495	}
496
497	/// Clear a child storage key.
498	///
499	/// See `Storage` module `clear_prefix` documentation for `limit` usage.
500	#[version(3)]
501	fn storage_kill(
502		&mut self,
503		storage_key: PassFatPointerAndRead<&[u8]>,
504		limit: PassFatPointerAndDecode<Option<u32>>,
505	) -> AllocateAndReturnByCodec<KillStorageResult> {
506		let child_info = ChildInfo::new_default(storage_key);
507		self.kill_child_storage(&child_info, limit, None).into()
508	}
509
510	/// Clear a child storage key.
511	///
512	/// See `Storage` module `clear_prefix` documentation for `limit` usage.
513	#[version(4, register_only)]
514	fn storage_kill(
515		&mut self,
516		storage_key: PassFatPointerAndRead<&[u8]>,
517		maybe_limit: PassFatPointerAndDecode<Option<u32>>,
518		maybe_cursor: PassFatPointerAndDecode<Option<Vec<u8>>>,
519	) -> AllocateAndReturnByCodec<MultiRemovalResults> {
520		let child_info = ChildInfo::new_default(storage_key);
521		self.kill_child_storage(&child_info, maybe_limit, maybe_cursor.as_ref().map(|x| &x[..]))
522			.into()
523	}
524
525	/// Check a child storage key.
526	///
527	/// Check whether the given `key` exists in default child defined at `storage_key`.
528	fn exists(
529		&mut self,
530		storage_key: PassFatPointerAndRead<&[u8]>,
531		key: PassFatPointerAndRead<&[u8]>,
532	) -> bool {
533		let child_info = ChildInfo::new_default(storage_key);
534		self.exists_child_storage(&child_info, key)
535	}
536
537	/// Clear child default key by prefix.
538	///
539	/// Clear the child storage of each key-value pair where the key starts with the given `prefix`.
540	fn clear_prefix(
541		&mut self,
542		storage_key: PassFatPointerAndRead<&[u8]>,
543		prefix: PassFatPointerAndRead<&[u8]>,
544	) {
545		let child_info = ChildInfo::new_default(storage_key);
546		let _ = self.clear_child_prefix(&child_info, prefix, None, None);
547	}
548
549	/// Clear the child storage of each key-value pair where the key starts with the given `prefix`.
550	///
551	/// See `Storage` module `clear_prefix` documentation for `limit` usage.
552	#[version(2)]
553	fn clear_prefix(
554		&mut self,
555		storage_key: PassFatPointerAndRead<&[u8]>,
556		prefix: PassFatPointerAndRead<&[u8]>,
557		limit: PassFatPointerAndDecode<Option<u32>>,
558	) -> AllocateAndReturnByCodec<KillStorageResult> {
559		let child_info = ChildInfo::new_default(storage_key);
560		self.clear_child_prefix(&child_info, prefix, limit, None).into()
561	}
562
563	/// Clear the child storage of each key-value pair where the key starts with the given `prefix`.
564	///
565	/// See `Storage` module `clear_prefix` documentation for `limit` usage.
566	#[version(3, register_only)]
567	fn clear_prefix(
568		&mut self,
569		storage_key: PassFatPointerAndRead<&[u8]>,
570		prefix: PassFatPointerAndRead<&[u8]>,
571		maybe_limit: PassFatPointerAndDecode<Option<u32>>,
572		maybe_cursor: PassFatPointerAndDecode<Option<Vec<u8>>>,
573	) -> AllocateAndReturnByCodec<MultiRemovalResults> {
574		let child_info = ChildInfo::new_default(storage_key);
575		self.clear_child_prefix(
576			&child_info,
577			prefix,
578			maybe_limit,
579			maybe_cursor.as_ref().map(|x| &x[..]),
580		)
581		.into()
582	}
583
584	/// Default child root calculation.
585	///
586	/// "Commit" all existing operations and compute the resulting child storage root.
587	/// The hashing algorithm is defined by the `Block`.
588	///
589	/// Returns a `Vec<u8>` that holds the SCALE encoded hash.
590	fn root(
591		&mut self,
592		storage_key: PassFatPointerAndRead<&[u8]>,
593	) -> AllocateAndReturnFatPointer<Vec<u8>> {
594		let child_info = ChildInfo::new_default(storage_key);
595		self.child_storage_root(&child_info, StateVersion::V0)
596	}
597
598	/// Default child root calculation.
599	///
600	/// "Commit" all existing operations and compute the resulting child storage root.
601	/// The hashing algorithm is defined by the `Block`.
602	///
603	/// Returns a `Vec<u8>` that holds the SCALE encoded hash.
604	#[version(2)]
605	fn root(
606		&mut self,
607		storage_key: PassFatPointerAndRead<&[u8]>,
608		version: PassAs<StateVersion, u8>,
609	) -> AllocateAndReturnFatPointer<Vec<u8>> {
610		let child_info = ChildInfo::new_default(storage_key);
611		self.child_storage_root(&child_info, version)
612	}
613
614	/// Child storage key iteration.
615	///
616	/// Get the next key in storage after the given one in lexicographic order in child storage.
617	fn next_key(
618		&mut self,
619		storage_key: PassFatPointerAndRead<&[u8]>,
620		key: PassFatPointerAndRead<&[u8]>,
621	) -> AllocateAndReturnByCodec<Option<Vec<u8>>> {
622		let child_info = ChildInfo::new_default(storage_key);
623		self.next_child_storage_key(&child_info, key)
624	}
625}
626
627/// Interface that provides trie related functionality.
628#[runtime_interface]
629pub trait Trie {
630	/// A trie root formed from the iterated items.
631	fn blake2_256_root(
632		input: PassFatPointerAndDecode<Vec<(Vec<u8>, Vec<u8>)>>,
633	) -> AllocateAndReturnPointer<H256, 32> {
634		LayoutV0::<pezsp_core::Blake2Hasher>::trie_root(input)
635	}
636
637	/// A trie root formed from the iterated items.
638	#[version(2)]
639	fn blake2_256_root(
640		input: PassFatPointerAndDecode<Vec<(Vec<u8>, Vec<u8>)>>,
641		version: PassAs<StateVersion, u8>,
642	) -> AllocateAndReturnPointer<H256, 32> {
643		match version {
644			StateVersion::V0 => LayoutV0::<pezsp_core::Blake2Hasher>::trie_root(input),
645			StateVersion::V1 => LayoutV1::<pezsp_core::Blake2Hasher>::trie_root(input),
646		}
647	}
648
649	/// A trie root formed from the enumerated items.
650	fn blake2_256_ordered_root(
651		input: PassFatPointerAndDecode<Vec<Vec<u8>>>,
652	) -> AllocateAndReturnPointer<H256, 32> {
653		LayoutV0::<pezsp_core::Blake2Hasher>::ordered_trie_root(input)
654	}
655
656	/// A trie root formed from the enumerated items.
657	#[version(2)]
658	fn blake2_256_ordered_root(
659		input: PassFatPointerAndDecode<Vec<Vec<u8>>>,
660		version: PassAs<StateVersion, u8>,
661	) -> AllocateAndReturnPointer<H256, 32> {
662		match version {
663			StateVersion::V0 => LayoutV0::<pezsp_core::Blake2Hasher>::ordered_trie_root(input),
664			StateVersion::V1 => LayoutV1::<pezsp_core::Blake2Hasher>::ordered_trie_root(input),
665		}
666	}
667
668	/// A trie root formed from the iterated items.
669	fn keccak_256_root(
670		input: PassFatPointerAndDecode<Vec<(Vec<u8>, Vec<u8>)>>,
671	) -> AllocateAndReturnPointer<H256, 32> {
672		LayoutV0::<pezsp_core::KeccakHasher>::trie_root(input)
673	}
674
675	/// A trie root formed from the iterated items.
676	#[version(2)]
677	fn keccak_256_root(
678		input: PassFatPointerAndDecode<Vec<(Vec<u8>, Vec<u8>)>>,
679		version: PassAs<StateVersion, u8>,
680	) -> AllocateAndReturnPointer<H256, 32> {
681		match version {
682			StateVersion::V0 => LayoutV0::<pezsp_core::KeccakHasher>::trie_root(input),
683			StateVersion::V1 => LayoutV1::<pezsp_core::KeccakHasher>::trie_root(input),
684		}
685	}
686
687	/// A trie root formed from the enumerated items.
688	fn keccak_256_ordered_root(
689		input: PassFatPointerAndDecode<Vec<Vec<u8>>>,
690	) -> AllocateAndReturnPointer<H256, 32> {
691		LayoutV0::<pezsp_core::KeccakHasher>::ordered_trie_root(input)
692	}
693
694	/// A trie root formed from the enumerated items.
695	#[version(2)]
696	fn keccak_256_ordered_root(
697		input: PassFatPointerAndDecode<Vec<Vec<u8>>>,
698		version: PassAs<StateVersion, u8>,
699	) -> AllocateAndReturnPointer<H256, 32> {
700		match version {
701			StateVersion::V0 => LayoutV0::<pezsp_core::KeccakHasher>::ordered_trie_root(input),
702			StateVersion::V1 => LayoutV1::<pezsp_core::KeccakHasher>::ordered_trie_root(input),
703		}
704	}
705
706	/// Verify trie proof
707	fn blake2_256_verify_proof(
708		root: PassPointerAndReadCopy<H256, 32>,
709		proof: PassFatPointerAndDecodeSlice<&[Vec<u8>]>,
710		key: PassFatPointerAndRead<&[u8]>,
711		value: PassFatPointerAndRead<&[u8]>,
712	) -> bool {
713		pezsp_trie::verify_trie_proof::<LayoutV0<pezsp_core::Blake2Hasher>, _, _, _>(
714			&root,
715			proof,
716			&[(key, Some(value))],
717		)
718		.is_ok()
719	}
720
721	/// Verify trie proof
722	#[version(2)]
723	fn blake2_256_verify_proof(
724		root: PassPointerAndReadCopy<H256, 32>,
725		proof: PassFatPointerAndDecodeSlice<&[Vec<u8>]>,
726		key: PassFatPointerAndRead<&[u8]>,
727		value: PassFatPointerAndRead<&[u8]>,
728		version: PassAs<StateVersion, u8>,
729	) -> bool {
730		match version {
731			StateVersion::V0 => pezsp_trie::verify_trie_proof::<
732				LayoutV0<pezsp_core::Blake2Hasher>,
733				_,
734				_,
735				_,
736			>(&root, proof, &[(key, Some(value))])
737			.is_ok(),
738			StateVersion::V1 => pezsp_trie::verify_trie_proof::<
739				LayoutV1<pezsp_core::Blake2Hasher>,
740				_,
741				_,
742				_,
743			>(&root, proof, &[(key, Some(value))])
744			.is_ok(),
745		}
746	}
747
748	/// Verify trie proof
749	fn keccak_256_verify_proof(
750		root: PassPointerAndReadCopy<H256, 32>,
751		proof: PassFatPointerAndDecodeSlice<&[Vec<u8>]>,
752		key: PassFatPointerAndRead<&[u8]>,
753		value: PassFatPointerAndRead<&[u8]>,
754	) -> bool {
755		pezsp_trie::verify_trie_proof::<LayoutV0<pezsp_core::KeccakHasher>, _, _, _>(
756			&root,
757			proof,
758			&[(key, Some(value))],
759		)
760		.is_ok()
761	}
762
763	/// Verify trie proof
764	#[version(2)]
765	fn keccak_256_verify_proof(
766		root: PassPointerAndReadCopy<H256, 32>,
767		proof: PassFatPointerAndDecodeSlice<&[Vec<u8>]>,
768		key: PassFatPointerAndRead<&[u8]>,
769		value: PassFatPointerAndRead<&[u8]>,
770		version: PassAs<StateVersion, u8>,
771	) -> bool {
772		match version {
773			StateVersion::V0 => pezsp_trie::verify_trie_proof::<
774				LayoutV0<pezsp_core::KeccakHasher>,
775				_,
776				_,
777				_,
778			>(&root, proof, &[(key, Some(value))])
779			.is_ok(),
780			StateVersion::V1 => pezsp_trie::verify_trie_proof::<
781				LayoutV1<pezsp_core::KeccakHasher>,
782				_,
783				_,
784				_,
785			>(&root, proof, &[(key, Some(value))])
786			.is_ok(),
787		}
788	}
789}
790
791/// Interface that provides miscellaneous functions for communicating between the runtime and the
792/// node.
793#[runtime_interface]
794pub trait Misc {
795	// NOTE: We use the target 'runtime' for messages produced by general printing functions,
796	// instead of LOG_TARGET.
797
798	/// Print a number.
799	fn print_num(val: u64) {
800		log::debug!(target: "runtime", "{}", val);
801	}
802
803	/// Print any valid `utf8` buffer.
804	fn print_utf8(utf8: PassFatPointerAndRead<&[u8]>) {
805		if let Ok(data) = core::str::from_utf8(utf8) {
806			log::debug!(target: "runtime", "{}", data)
807		}
808	}
809
810	/// Print any `u8` slice as hex.
811	fn print_hex(data: PassFatPointerAndRead<&[u8]>) {
812		log::debug!(target: "runtime", "{}", HexDisplay::from(&data));
813	}
814
815	/// Extract the runtime version of the given wasm blob by calling `Core_version`.
816	///
817	/// Returns `None` if calling the function failed for any reason or `Some(Vec<u8>)` where
818	/// the `Vec<u8>` holds the SCALE encoded runtime version.
819	///
820	/// # Performance
821	///
822	/// This function may be very expensive to call depending on the wasm binary. It may be
823	/// relatively cheap if the wasm binary contains version information. In that case,
824	/// uncompression of the wasm blob is the dominating factor.
825	///
826	/// If the wasm binary does not have the version information attached, then a legacy mechanism
827	/// may be involved. This means that a runtime call will be performed to query the version.
828	///
829	/// Calling into the runtime may be incredible expensive and should be approached with care.
830	fn runtime_version(
831		&mut self,
832		wasm: PassFatPointerAndRead<&[u8]>,
833	) -> AllocateAndReturnByCodec<Option<Vec<u8>>> {
834		use pezsp_core::traits::ReadRuntimeVersionExt;
835
836		let mut ext = pezsp_state_machine::BasicExternalities::default();
837
838		match self
839			.extension::<ReadRuntimeVersionExt>()
840			.expect("No `ReadRuntimeVersionExt` associated for the current context!")
841			.read_runtime_version(wasm, &mut ext)
842		{
843			Ok(v) => Some(v),
844			Err(err) => {
845				log::debug!(
846					target: LOG_TARGET,
847					"cannot read version from the given runtime: {}",
848					err,
849				);
850				None
851			},
852		}
853	}
854}
855
856#[cfg(not(bizinikiwi_runtime))]
857pezsp_externalities::decl_extension! {
858	/// Extension to signal to [`crypt::ed25519_verify`] to use the dalek crate.
859	///
860	/// The switch from `ed25519-dalek` to `ed25519-zebra` was a breaking change.
861	/// `ed25519-zebra` is more permissive when it comes to the verification of signatures.
862	/// This means that some chains may fail to sync from genesis when using `ed25519-zebra`.
863	/// So, this extension can be registered to the runtime execution environment to signal
864	/// that `ed25519-dalek` should be used for verification. The extension can be registered
865	/// in the following way:
866	///
867	/// ```nocompile
868	/// client.execution_extensions().set_extensions_factory(
869	/// 	// Let the `UseDalekExt` extension being registered for each runtime invocation
870	/// 	// until the execution happens in the context of block `1000`.
871	/// 	pezsc_client_api::execution_extensions::ExtensionBeforeBlock::<Block, UseDalekExt>::new(1000)
872	/// );
873	/// ```
874	pub struct UseDalekExt;
875}
876
877#[cfg(not(bizinikiwi_runtime))]
878impl Default for UseDalekExt {
879	fn default() -> Self {
880		Self
881	}
882}
883
884/// Interfaces for working with crypto related types from within the runtime.
885#[runtime_interface]
886pub trait Crypto {
887	/// Returns all `ed25519` public keys for the given key id from the keystore.
888	fn ed25519_public_keys(
889		&mut self,
890		id: PassPointerAndReadCopy<KeyTypeId, 4>,
891	) -> AllocateAndReturnByCodec<Vec<ed25519::Public>> {
892		self.extension::<KeystoreExt>()
893			.expect("No `keystore` associated for the current context!")
894			.ed25519_public_keys(id)
895	}
896
897	/// Generate an `ed22519` key for the given key type using an optional `seed` and
898	/// store it in the keystore.
899	///
900	/// The `seed` needs to be a valid utf8.
901	///
902	/// Returns the public key.
903	fn ed25519_generate(
904		&mut self,
905		id: PassPointerAndReadCopy<KeyTypeId, 4>,
906		seed: PassFatPointerAndDecode<Option<Vec<u8>>>,
907	) -> AllocateAndReturnPointer<ed25519::Public, 32> {
908		let seed = seed.as_ref().map(|s| core::str::from_utf8(s).expect("Seed is valid utf8!"));
909		self.extension::<KeystoreExt>()
910			.expect("No `keystore` associated for the current context!")
911			.ed25519_generate_new(id, seed)
912			.expect("`ed25519_generate` failed")
913	}
914
915	/// Sign the given `msg` with the `ed25519` key that corresponds to the given public key and
916	/// key type in the keystore.
917	///
918	/// Returns the signature.
919	fn ed25519_sign(
920		&mut self,
921		id: PassPointerAndReadCopy<KeyTypeId, 4>,
922		pub_key: PassPointerAndRead<&ed25519::Public, 32>,
923		msg: PassFatPointerAndRead<&[u8]>,
924	) -> AllocateAndReturnByCodec<Option<ed25519::Signature>> {
925		self.extension::<KeystoreExt>()
926			.expect("No `keystore` associated for the current context!")
927			.ed25519_sign(id, pub_key, msg)
928			.ok()
929			.flatten()
930	}
931
932	/// Verify `ed25519` signature.
933	///
934	/// Returns `true` when the verification was successful.
935	fn ed25519_verify(
936		sig: PassPointerAndRead<&ed25519::Signature, 64>,
937		msg: PassFatPointerAndRead<&[u8]>,
938		pub_key: PassPointerAndRead<&ed25519::Public, 32>,
939	) -> bool {
940		// We don't want to force everyone needing to call the function in an externalities context.
941		// So, we assume that we should not use dalek when we are not in externalities context.
942		// Otherwise, we check if the extension is present.
943		if pezsp_externalities::with_externalities(|mut e| e.extension::<UseDalekExt>().is_some())
944			.unwrap_or_default()
945		{
946			use ed25519_dalek::Verifier;
947
948			let Ok(public_key) = ed25519_dalek::VerifyingKey::from_bytes(&pub_key.0) else {
949				return false;
950			};
951
952			let sig = ed25519_dalek::Signature::from_bytes(&sig.0);
953
954			public_key.verify(msg, &sig).is_ok()
955		} else {
956			ed25519::Pair::verify(sig, msg, pub_key)
957		}
958	}
959
960	/// Register a `ed25519` signature for batch verification.
961	///
962	/// Batch verification must be enabled by calling [`start_batch_verify`].
963	/// If batch verification is not enabled, the signature will be verified immediately.
964	/// To get the result of the batch verification, [`finish_batch_verify`]
965	/// needs to be called.
966	///
967	/// Returns `true` when the verification is either successful or batched.
968	///
969	/// NOTE: Is tagged with `register_only` to keep the functions around for backwards
970	/// compatibility with old runtimes, but it should not be used anymore by new runtimes.
971	/// The implementation emulates the old behavior, but isn't doing any batch verification
972	/// anymore.
973	#[version(1, register_only)]
974	fn ed25519_batch_verify(
975		&mut self,
976		sig: PassPointerAndRead<&ed25519::Signature, 64>,
977		msg: PassFatPointerAndRead<&[u8]>,
978		pub_key: PassPointerAndRead<&ed25519::Public, 32>,
979	) -> bool {
980		let res = ed25519_verify(sig, msg, pub_key);
981
982		if let Some(ext) = self.extension::<VerificationExtDeprecated>() {
983			ext.0 &= res;
984		}
985
986		res
987	}
988
989	/// Verify `sr25519` signature.
990	///
991	/// Returns `true` when the verification was successful.
992	#[version(2)]
993	fn sr25519_verify(
994		sig: PassPointerAndRead<&sr25519::Signature, 64>,
995		msg: PassFatPointerAndRead<&[u8]>,
996		pub_key: PassPointerAndRead<&sr25519::Public, 32>,
997	) -> bool {
998		sr25519::Pair::verify(sig, msg, pub_key)
999	}
1000
1001	/// Register a `sr25519` signature for batch verification.
1002	///
1003	/// Batch verification must be enabled by calling [`start_batch_verify`].
1004	/// If batch verification is not enabled, the signature will be verified immediately.
1005	/// To get the result of the batch verification, [`finish_batch_verify`]
1006	/// needs to be called.
1007	///
1008	/// Returns `true` when the verification is either successful or batched.
1009	///
1010	/// NOTE: Is tagged with `register_only` to keep the functions around for backwards
1011	/// compatibility with old runtimes, but it should not be used anymore by new runtimes.
1012	/// The implementation emulates the old behavior, but isn't doing any batch verification
1013	/// anymore.
1014	#[version(1, register_only)]
1015	fn sr25519_batch_verify(
1016		&mut self,
1017		sig: PassPointerAndRead<&sr25519::Signature, 64>,
1018		msg: PassFatPointerAndRead<&[u8]>,
1019		pub_key: PassPointerAndRead<&sr25519::Public, 32>,
1020	) -> bool {
1021		let res = sr25519_verify(sig, msg, pub_key);
1022
1023		if let Some(ext) = self.extension::<VerificationExtDeprecated>() {
1024			ext.0 &= res;
1025		}
1026
1027		res
1028	}
1029
1030	/// Start verification extension.
1031	///
1032	/// NOTE: Is tagged with `register_only` to keep the functions around for backwards
1033	/// compatibility with old runtimes, but it should not be used anymore by new runtimes.
1034	/// The implementation emulates the old behavior, but isn't doing any batch verification
1035	/// anymore.
1036	#[version(1, register_only)]
1037	fn start_batch_verify(&mut self) {
1038		self.register_extension(VerificationExtDeprecated(true))
1039			.expect("Failed to register required extension: `VerificationExt`");
1040	}
1041
1042	/// Finish batch-verification of signatures.
1043	///
1044	/// Verify or wait for verification to finish for all signatures which were previously
1045	/// deferred by `sr25519_verify`/`ed25519_verify`.
1046	///
1047	/// Will panic if no `VerificationExt` is registered (`start_batch_verify` was not called).
1048	///
1049	/// NOTE: Is tagged with `register_only` to keep the functions around for backwards
1050	/// compatibility with old runtimes, but it should not be used anymore by new runtimes.
1051	/// The implementation emulates the old behavior, but isn't doing any batch verification
1052	/// anymore.
1053	#[version(1, register_only)]
1054	fn finish_batch_verify(&mut self) -> bool {
1055		let result = self
1056			.extension::<VerificationExtDeprecated>()
1057			.expect("`finish_batch_verify` should only be called after `start_batch_verify`")
1058			.0;
1059
1060		self.deregister_extension::<VerificationExtDeprecated>()
1061			.expect("No verification extension in current context!");
1062
1063		result
1064	}
1065
1066	/// Returns all `sr25519` public keys for the given key id from the keystore.
1067	fn sr25519_public_keys(
1068		&mut self,
1069		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1070	) -> AllocateAndReturnByCodec<Vec<sr25519::Public>> {
1071		self.extension::<KeystoreExt>()
1072			.expect("No `keystore` associated for the current context!")
1073			.sr25519_public_keys(id)
1074	}
1075
1076	/// Generate an `sr22519` key for the given key type using an optional seed and
1077	/// store it in the keystore.
1078	///
1079	/// The `seed` needs to be a valid utf8.
1080	///
1081	/// Returns the public key.
1082	fn sr25519_generate(
1083		&mut self,
1084		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1085		seed: PassFatPointerAndDecode<Option<Vec<u8>>>,
1086	) -> AllocateAndReturnPointer<sr25519::Public, 32> {
1087		let seed = seed.as_ref().map(|s| core::str::from_utf8(s).expect("Seed is valid utf8!"));
1088		self.extension::<KeystoreExt>()
1089			.expect("No `keystore` associated for the current context!")
1090			.sr25519_generate_new(id, seed)
1091			.expect("`sr25519_generate` failed")
1092	}
1093
1094	/// Sign the given `msg` with the `sr25519` key that corresponds to the given public key and
1095	/// key type in the keystore.
1096	///
1097	/// Returns the signature.
1098	fn sr25519_sign(
1099		&mut self,
1100		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1101		pub_key: PassPointerAndRead<&sr25519::Public, 32>,
1102		msg: PassFatPointerAndRead<&[u8]>,
1103	) -> AllocateAndReturnByCodec<Option<sr25519::Signature>> {
1104		self.extension::<KeystoreExt>()
1105			.expect("No `keystore` associated for the current context!")
1106			.sr25519_sign(id, pub_key, msg)
1107			.ok()
1108			.flatten()
1109	}
1110
1111	/// Verify an `sr25519` signature.
1112	///
1113	/// Returns `true` when the verification in successful regardless of
1114	/// signature version.
1115	fn sr25519_verify(
1116		sig: PassPointerAndRead<&sr25519::Signature, 64>,
1117		msg: PassFatPointerAndRead<&[u8]>,
1118		pubkey: PassPointerAndRead<&sr25519::Public, 32>,
1119	) -> bool {
1120		sr25519::Pair::verify_deprecated(sig, msg, pubkey)
1121	}
1122
1123	/// Returns all `ecdsa` public keys for the given key id from the keystore.
1124	fn ecdsa_public_keys(
1125		&mut self,
1126		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1127	) -> AllocateAndReturnByCodec<Vec<ecdsa::Public>> {
1128		self.extension::<KeystoreExt>()
1129			.expect("No `keystore` associated for the current context!")
1130			.ecdsa_public_keys(id)
1131	}
1132
1133	/// Generate an `ecdsa` key for the given key type using an optional `seed` and
1134	/// store it in the keystore.
1135	///
1136	/// The `seed` needs to be a valid utf8.
1137	///
1138	/// Returns the public key.
1139	fn ecdsa_generate(
1140		&mut self,
1141		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1142		seed: PassFatPointerAndDecode<Option<Vec<u8>>>,
1143	) -> AllocateAndReturnPointer<ecdsa::Public, 33> {
1144		let seed = seed.as_ref().map(|s| core::str::from_utf8(s).expect("Seed is valid utf8!"));
1145		self.extension::<KeystoreExt>()
1146			.expect("No `keystore` associated for the current context!")
1147			.ecdsa_generate_new(id, seed)
1148			.expect("`ecdsa_generate` failed")
1149	}
1150
1151	/// Sign the given `msg` with the `ecdsa` key that corresponds to the given public key and
1152	/// key type in the keystore.
1153	///
1154	/// Returns the signature.
1155	fn ecdsa_sign(
1156		&mut self,
1157		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1158		pub_key: PassPointerAndRead<&ecdsa::Public, 33>,
1159		msg: PassFatPointerAndRead<&[u8]>,
1160	) -> AllocateAndReturnByCodec<Option<ecdsa::Signature>> {
1161		self.extension::<KeystoreExt>()
1162			.expect("No `keystore` associated for the current context!")
1163			.ecdsa_sign(id, pub_key, msg)
1164			.ok()
1165			.flatten()
1166	}
1167
1168	/// Sign the given a pre-hashed `msg` with the `ecdsa` key that corresponds to the given public
1169	/// key and key type in the keystore.
1170	///
1171	/// Returns the signature.
1172	fn ecdsa_sign_prehashed(
1173		&mut self,
1174		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1175		pub_key: PassPointerAndRead<&ecdsa::Public, 33>,
1176		msg: PassPointerAndRead<&[u8; 32], 32>,
1177	) -> AllocateAndReturnByCodec<Option<ecdsa::Signature>> {
1178		self.extension::<KeystoreExt>()
1179			.expect("No `keystore` associated for the current context!")
1180			.ecdsa_sign_prehashed(id, pub_key, msg)
1181			.ok()
1182			.flatten()
1183	}
1184
1185	/// Verify `ecdsa` signature.
1186	///
1187	/// Returns `true` when the verification was successful.
1188	/// This version is able to handle, non-standard, overflowing signatures.
1189	fn ecdsa_verify(
1190		sig: PassPointerAndRead<&ecdsa::Signature, 65>,
1191		msg: PassFatPointerAndRead<&[u8]>,
1192		pub_key: PassPointerAndRead<&ecdsa::Public, 33>,
1193	) -> bool {
1194		#[allow(deprecated)]
1195		ecdsa::Pair::verify_deprecated(sig, msg, pub_key)
1196	}
1197
1198	/// Verify `ecdsa` signature.
1199	///
1200	/// Returns `true` when the verification was successful.
1201	#[version(2)]
1202	fn ecdsa_verify(
1203		sig: PassPointerAndRead<&ecdsa::Signature, 65>,
1204		msg: PassFatPointerAndRead<&[u8]>,
1205		pub_key: PassPointerAndRead<&ecdsa::Public, 33>,
1206	) -> bool {
1207		ecdsa::Pair::verify(sig, msg, pub_key)
1208	}
1209
1210	/// Verify `ecdsa` signature with pre-hashed `msg`.
1211	///
1212	/// Returns `true` when the verification was successful.
1213	fn ecdsa_verify_prehashed(
1214		sig: PassPointerAndRead<&ecdsa::Signature, 65>,
1215		msg: PassPointerAndRead<&[u8; 32], 32>,
1216		pub_key: PassPointerAndRead<&ecdsa::Public, 33>,
1217	) -> bool {
1218		ecdsa::Pair::verify_prehashed(sig, msg, pub_key)
1219	}
1220
1221	/// Register a `ecdsa` signature for batch verification.
1222	///
1223	/// Batch verification must be enabled by calling [`start_batch_verify`].
1224	/// If batch verification is not enabled, the signature will be verified immediately.
1225	/// To get the result of the batch verification, [`finish_batch_verify`]
1226	/// needs to be called.
1227	///
1228	/// Returns `true` when the verification is either successful or batched.
1229	///
1230	/// NOTE: Is tagged with `register_only` to keep the functions around for backwards
1231	/// compatibility with old runtimes, but it should not be used anymore by new runtimes.
1232	/// The implementation emulates the old behavior, but isn't doing any batch verification
1233	/// anymore.
1234	#[version(1, register_only)]
1235	fn ecdsa_batch_verify(
1236		&mut self,
1237		sig: PassPointerAndRead<&ecdsa::Signature, 65>,
1238		msg: PassFatPointerAndRead<&[u8]>,
1239		pub_key: PassPointerAndRead<&ecdsa::Public, 33>,
1240	) -> bool {
1241		let res = ecdsa_verify(sig, msg, pub_key);
1242
1243		if let Some(ext) = self.extension::<VerificationExtDeprecated>() {
1244			ext.0 &= res;
1245		}
1246
1247		res
1248	}
1249
1250	/// Verify and recover a SECP256k1 ECDSA signature.
1251	///
1252	/// - `sig` is passed in RSV format. V should be either `0/1` or `27/28`.
1253	/// - `msg` is the blake2-256 hash of the message.
1254	///
1255	/// Returns `Err` if the signature is bad, otherwise the 64-byte pubkey
1256	/// (doesn't include the 0x04 prefix).
1257	/// This version is able to handle, non-standard, overflowing signatures.
1258	fn secp256k1_ecdsa_recover(
1259		sig: PassPointerAndRead<&[u8; 65], 65>,
1260		msg: PassPointerAndRead<&[u8; 32], 32>,
1261	) -> AllocateAndReturnByCodec<Result<[u8; 64], EcdsaVerifyError>> {
1262		let rid = libsecp256k1::RecoveryId::parse(
1263			if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8,
1264		)
1265		.map_err(|_| EcdsaVerifyError::BadV)?;
1266		let sig = libsecp256k1::Signature::parse_overflowing_slice(&sig[..64])
1267			.map_err(|_| EcdsaVerifyError::BadRS)?;
1268		let msg = libsecp256k1::Message::parse(msg);
1269		let pubkey =
1270			libsecp256k1::recover(&msg, &sig, &rid).map_err(|_| EcdsaVerifyError::BadSignature)?;
1271		let mut res = [0u8; 64];
1272		res.copy_from_slice(&pubkey.serialize()[1..65]);
1273		Ok(res)
1274	}
1275
1276	/// Verify and recover a SECP256k1 ECDSA signature.
1277	///
1278	/// - `sig` is passed in RSV format. V should be either `0/1` or `27/28`.
1279	/// - `msg` is the blake2-256 hash of the message.
1280	///
1281	/// Returns `Err` if the signature is bad, otherwise the 64-byte pubkey
1282	/// (doesn't include the 0x04 prefix).
1283	#[version(2)]
1284	fn secp256k1_ecdsa_recover(
1285		sig: PassPointerAndRead<&[u8; 65], 65>,
1286		msg: PassPointerAndRead<&[u8; 32], 32>,
1287	) -> AllocateAndReturnByCodec<Result<[u8; 64], EcdsaVerifyError>> {
1288		let rid = RecoveryId::from_i32(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as i32)
1289			.map_err(|_| EcdsaVerifyError::BadV)?;
1290		let sig = RecoverableSignature::from_compact(&sig[..64], rid)
1291			.map_err(|_| EcdsaVerifyError::BadRS)?;
1292		let msg = Message::from_digest_slice(msg).expect("Message is 32 bytes; qed");
1293		#[cfg(feature = "std")]
1294		let ctx = secp256k1::SECP256K1;
1295		#[cfg(not(feature = "std"))]
1296		let ctx = secp256k1::Secp256k1::<secp256k1::VerifyOnly>::gen_new();
1297		let pubkey = ctx.recover_ecdsa(&msg, &sig).map_err(|_| EcdsaVerifyError::BadSignature)?;
1298		let mut res = [0u8; 64];
1299		res.copy_from_slice(&pubkey.serialize_uncompressed()[1..]);
1300		Ok(res)
1301	}
1302
1303	/// Verify and recover a SECP256k1 ECDSA signature.
1304	///
1305	/// - `sig` is passed in RSV format. V should be either `0/1` or `27/28`.
1306	/// - `msg` is the blake2-256 hash of the message.
1307	///
1308	/// Returns `Err` if the signature is bad, otherwise the 33-byte compressed pubkey.
1309	fn secp256k1_ecdsa_recover_compressed(
1310		sig: PassPointerAndRead<&[u8; 65], 65>,
1311		msg: PassPointerAndRead<&[u8; 32], 32>,
1312	) -> AllocateAndReturnByCodec<Result<[u8; 33], EcdsaVerifyError>> {
1313		let rid = libsecp256k1::RecoveryId::parse(
1314			if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8,
1315		)
1316		.map_err(|_| EcdsaVerifyError::BadV)?;
1317		let sig = libsecp256k1::Signature::parse_overflowing_slice(&sig[0..64])
1318			.map_err(|_| EcdsaVerifyError::BadRS)?;
1319		let msg = libsecp256k1::Message::parse(msg);
1320		let pubkey =
1321			libsecp256k1::recover(&msg, &sig, &rid).map_err(|_| EcdsaVerifyError::BadSignature)?;
1322		Ok(pubkey.serialize_compressed())
1323	}
1324
1325	/// Verify and recover a SECP256k1 ECDSA signature.
1326	///
1327	/// - `sig` is passed in RSV format. V should be either `0/1` or `27/28`.
1328	/// - `msg` is the blake2-256 hash of the message.
1329	///
1330	/// Returns `Err` if the signature is bad, otherwise the 33-byte compressed pubkey.
1331	#[version(2)]
1332	fn secp256k1_ecdsa_recover_compressed(
1333		sig: PassPointerAndRead<&[u8; 65], 65>,
1334		msg: PassPointerAndRead<&[u8; 32], 32>,
1335	) -> AllocateAndReturnByCodec<Result<[u8; 33], EcdsaVerifyError>> {
1336		let rid = RecoveryId::from_i32(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as i32)
1337			.map_err(|_| EcdsaVerifyError::BadV)?;
1338		let sig = RecoverableSignature::from_compact(&sig[..64], rid)
1339			.map_err(|_| EcdsaVerifyError::BadRS)?;
1340		let msg = Message::from_digest_slice(msg).expect("Message is 32 bytes; qed");
1341		#[cfg(feature = "std")]
1342		let ctx = secp256k1::SECP256K1;
1343		#[cfg(not(feature = "std"))]
1344		let ctx = secp256k1::Secp256k1::<secp256k1::VerifyOnly>::gen_new();
1345		let pubkey = ctx.recover_ecdsa(&msg, &sig).map_err(|_| EcdsaVerifyError::BadSignature)?;
1346		Ok(pubkey.serialize())
1347	}
1348
1349	/// Generate an `bls12-381` key for the given key type using an optional `seed` and
1350	/// store it in the keystore.
1351	///
1352	/// The `seed` needs to be a valid utf8.
1353	///
1354	/// Returns the public key.
1355	#[cfg(feature = "bls-experimental")]
1356	fn bls381_generate(
1357		&mut self,
1358		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1359		seed: PassFatPointerAndDecode<Option<Vec<u8>>>,
1360	) -> AllocateAndReturnPointer<bls381::Public, 144> {
1361		let seed = seed.as_ref().map(|s| core::str::from_utf8(s).expect("Seed is valid utf8!"));
1362		self.extension::<KeystoreExt>()
1363			.expect("No `keystore` associated for the current context!")
1364			.bls381_generate_new(id, seed)
1365			.expect("`bls381_generate` failed")
1366	}
1367
1368	/// Generate a 'bls12-381' Proof Of Possession for the corresponding public key.
1369	///
1370	/// Returns the Proof Of Possession as an option of the ['bls381::Signature'] type
1371	/// or 'None' if an error occurs.
1372	#[cfg(feature = "bls-experimental")]
1373	fn bls381_generate_proof_of_possession(
1374		&mut self,
1375		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1376		pub_key: PassPointerAndRead<&bls381::Public, 144>,
1377		owner: PassFatPointerAndRead<&[u8]>,
1378	) -> AllocateAndReturnByCodec<Option<bls381::ProofOfPossession>> {
1379		self.extension::<KeystoreExt>()
1380			.expect("No `keystore` associated for the current context!")
1381			.bls381_generate_proof_of_possession(id, pub_key, owner)
1382			.ok()
1383			.flatten()
1384	}
1385
1386	/// Generate combination `ecdsa & bls12-381` key for the given key type using an optional `seed`
1387	/// and store it in the keystore.
1388	///
1389	/// The `seed` needs to be a valid utf8.
1390	///
1391	/// Returns the public key.
1392	#[cfg(feature = "bls-experimental")]
1393	fn ecdsa_bls381_generate(
1394		&mut self,
1395		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1396		seed: PassFatPointerAndDecode<Option<Vec<u8>>>,
1397	) -> AllocateAndReturnPointer<ecdsa_bls381::Public, { 144 + 33 }> {
1398		let seed = seed.as_ref().map(|s| core::str::from_utf8(s).expect("Seed is valid utf8!"));
1399		self.extension::<KeystoreExt>()
1400			.expect("No `keystore` associated for the current context!")
1401			.ecdsa_bls381_generate_new(id, seed)
1402			.expect("`ecdsa_bls381_generate` failed")
1403	}
1404
1405	/// Generate a `bandersnatch` key pair for the given key type using an optional
1406	/// `seed` and store it in the keystore.
1407	///
1408	/// The `seed` needs to be a valid utf8.
1409	///
1410	/// Returns the public key.
1411	#[cfg(feature = "bandersnatch-experimental")]
1412	fn bandersnatch_generate(
1413		&mut self,
1414		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1415		seed: PassFatPointerAndDecode<Option<Vec<u8>>>,
1416	) -> AllocateAndReturnPointer<bandersnatch::Public, 32> {
1417		let seed = seed.as_ref().map(|s| core::str::from_utf8(s).expect("Seed is valid utf8!"));
1418		self.extension::<KeystoreExt>()
1419			.expect("No `keystore` associated for the current context!")
1420			.bandersnatch_generate_new(id, seed)
1421			.expect("`bandernatch_generate` failed")
1422	}
1423
1424	/// Sign the given `msg` with the `bandersnatch` key that corresponds to the given public key
1425	/// and key type in the keystore.
1426	///
1427	/// Returns the signature or `None` if an error occurred.
1428	#[cfg(feature = "bandersnatch-experimental")]
1429	fn bandersnatch_sign(
1430		&mut self,
1431		id: PassPointerAndReadCopy<KeyTypeId, 4>,
1432		pub_key: PassPointerAndRead<&bandersnatch::Public, 32>,
1433		msg: PassFatPointerAndRead<&[u8]>,
1434	) -> AllocateAndReturnByCodec<Option<bandersnatch::Signature>> {
1435		self.extension::<KeystoreExt>()
1436			.expect("No `keystore` associated for the current context!")
1437			.bandersnatch_sign(id, pub_key, msg)
1438			.ok()
1439			.flatten()
1440	}
1441}
1442
1443/// Interface that provides functions for hashing with different algorithms.
1444#[runtime_interface]
1445pub trait Hashing {
1446	/// Conduct a 256-bit Keccak hash.
1447	fn keccak_256(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnPointer<[u8; 32], 32> {
1448		pezsp_crypto_hashing::keccak_256(data)
1449	}
1450
1451	/// Conduct a 512-bit Keccak hash.
1452	fn keccak_512(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnPointer<[u8; 64], 64> {
1453		pezsp_crypto_hashing::keccak_512(data)
1454	}
1455
1456	/// Conduct a 256-bit Sha2 hash.
1457	fn sha2_256(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnPointer<[u8; 32], 32> {
1458		pezsp_crypto_hashing::sha2_256(data)
1459	}
1460
1461	/// Conduct a 128-bit Blake2 hash.
1462	fn blake2_128(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnPointer<[u8; 16], 16> {
1463		pezsp_crypto_hashing::blake2_128(data)
1464	}
1465
1466	/// Conduct a 256-bit Blake2 hash.
1467	fn blake2_256(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnPointer<[u8; 32], 32> {
1468		pezsp_crypto_hashing::blake2_256(data)
1469	}
1470
1471	/// Conduct four XX hashes to give a 256-bit result.
1472	fn twox_256(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnPointer<[u8; 32], 32> {
1473		pezsp_crypto_hashing::twox_256(data)
1474	}
1475
1476	/// Conduct two XX hashes to give a 128-bit result.
1477	fn twox_128(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnPointer<[u8; 16], 16> {
1478		pezsp_crypto_hashing::twox_128(data)
1479	}
1480
1481	/// Conduct two XX hashes to give a 64-bit result.
1482	fn twox_64(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnPointer<[u8; 8], 8> {
1483		pezsp_crypto_hashing::twox_64(data)
1484	}
1485}
1486
1487/// Interface that provides transaction indexing API.
1488#[runtime_interface]
1489pub trait TransactionIndex {
1490	/// Indexes the specified transaction for the given `extrinsic` and `context_hash`.
1491	fn index(
1492		&mut self,
1493		extrinsic: u32,
1494		size: u32,
1495		context_hash: PassPointerAndReadCopy<[u8; 32], 32>,
1496	) {
1497		self.storage_index_transaction(extrinsic, &context_hash, size);
1498	}
1499
1500	/// Renews the transaction index entry for the given `extrinsic` using the provided
1501	/// `context_hash`.
1502	fn renew(&mut self, extrinsic: u32, context_hash: PassPointerAndReadCopy<[u8; 32], 32>) {
1503		self.storage_renew_transaction_index(extrinsic, &context_hash);
1504	}
1505}
1506
1507/// Interface that provides functions to access the Offchain DB.
1508#[runtime_interface]
1509pub trait OffchainIndex {
1510	/// Write a key value pair to the Offchain DB database in a buffered fashion.
1511	fn set(&mut self, key: PassFatPointerAndRead<&[u8]>, value: PassFatPointerAndRead<&[u8]>) {
1512		self.set_offchain_storage(key, Some(value));
1513	}
1514
1515	/// Remove a key and its associated value from the Offchain DB.
1516	fn clear(&mut self, key: PassFatPointerAndRead<&[u8]>) {
1517		self.set_offchain_storage(key, None);
1518	}
1519}
1520
1521#[cfg(not(bizinikiwi_runtime))]
1522pezsp_externalities::decl_extension! {
1523	/// Deprecated verification context.
1524	///
1525	/// Stores the combined result of all verifications that are done in the same context.
1526	struct VerificationExtDeprecated(bool);
1527}
1528
1529/// Interface that provides functions to access the offchain functionality.
1530///
1531/// These functions are being made available to the runtime and are called by the runtime.
1532#[runtime_interface]
1533pub trait Offchain {
1534	/// Returns if the local node is a potential validator.
1535	///
1536	/// Even if this function returns `true`, it does not mean that any keys are configured
1537	/// and that the validator is registered in the chain.
1538	fn is_validator(&mut self) -> bool {
1539		self.extension::<OffchainWorkerExt>()
1540			.expect("is_validator can be called only in the offchain worker context")
1541			.is_validator()
1542	}
1543
1544	/// Submit an encoded transaction to the pool.
1545	///
1546	/// The transaction will end up in the pool.
1547	fn submit_transaction(
1548		&mut self,
1549		data: PassFatPointerAndRead<Vec<u8>>,
1550	) -> AllocateAndReturnByCodec<Result<(), ()>> {
1551		self.extension::<TransactionPoolExt>()
1552			.expect(
1553				"submit_transaction can be called only in the offchain call context with
1554				TransactionPool capabilities enabled",
1555			)
1556			.submit_transaction(data)
1557	}
1558
1559	/// Returns information about the local node's network state.
1560	fn network_state(&mut self) -> AllocateAndReturnByCodec<Result<OpaqueNetworkState, ()>> {
1561		self.extension::<OffchainWorkerExt>()
1562			.expect("network_state can be called only in the offchain worker context")
1563			.network_state()
1564	}
1565
1566	/// Returns current UNIX timestamp (in millis)
1567	fn timestamp(&mut self) -> ReturnAs<Timestamp, u64> {
1568		self.extension::<OffchainWorkerExt>()
1569			.expect("timestamp can be called only in the offchain worker context")
1570			.timestamp()
1571	}
1572
1573	/// Pause the execution until `deadline` is reached.
1574	fn sleep_until(&mut self, deadline: PassAs<Timestamp, u64>) {
1575		self.extension::<OffchainWorkerExt>()
1576			.expect("sleep_until can be called only in the offchain worker context")
1577			.sleep_until(deadline)
1578	}
1579
1580	/// Returns a random seed.
1581	///
1582	/// This is a truly random, non-deterministic seed generated by host environment.
1583	/// Obviously fine in the off-chain worker context.
1584	fn random_seed(&mut self) -> AllocateAndReturnPointer<[u8; 32], 32> {
1585		self.extension::<OffchainWorkerExt>()
1586			.expect("random_seed can be called only in the offchain worker context")
1587			.random_seed()
1588	}
1589
1590	/// Sets a value in the local storage.
1591	///
1592	/// Note this storage is not part of the consensus, it's only accessible by
1593	/// offchain worker tasks running on the same machine. It IS persisted between runs.
1594	fn local_storage_set(
1595		&mut self,
1596		kind: PassAs<StorageKind, u32>,
1597		key: PassFatPointerAndRead<&[u8]>,
1598		value: PassFatPointerAndRead<&[u8]>,
1599	) {
1600		self.extension::<OffchainDbExt>()
1601			.expect(
1602				"local_storage_set can be called only in the offchain call context with
1603				OffchainDb extension",
1604			)
1605			.local_storage_set(kind, key, value)
1606	}
1607
1608	/// Remove a value from the local storage.
1609	///
1610	/// Note this storage is not part of the consensus, it's only accessible by
1611	/// offchain worker tasks running on the same machine. It IS persisted between runs.
1612	fn local_storage_clear(
1613		&mut self,
1614		kind: PassAs<StorageKind, u32>,
1615		key: PassFatPointerAndRead<&[u8]>,
1616	) {
1617		self.extension::<OffchainDbExt>()
1618			.expect(
1619				"local_storage_clear can be called only in the offchain call context with
1620				OffchainDb extension",
1621			)
1622			.local_storage_clear(kind, key)
1623	}
1624
1625	/// Sets a value in the local storage if it matches current value.
1626	///
1627	/// Since multiple offchain workers may be running concurrently, to prevent
1628	/// data races use CAS to coordinate between them.
1629	///
1630	/// Returns `true` if the value has been set, `false` otherwise.
1631	///
1632	/// Note this storage is not part of the consensus, it's only accessible by
1633	/// offchain worker tasks running on the same machine. It IS persisted between runs.
1634	fn local_storage_compare_and_set(
1635		&mut self,
1636		kind: PassAs<StorageKind, u32>,
1637		key: PassFatPointerAndRead<&[u8]>,
1638		old_value: PassFatPointerAndDecode<Option<Vec<u8>>>,
1639		new_value: PassFatPointerAndRead<&[u8]>,
1640	) -> bool {
1641		self.extension::<OffchainDbExt>()
1642			.expect(
1643				"local_storage_compare_and_set can be called only in the offchain call context
1644				with OffchainDb extension",
1645			)
1646			.local_storage_compare_and_set(kind, key, old_value.as_deref(), new_value)
1647	}
1648
1649	/// Gets a value from the local storage.
1650	///
1651	/// If the value does not exist in the storage `None` will be returned.
1652	/// Note this storage is not part of the consensus, it's only accessible by
1653	/// offchain worker tasks running on the same machine. It IS persisted between runs.
1654	fn local_storage_get(
1655		&mut self,
1656		kind: PassAs<StorageKind, u32>,
1657		key: PassFatPointerAndRead<&[u8]>,
1658	) -> AllocateAndReturnByCodec<Option<Vec<u8>>> {
1659		self.extension::<OffchainDbExt>()
1660			.expect(
1661				"local_storage_get can be called only in the offchain call context with
1662				OffchainDb extension",
1663			)
1664			.local_storage_get(kind, key)
1665	}
1666
1667	/// Initiates a http request given HTTP verb and the URL.
1668	///
1669	/// Meta is a future-reserved field containing additional, parity-scale-codec encoded
1670	/// parameters. Returns the id of newly started request.
1671	fn http_request_start(
1672		&mut self,
1673		method: PassFatPointerAndRead<&str>,
1674		uri: PassFatPointerAndRead<&str>,
1675		meta: PassFatPointerAndRead<&[u8]>,
1676	) -> AllocateAndReturnByCodec<Result<HttpRequestId, ()>> {
1677		self.extension::<OffchainWorkerExt>()
1678			.expect("http_request_start can be called only in the offchain worker context")
1679			.http_request_start(method, uri, meta)
1680	}
1681
1682	/// Append header to the request.
1683	fn http_request_add_header(
1684		&mut self,
1685		request_id: PassAs<HttpRequestId, u16>,
1686		name: PassFatPointerAndRead<&str>,
1687		value: PassFatPointerAndRead<&str>,
1688	) -> AllocateAndReturnByCodec<Result<(), ()>> {
1689		self.extension::<OffchainWorkerExt>()
1690			.expect("http_request_add_header can be called only in the offchain worker context")
1691			.http_request_add_header(request_id, name, value)
1692	}
1693
1694	/// Write a chunk of request body.
1695	///
1696	/// Writing an empty chunks finalizes the request.
1697	/// Passing `None` as deadline blocks forever.
1698	///
1699	/// Returns an error in case deadline is reached or the chunk couldn't be written.
1700	fn http_request_write_body(
1701		&mut self,
1702		request_id: PassAs<HttpRequestId, u16>,
1703		chunk: PassFatPointerAndRead<&[u8]>,
1704		deadline: PassFatPointerAndDecode<Option<Timestamp>>,
1705	) -> AllocateAndReturnByCodec<Result<(), HttpError>> {
1706		self.extension::<OffchainWorkerExt>()
1707			.expect("http_request_write_body can be called only in the offchain worker context")
1708			.http_request_write_body(request_id, chunk, deadline)
1709	}
1710
1711	/// Block and wait for the responses for given requests.
1712	///
1713	/// Returns a vector of request statuses (the len is the same as ids).
1714	/// Note that if deadline is not provided the method will block indefinitely,
1715	/// otherwise unready responses will produce `DeadlineReached` status.
1716	///
1717	/// Passing `None` as deadline blocks forever.
1718	fn http_response_wait(
1719		&mut self,
1720		ids: PassFatPointerAndDecodeSlice<&[HttpRequestId]>,
1721		deadline: PassFatPointerAndDecode<Option<Timestamp>>,
1722	) -> AllocateAndReturnByCodec<Vec<HttpRequestStatus>> {
1723		self.extension::<OffchainWorkerExt>()
1724			.expect("http_response_wait can be called only in the offchain worker context")
1725			.http_response_wait(ids, deadline)
1726	}
1727
1728	/// Read all response headers.
1729	///
1730	/// Returns a vector of pairs `(HeaderKey, HeaderValue)`.
1731	/// NOTE: response headers have to be read before response body.
1732	fn http_response_headers(
1733		&mut self,
1734		request_id: PassAs<HttpRequestId, u16>,
1735	) -> AllocateAndReturnByCodec<Vec<(Vec<u8>, Vec<u8>)>> {
1736		self.extension::<OffchainWorkerExt>()
1737			.expect("http_response_headers can be called only in the offchain worker context")
1738			.http_response_headers(request_id)
1739	}
1740
1741	/// Read a chunk of body response to given buffer.
1742	///
1743	/// Returns the number of bytes written or an error in case a deadline
1744	/// is reached or server closed the connection.
1745	/// If `0` is returned it means that the response has been fully consumed
1746	/// and the `request_id` is now invalid.
1747	/// NOTE: this implies that response headers must be read before draining the body.
1748	/// Passing `None` as a deadline blocks forever.
1749	fn http_response_read_body(
1750		&mut self,
1751		request_id: PassAs<HttpRequestId, u16>,
1752		buffer: PassFatPointerAndReadWrite<&mut [u8]>,
1753		deadline: PassFatPointerAndDecode<Option<Timestamp>>,
1754	) -> AllocateAndReturnByCodec<Result<u32, HttpError>> {
1755		self.extension::<OffchainWorkerExt>()
1756			.expect("http_response_read_body can be called only in the offchain worker context")
1757			.http_response_read_body(request_id, buffer, deadline)
1758			.map(|r| r as u32)
1759	}
1760
1761	/// Set the authorized nodes and authorized_only flag.
1762	fn set_authorized_nodes(
1763		&mut self,
1764		nodes: PassFatPointerAndDecode<Vec<OpaquePeerId>>,
1765		authorized_only: bool,
1766	) {
1767		self.extension::<OffchainWorkerExt>()
1768			.expect("set_authorized_nodes can be called only in the offchain worker context")
1769			.set_authorized_nodes(nodes, authorized_only)
1770	}
1771}
1772
1773/// Wasm only interface that provides functions for calling into the allocator.
1774#[runtime_interface(wasm_only)]
1775pub trait Allocator {
1776	/// Malloc the given number of bytes and return the pointer to the allocated memory location.
1777	fn malloc(&mut self, size: u32) -> Pointer<u8> {
1778		self.allocate_memory(size).expect("Failed to allocate memory")
1779	}
1780
1781	/// Free the given pointer.
1782	fn free(&mut self, ptr: Pointer<u8>) {
1783		self.deallocate_memory(ptr).expect("Failed to deallocate memory")
1784	}
1785}
1786
1787/// WASM-only interface which allows for aborting the execution in case
1788/// of an unrecoverable error.
1789#[runtime_interface(wasm_only)]
1790pub trait PanicHandler {
1791	/// Aborts the current execution with the given error message.
1792	#[trap_on_return]
1793	fn abort_on_panic(&mut self, message: PassFatPointerAndRead<&str>) {
1794		self.register_panic_error_message(message);
1795	}
1796}
1797
1798/// Interface that provides functions for logging from within the runtime.
1799#[runtime_interface]
1800pub trait Logging {
1801	/// Request to print a log message on the host.
1802	///
1803	/// Note that this will be only displayed if the host is enabled to display log messages with
1804	/// given level and target.
1805	///
1806	/// Instead of using directly, prefer setting up `RuntimeLogger` and using `log` macros.
1807	fn log(
1808		level: PassAs<RuntimeInterfaceLogLevel, u8>,
1809		target: PassFatPointerAndRead<&str>,
1810		message: PassFatPointerAndRead<&[u8]>,
1811	) {
1812		if let Ok(message) = core::str::from_utf8(message) {
1813			log::log!(target: target, log::Level::from(level), "{}", message)
1814		}
1815	}
1816
1817	/// Returns the max log level used by the host.
1818	fn max_level() -> ReturnAs<LogLevelFilter, u8> {
1819		log::max_level().into()
1820	}
1821}
1822
1823/// Interface to provide tracing facilities for wasm. Modelled after tokios `tracing`-crate
1824/// interfaces. See `sp-tracing` for more information.
1825#[runtime_interface(wasm_only, no_tracing)]
1826pub trait WasmTracing {
1827	/// Whether the span described in `WasmMetadata` should be traced wasm-side
1828	/// On the host converts into a static Metadata and checks against the global `tracing`
1829	/// dispatcher.
1830	///
1831	/// When returning false the calling code should skip any tracing-related execution. In general
1832	/// within the same block execution this is not expected to change and it doesn't have to be
1833	/// checked more than once per metadata. This exists for optimisation purposes but is still not
1834	/// cheap as it will jump the wasm-native-barrier every time it is called. So an implementation
1835	/// might chose to cache the result for the execution of the entire block.
1836	fn enabled(&mut self, metadata: PassFatPointerAndDecode<pezsp_tracing::WasmMetadata>) -> bool {
1837		let metadata: &tracing_core::metadata::Metadata<'static> = (&metadata).into();
1838		tracing::dispatcher::get_default(|d| d.enabled(metadata))
1839	}
1840
1841	/// Open a new span with the given attributes. Return the u64 Id of the span.
1842	///
1843	/// On the native side this goes through the default `tracing` dispatcher to register the span
1844	/// and then calls `clone_span` with the ID to signal that we are keeping it around on the wasm-
1845	/// side even after the local span is dropped. The resulting ID is then handed over to the wasm-
1846	/// side.
1847	fn enter_span(
1848		&mut self,
1849		span: PassFatPointerAndDecode<pezsp_tracing::WasmEntryAttributes>,
1850	) -> u64 {
1851		let span: tracing::Span = span.into();
1852		match span.id() {
1853			Some(id) => tracing::dispatcher::get_default(|d| {
1854				// inform dispatch that we'll keep the ID around
1855				// then enter it immediately
1856				let final_id = d.clone_span(&id);
1857				d.enter(&final_id);
1858				final_id.into_u64()
1859			}),
1860			_ => 0,
1861		}
1862	}
1863
1864	/// Emit the given event to the global tracer on the native side
1865	fn event(&mut self, event: PassFatPointerAndDecode<pezsp_tracing::WasmEntryAttributes>) {
1866		event.emit();
1867	}
1868
1869	/// Signal that a given span-id has been exited. On native, this directly
1870	/// proxies the span to the global dispatcher.
1871	fn exit(&mut self, span: u64) {
1872		tracing::dispatcher::get_default(|d| {
1873			let id = tracing_core::span::Id::from_u64(span);
1874			d.exit(&id);
1875		});
1876	}
1877}
1878
1879#[cfg(all(bizinikiwi_runtime, feature = "with-tracing"))]
1880mod tracing_setup {
1881	use super::wasm_tracing;
1882	use core::sync::atomic::{AtomicBool, Ordering};
1883	use tracing_core::{
1884		dispatcher::{set_global_default, Dispatch},
1885		span::{Attributes, Id, Record},
1886		Event, Metadata,
1887	};
1888
1889	static TRACING_SET: AtomicBool = AtomicBool::new(false);
1890
1891	/// The PassingTracingSubscriber implements `tracing_core::Subscriber`
1892	/// and pushes the information across the runtime interface to the host
1893	struct PassingTracingSubscriber;
1894
1895	impl tracing_core::Subscriber for PassingTracingSubscriber {
1896		fn enabled(&self, metadata: &Metadata<'_>) -> bool {
1897			wasm_tracing::enabled(metadata.into())
1898		}
1899		fn new_span(&self, attrs: &Attributes<'_>) -> Id {
1900			Id::from_u64(wasm_tracing::enter_span(attrs.into()))
1901		}
1902		fn enter(&self, _: &Id) {
1903			// Do nothing, we already entered the span previously
1904		}
1905		/// Not implemented! We do not support recording values later
1906		/// Will panic when used.
1907		fn record(&self, _: &Id, _: &Record<'_>) {
1908			unimplemented! {} // this usage is not supported
1909		}
1910		/// Not implemented! We do not support recording values later
1911		/// Will panic when used.
1912		fn record_follows_from(&self, _: &Id, _: &Id) {
1913			unimplemented! {} // this usage is not supported
1914		}
1915		fn event(&self, event: &Event<'_>) {
1916			wasm_tracing::event(event.into())
1917		}
1918		fn exit(&self, span: &Id) {
1919			wasm_tracing::exit(span.into_u64())
1920		}
1921	}
1922
1923	/// Initialize tracing of pezsp_tracing on wasm with `with-tracing` enabled.
1924	/// Can be called multiple times from within the same process and will only
1925	/// set the global bridging subscriber once.
1926	pub fn init_tracing() {
1927		if TRACING_SET.load(Ordering::Relaxed) == false {
1928			set_global_default(Dispatch::new(PassingTracingSubscriber {}))
1929				.expect("We only ever call this once");
1930			TRACING_SET.store(true, Ordering::Relaxed);
1931		}
1932	}
1933}
1934
1935#[cfg(not(all(bizinikiwi_runtime, feature = "with-tracing")))]
1936mod tracing_setup {
1937	/// Initialize tracing of pezsp_tracing not necessary – noop. To enable build
1938	/// when not both `bizinikiwi_runtime` and `with-tracing`-feature.
1939	pub fn init_tracing() {}
1940}
1941
1942pub use tracing_setup::init_tracing;
1943
1944/// Crashes the execution of the program.
1945///
1946/// Equivalent to the WASM `unreachable` instruction, RISC-V `unimp` instruction,
1947/// or just the `unreachable!()` macro everywhere else.
1948pub fn unreachable() -> ! {
1949	#[cfg(target_family = "wasm")]
1950	{
1951		core::arch::wasm32::unreachable();
1952	}
1953
1954	#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
1955	unsafe {
1956		core::arch::asm!("unimp", options(noreturn));
1957	}
1958
1959	#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64", target_family = "wasm")))]
1960	unreachable!();
1961}
1962
1963/// A default panic handler for the runtime environment.
1964#[cfg(all(not(feature = "disable_panic_handler"), bizinikiwi_runtime))]
1965#[panic_handler]
1966pub fn panic(info: &core::panic::PanicInfo) -> ! {
1967	let message = alloc::format!("{}", info);
1968	#[cfg(feature = "improved_panic_error_reporting")]
1969	{
1970		panic_handler::abort_on_panic(&message);
1971	}
1972	#[cfg(not(feature = "improved_panic_error_reporting"))]
1973	{
1974		logging::log(RuntimeInterfaceLogLevel::Error, "runtime", message.as_bytes());
1975		unreachable();
1976	}
1977}
1978
1979/// A default OOM handler for the runtime environment.
1980#[cfg(all(not(feature = "disable_oom"), enable_alloc_error_handler))]
1981#[alloc_error_handler]
1982pub fn oom(_: core::alloc::Layout) -> ! {
1983	#[cfg(feature = "improved_panic_error_reporting")]
1984	{
1985		panic_handler::abort_on_panic("Runtime memory exhausted.");
1986	}
1987	#[cfg(not(feature = "improved_panic_error_reporting"))]
1988	{
1989		logging::log(
1990			RuntimeInterfaceLogLevel::Error,
1991			"runtime",
1992			b"Runtime memory exhausted. Aborting",
1993		);
1994		unreachable();
1995	}
1996}
1997
1998/// Type alias for Externalities implementation used in tests.
1999#[cfg(feature = "std")] // NOTE: Deliberately isn't `not(bizinikiwi_runtime)`.
2000pub type TestExternalities = pezsp_state_machine::TestExternalities<pezsp_core::Blake2Hasher>;
2001
2002/// The host functions Bizinikiwi provides for the Wasm runtime environment.
2003///
2004/// All these host functions will be callable from inside the Wasm environment.
2005#[docify::export]
2006#[cfg(not(bizinikiwi_runtime))]
2007pub type BizinikiwiHostFunctions = (
2008	storage::HostFunctions,
2009	default_child_storage::HostFunctions,
2010	misc::HostFunctions,
2011	wasm_tracing::HostFunctions,
2012	offchain::HostFunctions,
2013	crypto::HostFunctions,
2014	hashing::HostFunctions,
2015	allocator::HostFunctions,
2016	panic_handler::HostFunctions,
2017	logging::HostFunctions,
2018	crate::trie::HostFunctions,
2019	offchain_index::HostFunctions,
2020	transaction_index::HostFunctions,
2021);
2022
2023#[cfg(test)]
2024mod tests {
2025	use super::*;
2026	use pezsp_core::{crypto::UncheckedInto, map, storage::Storage};
2027	use pezsp_state_machine::BasicExternalities;
2028
2029	#[test]
2030	fn storage_works() {
2031		let mut t = BasicExternalities::default();
2032		t.execute_with(|| {
2033			assert_eq!(storage::get(b"hello"), None);
2034			storage::set(b"hello", b"world");
2035			assert_eq!(storage::get(b"hello"), Some(b"world".to_vec().into()));
2036			assert_eq!(storage::get(b"foo"), None);
2037			storage::set(b"foo", &[1, 2, 3][..]);
2038		});
2039
2040		t = BasicExternalities::new(Storage {
2041			top: map![b"foo".to_vec() => b"bar".to_vec()],
2042			children_default: map![],
2043		});
2044
2045		t.execute_with(|| {
2046			assert_eq!(storage::get(b"hello"), None);
2047			assert_eq!(storage::get(b"foo"), Some(b"bar".to_vec().into()));
2048		});
2049
2050		let value = vec![7u8; 35];
2051		let storage =
2052			Storage { top: map![b"foo00".to_vec() => value.clone()], children_default: map![] };
2053		t = BasicExternalities::new(storage);
2054
2055		t.execute_with(|| {
2056			assert_eq!(storage::get(b"hello"), None);
2057			assert_eq!(storage::get(b"foo00"), Some(value.clone().into()));
2058		});
2059	}
2060
2061	#[test]
2062	fn read_storage_works() {
2063		let value = b"\x0b\0\0\0Hello world".to_vec();
2064		let mut t = BasicExternalities::new(Storage {
2065			top: map![b":test".to_vec() => value.clone()],
2066			children_default: map![],
2067		});
2068
2069		t.execute_with(|| {
2070			let mut v = [0u8; 4];
2071			assert_eq!(storage::read(b":test", &mut v[..], 0).unwrap(), value.len() as u32);
2072			assert_eq!(v, [11u8, 0, 0, 0]);
2073			let mut w = [0u8; 11];
2074			assert_eq!(storage::read(b":test", &mut w[..], 4).unwrap(), value.len() as u32 - 4);
2075			assert_eq!(&w, b"Hello world");
2076		});
2077	}
2078
2079	#[test]
2080	fn clear_prefix_works() {
2081		let mut t = BasicExternalities::new(Storage {
2082			top: map![
2083				b":a".to_vec() => b"\x0b\0\0\0Hello world".to_vec(),
2084				b":abcd".to_vec() => b"\x0b\0\0\0Hello world".to_vec(),
2085				b":abc".to_vec() => b"\x0b\0\0\0Hello world".to_vec(),
2086				b":abdd".to_vec() => b"\x0b\0\0\0Hello world".to_vec()
2087			],
2088			children_default: map![],
2089		});
2090
2091		t.execute_with(|| {
2092			// We can switch to this once we enable v3 of the `clear_prefix`.
2093			//assert!(matches!(
2094			//	storage::clear_prefix(b":abc", None),
2095			//	MultiRemovalResults::NoneLeft { db: 2, total: 2 }
2096			//));
2097			assert!(matches!(
2098				storage::clear_prefix(b":abc", None),
2099				KillStorageResult::AllRemoved(2),
2100			));
2101
2102			assert!(storage::get(b":a").is_some());
2103			assert!(storage::get(b":abdd").is_some());
2104			assert!(storage::get(b":abcd").is_none());
2105			assert!(storage::get(b":abc").is_none());
2106
2107			// We can switch to this once we enable v3 of the `clear_prefix`.
2108			//assert!(matches!(
2109			//	storage::clear_prefix(b":abc", None),
2110			//	MultiRemovalResults::NoneLeft { db: 0, total: 0 }
2111			//));
2112			assert!(matches!(
2113				storage::clear_prefix(b":abc", None),
2114				KillStorageResult::AllRemoved(0),
2115			));
2116		});
2117	}
2118
2119	fn zero_ed_pub() -> ed25519::Public {
2120		[0u8; 32].unchecked_into()
2121	}
2122
2123	fn zero_ed_sig() -> ed25519::Signature {
2124		ed25519::Signature::from_raw([0u8; 64])
2125	}
2126
2127	#[test]
2128	fn use_dalek_ext_works() {
2129		let mut ext = BasicExternalities::default();
2130		ext.register_extension(UseDalekExt::default());
2131
2132		// With dalek the zero signature should fail to verify.
2133		ext.execute_with(|| {
2134			assert!(!crypto::ed25519_verify(&zero_ed_sig(), &Vec::new(), &zero_ed_pub()));
2135		});
2136
2137		// But with zebra it should work.
2138		BasicExternalities::default().execute_with(|| {
2139			assert!(crypto::ed25519_verify(&zero_ed_sig(), &Vec::new(), &zero_ed_pub()));
2140		})
2141	}
2142
2143	#[test]
2144	fn dalek_should_not_panic_on_invalid_signature() {
2145		let mut ext = BasicExternalities::default();
2146		ext.register_extension(UseDalekExt::default());
2147
2148		ext.execute_with(|| {
2149			let mut bytes = [0u8; 64];
2150			// Make it invalid
2151			bytes[63] = 0b1110_0000;
2152
2153			assert!(!crypto::ed25519_verify(
2154				&ed25519::Signature::from_raw(bytes),
2155				&Vec::new(),
2156				&zero_ed_pub()
2157			));
2158		});
2159	}
2160}