mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-06 21:58:06 +00:00
Verify messages proofs (#480)
* verify messages proofs * fmt * clippy * grumbles
This commit is contained in:
committed by
Bastian Köcher
parent
3d24a4e34e
commit
20fea45d1f
@@ -184,8 +184,8 @@ impl SourceHeaderChain<bp_rialto::Balance> for Rialto {
|
||||
type MessagesProof = FromRialtoMessagesProof;
|
||||
|
||||
fn verify_messages_proof(
|
||||
_proof: Self::MessagesProof,
|
||||
proof: Self::MessagesProof,
|
||||
) -> Result<ProvedMessages<Message<bp_rialto::Balance>>, Self::Error> {
|
||||
unimplemented!("https://github.com/paritytech/parity-bridges-common/issues/397")
|
||||
messages::target::verify_messages_proof::<WithRialtoMessageBridge, Runtime>(proof)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,8 +184,8 @@ impl SourceHeaderChain<bp_millau::Balance> for Millau {
|
||||
type MessagesProof = FromMillauMessagesProof;
|
||||
|
||||
fn verify_messages_proof(
|
||||
_proof: Self::MessagesProof,
|
||||
proof: Self::MessagesProof,
|
||||
) -> Result<ProvedMessages<Message<bp_millau::Balance>>, Self::Error> {
|
||||
unimplemented!("https://github.com/paritytech/parity-bridges-common/issues/397")
|
||||
messages::target::verify_messages_proof::<WithMillauMessageBridge, Runtime>(proof)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
use bp_message_dispatch::MessageDispatch as _;
|
||||
use bp_message_lane::{
|
||||
source_chain::LaneMessageVerifier,
|
||||
target_chain::{DispatchMessage, MessageDispatch},
|
||||
InboundLaneData, LaneId, MessageNonce,
|
||||
target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages},
|
||||
InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce, OutboundLaneData,
|
||||
};
|
||||
use bp_runtime::InstanceId;
|
||||
use codec::{Compact, Decode, Input};
|
||||
@@ -90,7 +90,7 @@ pub trait ChainWithMessageLanes {
|
||||
/// different weights.
|
||||
type Weight: From<frame_support::weights::Weight>;
|
||||
/// Type of balances that is used on the chain.
|
||||
type Balance: CheckedAdd + CheckedDiv + CheckedMul + PartialOrd + From<u32> + Copy;
|
||||
type Balance: Decode + CheckedAdd + CheckedDiv + CheckedMul + PartialOrd + From<u32> + Copy;
|
||||
|
||||
/// Instance of the message-lane pallet.
|
||||
type MessageLaneInstance: Instance;
|
||||
@@ -333,6 +333,76 @@ pub mod target {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify proof of Bridged -> This chain messages.
|
||||
pub fn verify_messages_proof<B: MessageBridge, ThisRuntime>(
|
||||
proof: FromBridgedChainMessagesProof<B>,
|
||||
) -> Result<ProvedMessages<Message<BalanceOf<BridgedChain<B>>>>, &'static str>
|
||||
where
|
||||
ThisRuntime: pallet_substrate_bridge::Trait,
|
||||
ThisRuntime: pallet_message_lane::Trait<MessageLaneInstanceOf<BridgedChain<B>>>,
|
||||
HashOf<BridgedChain<B>>:
|
||||
Into<bp_runtime::HashOf<<ThisRuntime as pallet_substrate_bridge::Trait>::BridgedChain>>,
|
||||
{
|
||||
let (bridged_header_hash, bridged_storage_proof, lane_id, begin, end) = proof;
|
||||
pallet_substrate_bridge::Module::<ThisRuntime>::parse_finalized_storage_proof(
|
||||
bridged_header_hash.into(),
|
||||
bridged_storage_proof,
|
||||
|storage| {
|
||||
// Read messages first. All messages that are claimed to be in the proof must
|
||||
// be in the proof. So any error in `read_value`, or even missing value is fatal.
|
||||
//
|
||||
// Mind that we allow proofs with no messages if outbound lane state is proved.
|
||||
let mut messages = Vec::with_capacity(end.saturating_sub(begin) as _);
|
||||
for nonce in begin..=end {
|
||||
let message_key = MessageKey { lane_id, nonce };
|
||||
let storage_message_key = pallet_message_lane::storage_keys::message_key::<
|
||||
ThisRuntime,
|
||||
MessageLaneInstanceOf<BridgedChain<B>>,
|
||||
>(&lane_id, nonce);
|
||||
let raw_message_data = storage
|
||||
.read_value(storage_message_key.0.as_ref())
|
||||
.map_err(|_| "Failed to read message from storage proof")?
|
||||
.ok_or("Message is missing from the messages proof")?;
|
||||
let message_data = MessageData::<BalanceOf<BridgedChain<B>>>::decode(&mut &raw_message_data[..])
|
||||
.map_err(|_| "Failed to decode message from the proof")?;
|
||||
messages.push(Message {
|
||||
key: message_key,
|
||||
data: message_data,
|
||||
});
|
||||
}
|
||||
|
||||
// Now let's check if proof contains outbound lane state proof. It is optional, so we
|
||||
// simply ignore `read_value` errors and missing value.
|
||||
let mut proved_lane_messages = ProvedLaneMessages {
|
||||
lane_state: None,
|
||||
messages,
|
||||
};
|
||||
let storage_outbound_lane_data_key = pallet_message_lane::storage_keys::outbound_lane_data_key::<
|
||||
MessageLaneInstanceOf<BridgedChain<B>>,
|
||||
>(&lane_id);
|
||||
let raw_outbound_lane_data = storage.read_value(storage_outbound_lane_data_key.0.as_ref());
|
||||
if let Ok(Some(raw_outbound_lane_data)) = raw_outbound_lane_data {
|
||||
proved_lane_messages.lane_state = Some(
|
||||
OutboundLaneData::decode(&mut &raw_outbound_lane_data[..])
|
||||
.map_err(|_| "Failed to decode outbound lane data from the proof")?,
|
||||
);
|
||||
}
|
||||
|
||||
// Now we may actually check if the proof is empty or not.
|
||||
if proved_lane_messages.lane_state.is_none() && proved_lane_messages.messages.is_empty() {
|
||||
return Err("Messages proof is empty");
|
||||
}
|
||||
|
||||
// We only support single lane messages in this schema
|
||||
let mut proved_messages = ProvedMessages::new();
|
||||
proved_messages.insert(lane_id, proved_lane_messages);
|
||||
|
||||
Ok(proved_messages)
|
||||
},
|
||||
)
|
||||
.map_err(<&'static str>::from)?
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user