pezframe_support/
view_functions.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 fsor the specific language governing permissions and
16// limitations under the License.
17
18//! Traits for querying pezpallet view functions.
19
20use alloc::vec::Vec;
21use codec::{Decode, DecodeAll, Encode, Output};
22use pezsp_runtime::RuntimeDebug;
23use scale_info::TypeInfo;
24
25/// The unique identifier for a view function.
26#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
27pub struct ViewFunctionId {
28	/// The part of the id for dispatching view functions from the top level of the runtime.
29	///
30	/// Specifies which view function grouping this view function belongs to. This could be a group
31	/// of view functions associated with a pezpallet, or a pezpallet agnostic group of view
32	/// functions.
33	pub prefix: [u8; 16],
34	/// The part of the id for dispatching to a view function within a group.
35	pub suffix: [u8; 16],
36}
37
38impl From<ViewFunctionId> for [u8; 32] {
39	fn from(value: ViewFunctionId) -> Self {
40		let mut output = [0u8; 32];
41		output[..16].copy_from_slice(&value.prefix);
42		output[16..].copy_from_slice(&value.suffix);
43		output
44	}
45}
46
47/// Error type for view function dispatching.
48#[derive(Encode, Decode, RuntimeDebug, TypeInfo)]
49pub enum ViewFunctionDispatchError {
50	/// View functions are not implemented for this runtime.
51	NotImplemented,
52	/// A view function with the given `ViewFunctionId` was not found
53	NotFound(ViewFunctionId),
54	/// Failed to decode the view function input.
55	Codec,
56}
57
58impl From<codec::Error> for ViewFunctionDispatchError {
59	fn from(_: codec::Error) -> Self {
60		ViewFunctionDispatchError::Codec
61	}
62}
63
64/// Implemented by both pallets and the runtime. The runtime is dispatching by prefix using the
65/// pezpallet implementation of `ViewFunctionIdPrefix` then the pezpallet is dispatching by suffix
66/// using the methods implementation of `ViewFunctionIdSuffix`.
67///
68/// In more details, `ViewFunctionId` = `ViewFunctionIdPrefix` ++ `ViewFunctionIdSuffix`, where
69/// `ViewFunctionIdPrefix=twox_128(pezpallet_name)` and
70/// `ViewFunctionIdSuffix=twox_128("fn_name(fnarg_types) -> return_ty")`. The prefix is the same as
71/// the storage prefix for pallets. The suffix is generated from the view function method type
72/// signature, so is guaranteed to be unique for that pezpallet implementation.
73pub trait DispatchViewFunction {
74	fn dispatch_view_function<O: Output>(
75		id: &ViewFunctionId,
76		input: &mut &[u8],
77		output: &mut O,
78	) -> Result<(), ViewFunctionDispatchError>;
79}
80
81impl DispatchViewFunction for () {
82	fn dispatch_view_function<O: Output>(
83		_id: &ViewFunctionId,
84		_input: &mut &[u8],
85		_output: &mut O,
86	) -> Result<(), ViewFunctionDispatchError> {
87		Err(ViewFunctionDispatchError::NotImplemented)
88	}
89}
90
91/// Automatically implemented for each pezpallet by the macro [`pezpallet`](crate::pezpallet).
92pub trait ViewFunctionIdPrefix {
93	fn prefix() -> [u8; 16];
94}
95
96/// Automatically implemented for each pezpallet view function method by the macro
97/// [`pezpallet`](crate::pezpallet).
98pub trait ViewFunctionIdSuffix {
99	const SUFFIX: [u8; 16];
100}
101
102/// Automatically implemented for each pezpallet view function method by the macro
103/// [`pezpallet`](crate::pezpallet).
104pub trait ViewFunction: DecodeAll {
105	fn id() -> ViewFunctionId;
106	type ReturnType: Encode;
107
108	fn invoke(self) -> Self::ReturnType;
109
110	fn execute<O: Output>(
111		input: &mut &[u8],
112		output: &mut O,
113	) -> Result<(), ViewFunctionDispatchError> {
114		let view_function = Self::decode_all(input)?;
115		let result = view_function.invoke();
116		Encode::encode_to(&result, output);
117		Ok(())
118	}
119}
120
121pub mod runtime_api {
122	use super::*;
123
124	pezsp_api::decl_runtime_apis! {
125		#[api_version(1)]
126		/// Runtime API for executing view functions
127		pub trait RuntimeViewFunction {
128			/// Execute a view function query.
129			fn execute_view_function(
130				query_id: ViewFunctionId,
131				input: Vec<u8>,
132			) -> Result<Vec<u8>, ViewFunctionDispatchError>;
133		}
134	}
135}