Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define a separate signed extension for BHR/BHW #1776

Merged
merged 1 commit into from
Jan 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions primitives/chain-bridge-hub-cumulus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

use bp_messages::*;
pub use bp_polkadot_core::{
AccountId, AccountInfoStorageMapKeyProvider, AccountPublic, Balance, BlockNumber, Hash, Hasher,
Hashing, Header, Index, Nonce, Perbill, Signature, SignedBlock, SignedExtensions,
UncheckedExtrinsic, TX_EXTRA_BYTES,
AccountId, AccountInfoStorageMapKeyProvider, AccountPublic, Balance, BlockNumber,
BridgeSignedExtension, Hash, Hasher, Hashing, Header, Index, Nonce, Perbill,
PolkadotSignedExtension, Signature, SignedBlock, UncheckedExtrinsic, TX_EXTRA_BYTES,
};
use frame_support::{
dispatch::DispatchClass,
Expand Down
218 changes: 125 additions & 93 deletions primitives/polkadot-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

use bp_messages::MessageNonce;
use bp_runtime::{Chain, EncodedOrDecodedCall, StorageMapKeyProvider};
use codec::Compact;
use frame_support::{
dispatch::DispatchClass,
parameter_types,
Expand All @@ -29,17 +28,16 @@ use frame_support::{
Blake2_128Concat, RuntimeDebug,
};
use frame_system::limits;
use scale_info::TypeInfo;
use sp_core::{storage::StorageKey, Hasher as HasherT};
use sp_runtime::{
generic,
traits::{BlakeTwo256, DispatchInfoOf, IdentifyAccount, Verify},
transaction_validity::TransactionValidityError,
traits::{BlakeTwo256, IdentifyAccount, Verify},
MultiAddress, MultiSignature, OpaqueExtrinsic,
};
use sp_std::prelude::Vec;

// Re-export's to avoid extra substrate dependencies in chain-specific crates.
use bp_runtime::extensions::*;
pub use frame_support::{weights::constants::ExtrinsicBaseWeight, Parameter};
pub use sp_runtime::{traits::Convert, Perbill};

Expand Down Expand Up @@ -184,48 +182,81 @@ pub type SignedBlock = generic::SignedBlock<Block>;
pub type Balance = u128;

/// Unchecked Extrinsic type.
pub type UncheckedExtrinsic<Call> = generic::UncheckedExtrinsic<
AccountAddress,
EncodedOrDecodedCall<Call>,
Signature,
SignedExtensions,
>;
pub type UncheckedExtrinsic<Call, SignedExt> =
generic::UncheckedExtrinsic<AccountAddress, EncodedOrDecodedCall<Call>, Signature, SignedExt>;

/// Account address, used by the Polkadot-like chain.
pub type Address = MultiAddress<AccountId, ()>;

/// A type of the data encoded as part of the transaction.
pub type SignedExtra =
((), (), (), (), sp_runtime::generic::Era, Compact<Nonce>, (), Compact<Balance>);

/// Parameters which are part of the payload used to produce transaction signature,
/// but don't end up in the transaction itself (i.e. inherent part of the runtime).
pub type AdditionalSigned = ((), u32, u32, Hash, Hash, (), (), ());

/// A simplified version of signed extensions meant for producing signed transactions
/// and signed payload in the client code.
#[derive(codec::Encode, codec::Decode, PartialEq, Eq, Clone, RuntimeDebug, TypeInfo)]
pub struct SignedExtensions {
encode_payload: SignedExtra,
// It may be set to `None` if extensions are decoded. We are never reconstructing transactions
// (and it makes no sense to do that) => decoded version of `SignedExtensions` is only used to
// read fields of `encode_payload`. And when resigning transaction, we're reconstructing
// `SignedExtensions` from the scratch.
#[codec(skip)]
additional_signed: Option<AdditionalSigned>,
/// Polkadot-like chain.
#[derive(RuntimeDebug)]
pub struct PolkadotLike;

impl Chain for PolkadotLike {
type BlockNumber = BlockNumber;
type Hash = Hash;
type Hasher = Hasher;
type Header = Header;

type AccountId = AccountId;
type Balance = Balance;
type Index = Index;
type Signature = Signature;

fn max_extrinsic_size() -> u32 {
*BlockLength::get().max.get(DispatchClass::Normal)
}

fn max_extrinsic_weight() -> Weight {
BlockWeights::get()
.get(DispatchClass::Normal)
.max_extrinsic
.unwrap_or(Weight::MAX)
}
}

/// Some functionality associated with the default signed extension used by Polkadot and
/// Polkadot-like chains.
pub trait PolkadotSignedExtension {
fn from_params(
spec_version: u32,
transaction_version: u32,
era: bp_runtime::TransactionEraOf<PolkadotLike>,
genesis_hash: Hash,
nonce: Nonce,
tip: Balance,
) -> Self;

fn nonce(&self) -> Nonce;

fn tip(&self) -> Balance;
}

impl SignedExtensions {
pub fn new(
type DefaultSignedExtra = (
CheckNonZeroSender,
CheckSpecVersion,
CheckTxVersion,
CheckGenesis<PolkadotLike>,
CheckEra<PolkadotLike>,
CheckNonce<Nonce>,
CheckWeight,
ChargeTransactionPayment<PolkadotLike>,
);

/// The default signed extension used by Polkadot and Polkadot-like chains.
pub type DefaultSignedExtension = GenericSignedExtension<DefaultSignedExtra>;

impl PolkadotSignedExtension for DefaultSignedExtension {
fn from_params(
spec_version: u32,
transaction_version: u32,
era: bp_runtime::TransactionEraOf<PolkadotLike>,
genesis_hash: Hash,
nonce: Nonce,
tip: Balance,
) -> Self {
Self {
encode_payload: (
Self::new(
(
(), // non-zero sender
(), // spec version
(), // tx version
Expand All @@ -235,7 +266,7 @@ impl SignedExtensions {
(), // Check weight
tip.into(), // transaction payment / tip (compact encoding)
),
additional_signed: Some((
(
(),
spec_version,
transaction_version,
Expand All @@ -244,78 +275,79 @@ impl SignedExtensions {
(),
(),
(),
)),
}
),
)
}
}

impl SignedExtensions {
/// Return signer nonce, used to craft transaction.
pub fn nonce(&self) -> Nonce {
self.encode_payload.5.into()
fn nonce(&self) -> Nonce {
self.payload.5.into()
}

/// Return transaction tip.
pub fn tip(&self) -> Balance {
self.encode_payload.7.into()
fn tip(&self) -> Balance {
self.payload.7.into()
}
}

impl sp_runtime::traits::SignedExtension for SignedExtensions {
const IDENTIFIER: &'static str = "Not needed.";

type AccountId = AccountId;
type Call = ();
type AdditionalSigned = AdditionalSigned;
type Pre = ();

fn additional_signed(
&self,
) -> Result<Self::AdditionalSigned, frame_support::unsigned::TransactionValidityError> {
// we shall not ever see this error in relay, because we are never signing decoded
// transactions. Instead we're constructing and signing new transactions. So the error code
// is kinda random here
self.additional_signed
.ok_or(frame_support::unsigned::TransactionValidityError::Unknown(
frame_support::unsigned::UnknownTransaction::Custom(0xFF),
))
}

fn pre_dispatch(
self,
_who: &Self::AccountId,
_call: &Self::Call,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
Ok(())
type BridgeSignedExtra = (
CheckNonZeroSender,
CheckSpecVersion,
CheckTxVersion,
CheckGenesis<PolkadotLike>,
CheckEra<PolkadotLike>,
CheckNonce<Nonce>,
CheckWeight,
ChargeTransactionPayment<PolkadotLike>,
BridgeRejectObsoleteHeadersAndMessages,
);

/// The default signed extension used by Polkadot and Polkadot-like chains with bridging.
pub type BridgeSignedExtension = GenericSignedExtension<BridgeSignedExtra>;

impl PolkadotSignedExtension for BridgeSignedExtension {
fn from_params(
spec_version: u32,
transaction_version: u32,
era: bp_runtime::TransactionEraOf<PolkadotLike>,
genesis_hash: Hash,
nonce: Nonce,
tip: Balance,
) -> Self {
Self::new(
(
(), // non-zero sender
(), // spec version
(), // tx version
(), // genesis
era.frame_era(), // era
nonce.into(), // nonce (compact encoding)
(), // Check weight
tip.into(), // transaction payment / tip (compact encoding)
(), // bridge reject obsolete headers and msgs
),
(
(),
spec_version,
transaction_version,
genesis_hash,
era.signed_payload(genesis_hash),
(),
(),
(),
(),
),
)
}
}

/// Polkadot-like chain.
#[derive(RuntimeDebug)]
pub struct PolkadotLike;

impl Chain for PolkadotLike {
type BlockNumber = BlockNumber;
type Hash = Hash;
type Hasher = Hasher;
type Header = Header;

type AccountId = AccountId;
type Balance = Balance;
type Index = Index;
type Signature = Signature;

fn max_extrinsic_size() -> u32 {
*BlockLength::get().max.get(DispatchClass::Normal)
/// Return signer nonce, used to craft transaction.
fn nonce(&self) -> Nonce {
self.payload.5.into()
}

fn max_extrinsic_weight() -> Weight {
BlockWeights::get()
.get(DispatchClass::Normal)
.max_extrinsic
.unwrap_or(Weight::MAX)
/// Return transaction tip.
fn tip(&self) -> Balance {
self.payload.7.into()
}
}

Expand Down
1 change: 1 addition & 0 deletions primitives/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false }
hash-db = { version = "0.15.2", default-features = false }
impl-trait-for-tuples = "0.2.2"
num-traits = { version = "0.2", default-features = false }
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
serde = { version = "1.0", optional = true, features = ["derive"] }
Expand Down
Loading