From 0d60f42b5e06cfca3dab40e9436f3bc201dd7868 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Wed, 14 Apr 2021 09:12:38 +0300 Subject: [PATCH] Use Substrate state_getReadProof RPC method to get storage proofs (#893) * use Substrate state_getReadProof method instead of pallet-bridge-messages-rpc * Fix typo Co-authored-by: Hernando Castano --- bridges/bin/millau/node/Cargo.toml | 1 - bridges/bin/millau/node/src/service.rs | 38 +--- bridges/bin/millau/runtime/src/lib.rs | 5 +- .../bin/millau/runtime/src/rialto_messages.rs | 27 +-- bridges/bin/rialto/node/Cargo.toml | 1 - bridges/bin/rialto/node/src/service.rs | 38 +--- bridges/bin/rialto/runtime/src/lib.rs | 6 +- .../bin/rialto/runtime/src/millau_messages.rs | 25 +-- bridges/modules/messages/rpc/Cargo.toml | 29 --- bridges/modules/messages/rpc/src/error.rs | 59 ----- bridges/modules/messages/rpc/src/lib.rs | 202 ------------------ .../bin-substrate/src/messages_source.rs | 47 ++-- .../bin-substrate/src/messages_target.rs | 32 ++- .../millau_messages_to_rialto.rs | 16 +- .../rialto_messages_to_millau.rs | 16 +- bridges/relays/client-substrate/Cargo.toml | 1 + bridges/relays/client-substrate/src/client.rs | 56 +---- bridges/relays/client-substrate/src/error.rs | 4 + .../src/metrics/storage_proof_overhead.rs | 58 ++--- bridges/relays/client-substrate/src/rpc.rs | 29 +-- 20 files changed, 130 insertions(+), 560 deletions(-) delete mode 100644 bridges/modules/messages/rpc/Cargo.toml delete mode 100644 bridges/modules/messages/rpc/src/error.rs delete mode 100644 bridges/modules/messages/rpc/src/lib.rs diff --git a/bridges/bin/millau/node/Cargo.toml b/bridges/bin/millau/node/Cargo.toml index 076e282bae..e31e2c871a 100644 --- a/bridges/bin/millau/node/Cargo.toml +++ b/bridges/bin/millau/node/Cargo.toml @@ -20,7 +20,6 @@ bp-millau= { path = "../../../primitives/chain-millau" } bp-runtime = { path = "../../../primitives/runtime" } millau-runtime = { path = "../runtime" } pallet-bridge-messages = { path = "../../../modules/messages" } -pallet-bridge-messages-rpc = { path = "../../../modules/messages/rpc" } # Substrate Dependencies diff --git a/bridges/bin/millau/node/src/service.rs b/bridges/bin/millau/node/src/service.rs index b3834ff68a..8677ec2e70 100644 --- a/bridges/bin/millau/node/src/service.rs +++ b/bridges/bin/millau/node/src/service.rs @@ -211,40 +211,8 @@ pub fn new_full(mut config: Configuration) -> Result let prometheus_registry = config.prometheus_registry().cloned(); let rpc_extensions_builder = { - use bp_messages::{LaneId, MessageNonce}; - use bp_runtime::{InstanceId, RIALTO_BRIDGE_INSTANCE}; use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider; - use sp_core::storage::StorageKey; - // This struct is here to ease update process. - - /// Millau runtime from messages RPC point of view. - struct MillauMessagesKeys; - - impl pallet_bridge_messages_rpc::Runtime for MillauMessagesKeys { - fn message_key(&self, instance: &InstanceId, lane: &LaneId, nonce: MessageNonce) -> Option { - match *instance { - RIALTO_BRIDGE_INSTANCE => Some(millau_runtime::rialto_messages::message_key(lane, nonce)), - _ => None, - } - } - - fn outbound_lane_data_key(&self, instance: &InstanceId, lane: &LaneId) -> Option { - match *instance { - RIALTO_BRIDGE_INSTANCE => Some(millau_runtime::rialto_messages::outbound_lane_data_key(lane)), - _ => None, - } - } - - fn inbound_lane_data_key(&self, instance: &InstanceId, lane: &LaneId) -> Option { - match *instance { - RIALTO_BRIDGE_INSTANCE => Some(millau_runtime::rialto_messages::inbound_lane_data_key(lane)), - _ => None, - } - } - } - - use pallet_bridge_messages_rpc::{MessagesApi, MessagesRpcHandler}; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; use sc_finality_grandpa_rpc::{GrandpaApi, GrandpaRpcHandler}; use sc_rpc::DenyUnsafe; @@ -259,7 +227,7 @@ pub fn new_full(mut config: Configuration) -> Result let shared_voter_state = sc_finality_grandpa::SharedVoterState::empty(); let finality_proof_provider = - GrandpaFinalityProofProvider::new_for_service(backend.clone(), Some(shared_authority_set.clone())); + GrandpaFinalityProofProvider::new_for_service(backend, Some(shared_authority_set.clone())); Box::new(move |_, subscription_executor| { let mut io = jsonrpc_core::IoHandler::default(); @@ -278,10 +246,6 @@ pub fn new_full(mut config: Configuration) -> Result subscription_executor, finality_proof_provider.clone(), ))); - io.extend_with(MessagesApi::to_delegate(MessagesRpcHandler::new( - backend.clone(), - Arc::new(MillauMessagesKeys), - ))); io }) }; diff --git a/bridges/bin/millau/runtime/src/lib.rs b/bridges/bin/millau/runtime/src/lib.rs index 822c0229ea..30cf1bd87c 100644 --- a/bridges/bin/millau/runtime/src/lib.rs +++ b/bridges/bin/millau/runtime/src/lib.rs @@ -351,7 +351,10 @@ parameter_types! { pub const RootAccountForPayments: Option = None; } -impl pallet_bridge_messages::Config for Runtime { +/// Instance of the messages pallet used to relay messages to/from Rialto chain. +pub type WithRialtoMessagesInstance = pallet_bridge_messages::DefaultInstance; + +impl pallet_bridge_messages::Config for Runtime { type Event = Event; // TODO: https://github.com/paritytech/parity-bridges-common/issues/390 type WeightInfo = pallet_bridge_messages::weights::RialtoWeight; diff --git a/bridges/bin/millau/runtime/src/rialto_messages.rs b/bridges/bin/millau/runtime/src/rialto_messages.rs index 9162596e7c..30f373fa0a 100644 --- a/bridges/bin/millau/runtime/src/rialto_messages.rs +++ b/bridges/bin/millau/runtime/src/rialto_messages.rs @@ -24,14 +24,13 @@ use bp_messages::{ InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter, }; use bp_runtime::{InstanceId, RIALTO_BRIDGE_INSTANCE}; -use bridge_runtime_common::messages::{self, ChainWithMessages, MessageBridge, MessageTransaction}; +use bridge_runtime_common::messages::{self, MessageBridge, MessageTransaction}; use codec::{Decode, Encode}; use frame_support::{ parameter_types, weights::{DispatchClass, Weight}, RuntimeDebug, }; -use sp_core::storage::StorageKey; use sp_runtime::{FixedPointNumber, FixedU128}; use sp_std::{convert::TryFrom, ops::RangeInclusive}; @@ -43,28 +42,6 @@ parameter_types! { pub storage RialtoToMillauConversionRate: FixedU128 = INITIAL_RIALTO_TO_MILLAU_CONVERSION_RATE; } -/// Storage key of the Millau -> Rialto message in the runtime storage. -pub fn message_key(lane: &LaneId, nonce: MessageNonce) -> StorageKey { - pallet_bridge_messages::storage_keys::message_key::::MessagesInstance>( - lane, nonce, - ) -} - -/// Storage key of the Millau -> Rialto message lane state in the runtime storage. -pub fn outbound_lane_data_key(lane: &LaneId) -> StorageKey { - pallet_bridge_messages::storage_keys::outbound_lane_data_key::<::MessagesInstance>( - lane, - ) -} - -/// Storage key of the Rialto -> Millau message lane state in the runtime storage. -pub fn inbound_lane_data_key(lane: &LaneId) -> StorageKey { - pallet_bridge_messages::storage_keys::inbound_lane_data_key::< - Runtime, - ::MessagesInstance, - >(lane) -} - /// Message payload for Millau -> Rialto messages. pub type ToRialtoMessagePayload = messages::source::FromThisChainMessagePayload; @@ -120,7 +97,7 @@ impl messages::ChainWithMessages for Millau { type Weight = Weight; type Balance = bp_millau::Balance; - type MessagesInstance = pallet_bridge_messages::DefaultInstance; + type MessagesInstance = crate::WithRialtoMessagesInstance; } impl messages::ThisChainWithMessages for Millau { diff --git a/bridges/bin/rialto/node/Cargo.toml b/bridges/bin/rialto/node/Cargo.toml index fffbe9655a..a51ee7a5ab 100644 --- a/bridges/bin/rialto/node/Cargo.toml +++ b/bridges/bin/rialto/node/Cargo.toml @@ -19,7 +19,6 @@ bp-messages = { path = "../../../primitives/messages" } bp-runtime = { path = "../../../primitives/runtime" } bp-rialto = { path = "../../../primitives/chain-rialto" } pallet-bridge-messages = { path = "../../../modules/messages" } -pallet-bridge-messages-rpc = { path = "../../../modules/messages/rpc" } rialto-runtime = { path = "../runtime" } # Substrate Dependencies diff --git a/bridges/bin/rialto/node/src/service.rs b/bridges/bin/rialto/node/src/service.rs index 380b0cc817..841202ac7b 100644 --- a/bridges/bin/rialto/node/src/service.rs +++ b/bridges/bin/rialto/node/src/service.rs @@ -211,40 +211,8 @@ pub fn new_full(mut config: Configuration) -> Result let prometheus_registry = config.prometheus_registry().cloned(); let rpc_extensions_builder = { - use bp_messages::{LaneId, MessageNonce}; - use bp_runtime::{InstanceId, MILLAU_BRIDGE_INSTANCE}; use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider; - use sp_core::storage::StorageKey; - // This struct is here to ease update process. - - /// Rialto runtime from messages RPC point of view. - struct RialtoMessagesKeys; - - impl pallet_bridge_messages_rpc::Runtime for RialtoMessagesKeys { - fn message_key(&self, instance: &InstanceId, lane: &LaneId, nonce: MessageNonce) -> Option { - match *instance { - MILLAU_BRIDGE_INSTANCE => Some(rialto_runtime::millau_messages::message_key(lane, nonce)), - _ => None, - } - } - - fn outbound_lane_data_key(&self, instance: &InstanceId, lane: &LaneId) -> Option { - match *instance { - MILLAU_BRIDGE_INSTANCE => Some(rialto_runtime::millau_messages::outbound_lane_data_key(lane)), - _ => None, - } - } - - fn inbound_lane_data_key(&self, instance: &InstanceId, lane: &LaneId) -> Option { - match *instance { - MILLAU_BRIDGE_INSTANCE => Some(rialto_runtime::millau_messages::inbound_lane_data_key(lane)), - _ => None, - } - } - } - - use pallet_bridge_messages_rpc::{MessagesApi, MessagesRpcHandler}; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; use sc_finality_grandpa_rpc::{GrandpaApi, GrandpaRpcHandler}; use sc_rpc::DenyUnsafe; @@ -259,7 +227,7 @@ pub fn new_full(mut config: Configuration) -> Result let shared_voter_state = sc_finality_grandpa::SharedVoterState::empty(); let finality_proof_provider = - GrandpaFinalityProofProvider::new_for_service(backend.clone(), Some(shared_authority_set.clone())); + GrandpaFinalityProofProvider::new_for_service(backend, Some(shared_authority_set.clone())); Box::new(move |_, subscription_executor| { let mut io = jsonrpc_core::IoHandler::default(); @@ -278,10 +246,6 @@ pub fn new_full(mut config: Configuration) -> Result subscription_executor, finality_proof_provider.clone(), ))); - io.extend_with(MessagesApi::to_delegate(MessagesRpcHandler::new( - backend.clone(), - Arc::new(RialtoMessagesKeys), - ))); io }) diff --git a/bridges/bin/rialto/runtime/src/lib.rs b/bridges/bin/rialto/runtime/src/lib.rs index 603365130a..4e81d3efb1 100644 --- a/bridges/bin/rialto/runtime/src/lib.rs +++ b/bridges/bin/rialto/runtime/src/lib.rs @@ -443,8 +443,10 @@ parameter_types! { pub const RootAccountForPayments: Option = None; } -pub(crate) type WithMillauMessagesInstance = pallet_bridge_messages::DefaultInstance; -impl pallet_bridge_messages::Config for Runtime { +/// Instance of the messages pallet used to relay messages to/from Millau chain. +pub type WithMillauMessagesInstance = pallet_bridge_messages::DefaultInstance; + +impl pallet_bridge_messages::Config for Runtime { type Event = Event; type WeightInfo = pallet_bridge_messages::weights::RialtoWeight; type Parameter = millau_messages::RialtoToMillauMessagesParameter; diff --git a/bridges/bin/rialto/runtime/src/millau_messages.rs b/bridges/bin/rialto/runtime/src/millau_messages.rs index 62f4ec7147..e8785c464a 100644 --- a/bridges/bin/rialto/runtime/src/millau_messages.rs +++ b/bridges/bin/rialto/runtime/src/millau_messages.rs @@ -24,14 +24,13 @@ use bp_messages::{ InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter, }; use bp_runtime::{InstanceId, MILLAU_BRIDGE_INSTANCE}; -use bridge_runtime_common::messages::{self, ChainWithMessages, MessageBridge, MessageTransaction}; +use bridge_runtime_common::messages::{self, MessageBridge, MessageTransaction}; use codec::{Decode, Encode}; use frame_support::{ parameter_types, weights::{DispatchClass, Weight}, RuntimeDebug, }; -use sp_core::storage::StorageKey; use sp_runtime::{FixedPointNumber, FixedU128}; use sp_std::{convert::TryFrom, ops::RangeInclusive}; @@ -43,28 +42,6 @@ parameter_types! { pub storage MillauToRialtoConversionRate: FixedU128 = INITIAL_MILLAU_TO_RIALTO_CONVERSION_RATE; } -/// Storage key of the Rialto -> Millau message in the runtime storage. -pub fn message_key(lane: &LaneId, nonce: MessageNonce) -> StorageKey { - pallet_bridge_messages::storage_keys::message_key::::MessagesInstance>( - lane, nonce, - ) -} - -/// Storage key of the Rialto -> Millau message lane state in the runtime storage. -pub fn outbound_lane_data_key(lane: &LaneId) -> StorageKey { - pallet_bridge_messages::storage_keys::outbound_lane_data_key::<::MessagesInstance>( - lane, - ) -} - -/// Storage key of the Millau -> Rialto message lane state in the runtime storage. -pub fn inbound_lane_data_key(lane: &LaneId) -> StorageKey { - pallet_bridge_messages::storage_keys::inbound_lane_data_key::< - Runtime, - ::MessagesInstance, - >(lane) -} - /// Message payload for Rialto -> Millau messages. pub type ToMillauMessagePayload = messages::source::FromThisChainMessagePayload; diff --git a/bridges/modules/messages/rpc/Cargo.toml b/bridges/modules/messages/rpc/Cargo.toml deleted file mode 100644 index bb0d1e0c54..0000000000 --- a/bridges/modules/messages/rpc/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "pallet-bridge-messages-rpc" -description = "Module that provides RPC methods specific to pallet-bridge-messages pallet." -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2018" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -derive_more = "0.99.2" -futures = { version = "0.3.5", features = ["compat"] } -jsonrpc-core = "15.1.0" -jsonrpc-core-client = "15.1.0" -jsonrpc-derive = "15.1.0" -log = "0.4.11" - -# Bridge dependencies - -bp-runtime = { path = "../../../primitives/runtime" } -bp-messages = { path = "../../../primitives/messages" } - -# Substrate Dependencies - -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/bridges/modules/messages/rpc/src/error.rs b/bridges/modules/messages/rpc/src/error.rs deleted file mode 100644 index 983b53b65b..0000000000 --- a/bridges/modules/messages/rpc/src/error.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Bridges Common is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Bridges Common. If not, see . - -//! Possible errors and results of messages pallet RPC calls. - -/// Future Result type. -pub type FutureResult = jsonrpc_core::BoxFuture; - -/// State RPC errors. -#[derive(Debug, derive_more::Display, derive_more::From)] -pub enum Error { - /// When unknown instance id is passed. - #[display(fmt = "Message lane instance is unknown")] - UnknownInstance, - /// Client error. - #[display(fmt = "Client error: {}", _0)] - Client(Box), -} - -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - Error::UnknownInstance => None, - Error::Client(ref err) => Some(&**err), - } - } -} - -impl From for jsonrpc_core::Error { - fn from(e: Error) -> Self { - const UNKNOW_INSTANCE_CODE: i64 = 1; - - match e { - Error::UnknownInstance => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(UNKNOW_INSTANCE_CODE), - message: "Unknown instance passed".into(), - data: None, - }, - Error::Client(e) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::InternalError, - message: format!("Unknown error occured: {}", e), - data: Some(format!("{:?}", e).into()), - }, - } - } -} diff --git a/bridges/modules/messages/rpc/src/lib.rs b/bridges/modules/messages/rpc/src/lib.rs deleted file mode 100644 index a53dcfeb02..0000000000 --- a/bridges/modules/messages/rpc/src/lib.rs +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2019-2021 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Bridges Common is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Bridges Common. If not, see . - -//! Pallet that provides RPC methods specific to messages pallet. - -use crate::error::{Error, FutureResult}; - -use bp_messages::{LaneId, MessageNonce}; -use bp_runtime::InstanceId; -use futures::{FutureExt, TryFutureExt}; -use jsonrpc_core::futures::Future as _; -use jsonrpc_derive::rpc; -use sc_client_api::Backend as BackendT; -use sp_blockchain::{Error as BlockchainError, HeaderBackend}; -use sp_core::{storage::StorageKey, Bytes}; -use sp_runtime::{codec::Encode, generic::BlockId, traits::Block as BlockT}; -use sp_state_machine::prove_read; -use sp_trie::StorageProof; -use std::sync::Arc; - -mod error; - -/// Trie-based storage proof that the message(s) with given key(s) have been sent by the bridged chain. -/// SCALE-encoded trie nodes array `Vec>`. -pub type MessagesProof = Bytes; - -/// Trie-based storage proof that the message(s) with given key(s) have been received by the bridged chain. -/// SCALE-encoded trie nodes array `Vec>`. -pub type MessagesDeliveryProof = Bytes; - -/// Runtime adapter. -pub trait Runtime: Send + Sync + 'static { - /// Return runtime storage key for given message. May return None if instance is unknown. - fn message_key(&self, instance: &InstanceId, lane: &LaneId, nonce: MessageNonce) -> Option; - /// Return runtime storage key for outbound lane state. May return None if instance is unknown. - fn outbound_lane_data_key(&self, instance: &InstanceId, lane: &LaneId) -> Option; - /// Return runtime storage key for inbound lane state. May return None if instance is unknown. - fn inbound_lane_data_key(&self, instance: &InstanceId, lane: &LaneId) -> Option; -} - -/// Provides RPC methods for interacting with messages pallet. -#[rpc] -pub trait MessagesApi { - /// Returns storage proof of messages in given inclusive range. The state of outbound - /// lane is included in the proof if `include_outbound_lane_state` is true. - #[rpc(name = "messages_proveMessages")] - fn prove_messages( - &self, - instance: InstanceId, - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, - include_outbound_lane_state: bool, - block: Option, - ) -> FutureResult; - - /// Returns proof-of-message(s) delivery. - #[rpc(name = "messages_proveMessagesDelivery")] - fn prove_messages_delivery( - &self, - instance: InstanceId, - lane: LaneId, - block: Option, - ) -> FutureResult; -} - -/// Implements the MessagesApi trait for interacting with message lanes. -pub struct MessagesRpcHandler { - backend: Arc, - runtime: Arc, - _phantom: std::marker::PhantomData, -} - -impl MessagesRpcHandler { - /// Creates new mesage lane RPC handler. - pub fn new(backend: Arc, runtime: Arc) -> Self { - Self { - backend, - runtime, - _phantom: Default::default(), - } - } -} - -impl MessagesApi for MessagesRpcHandler -where - Block: BlockT, - Backend: BackendT + 'static, - R: Runtime, -{ - fn prove_messages( - &self, - instance: InstanceId, - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, - include_outbound_lane_state: bool, - block: Option, - ) -> FutureResult { - let runtime = self.runtime.clone(); - let outbound_lane_data_key = if include_outbound_lane_state { - Some(runtime.outbound_lane_data_key(&instance, &lane)) - } else { - None - }; - let messages_count = if end >= begin { end - begin + 1 } else { 0 }; - Box::new( - prove_keys_read( - self.backend.clone(), - block, - (begin..=end) - .map(move |nonce| runtime.message_key(&instance, &lane, nonce)) - .chain(outbound_lane_data_key.into_iter()), - ) - .boxed() - .compat() - .map(move |proof| { - let serialized_proof = serialize_storage_proof(proof); - log::trace!( - "Generated proof of {} messages. Size: {}", - messages_count, - serialized_proof.len() - ); - serialized_proof - }) - .map_err(Into::into), - ) - } - - fn prove_messages_delivery( - &self, - instance: InstanceId, - lane: LaneId, - block: Option, - ) -> FutureResult { - Box::new( - prove_keys_read( - self.backend.clone(), - block, - vec![self.runtime.inbound_lane_data_key(&instance, &lane)], - ) - .boxed() - .compat() - .map(|proof| { - let serialized_proof = serialize_storage_proof(proof); - log::trace!("Generated message delivery proof. Size: {}", serialized_proof.len()); - serialized_proof - }) - .map_err(Into::into), - ) - } -} - -async fn prove_keys_read( - backend: Arc, - block: Option, - keys: impl IntoIterator>, -) -> Result -where - Block: BlockT, - Backend: BackendT + 'static, -{ - let block = unwrap_or_best(&*backend, block); - let state = backend.state_at(BlockId::Hash(block)).map_err(blockchain_err)?; - let keys = keys - .into_iter() - .map(|key| key.ok_or(Error::UnknownInstance).map(|key| key.0)) - .collect::, _>>()?; - let storage_proof = prove_read(state, keys) - .map_err(BlockchainError::Execution) - .map_err(blockchain_err)?; - Ok(storage_proof) -} - -fn serialize_storage_proof(proof: StorageProof) -> Bytes { - let raw_nodes: Vec> = proof.iter_nodes().map(Into::into).collect(); - raw_nodes.encode().into() -} - -fn unwrap_or_best(backend: &impl BackendT, block: Option) -> Block::Hash { - match block { - Some(block) => block, - None => backend.blockchain().info().best_hash, - } -} - -fn blockchain_err(err: BlockchainError) -> Error { - Error::Client(Box::new(err)) -} diff --git a/bridges/relays/bin-substrate/src/messages_source.rs b/bridges/relays/bin-substrate/src/messages_source.rs index 99f88fbbbb..3123446caa 100644 --- a/bridges/relays/bin-substrate/src/messages_source.rs +++ b/bridges/relays/bin-substrate/src/messages_source.rs @@ -25,18 +25,19 @@ use bp_messages::{LaneId, MessageNonce}; use bp_runtime::InstanceId; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use codec::{Decode, Encode}; -use frame_support::weights::Weight; +use frame_support::{traits::Instance, weights::Weight}; use messages_relay::{ message_lane::{SourceHeaderIdOf, TargetHeaderIdOf}, message_lane_loop::{ ClientState, MessageProofParameters, MessageWeights, MessageWeightsMap, SourceClient, SourceClientState, }, }; +use pallet_bridge_messages::Config as MessagesConfig; use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf, HeaderIdOf}; use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase, HeaderId}; use sp_core::Bytes; use sp_runtime::{traits::Header as HeaderT, DeserializeOwned}; -use std::ops::RangeInclusive; +use std::{marker::PhantomData, ops::RangeInclusive}; /// Intermediate message proof returned by the source Substrate node. Includes everything /// required to submit to the target node: cumulative dispatch weight of bundled messages and @@ -44,14 +45,15 @@ use std::ops::RangeInclusive; pub type SubstrateMessagesProof = (Weight, FromBridgedChainMessagesProof>); /// Substrate client as Substrate messages source. -pub struct SubstrateMessagesSource { +pub struct SubstrateMessagesSource { client: Client, lane: P, lane_id: LaneId, instance: InstanceId, + _phantom: PhantomData<(R, I)>, } -impl SubstrateMessagesSource { +impl SubstrateMessagesSource { /// Create new Substrate headers source. pub fn new(client: Client, lane: P, lane_id: LaneId, instance: InstanceId) -> Self { SubstrateMessagesSource { @@ -59,23 +61,31 @@ impl SubstrateMessagesSource { lane, lane_id, instance, + _phantom: Default::default(), } } } -impl Clone for SubstrateMessagesSource { +impl Clone for SubstrateMessagesSource { fn clone(&self) -> Self { Self { client: self.client.clone(), lane: self.lane.clone(), lane_id: self.lane_id, instance: self.instance, + _phantom: Default::default(), } } } #[async_trait] -impl RelayClient for SubstrateMessagesSource { +impl RelayClient for SubstrateMessagesSource +where + C: Chain, + P: SubstrateMessageLane, + R: Send + Sync, + I: Send + Sync + Instance, +{ type Error = SubstrateError; async fn reconnect(&mut self) -> Result<(), SubstrateError> { @@ -84,7 +94,7 @@ impl RelayClient for SubstrateMessagesSource< } #[async_trait] -impl SourceClient

for SubstrateMessagesSource +impl SourceClient

for SubstrateMessagesSource where C: Chain, C::Header: DeserializeOwned, @@ -98,6 +108,8 @@ where >, P::TargetHeaderNumber: Decode, P::TargetHeaderHash: Decode, + R: Send + Sync + MessagesConfig, + I: Send + Sync + Instance, { async fn state(&self) -> Result, SubstrateError> { // we can't continue to deliver confirmations if source node is out of sync, because @@ -171,15 +183,22 @@ where nonces: RangeInclusive, proof_parameters: MessageProofParameters, ) -> Result<(SourceHeaderIdOf

, RangeInclusive, P::MessagesProof), SubstrateError> { + let mut storage_keys = Vec::with_capacity(nonces.end().saturating_sub(*nonces.start()) as usize + 1); + let mut message_nonce = *nonces.start(); + while message_nonce <= *nonces.end() { + let message_key = pallet_bridge_messages::storage_keys::message_key::(&self.lane_id, message_nonce); + storage_keys.push(message_key); + message_nonce += 1; + } + if proof_parameters.outbound_state_proof_required { + storage_keys.push(pallet_bridge_messages::storage_keys::outbound_lane_data_key::( + &self.lane_id, + )); + } + let proof = self .client - .prove_messages( - self.instance, - self.lane_id, - nonces.clone(), - proof_parameters.outbound_state_proof_required, - id.1, - ) + .prove_storage(storage_keys, id.1) .await? .iter_nodes() .collect(); diff --git a/bridges/relays/bin-substrate/src/messages_target.rs b/bridges/relays/bin-substrate/src/messages_target.rs index 3d8ab4fd00..fe3f95ca8e 100644 --- a/bridges/relays/bin-substrate/src/messages_target.rs +++ b/bridges/relays/bin-substrate/src/messages_target.rs @@ -26,15 +26,17 @@ use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState}; use bp_runtime::InstanceId; use bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof; use codec::{Decode, Encode}; +use frame_support::traits::Instance; use messages_relay::{ message_lane::{SourceHeaderIdOf, TargetHeaderIdOf}, message_lane_loop::{TargetClient, TargetClientState}, }; +use pallet_bridge_messages::Config as MessagesConfig; use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf}; use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase}; use sp_core::Bytes; use sp_runtime::{traits::Header as HeaderT, DeserializeOwned}; -use std::ops::RangeInclusive; +use std::{marker::PhantomData, ops::RangeInclusive}; /// Message receiving proof returned by the target Substrate node. pub type SubstrateMessagesReceivingProof = ( @@ -43,14 +45,15 @@ pub type SubstrateMessagesReceivingProof = ( ); /// Substrate client as Substrate messages target. -pub struct SubstrateMessagesTarget { +pub struct SubstrateMessagesTarget { client: Client, lane: P, lane_id: LaneId, instance: InstanceId, + _phantom: PhantomData<(R, I)>, } -impl SubstrateMessagesTarget { +impl SubstrateMessagesTarget { /// Create new Substrate headers target. pub fn new(client: Client, lane: P, lane_id: LaneId, instance: InstanceId) -> Self { SubstrateMessagesTarget { @@ -58,23 +61,31 @@ impl SubstrateMessagesTarget { lane, lane_id, instance, + _phantom: Default::default(), } } } -impl Clone for SubstrateMessagesTarget { +impl Clone for SubstrateMessagesTarget { fn clone(&self) -> Self { Self { client: self.client.clone(), lane: self.lane.clone(), lane_id: self.lane_id, instance: self.instance, + _phantom: Default::default(), } } } #[async_trait] -impl RelayClient for SubstrateMessagesTarget { +impl RelayClient for SubstrateMessagesTarget +where + C: Chain, + P: SubstrateMessageLane, + R: Send + Sync, + I: Send + Sync + Instance, +{ type Error = SubstrateError; async fn reconnect(&mut self) -> Result<(), SubstrateError> { @@ -83,7 +94,7 @@ impl RelayClient for SubstrateMessagesTarget< } #[async_trait] -impl TargetClient

for SubstrateMessagesTarget +impl TargetClient

for SubstrateMessagesTarget where C: Chain, C::Header: DeserializeOwned, @@ -97,6 +108,8 @@ where >, P::SourceHeaderNumber: Decode, P::SourceHeaderHash: Decode, + R: Send + Sync + MessagesConfig, + I: Send + Sync + Instance, { async fn state(&self) -> Result, SubstrateError> { // we can't continue to deliver messages if target node is out of sync, because @@ -166,10 +179,13 @@ where id: TargetHeaderIdOf

, ) -> Result<(TargetHeaderIdOf

, P::MessagesReceivingProof), SubstrateError> { let (id, relayers_state) = self.unrewarded_relayers_state(id).await?; + let inbound_data_key = pallet_bridge_messages::storage_keys::inbound_lane_data_key::(&self.lane_id); let proof = self .client - .prove_messages_delivery(self.instance, self.lane_id, id.1) - .await?; + .prove_storage(vec![inbound_data_key], id.1) + .await? + .iter_nodes() + .collect(); let proof = FromBridgedChainMessagesDeliveryProof { bridged_header_hash: id.1, storage_proof: proof, diff --git a/bridges/relays/bin-substrate/src/rialto_millau/millau_messages_to_rialto.rs b/bridges/relays/bin-substrate/src/rialto_millau/millau_messages_to_rialto.rs index 82c3dbaa3b..31a0061819 100644 --- a/bridges/relays/bin-substrate/src/rialto_millau/millau_messages_to_rialto.rs +++ b/bridges/relays/bin-substrate/src/rialto_millau/millau_messages_to_rialto.rs @@ -126,10 +126,20 @@ impl SubstrateMessageLane for MillauMessagesToRialto { } /// Millau node as messages source. -type MillauSourceClient = SubstrateMessagesSource; +type MillauSourceClient = SubstrateMessagesSource< + Millau, + MillauMessagesToRialto, + millau_runtime::Runtime, + millau_runtime::WithRialtoMessagesInstance, +>; /// Rialto node as messages target. -type RialtoTargetClient = SubstrateMessagesTarget; +type RialtoTargetClient = SubstrateMessagesTarget< + Rialto, + MillauMessagesToRialto, + rialto_runtime::Runtime, + rialto_runtime::WithMillauMessagesInstance, +>; /// Run Millau-to-Rialto messages sync. pub async fn run( @@ -196,8 +206,6 @@ pub async fn run( ) .standalone_metric(StorageProofOverheadMetric::new( millau_client.clone(), - (bp_runtime::RIALTO_BRIDGE_INSTANCE, lane_id), - millau_runtime::rialto_messages::inbound_lane_data_key(&lane_id), "millau_storage_proof_overhead".into(), "Millau storage proof overhead".into(), ))? diff --git a/bridges/relays/bin-substrate/src/rialto_millau/rialto_messages_to_millau.rs b/bridges/relays/bin-substrate/src/rialto_millau/rialto_messages_to_millau.rs index b98edccdc2..3b11d998b3 100644 --- a/bridges/relays/bin-substrate/src/rialto_millau/rialto_messages_to_millau.rs +++ b/bridges/relays/bin-substrate/src/rialto_millau/rialto_messages_to_millau.rs @@ -126,10 +126,20 @@ impl SubstrateMessageLane for RialtoMessagesToMillau { } /// Rialto node as messages source. -type RialtoSourceClient = SubstrateMessagesSource; +type RialtoSourceClient = SubstrateMessagesSource< + Rialto, + RialtoMessagesToMillau, + rialto_runtime::Runtime, + rialto_runtime::WithMillauMessagesInstance, +>; /// Millau node as messages target. -type MillauTargetClient = SubstrateMessagesTarget; +type MillauTargetClient = SubstrateMessagesTarget< + Millau, + RialtoMessagesToMillau, + millau_runtime::Runtime, + millau_runtime::WithRialtoMessagesInstance, +>; /// Run Rialto-to-Millau messages sync. pub async fn run( @@ -195,8 +205,6 @@ pub async fn run( ) .standalone_metric(StorageProofOverheadMetric::new( rialto_client.clone(), - (bp_runtime::MILLAU_BRIDGE_INSTANCE, lane_id), - rialto_runtime::millau_messages::inbound_lane_data_key(&lane_id), "rialto_storage_proof_overhead".into(), "Rialto storage proof overhead".into(), ))? diff --git a/bridges/relays/client-substrate/Cargo.toml b/bridges/relays/client-substrate/Cargo.toml index e70351877c..012913d4a4 100644 --- a/bridges/relays/client-substrate/Cargo.toml +++ b/bridges/relays/client-substrate/Cargo.toml @@ -34,6 +34,7 @@ sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "master sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-std = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/bridges/relays/client-substrate/src/client.rs b/bridges/relays/client-substrate/src/client.rs index 34763e9979..ce91f4e33f 100644 --- a/bridges/relays/client-substrate/src/client.rs +++ b/bridges/relays/client-substrate/src/client.rs @@ -17,12 +17,10 @@ //! Substrate node client. use crate::chain::{Chain, ChainWithBalances}; -use crate::rpc::{Substrate, SubstrateMessages}; +use crate::rpc::Substrate; use crate::{ConnectionParams, Error, Result}; use async_std::sync::{Arc, Mutex}; -use bp_messages::{LaneId, MessageNonce}; -use bp_runtime::InstanceId; use codec::Decode; use frame_system::AccountInfo; use jsonrpsee_types::{jsonrpc::DeserializeOwned, traits::SubscriptionClient}; @@ -32,7 +30,6 @@ use pallet_balances::AccountData; use sp_core::{storage::StorageKey, Bytes}; use sp_trie::StorageProof; use sp_version::RuntimeVersion; -use std::ops::RangeInclusive; const SUB_API_GRANDPA_AUTHORITIES: &str = "GrandpaApi_grandpa_authorities"; const MAX_SUBSCRIPTION_CAPACITY: usize = 4096; @@ -175,12 +172,12 @@ impl Client { /// Return runtime version. pub async fn runtime_version(&self) -> Result { - Ok(Substrate::::runtime_version(&*self.client).await?) + Ok(Substrate::::state_runtime_version(&*self.client).await?) } /// Read value from runtime storage. pub async fn storage_value(&self, storage_key: StorageKey) -> Result> { - Substrate::::get_storage(&*self.client, storage_key) + Substrate::::state_get_storage(&*self.client, storage_key) .await? .map(|encoded_value| T::decode(&mut &encoded_value.0[..]).map_err(Error::ResponseParseFailed)) .transpose() @@ -192,7 +189,7 @@ impl Client { C: ChainWithBalances, { let storage_key = C::account_info_storage_key(&account); - let encoded_account_data = Substrate::::get_storage(&*self.client, storage_key) + let encoded_account_data = Substrate::::state_get_storage(&*self.client, storage_key) .await? .ok_or(Error::AccountDoesNotExist)?; let decoded_account_data = @@ -255,45 +252,12 @@ impl Client { .map_err(Into::into) } - /// Returns proof-of-message(s) in given inclusive range. - pub async fn prove_messages( - &self, - instance: InstanceId, - lane: LaneId, - range: RangeInclusive, - include_outbound_lane_state: bool, - at_block: C::Hash, - ) -> Result { - let encoded_trie_nodes = SubstrateMessages::::prove_messages( - &*self.client, - instance, - lane, - *range.start(), - *range.end(), - include_outbound_lane_state, - Some(at_block), - ) - .await - .map_err(Error::RpcError)?; - let decoded_trie_nodes: Vec> = - Decode::decode(&mut &encoded_trie_nodes[..]).map_err(Error::ResponseParseFailed)?; - Ok(StorageProof::new(decoded_trie_nodes)) - } - - /// Returns proof-of-message(s) delivery. - pub async fn prove_messages_delivery( - &self, - instance: InstanceId, - lane: LaneId, - at_block: C::Hash, - ) -> Result>> { - let encoded_trie_nodes = - SubstrateMessages::::prove_messages_delivery(&*self.client, instance, lane, Some(at_block)) - .await - .map_err(Error::RpcError)?; - let decoded_trie_nodes: Vec> = - Decode::decode(&mut &encoded_trie_nodes[..]).map_err(Error::ResponseParseFailed)?; - Ok(decoded_trie_nodes) + /// Returns storage proof of given storage keys. + pub async fn prove_storage(&self, keys: Vec, at_block: C::Hash) -> Result { + Substrate::::state_prove_storage(&*self.client, keys, Some(at_block)) + .await + .map(|proof| StorageProof::new(proof.proof.into_iter().map(|b| b.0).collect())) + .map_err(Into::into) } /// Return new justifications stream. diff --git a/bridges/relays/client-substrate/src/error.rs b/bridges/relays/client-substrate/src/error.rs index e1269306c3..7aee28df18 100644 --- a/bridges/relays/client-substrate/src/error.rs +++ b/bridges/relays/client-substrate/src/error.rs @@ -36,6 +36,8 @@ pub enum Error { UninitializedBridgePallet, /// Account does not exist on the chain. AccountDoesNotExist, + /// Runtime storage is missing mandatory ":code:" entry. + MissingMandatoryCodeEntry, /// The client we're connected to is not synced, so we can't rely on its state. ClientNotSynced(Health), /// An error has happened when we have tried to parse storage proof. @@ -51,6 +53,7 @@ impl std::error::Error for Error { Self::ResponseParseFailed(ref e) => Some(e), Self::UninitializedBridgePallet => None, Self::AccountDoesNotExist => None, + Self::MissingMandatoryCodeEntry => None, Self::ClientNotSynced(_) => None, Self::StorageProofError(_) => None, Self::Custom(_) => None, @@ -85,6 +88,7 @@ impl std::fmt::Display for Error { Self::ResponseParseFailed(e) => e.to_string(), Self::UninitializedBridgePallet => "The Substrate bridge pallet has not been initialized yet.".into(), Self::AccountDoesNotExist => "Account does not exist on the chain".into(), + Self::MissingMandatoryCodeEntry => "Mandatory :code: entry is missing from runtime storage".into(), Self::StorageProofError(e) => format!("Error when parsing storage proof: {:?}", e), Self::ClientNotSynced(health) => format!("Substrate client is not synced: {}", health), Self::Custom(e) => e.clone(), diff --git a/bridges/relays/client-substrate/src/metrics/storage_proof_overhead.rs b/bridges/relays/client-substrate/src/metrics/storage_proof_overhead.rs index 167f59605d..e440683f52 100644 --- a/bridges/relays/client-substrate/src/metrics/storage_proof_overhead.rs +++ b/bridges/relays/client-substrate/src/metrics/storage_proof_overhead.rs @@ -19,12 +19,10 @@ use crate::client::Client; use crate::error::Error; use async_trait::async_trait; -use bp_messages::LaneId; -use bp_runtime::InstanceId; use relay_utils::metrics::{register, Gauge, Metrics, Registry, StandaloneMetrics, U64}; use sp_core::storage::StorageKey; use sp_runtime::traits::Header as HeaderT; -use sp_trie::StorageProof; +use sp_storage::well_known_keys::CODE; use std::time::Duration; /// Storage proof overhead update interval (in blocks). @@ -32,20 +30,11 @@ const UPDATE_INTERVAL_IN_BLOCKS: u32 = 100; /// Metric that represents extra size of storage proof as unsigned integer gauge. /// -/// Regular Substrate node does not provide any RPC endpoints that return storage proofs. -/// So here we're using our own `pallet-bridge-messages-rpc` RPC API, which returns proof -/// of the inbound message lane state. Then we simply subtract size of this state from -/// the size of storage proof to compute metric value. -/// -/// There are two things to keep in mind when using this metric: -/// -/// 1) it'll only work on inbound lanes that have already accepted at least one message; -/// 2) the overhead may be slightly different for other values, but this metric gives a good estimation. +/// There's one thing to keep in mind when using this metric: the overhead may be slightly +/// different for other values, but this metric gives a good estimation. #[derive(Debug)] pub struct StorageProofOverheadMetric { client: Client, - inbound_lane: (InstanceId, LaneId), - inbound_lane_data_key: StorageKey, metric: Gauge, } @@ -53,8 +42,6 @@ impl Clone for StorageProofOverheadMetric { fn clone(&self) -> Self { StorageProofOverheadMetric { client: self.client.clone(), - inbound_lane: self.inbound_lane, - inbound_lane_data_key: self.inbound_lane_data_key.clone(), metric: self.metric.clone(), } } @@ -62,17 +49,9 @@ impl Clone for StorageProofOverheadMetric { impl StorageProofOverheadMetric { /// Create new metric instance with given name and help. - pub fn new( - client: Client, - inbound_lane: (InstanceId, LaneId), - inbound_lane_data_key: StorageKey, - name: String, - help: String, - ) -> Self { + pub fn new(client: Client, name: String, help: String) -> Self { StorageProofOverheadMetric { client, - inbound_lane, - inbound_lane_data_key, metric: Gauge::new(name, help).expect( "only fails if gauge options are customized;\ we use default options;\ @@ -82,32 +61,27 @@ impl StorageProofOverheadMetric { } /// Returns approximate storage proof size overhead. - /// - /// Returs `Ok(None)` if inbound lane we're watching for has no state. This shouldn't be treated as error. - async fn compute_storage_proof_overhead(&self) -> Result, Error> { + async fn compute_storage_proof_overhead(&self) -> Result { let best_header_hash = self.client.best_finalized_header_hash().await?; let best_header = self.client.header_by_hash(best_header_hash).await?; let storage_proof = self .client - .prove_messages_delivery(self.inbound_lane.0, self.inbound_lane.1, best_header_hash) + .prove_storage(vec![StorageKey(CODE.to_vec())], best_header_hash) .await?; - let storage_proof_size: usize = storage_proof.iter().map(|n| n.len()).sum(); + let storage_proof_size: usize = storage_proof.clone().iter_nodes().map(|n| n.len()).sum(); - let storage_value_reader = bp_runtime::StorageProofChecker::::new( - *best_header.state_root(), - StorageProof::new(storage_proof), - ) - .map_err(Error::StorageProofError)?; + let storage_value_reader = + bp_runtime::StorageProofChecker::::new(*best_header.state_root(), storage_proof) + .map_err(Error::StorageProofError)?; let maybe_encoded_storage_value = storage_value_reader - .read_value(&self.inbound_lane_data_key.0) + .read_value(CODE) .map_err(Error::StorageProofError)?; - let encoded_storage_value_size = match maybe_encoded_storage_value { - Some(encoded_storage_value) => encoded_storage_value.len(), - None => return Ok(None), - }; + let encoded_storage_value_size = maybe_encoded_storage_value + .ok_or(Error::MissingMandatoryCodeEntry)? + .len(); - Ok(Some(storage_proof_size - encoded_storage_value_size)) + Ok(storage_proof_size - encoded_storage_value_size) } } @@ -129,7 +103,7 @@ impl StandaloneMetrics for StorageProofOverheadMetric { &self.metric, self.compute_storage_proof_overhead() .await - .map(|v| v.map(|overhead| overhead as u64)), + .map(|overhead| Some(overhead as u64)), ); } } diff --git a/bridges/relays/client-substrate/src/rpc.rs b/bridges/relays/client-substrate/src/rpc.rs index 1816e8cd3f..06df1f705d 100644 --- a/bridges/relays/client-substrate/src/rpc.rs +++ b/bridges/relays/client-substrate/src/rpc.rs @@ -18,9 +18,7 @@ use crate::chain::Chain; -use bp_messages::{LaneId, MessageNonce}; -use bp_runtime::InstanceId; -use sc_rpc_api::system::Health; +use sc_rpc_api::{state::ReadProof, system::Health}; use sp_core::{ storage::{StorageData, StorageKey}, Bytes, @@ -46,27 +44,10 @@ jsonrpsee_proc_macros::rpc_client_api! { #[rpc(method = "state_call", positional_params)] fn state_call(method: String, data: Bytes, at_block: Option) -> Bytes; #[rpc(method = "state_getStorage", positional_params)] - fn get_storage(key: StorageKey) -> Option; + fn state_get_storage(key: StorageKey) -> Option; + #[rpc(method = "state_getReadProof", positional_params)] + fn state_prove_storage(keys: Vec, hash: Option) -> ReadProof; #[rpc(method = "state_getRuntimeVersion", positional_params)] - fn runtime_version() -> RuntimeVersion; - } - - pub(crate) SubstrateMessages { - #[rpc(method = "messages_proveMessages", positional_params)] - fn prove_messages( - instance: InstanceId, - lane: LaneId, - begin: MessageNonce, - end: MessageNonce, - include_outbound_lane_state: bool, - block: Option, - ) -> Bytes; - - #[rpc(method = "messages_proveMessagesDelivery", positional_params)] - fn prove_messages_delivery( - instance: InstanceId, - lane: LaneId, - block: Option, - ) -> Bytes; + fn state_runtime_version() -> RuntimeVersion; } }