Skip to content

Commit 984749b

Browse files
authored
Define separate signed extension for BHR/BHW (#1776)
- Make signed extensions for indirect runtimes more extensible - Define separate signed extension for BHR/BHW
1 parent 72b03d4 commit 984749b

File tree

11 files changed

+279
-104
lines changed

11 files changed

+279
-104
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

primitives/chain-bridge-hub-cumulus/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

1919
use bp_messages::*;
2020
pub use bp_polkadot_core::{
21-
AccountId, AccountInfoStorageMapKeyProvider, AccountPublic, Balance, BlockNumber, Hash, Hasher,
22-
Hashing, Header, Index, Nonce, Perbill, Signature, SignedBlock, SignedExtensions,
23-
UncheckedExtrinsic, TX_EXTRA_BYTES,
21+
AccountId, AccountInfoStorageMapKeyProvider, AccountPublic, Balance, BlockNumber,
22+
BridgeSignedExtension, Hash, Hasher, Hashing, Header, Index, Nonce, Perbill,
23+
PolkadotSignedExtension, Signature, SignedBlock, UncheckedExtrinsic, TX_EXTRA_BYTES,
2424
};
2525
use frame_support::{
2626
dispatch::DispatchClass,

primitives/polkadot-core/src/lib.rs

Lines changed: 125 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
use bp_messages::MessageNonce;
2020
use bp_runtime::{Chain, EncodedOrDecodedCall, StorageMapKeyProvider};
21-
use codec::Compact;
2221
use frame_support::{
2322
dispatch::DispatchClass,
2423
parameter_types,
@@ -29,17 +28,16 @@ use frame_support::{
2928
Blake2_128Concat, RuntimeDebug,
3029
};
3130
use frame_system::limits;
32-
use scale_info::TypeInfo;
3331
use sp_core::{storage::StorageKey, Hasher as HasherT};
3432
use sp_runtime::{
3533
generic,
36-
traits::{BlakeTwo256, DispatchInfoOf, IdentifyAccount, Verify},
37-
transaction_validity::TransactionValidityError,
34+
traits::{BlakeTwo256, IdentifyAccount, Verify},
3835
MultiAddress, MultiSignature, OpaqueExtrinsic,
3936
};
4037
use sp_std::prelude::Vec;
4138

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

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

186184
/// Unchecked Extrinsic type.
187-
pub type UncheckedExtrinsic<Call> = generic::UncheckedExtrinsic<
188-
AccountAddress,
189-
EncodedOrDecodedCall<Call>,
190-
Signature,
191-
SignedExtensions,
192-
>;
185+
pub type UncheckedExtrinsic<Call, SignedExt> =
186+
generic::UncheckedExtrinsic<AccountAddress, EncodedOrDecodedCall<Call>, Signature, SignedExt>;
193187

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

197-
/// A type of the data encoded as part of the transaction.
198-
pub type SignedExtra =
199-
((), (), (), (), sp_runtime::generic::Era, Compact<Nonce>, (), Compact<Balance>);
200-
201-
/// Parameters which are part of the payload used to produce transaction signature,
202-
/// but don't end up in the transaction itself (i.e. inherent part of the runtime).
203-
pub type AdditionalSigned = ((), u32, u32, Hash, Hash, (), (), ());
204-
205-
/// A simplified version of signed extensions meant for producing signed transactions
206-
/// and signed payload in the client code.
207-
#[derive(codec::Encode, codec::Decode, PartialEq, Eq, Clone, RuntimeDebug, TypeInfo)]
208-
pub struct SignedExtensions {
209-
encode_payload: SignedExtra,
210-
// It may be set to `None` if extensions are decoded. We are never reconstructing transactions
211-
// (and it makes no sense to do that) => decoded version of `SignedExtensions` is only used to
212-
// read fields of `encode_payload`. And when resigning transaction, we're reconstructing
213-
// `SignedExtensions` from the scratch.
214-
#[codec(skip)]
215-
additional_signed: Option<AdditionalSigned>,
191+
/// Polkadot-like chain.
192+
#[derive(RuntimeDebug)]
193+
pub struct PolkadotLike;
194+
195+
impl Chain for PolkadotLike {
196+
type BlockNumber = BlockNumber;
197+
type Hash = Hash;
198+
type Hasher = Hasher;
199+
type Header = Header;
200+
201+
type AccountId = AccountId;
202+
type Balance = Balance;
203+
type Index = Index;
204+
type Signature = Signature;
205+
206+
fn max_extrinsic_size() -> u32 {
207+
*BlockLength::get().max.get(DispatchClass::Normal)
208+
}
209+
210+
fn max_extrinsic_weight() -> Weight {
211+
BlockWeights::get()
212+
.get(DispatchClass::Normal)
213+
.max_extrinsic
214+
.unwrap_or(Weight::MAX)
215+
}
216+
}
217+
218+
/// Some functionality associated with the default signed extension used by Polkadot and
219+
/// Polkadot-like chains.
220+
pub trait PolkadotSignedExtension {
221+
fn from_params(
222+
spec_version: u32,
223+
transaction_version: u32,
224+
era: bp_runtime::TransactionEraOf<PolkadotLike>,
225+
genesis_hash: Hash,
226+
nonce: Nonce,
227+
tip: Balance,
228+
) -> Self;
229+
230+
fn nonce(&self) -> Nonce;
231+
232+
fn tip(&self) -> Balance;
216233
}
217234

218-
impl SignedExtensions {
219-
pub fn new(
235+
type DefaultSignedExtra = (
236+
CheckNonZeroSender,
237+
CheckSpecVersion,
238+
CheckTxVersion,
239+
CheckGenesis<PolkadotLike>,
240+
CheckEra<PolkadotLike>,
241+
CheckNonce<Nonce>,
242+
CheckWeight,
243+
ChargeTransactionPayment<PolkadotLike>,
244+
);
245+
246+
/// The default signed extension used by Polkadot and Polkadot-like chains.
247+
pub type DefaultSignedExtension = GenericSignedExtension<DefaultSignedExtra>;
248+
249+
impl PolkadotSignedExtension for DefaultSignedExtension {
250+
fn from_params(
220251
spec_version: u32,
221252
transaction_version: u32,
222253
era: bp_runtime::TransactionEraOf<PolkadotLike>,
223254
genesis_hash: Hash,
224255
nonce: Nonce,
225256
tip: Balance,
226257
) -> Self {
227-
Self {
228-
encode_payload: (
258+
Self::new(
259+
(
229260
(), // non-zero sender
230261
(), // spec version
231262
(), // tx version
@@ -235,7 +266,7 @@ impl SignedExtensions {
235266
(), // Check weight
236267
tip.into(), // transaction payment / tip (compact encoding)
237268
),
238-
additional_signed: Some((
269+
(
239270
(),
240271
spec_version,
241272
transaction_version,
@@ -244,78 +275,79 @@ impl SignedExtensions {
244275
(),
245276
(),
246277
(),
247-
)),
248-
}
278+
),
279+
)
249280
}
250-
}
251281

252-
impl SignedExtensions {
253282
/// Return signer nonce, used to craft transaction.
254-
pub fn nonce(&self) -> Nonce {
255-
self.encode_payload.5.into()
283+
fn nonce(&self) -> Nonce {
284+
self.payload.5.into()
256285
}
257286

258287
/// Return transaction tip.
259-
pub fn tip(&self) -> Balance {
260-
self.encode_payload.7.into()
288+
fn tip(&self) -> Balance {
289+
self.payload.7.into()
261290
}
262291
}
263292

264-
impl sp_runtime::traits::SignedExtension for SignedExtensions {
265-
const IDENTIFIER: &'static str = "Not needed.";
266-
267-
type AccountId = AccountId;
268-
type Call = ();
269-
type AdditionalSigned = AdditionalSigned;
270-
type Pre = ();
271-
272-
fn additional_signed(
273-
&self,
274-
) -> Result<Self::AdditionalSigned, frame_support::unsigned::TransactionValidityError> {
275-
// we shall not ever see this error in relay, because we are never signing decoded
276-
// transactions. Instead we're constructing and signing new transactions. So the error code
277-
// is kinda random here
278-
self.additional_signed
279-
.ok_or(frame_support::unsigned::TransactionValidityError::Unknown(
280-
frame_support::unsigned::UnknownTransaction::Custom(0xFF),
281-
))
282-
}
283-
284-
fn pre_dispatch(
285-
self,
286-
_who: &Self::AccountId,
287-
_call: &Self::Call,
288-
_info: &DispatchInfoOf<Self::Call>,
289-
_len: usize,
290-
) -> Result<Self::Pre, TransactionValidityError> {
291-
Ok(())
293+
type BridgeSignedExtra = (
294+
CheckNonZeroSender,
295+
CheckSpecVersion,
296+
CheckTxVersion,
297+
CheckGenesis<PolkadotLike>,
298+
CheckEra<PolkadotLike>,
299+
CheckNonce<Nonce>,
300+
CheckWeight,
301+
ChargeTransactionPayment<PolkadotLike>,
302+
BridgeRejectObsoleteHeadersAndMessages,
303+
);
304+
305+
/// The default signed extension used by Polkadot and Polkadot-like chains with bridging.
306+
pub type BridgeSignedExtension = GenericSignedExtension<BridgeSignedExtra>;
307+
308+
impl PolkadotSignedExtension for BridgeSignedExtension {
309+
fn from_params(
310+
spec_version: u32,
311+
transaction_version: u32,
312+
era: bp_runtime::TransactionEraOf<PolkadotLike>,
313+
genesis_hash: Hash,
314+
nonce: Nonce,
315+
tip: Balance,
316+
) -> Self {
317+
Self::new(
318+
(
319+
(), // non-zero sender
320+
(), // spec version
321+
(), // tx version
322+
(), // genesis
323+
era.frame_era(), // era
324+
nonce.into(), // nonce (compact encoding)
325+
(), // Check weight
326+
tip.into(), // transaction payment / tip (compact encoding)
327+
(), // bridge reject obsolete headers and msgs
328+
),
329+
(
330+
(),
331+
spec_version,
332+
transaction_version,
333+
genesis_hash,
334+
era.signed_payload(genesis_hash),
335+
(),
336+
(),
337+
(),
338+
(),
339+
),
340+
)
292341
}
293-
}
294-
295-
/// Polkadot-like chain.
296-
#[derive(RuntimeDebug)]
297-
pub struct PolkadotLike;
298-
299-
impl Chain for PolkadotLike {
300-
type BlockNumber = BlockNumber;
301-
type Hash = Hash;
302-
type Hasher = Hasher;
303-
type Header = Header;
304342

305-
type AccountId = AccountId;
306-
type Balance = Balance;
307-
type Index = Index;
308-
type Signature = Signature;
309-
310-
fn max_extrinsic_size() -> u32 {
311-
*BlockLength::get().max.get(DispatchClass::Normal)
343+
/// Return signer nonce, used to craft transaction.
344+
fn nonce(&self) -> Nonce {
345+
self.payload.5.into()
312346
}
313347

314-
fn max_extrinsic_weight() -> Weight {
315-
BlockWeights::get()
316-
.get(DispatchClass::Normal)
317-
.max_extrinsic
318-
.unwrap_or(Weight::MAX)
348+
/// Return transaction tip.
349+
fn tip(&self) -> Balance {
350+
self.payload.7.into()
319351
}
320352
}
321353

primitives/runtime/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
99
[dependencies]
1010
codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false }
1111
hash-db = { version = "0.15.2", default-features = false }
12+
impl-trait-for-tuples = "0.2.2"
1213
num-traits = { version = "0.2", default-features = false }
1314
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
1415
serde = { version = "1.0", optional = true, features = ["derive"] }

0 commit comments

Comments
 (0)