Newer
Older
// Copyright 2019-2021 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/>.
//! Types used to connect to the Polkadot chain.
Serban Iorga
committed
mod codegen_runtime;
use bp_polkadot::{AccountInfoStorageMapKeyProvider, POLKADOT_SYNCED_HEADERS_GRANDPA_INFO_METHOD};
Serban Iorga
committed
use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
use bp_runtime::ChainId;
Serban Iorga
committed
use codec::Encode;
use relay_substrate_client::{
Serban Iorga
committed
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
Serban Iorga
committed
use sp_core::{storage::StorageKey, Pair};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
use sp_session::MembershipProof;
Serban Iorga
committed
pub use codegen_runtime::api::runtime_types;
pub type RuntimeCall = runtime_types::polkadot_runtime::RuntimeCall;
pub type GrandpaCall = runtime_types::pallet_grandpa::pallet::Call;
/// Polkadot header id.
pub type HeaderId = relay_utils::HeaderId<bp_polkadot::Hash, bp_polkadot::BlockNumber>;
/// Polkadot header type used in headers sync.
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_polkadot::Header>;
Serban Iorga
committed
/// The address format for describing accounts.
pub type Address = MultiAddress<bp_polkadot::AccountId, ()>;
/// Polkadot chain definition
#[derive(Debug, Clone, Copy)]
pub struct Polkadot;
impl UnderlyingChainProvider for Polkadot {
type Chain = bp_polkadot::Polkadot;
const ID: ChainId = bp_runtime::POLKADOT_CHAIN_ID;
const BEST_FINALIZED_HEADER_ID_METHOD: &'static str =
bp_polkadot::BEST_FINALIZED_POLKADOT_HEADER_METHOD;
const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6);
type SignedBlock = bp_polkadot::SignedBlock;
Serban Iorga
committed
type Call = RuntimeCall;
impl ChainWithGrandpa for Polkadot {
const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str =
POLKADOT_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
type KeyOwnerProof = MembershipProof;
impl ChainWithBalances for Polkadot {
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
AccountInfoStorageMapKeyProvider::final_key(account_id)
impl RelayChain for Polkadot {
const PARAS_PALLET_NAME: &'static str = bp_polkadot::PARAS_PALLET_NAME;
}
Serban Iorga
committed
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
impl ChainWithTransactions for Polkadot {
type AccountKeyPair = sp_core::sr25519::Pair;
type SignedTransaction =
bp_polkadot_core::UncheckedExtrinsic<Self::Call, bp_polkadot::SignedExtension>;
fn sign_transaction(
param: SignParam<Self>,
unsigned: UnsignedTransaction<Self>,
) -> Result<Self::SignedTransaction, SubstrateError> {
let raw_payload = SignedPayload::new(
unsigned.call,
bp_polkadot::SignedExtension::from_params(
param.spec_version,
param.transaction_version,
unsigned.era,
param.genesis_hash,
unsigned.nonce,
unsigned.tip,
((), ()),
),
)?;
let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload));
let signer: sp_runtime::MultiSigner = param.signer.public().into();
let (call, extra, _) = raw_payload.deconstruct();
Ok(Self::SignedTransaction::new_signed(
call,
signer.into_account().into(),
signature.into(),
extra,
))
}
fn is_signed(tx: &Self::SignedTransaction) -> bool {
tx.signature.is_some()
}
fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool {
tx.signature
.as_ref()
.map(|(address, _, _)| *address == Address::Id(signer.public().into()))
.unwrap_or(false)
}
fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
let extra = &tx.signature.as_ref()?.2;
Some(UnsignedTransaction::new(tx.function, extra.nonce()).tip(extra.tip()))
}
}