Skip to content

Commit

Permalink
Ability to send messages from Rialto to Millau (paritytech#525)
Browse files Browse the repository at this point in the history
* relay Rialto messages to Millau

* impl SubmitRialtoToMillauMessage

* fmt
  • Loading branch information
svyatonik authored and serban300 committed Apr 9, 2024
1 parent d11c3f2 commit 76fc573
Show file tree
Hide file tree
Showing 7 changed files with 378 additions and 62 deletions.
1 change: 1 addition & 0 deletions bridges/bin/millau/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub use frame_support::{
StorageValue,
};

pub use frame_system::Call as SystemCall;
pub use pallet_balances::Call as BalancesCall;
pub use pallet_message_lane::Call as MessageLaneCall;
pub use pallet_substrate_bridge::Call as BridgeRialtoCall;
Expand Down
42 changes: 42 additions & 0 deletions bridges/relays/substrate/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,40 @@ pub enum Command {
#[structopt(long)]
fee: bp_millau::Balance,
},
/// Serve given lane of Rialto -> Millau messages.
RialtoMessagesToMillau {
#[structopt(flatten)]
rialto: RialtoConnectionParams,
#[structopt(flatten)]
rialto_sign: RialtoSigningParams,
#[structopt(flatten)]
millau: MillauConnectionParams,
#[structopt(flatten)]
millau_sign: MillauSigningParams,
#[structopt(flatten)]
prometheus_params: PrometheusParams,
/// Hex-encoded id of lane that should be served by relay.
#[structopt(long)]
lane: HexLaneId,
},
/// Submit message to given Rialto -> Millau lane.
SubmitRialtoToMillauMessage {
#[structopt(flatten)]
rialto: RialtoConnectionParams,
#[structopt(flatten)]
rialto_sign: RialtoSigningParams,
#[structopt(flatten)]
millau_sign: MillauSigningParams,
/// Hex-encoded lane id.
#[structopt(long)]
lane: HexLaneId,
/// Message type.
#[structopt(long, possible_values = &ToMillauMessage::variants())]
message: ToMillauMessage,
/// Delivery and dispatch fee.
#[structopt(long)]
fee: bp_rialto::Balance,
},
}

arg_enum! {
Expand All @@ -118,6 +152,14 @@ arg_enum! {
}
}

arg_enum! {
#[derive(Debug)]
/// All possible messages that may be delivered to the Millau chain.
pub enum ToMillauMessage {
Remark,
}
}

/// Lane id.
#[derive(Debug)]
pub struct HexLaneId(LaneId);
Expand Down
117 changes: 116 additions & 1 deletion bridges/relays/substrate/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ mod messages_target;
mod millau_headers_to_rialto;
mod millau_messages_to_rialto;
mod rialto_headers_to_millau;
mod rialto_messages_to_millau;

fn main() {
initialize_relay();
Expand Down Expand Up @@ -287,7 +288,7 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
millau_runtime::Call::BridgeRialtoMessageLane(millau_runtime::MessageLaneCall::send_message(
lane.into(),
MessagePayload {
spec_version: millau_runtime::VERSION.spec_version,
spec_version: rialto_runtime::VERSION.spec_version,
weight: rialto_call_weight,
origin: CallOrigin::RealAccount(
millau_sender_public,
Expand All @@ -312,6 +313,120 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
.submit_extrinsic(Bytes(signed_millau_call.encode()))
.await?;
}
cli::Command::RialtoMessagesToMillau {
rialto,
rialto_sign,
millau,
millau_sign,
prometheus_params,
lane,
} => {
let rialto_client = RialtoClient::new(ConnectionParams {
host: rialto.rialto_host,
port: rialto.rialto_port,
})
.await?;
let rialto_sign = RialtoSigningParams::from_suri(
&rialto_sign.rialto_signer,
rialto_sign.rialto_signer_password.as_deref(),
)
.map_err(|e| format!("Failed to parse rialto-signer: {:?}", e))?;
let millau_client = MillauClient::new(ConnectionParams {
host: millau.millau_host,
port: millau.millau_port,
})
.await?;
let millau_sign = MillauSigningParams::from_suri(
&millau_sign.millau_signer,
millau_sign.millau_signer_password.as_deref(),
)
.map_err(|e| format!("Failed to parse millau-signer: {:?}", e))?;

rialto_messages_to_millau::run(
rialto_client,
rialto_sign,
millau_client,
millau_sign,
lane.into(),
prometheus_params.into(),
);
}
cli::Command::SubmitRialtoToMillauMessage {
rialto,
rialto_sign,
millau_sign,
lane,
message,
fee,
} => {
let rialto_client = RialtoClient::new(ConnectionParams {
host: rialto.rialto_host,
port: rialto.rialto_port,
})
.await?;
let rialto_sign = RialtoSigningParams::from_suri(
&rialto_sign.rialto_signer,
rialto_sign.rialto_signer_password.as_deref(),
)
.map_err(|e| format!("Failed to parse rialto-signer: {:?}", e))?;
let millau_sign = MillauSigningParams::from_suri(
&millau_sign.millau_signer,
millau_sign.millau_signer_password.as_deref(),
)
.map_err(|e| format!("Failed to parse millau-signer: {:?}", e))?;

let millau_call = match message {
cli::ToMillauMessage::Remark => millau_runtime::Call::System(millau_runtime::SystemCall::remark(
format!(
"Unix time: {}",
std::time::SystemTime::now()
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.unwrap_or_default()
.as_secs(),
)
.as_bytes()
.to_vec(),
)),
};
let millau_call_weight = millau_call.get_dispatch_info().weight;

let rialto_sender_public: bp_rialto::AccountSigner = rialto_sign.signer.public().clone().into();
let millau_origin_public = millau_sign.signer.public();

let mut millau_origin_signature_message = Vec::new();
millau_call.encode_to(&mut millau_origin_signature_message);
rialto_sender_public.encode_to(&mut millau_origin_signature_message);
let millau_origin_signature = millau_sign.signer.sign(&millau_origin_signature_message);

let rialto_call =
rialto_runtime::Call::BridgeMillauMessageLane(rialto_runtime::MessageLaneCall::send_message(
lane.into(),
MessagePayload {
spec_version: millau_runtime::VERSION.spec_version,
weight: millau_call_weight,
origin: CallOrigin::RealAccount(
rialto_sender_public,
millau_origin_public.into(),
millau_origin_signature.into(),
),
call: millau_call.encode(),
},
fee,
));

let signed_rialto_call = Rialto::sign_transaction(
&rialto_client,
&rialto_sign.signer,
rialto_client
.next_account_index(rialto_sign.signer.public().clone().into())
.await?,
rialto_call,
);

rialto_client
.submit_extrinsic(Bytes(signed_rialto_call.encode()))
.await?;
}
}

Ok(())
Expand Down
56 changes: 55 additions & 1 deletion bridges/relays/substrate/src/messages_lane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@
// 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/>.

use crate::messages_source::SubstrateMessagesProof;
use crate::messages_target::SubstrateMessagesReceivingProof;

use async_trait::async_trait;
use bp_message_lane::MessageNonce;
use codec::Encode;
use messages_relay::message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf};
use relay_substrate_client::Error as SubstrateError;
use relay_substrate_client::{BlockNumberOf, Chain, Client, Error as SubstrateError, HashOf};
use relay_utils::BlockNumberBase;
use std::ops::RangeInclusive;

/// Message sync pipeline for Substrate <-> Substrate relays.
Expand Down Expand Up @@ -61,3 +65,53 @@ pub trait SubstrateMessageLane: MessageLane {
proof: Self::MessagesReceivingProof,
) -> Result<Self::SourceSignedTransaction, SubstrateError>;
}

/// Substrate-to-Substrate message lane.
#[derive(Debug)]
pub struct SubstrateMessageLaneToSubstrate<Source: Chain, SourceSignParams, Target: Chain, TargetSignParams> {
/// Client for the source Substrate chain.
pub(crate) source_client: Client<Source>,
/// Parameters required to sign transactions for source chain.
pub(crate) source_sign: SourceSignParams,
/// Client for the target Substrate chain.
pub(crate) target_client: Client<Target>,
/// Parameters required to sign transactions for target chain.
pub(crate) target_sign: TargetSignParams,
/// Account id of relayer at the source chain.
pub(crate) relayer_id_at_source: Source::AccountId,
}

impl<Source: Chain, SourceSignParams: Clone, Target: Chain, TargetSignParams: Clone> Clone
for SubstrateMessageLaneToSubstrate<Source, SourceSignParams, Target, TargetSignParams>
{
fn clone(&self) -> Self {
Self {
source_client: self.source_client.clone(),
source_sign: self.source_sign.clone(),
target_client: self.target_client.clone(),
target_sign: self.target_sign.clone(),
relayer_id_at_source: self.relayer_id_at_source.clone(),
}
}
}

impl<Source: Chain, SourceSignParams, Target: Chain, TargetSignParams> MessageLane
for SubstrateMessageLaneToSubstrate<Source, SourceSignParams, Target, TargetSignParams>
where
SourceSignParams: Clone + Send + Sync + 'static,
TargetSignParams: Clone + Send + Sync + 'static,
BlockNumberOf<Source>: BlockNumberBase,
BlockNumberOf<Target>: BlockNumberBase,
{
const SOURCE_NAME: &'static str = Source::NAME;
const TARGET_NAME: &'static str = Target::NAME;

type MessagesProof = SubstrateMessagesProof<Source>;
type MessagesReceivingProof = SubstrateMessagesReceivingProof<Target>;

type SourceHeaderNumber = BlockNumberOf<Source>;
type SourceHeaderHash = HashOf<Source>;

type TargetHeaderNumber = BlockNumberOf<Target>;
type TargetHeaderHash = HashOf<Target>;
}
5 changes: 4 additions & 1 deletion bridges/relays/substrate/src/messages_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ use sp_runtime::{traits::Header as HeaderT, DeserializeOwned};
use sp_trie::StorageProof;
use std::ops::RangeInclusive;

/// Message receiving proof returned by the target Substrate node.
pub type SubstrateMessagesReceivingProof<C> = (HashOf<C>, StorageProof, LaneId);

/// Substrate client as Substrate messages target.
pub struct SubstrateMessagesTarget<C: Chain, P> {
client: Client<C>,
Expand Down Expand Up @@ -75,7 +78,7 @@ where
C::Index: DeserializeOwned,
<C::Header as HeaderT>::Number: BlockNumberBase,
P: SubstrateMessageLane<
MessagesReceivingProof = (HashOf<C>, StorageProof, LaneId),
MessagesReceivingProof = SubstrateMessagesReceivingProof<C>,
TargetHeaderNumber = <C::Header as HeaderT>::Number,
TargetHeaderHash = <C::Header as HeaderT>::Hash,
>,
Expand Down
Loading

0 comments on commit 76fc573

Please sign in to comment.