1414// You should have received a copy of the GNU General Public License
1515// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
1616
17+ use anyhow:: anyhow;
18+ use bp_message_dispatch:: { CallOrigin , MessagePayload } ;
19+ use bp_runtime:: EncodedOrDecodedCall ;
1720use codec:: Decode ;
1821use frame_support:: weights:: { DispatchClass , DispatchInfo , Pays , Weight } ;
1922use relay_kusama_client:: Kusama ;
2023use sp_version:: RuntimeVersion ;
2124
2225use crate :: cli:: {
2326 bridge,
24- encode_call:: { Call , CliEncodeCall } ,
25- encode_message, CliChain ,
27+ encode_call:: { self , Call , CliEncodeCall } ,
28+ encode_message,
29+ send_message:: { self , DispatchFeePayment } ,
30+ CliChain ,
2631} ;
2732
2833/// Weight of the `system::remark` call at Kusama.
@@ -32,13 +37,15 @@ use crate::cli::{
3237pub ( crate ) const SYSTEM_REMARK_CALL_WEIGHT : Weight = 2 * 1_345_000 ;
3338
3439impl CliEncodeCall for Kusama {
35- fn encode_call ( call : & Call ) -> anyhow:: Result < Self :: Call > {
40+ fn encode_call ( call : & Call ) -> anyhow:: Result < EncodedOrDecodedCall < Self :: Call > > {
3641 Ok ( match call {
42+ Call :: Raw { data } => EncodedOrDecodedCall :: Encoded ( data. 0 . clone ( ) ) ,
3743 Call :: Remark { remark_payload, .. } => relay_kusama_client:: runtime:: Call :: System (
3844 relay_kusama_client:: runtime:: SystemCall :: remark (
3945 remark_payload. as_ref ( ) . map ( |x| x. 0 . clone ( ) ) . unwrap_or_default ( ) ,
4046 ) ,
41- ) ,
47+ )
48+ . into ( ) ,
4249 Call :: BridgeSendMessage { lane, payload, fee, bridge_instance_index } =>
4350 match * bridge_instance_index {
4451 bridge:: KUSAMA_TO_POLKADOT_INDEX => {
@@ -48,6 +55,7 @@ impl CliEncodeCall for Kusama {
4855 lane. 0 , payload, fee. 0 ,
4956 ) ,
5057 )
58+ . into ( )
5159 } ,
5260 _ => anyhow:: bail!(
5361 "Unsupported target bridge pallet with instance index: {}" ,
@@ -58,13 +66,11 @@ impl CliEncodeCall for Kusama {
5866 } )
5967 }
6068
61- fn get_dispatch_info (
62- call : & relay_kusama_client:: runtime:: Call ,
63- ) -> anyhow:: Result < DispatchInfo > {
69+ fn get_dispatch_info ( call : & EncodedOrDecodedCall < Self :: Call > ) -> anyhow:: Result < DispatchInfo > {
6470 match * call {
65- relay_kusama_client:: runtime:: Call :: System (
71+ EncodedOrDecodedCall :: Decoded ( relay_kusama_client:: runtime:: Call :: System (
6672 relay_kusama_client:: runtime:: SystemCall :: remark( _) ,
67- ) => Ok ( DispatchInfo {
73+ ) ) => Ok ( DispatchInfo {
6874 weight : crate :: chains:: kusama:: SYSTEM_REMARK_CALL_WEIGHT ,
6975 class : DispatchClass :: Normal ,
7076 pays_fee : Pays :: Yes ,
@@ -78,7 +84,12 @@ impl CliChain for Kusama {
7884 const RUNTIME_VERSION : RuntimeVersion = bp_kusama:: VERSION ;
7985
8086 type KeyPair = sp_core:: sr25519:: Pair ;
81- type MessagePayload = ( ) ;
87+ type MessagePayload = MessagePayload <
88+ bp_kusama:: AccountId ,
89+ bp_polkadot:: AccountPublic ,
90+ bp_polkadot:: Signature ,
91+ Vec < u8 > ,
92+ > ;
8293
8394 fn ss58_format ( ) -> u16 {
8495 sp_core:: crypto:: Ss58AddressFormat :: from (
@@ -88,8 +99,37 @@ impl CliChain for Kusama {
8899 }
89100
90101 fn encode_message (
91- _message : encode_message:: MessagePayload ,
102+ message : encode_message:: MessagePayload ,
92103 ) -> anyhow:: Result < Self :: MessagePayload > {
93- anyhow:: bail!( "Sending messages from Kusama is not yet supported." )
104+ match message {
105+ encode_message:: MessagePayload :: Raw { data } => MessagePayload :: decode ( & mut & * data. 0 )
106+ . map_err ( |e| anyhow ! ( "Failed to decode Kusama's MessagePayload: {:?}" , e) ) ,
107+ encode_message:: MessagePayload :: Call { mut call, mut sender, dispatch_weight } => {
108+ type Source = Kusama ;
109+ type Target = relay_polkadot_client:: Polkadot ;
110+
111+ sender. enforce_chain :: < Source > ( ) ;
112+ let spec_version = Target :: RUNTIME_VERSION . spec_version ;
113+ let origin = CallOrigin :: SourceAccount ( sender. raw_id ( ) ) ;
114+ encode_call:: preprocess_call :: < Source , Target > (
115+ & mut call,
116+ bridge:: KUSAMA_TO_POLKADOT_INDEX ,
117+ ) ;
118+ let call = Target :: encode_call ( & call) ?;
119+ let dispatch_weight = dispatch_weight. map ( Ok ) . unwrap_or_else ( || {
120+ Err ( anyhow:: format_err!(
121+ "Please specify dispatch weight of the encoded Polkadot call"
122+ ) )
123+ } ) ?;
124+
125+ Ok ( send_message:: message_payload (
126+ spec_version,
127+ dispatch_weight,
128+ origin,
129+ & call,
130+ DispatchFeePayment :: AtSourceChain ,
131+ ) )
132+ } ,
133+ }
94134 }
95135}
0 commit comments