subxt_core/view_functions/
mod.rs

1// Copyright 2019-2024 Parity Technologies (UK) Ltd.
2// This file is dual-licensed as Apache-2.0 or GPL-3.0.
3// see LICENSE for license details.
4
5//! Encode View Function payloads, decode the associated values returned from them, and validate
6//! static View Function payloads.
7
8pub mod payload;
9
10use crate::error::{Error, MetadataError};
11use crate::metadata::{DecodeWithMetadata, Metadata};
12use alloc::vec::Vec;
13use payload::Payload;
14
15/// Run the validation logic against some View Function payload you'd like to use. Returns `Ok(())`
16/// if the payload is valid (or if it's not possible to check since the payload has no validation hash).
17/// Return an error if the payload was not valid or something went wrong trying to validate it (ie
18/// the View Function in question do not exist at all)
19pub fn validate<P: Payload>(payload: &P, metadata: &Metadata) -> Result<(), Error> {
20    let Some(static_hash) = payload.validation_hash() else {
21        return Ok(());
22    };
23
24    let view_function = metadata
25        .view_function_by_query_id(payload.query_id())
26        .ok_or_else(|| MetadataError::ViewFunctionNotFound(*payload.query_id()))?;
27    if static_hash != view_function.hash() {
28        return Err(MetadataError::IncompatibleCodegen.into());
29    }
30
31    Ok(())
32}
33
34/// The name of the Runtime API call which can execute
35pub const CALL_NAME: &str = "RuntimeViewFunction_execute_view_function";
36
37/// Encode the bytes that will be passed to the "execute_view_function" Runtime API call,
38/// to execute the View Function represented by the given payload.
39pub fn call_args<P: Payload>(payload: &P, metadata: &Metadata) -> Result<Vec<u8>, Error> {
40    let mut call_args = Vec::with_capacity(32);
41    call_args.extend_from_slice(payload.query_id());
42
43    let mut call_arg_params = Vec::new();
44    payload.encode_args_to(metadata, &mut call_arg_params)?;
45
46    use codec::Encode;
47    call_arg_params.encode_to(&mut call_args);
48
49    Ok(call_args)
50}
51
52/// Decode the value bytes at the location given by the provided View Function payload.
53pub fn decode_value<P: Payload>(
54    bytes: &mut &[u8],
55    payload: &P,
56    metadata: &Metadata,
57) -> Result<P::ReturnType, Error> {
58    let view_function = metadata
59        .view_function_by_query_id(payload.query_id())
60        .ok_or_else(|| MetadataError::ViewFunctionNotFound(*payload.query_id()))?;
61
62    let val = <P::ReturnType as DecodeWithMetadata>::decode_with_metadata(
63        &mut &bytes[..],
64        view_function.output_ty(),
65        metadata,
66    )?;
67
68    Ok(val)
69}