referrerpolicy=no-referrer-when-downgrade
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright (C) 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 <http://www.gnu.org/licenses/>.

//! Primitives of messages module, that are used on the source chain.

use crate::{MessageNonce, UnrewardedRelayer};

use bp_runtime::{raw_storage_proof_size, RawStorageProof, Size};
use codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_core::RuntimeDebug;
use sp_std::{
	collections::{btree_map::BTreeMap, vec_deque::VecDeque},
	fmt::Debug,
	ops::RangeInclusive,
};

/// Messages delivery proof from the bridged chain.
///
/// It contains everything required to prove that our (this chain) messages have been
/// delivered to the bridged (target) chain:
///
/// - hash of finalized header;
///
/// - storage proof of the inbound lane state;
///
/// - lane id.
#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)]
pub struct FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash, LaneId> {
	/// Hash of the bridge header the proof is for.
	pub bridged_header_hash: BridgedHeaderHash,
	/// Storage trie proof generated for [`Self::bridged_header_hash`].
	pub storage_proof: RawStorageProof,
	/// Lane id of which messages were delivered and the proof is for.
	pub lane: LaneId,
}

impl<BridgedHeaderHash, LaneId> Size
	for FromBridgedChainMessagesDeliveryProof<BridgedHeaderHash, LaneId>
{
	fn size(&self) -> u32 {
		use frame_support::sp_runtime::SaturatedConversion;
		raw_storage_proof_size(&self.storage_proof).saturated_into()
	}
}

/// Number of messages, delivered by relayers.
pub type RelayersRewards<AccountId> = BTreeMap<AccountId, MessageNonce>;

/// Manages payments that are happening at the source chain during delivery confirmation
/// transaction.
pub trait DeliveryConfirmationPayments<AccountId, LaneId> {
	/// Error type.
	type Error: Debug + Into<&'static str>;

	/// Pay rewards for delivering messages to the given relayers.
	///
	/// The implementation may also choose to pay reward to the `confirmation_relayer`, which is
	/// a relayer that has submitted delivery confirmation transaction.
	///
	/// Returns number of actually rewarded relayers.
	fn pay_reward(
		lane_id: LaneId,
		messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
		confirmation_relayer: &AccountId,
		received_range: &RangeInclusive<MessageNonce>,
	) -> MessageNonce;
}

impl<AccountId, LaneId> DeliveryConfirmationPayments<AccountId, LaneId> for () {
	type Error = &'static str;

	fn pay_reward(
		_lane_id: LaneId,
		_messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
		_confirmation_relayer: &AccountId,
		_received_range: &RangeInclusive<MessageNonce>,
	) -> MessageNonce {
		// this implementation is not rewarding relayers at all
		0
	}
}

/// Callback that is called at the source chain (bridge hub) when we get delivery confirmation
/// for new messages.
pub trait OnMessagesDelivered<LaneId> {
	/// New messages delivery has been confirmed.
	///
	/// The only argument of the function is the number of yet undelivered messages
	fn on_messages_delivered(lane: LaneId, enqueued_messages: MessageNonce);
}

impl<LaneId> OnMessagesDelivered<LaneId> for () {
	fn on_messages_delivered(_lane: LaneId, _enqueued_messages: MessageNonce) {}
}

/// Send message artifacts.
#[derive(Eq, RuntimeDebug, PartialEq)]
pub struct SendMessageArtifacts {
	/// Nonce of the message.
	pub nonce: MessageNonce,
	/// Number of enqueued messages at the lane, after the message is sent.
	pub enqueued_messages: MessageNonce,
}

/// Messages bridge API to be used from other pallets.
pub trait MessagesBridge<Payload, LaneId> {
	/// Error type.
	type Error: Debug;

	/// Intermediary structure returned by `validate_message()`.
	///
	/// It can than be passed to `send_message()` in order to actually send the message
	/// on the bridge.
	type SendMessageArgs;

	/// Check if the message can be sent over the bridge.
	fn validate_message(
		lane: LaneId,
		message: &Payload,
	) -> Result<Self::SendMessageArgs, Self::Error>;

	/// Send message over the bridge.
	///
	/// Returns unique message nonce or error if send has failed.
	fn send_message(message: Self::SendMessageArgs) -> SendMessageArtifacts;
}

/// Structure that may be used in place `MessageDeliveryAndDispatchPayment` on chains,
/// where outbound messages are forbidden.
pub struct ForbidOutboundMessages;

impl<AccountId, LaneId> DeliveryConfirmationPayments<AccountId, LaneId> for ForbidOutboundMessages {
	type Error = &'static str;

	fn pay_reward(
		_lane_id: LaneId,
		_messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
		_confirmation_relayer: &AccountId,
		_received_range: &RangeInclusive<MessageNonce>,
	) -> MessageNonce {
		0
	}
}