substrate_api_client/api/runtime_api/
mmr.rs

1/*
2   Copyright 2024 Supercomputing Systems AG
3   Licensed under the Apache License, Version 2.0 (the "License");
4   you may not use this file except in compliance with the License.
5   You may obtain a copy of the License at
6	   http://www.apache.org/licenses/LICENSE-2.0
7   Unless required by applicable law or agreed to in writing, software
8   distributed under the License is distributed on an "AS IS" BASIS,
9   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10   See the License for the specific language governing permissions and
11   limitations under the License.
12*/
13
14use super::{RuntimeApi, RuntimeApiClient};
15use crate::{api::Result, rpc::Request};
16use ac_primitives::{config::Config, EncodableOpaqueLeaf, MmrError, Proof};
17#[cfg(all(not(feature = "sync-api"), not(feature = "std")))]
18use alloc::boxed::Box;
19use alloc::{vec, vec::Vec};
20use core::result::Result as StdResult;
21use sp_core::Encode;
22
23#[maybe_async::maybe_async(?Send)]
24pub trait MmrApi: RuntimeApi {
25	type Error;
26	type BlockNumber;
27	type EncodableOpaqueLeaf;
28	type Proof;
29
30	/// Generate MMR proof for the given block numbers.
31	#[allow(clippy::type_complexity)]
32	async fn generate_proof(
33		&self,
34		block_numbers: Vec<Self::BlockNumber>,
35		best_known_block_number: Option<Self::BlockNumber>,
36		at_block: Option<Self::Hash>,
37	) -> Result<StdResult<(Vec<Self::EncodableOpaqueLeaf>, Self::Proof), Self::Error>>;
38
39	/// Return the on-chain MMR root hash.
40	async fn root(
41		&self,
42		at_block: Option<Self::Hash>,
43	) -> Result<StdResult<Vec<Self::Hash>, Self::Error>>;
44
45	/// Verify MMR proof against on-chain MMR.
46	async fn verify_proof(
47		&self,
48		leaves: Vec<Self::EncodableOpaqueLeaf>,
49		proof: Self::Proof,
50		at_block: Option<Self::Hash>,
51	) -> Result<StdResult<(), Self::Error>>;
52
53	/// Verify MMR proof against given root hash.
54	async fn verify_proof_stateless(
55		&self,
56		root: Self::Hash,
57		leaves: Vec<Self::EncodableOpaqueLeaf>,
58		proof: Self::Proof,
59		at_block: Option<Self::Hash>,
60	) -> Result<StdResult<(), Self::Error>>;
61}
62
63#[maybe_async::maybe_async(?Send)]
64impl<T, Client> MmrApi for RuntimeApiClient<T, Client>
65where
66	T: Config,
67	Client: Request,
68{
69	type Error = MmrError;
70	type BlockNumber = T::BlockNumber;
71	type EncodableOpaqueLeaf = EncodableOpaqueLeaf;
72	type Proof = Proof<T::Hash>;
73
74	async fn generate_proof(
75		&self,
76		block_numbers: Vec<Self::BlockNumber>,
77		best_known_block_number: Option<Self::BlockNumber>,
78		at_block: Option<Self::Hash>,
79	) -> Result<StdResult<(Vec<Self::EncodableOpaqueLeaf>, Self::Proof), Self::Error>> {
80		self.runtime_call(
81			"MmrApi_generate_proof",
82			vec![block_numbers.encode(), best_known_block_number.encode()],
83			at_block,
84		)
85		.await
86	}
87
88	async fn root(
89		&self,
90		at_block: Option<Self::Hash>,
91	) -> Result<StdResult<Vec<Self::Hash>, Self::Error>> {
92		self.runtime_call("MmrApi_root", vec![], at_block).await
93	}
94
95	async fn verify_proof(
96		&self,
97		leaves: Vec<Self::EncodableOpaqueLeaf>,
98		proof: Self::Proof,
99		at_block: Option<Self::Hash>,
100	) -> Result<StdResult<(), Self::Error>> {
101		self.runtime_call("MmrApi_verify_proof", vec![leaves.encode(), proof.encode()], at_block)
102			.await
103	}
104
105	async fn verify_proof_stateless(
106		&self,
107		root: Self::Hash,
108		leaves: Vec<Self::EncodableOpaqueLeaf>,
109		proof: Self::Proof,
110		at_block: Option<Self::Hash>,
111	) -> Result<StdResult<(), Self::Error>> {
112		self.runtime_call(
113			"MmrApi_verify_proof_stateless",
114			vec![root.encode(), leaves.encode(), proof.encode()],
115			at_block,
116		)
117		.await
118	}
119}