diff --git a/bridges/bin/millau/node/Cargo.toml b/bridges/bin/millau/node/Cargo.toml
index 149731529f782..1696f73a48173 100644
--- a/bridges/bin/millau/node/Cargo.toml
+++ b/bridges/bin/millau/node/Cargo.toml
@@ -16,7 +16,7 @@ structopt = "0.3.21"
# Bridge dependencies
bp-message-lane = { path = "../../../primitives/message-lane" }
-bp-rialto = { path = "../../../primitives/rialto" }
+bp-millau= { path = "../../../primitives/millau" }
bp-runtime = { path = "../../../primitives/runtime" }
millau-runtime = { path = "../runtime" }
pallet-message-lane-rpc = { path = "../../../modules/message-lane/rpc" }
diff --git a/bridges/bin/millau/node/src/chain_spec.rs b/bridges/bin/millau/node/src/chain_spec.rs
index 8c7c40472751b..2ead8612fac21 100644
--- a/bridges/bin/millau/node/src/chain_spec.rs
+++ b/bridges/bin/millau/node/src/chain_spec.rs
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see .
+use bp_millau::derive_account_from_rialto_id;
use millau_runtime::{
AccountId, AuraConfig, BalancesConfig, BridgeRialtoConfig, GenesisConfig, GrandpaConfig, SessionConfig,
SessionKeys, Signature, SudoConfig, SystemConfig, WASM_BINARY,
@@ -121,6 +122,9 @@ impl Alternative {
get_account_id_from_seed::("Ferdie//stash"),
get_account_id_from_seed::("George//stash"),
get_account_id_from_seed::("Harry//stash"),
+ derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
+ get_account_id_from_seed::("Dave"),
+ )),
],
true,
)
@@ -173,3 +177,13 @@ fn testnet_genesis(
}),
}
}
+
+#[test]
+fn derived_dave_account_is_as_expected() {
+ let dave = get_account_id_from_seed::("Dave");
+ let derived: AccountId = derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(dave));
+ assert_eq!(
+ derived.to_string(),
+ "5G81vRqUUysQGtN5aEThD5UsLdt4rZWSbVLkjuZzLHadp8ZD".to_string()
+ );
+}
diff --git a/bridges/bin/rialto/node/src/chain_spec.rs b/bridges/bin/rialto/node/src/chain_spec.rs
index 229fbd1cc90ef..dc2a9afea6135 100644
--- a/bridges/bin/rialto/node/src/chain_spec.rs
+++ b/bridges/bin/rialto/node/src/chain_spec.rs
@@ -122,7 +122,6 @@ impl Alternative {
get_account_id_from_seed::("Ferdie//stash"),
get_account_id_from_seed::("George//stash"),
get_account_id_from_seed::("Harry//stash"),
- derive_account_from_millau_id(bp_runtime::SourceAccount::Root),
derive_account_from_millau_id(bp_runtime::SourceAccount::Account(
get_account_id_from_seed::("Dave"),
)),
@@ -206,12 +205,3 @@ fn derived_dave_account_is_as_expected() {
"5Hg7WQyk8C1FmPzxY3xSjR7S6zZZC5sAL35vMr6NpW17jBhQ".to_string()
);
}
-
-#[test]
-fn derived_root_account_is_as_expected() {
- let root: AccountId = derive_account_from_millau_id(bp_runtime::SourceAccount::Root);
- assert_eq!(
- root.to_string(),
- "5HYYwXQvxhgdcBYs6kzqfK1HW6M3UF3Kh4YM7j288yiqbhnt".to_string()
- );
-}
diff --git a/bridges/modules/message-lane/src/instant_payments.rs b/bridges/modules/message-lane/src/instant_payments.rs
index fe860fdb3f8ac..41f8b48b74749 100644
--- a/bridges/modules/message-lane/src/instant_payments.rs
+++ b/bridges/modules/message-lane/src/instant_payments.rs
@@ -46,9 +46,11 @@ where
Currency::transfer(submitter, relayer_fund_account, *fee, ExistenceRequirement::AllowDeath)
.map_err(Into::into)
}
- Sender::Root | Sender::None => {
- // fixme: we might want to add root account id to this struct.
- Err("Root and None account is not allowed to send regular messages.")
+ Sender::Root => {
+ Err("Sending messages from Root account is not supported yet. See GitHub issue #559 for more.")
+ }
+ Sender::None => {
+ Err("Sending messages from None account is not supported yet. See GitHub issue #559 for more.")
}
}
}
diff --git a/bridges/primitives/millau/src/lib.rs b/bridges/primitives/millau/src/lib.rs
index 5b74ec54c1318..8642b04cf0d43 100644
--- a/bridges/primitives/millau/src/lib.rs
+++ b/bridges/primitives/millau/src/lib.rs
@@ -29,6 +29,7 @@ use frame_support::{
RuntimeDebug,
};
use sp_core::Hasher as HasherT;
+use sp_runtime::traits::Convert;
use sp_runtime::{
traits::{IdentifyAccount, Verify},
MultiSignature, MultiSigner, Perbill,
@@ -161,6 +162,19 @@ impl sp_runtime::traits::Convert for AccountIdConverte
}
}
+/// We use this to get the account on Millau (target) which is derived from Rialto's (source)
+/// account. We do this so we can fund the derived account on Millau at Genesis to it can pay
+/// transaction fees.
+///
+/// The reason we can use the same `AccountId` type for both chains is because they share the same
+/// development seed phrase.
+///
+/// Note that this should only be used for testing.
+pub fn derive_account_from_rialto_id(id: bp_runtime::SourceAccount) -> AccountId {
+ let encoded_id = bp_runtime::derive_account_id(bp_runtime::RIALTO_BRIDGE_INSTANCE, id);
+ AccountIdConverter::convert(encoded_id)
+}
+
/// Get a struct which defines the weight limits and values used during extrinsic execution.
pub fn runtime_block_weights() -> frame_system::limits::BlockWeights {
frame_system::limits::BlockWeights::builder()
diff --git a/bridges/primitives/rialto/src/lib.rs b/bridges/primitives/rialto/src/lib.rs
index 26599786c2d45..71f0329afc37d 100644
--- a/bridges/primitives/rialto/src/lib.rs
+++ b/bridges/primitives/rialto/src/lib.rs
@@ -132,7 +132,7 @@ impl Convert for AccountIdConverter {
//
// Note that this should only be used for testing.
pub fn derive_account_from_millau_id(id: bp_runtime::SourceAccount) -> AccountId {
- let encoded_id = bp_runtime::derive_account_id(*b"mlau", id);
+ let encoded_id = bp_runtime::derive_account_id(bp_runtime::MILLAU_BRIDGE_INSTANCE, id);
AccountIdConverter::convert(encoded_id)
}
diff --git a/bridges/relays/substrate/src/cli.rs b/bridges/relays/substrate/src/cli.rs
index d3662ba26840e..0e7f92001a355 100644
--- a/bridges/relays/substrate/src/cli.rs
+++ b/bridges/relays/substrate/src/cli.rs
@@ -138,12 +138,15 @@ pub enum Command {
/// 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,
+ /// Message type.
+ #[structopt(subcommand)]
+ message: ToMillauMessage,
+ /// The origin to use when dispatching the message on the target chain.
+ #[structopt(long, possible_values = &Origins::variants())]
+ origin: Origins,
},
}
@@ -161,19 +164,24 @@ pub enum ToRialtoMessage {
},
}
-arg_enum! {
- #[derive(Debug)]
- /// All possible messages that may be delivered to the Millau chain.
- pub enum ToMillauMessage {
- Remark,
- }
+/// All possible messages that may be delivered to the Millau chain.
+#[derive(StructOpt, Debug)]
+pub enum ToMillauMessage {
+ /// Make an on-chain remark (comment).
+ Remark,
+ /// Transfer the specified `amount` of native tokens to a particular `recipient`.
+ Transfer {
+ #[structopt(long)]
+ recipient: bp_millau::AccountId,
+ #[structopt(long)]
+ amount: bp_millau::Balance,
+ },
}
arg_enum! {
#[derive(Debug)]
/// The origin to use when dispatching the message on the target chain.
pub enum Origins {
- Root,
Target,
Source,
}
diff --git a/bridges/relays/substrate/src/main.rs b/bridges/relays/substrate/src/main.rs
index 789105a27b18a..a63dc9623ed16 100644
--- a/bridges/relays/substrate/src/main.rs
+++ b/bridges/relays/substrate/src/main.rs
@@ -97,7 +97,7 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
&rialto_client,
&rialto_sign.signer,
rialto_signer_next_index,
- millau_runtime::SudoCall::sudo(Box::new(
+ rialto_runtime::SudoCall::sudo(Box::new(
rialto_runtime::BridgeMillauCall::initialize(initialization_data).into(),
))
.into(),
@@ -290,12 +290,6 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
let rialto_origin_public = rialto_sign.signer.public();
let payload = match origin {
- cli::Origins::Root => MessagePayload {
- spec_version: rialto_runtime::VERSION.spec_version,
- weight: rialto_call_weight,
- origin: CallOrigin::SourceRoot,
- call: rialto_call.encode(),
- },
cli::Origins::Source => MessagePayload {
spec_version: rialto_runtime::VERSION.spec_version,
weight: rialto_call_weight,
@@ -312,7 +306,7 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
spec_version: rialto_runtime::VERSION.spec_version,
weight: rialto_call_weight,
origin: CallOrigin::TargetAccount(
- millau_account_id.clone(),
+ millau_account_id,
rialto_origin_public.into(),
rialto_origin_signature.into(),
),
@@ -383,6 +377,8 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
lane,
message,
fee,
+ origin,
+ ..
} => {
let rialto_client = RialtoClient::new(ConnectionParams {
host: rialto.rialto_host,
@@ -412,21 +408,29 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
.as_bytes()
.to_vec(),
)),
+ cli::ToMillauMessage::Transfer { recipient, amount } => {
+ millau_runtime::Call::Balances(millau_runtime::BalancesCall::transfer(recipient, amount))
+ }
};
- let millau_call_weight = millau_call.get_dispatch_info().weight;
+ let millau_call_weight = millau_call.get_dispatch_info().weight;
let rialto_sender_public: bp_rialto::AccountSigner = rialto_sign.signer.public().clone().into();
let rialto_account_id: bp_rialto::AccountId = rialto_sender_public.into_account();
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_account_id.encode_to(&mut millau_origin_signature_message);
- let millau_origin_signature = millau_sign.signer.sign(&millau_origin_signature_message);
+ let payload = match origin {
+ cli::Origins::Source => MessagePayload {
+ spec_version: millau_runtime::VERSION.spec_version,
+ weight: millau_call_weight,
+ origin: CallOrigin::SourceAccount(rialto_account_id),
+ call: millau_call.encode(),
+ },
+ cli::Origins::Target => {
+ let mut millau_origin_signature_message = Vec::new();
+ millau_call.encode_to(&mut millau_origin_signature_message);
+ rialto_account_id.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,
@@ -436,9 +440,13 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
millau_origin_signature.into(),
),
call: millau_call.encode(),
- },
- fee,
- ));
+ }
+ }
+ };
+
+ let rialto_call = rialto_runtime::Call::BridgeMillauMessageLane(
+ rialto_runtime::MessageLaneCall::send_message(lane.into(), payload, fee),
+ );
let signed_rialto_call = Rialto::sign_transaction(
&rialto_client,