From 1b583a720ba16ebf8859fc4c2899de2d4641e2df Mon Sep 17 00:00:00 2001 From: Puneet Saraswat <61435908+saraswatpuneet@users.noreply.github.com> Date: Wed, 10 Jul 2024 12:19:14 -0500 Subject: [PATCH] Passkey miscellaneous checks part 1 (#2060) # Goal The goal of this PR is to incorporate more checks for passkey extrinsic inline with other SignedExtras - [x] Non Zero Sender Check - [x] Spec Check - [x] Tx version check - [x] Era check - [x] Genesis check Closes #2031 # Discussion # Checklist - [ ] Chain spec updated - [ ] Custom RPC OR Runtime API added/changed? Updated js/api-augment. - [ ] Design doc(s) updated - [ ] Tests added - [ ] Benchmarks added - [ ] Weights updated --- pallets/passkey/src/lib.rs | 76 ++++++++++++++++++++++++++++++++++-- runtime/frequency/src/lib.rs | 4 +- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/pallets/passkey/src/lib.rs b/pallets/passkey/src/lib.rs index 5bd0efa215..ff301d80c4 100644 --- a/pallets/passkey/src/lib.rs +++ b/pallets/passkey/src/lib.rs @@ -26,6 +26,7 @@ use frame_support::{ use frame_system::pallet_prelude::*; use pallet_transaction_payment::OnChargeTransaction; use sp_runtime::{ + generic::Era, traits::{Convert, Dispatchable, SignedExtension, Verify, Zero}, transaction_validity::{TransactionValidity, TransactionValidityError}, AccountId32, MultiSignature, @@ -73,7 +74,7 @@ pub mod module { #[pallet::config] pub trait Config: - frame_system::Config + pallet_transaction_payment::Config + Sync + Send + frame_system::Config + pallet_transaction_payment::Config + Send + Sync { /// The overarching event type. type RuntimeEvent: From> + IsType<::RuntimeEvent>; @@ -162,6 +163,10 @@ pub mod module { let valid_tx = ValidTransaction::default(); let payload = Self::filter_valid_calls(&call)?; + let frame_system_checks = + FrameSystemChecks(payload.passkey_call.account_id.clone(), call.clone()); + let frame_system_validity = frame_system_checks.validate()?; + let signatures_check = PasskeySignatureCheck::new(payload.clone()); let signature_validity = signatures_check.validate()?; @@ -178,6 +183,7 @@ pub mod module { let weight_validity = weight_check.validate()?; let valid_tx = valid_tx + .combine_with(frame_system_validity) .combine_with(signature_validity) .combine_with(nonce_validity) .combine_with(tx_payment_validity) @@ -188,6 +194,10 @@ pub mod module { fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { let payload = Self::filter_valid_calls(&call)?; + let frame_system_checks = + FrameSystemChecks(payload.passkey_call.account_id.clone(), call.clone()); + frame_system_checks.pre_dispatch()?; + let signatures_check = PasskeySignatureCheck::new(payload.clone()); signatures_check.pre_dispatch()?; @@ -337,7 +347,7 @@ where /// Validates the transaction fee paid with tokens. pub fn pre_dispatch(&self) -> Result<(), TransactionValidityError> { let info = &self.1.get_dispatch_info(); - let len = self.0.using_encoded(|c| c.len()); + let len = self.1.using_encoded(|c| c.len()); let runtime_call: ::RuntimeCall = ::RuntimeCall::from(self.1.clone()); let who = self.0.clone(); @@ -349,7 +359,7 @@ where /// Validates the transaction fee paid with tokens. pub fn validate(&self) -> TransactionValidity { let info = &self.1.get_dispatch_info(); - let len = self.0.using_encoded(|c| c.len()); + let len = self.1.using_encoded(|c| c.len()); let runtime_call: ::RuntimeCall = ::RuntimeCall::from(self.1.clone()); let who = self.0.clone(); @@ -363,6 +373,66 @@ where } } +/// Frame system related checks +#[derive(Encode, Decode, Clone, TypeInfo)] +#[scale_info(skip_type_params(T))] +pub struct FrameSystemChecks(pub T::AccountId, pub Call); + +impl FrameSystemChecks +where + ::RuntimeCall: + From> + Dispatchable, +{ + /// Validates the transaction fee paid with tokens. + pub fn pre_dispatch(&self) -> Result<(), TransactionValidityError> { + let info = &self.1.get_dispatch_info(); + let len = self.1.using_encoded(|c| c.len()); + let runtime_call: ::RuntimeCall = + ::RuntimeCall::from(self.1.clone()); + let who = self.0.clone(); + + let non_zero_sender_check = frame_system::CheckNonZeroSender::::new(); + let spec_version_check = frame_system::CheckSpecVersion::::new(); + let tx_version_check = frame_system::CheckTxVersion::::new(); + let genesis_hash_check = frame_system::CheckGenesis::::new(); + let era_check = frame_system::CheckEra::::from(Era::immortal()); + + non_zero_sender_check.pre_dispatch(&who, &runtime_call, info, len)?; + spec_version_check.pre_dispatch(&who, &runtime_call, info, len)?; + tx_version_check.pre_dispatch(&who, &runtime_call, info, len)?; + genesis_hash_check.pre_dispatch(&who, &runtime_call, info, len)?; + era_check.pre_dispatch(&who, &runtime_call, info, len) + } + + /// Validates the transaction fee paid with tokens. + pub fn validate(&self) -> TransactionValidity { + let info = &self.1.get_dispatch_info(); + let len = self.1.using_encoded(|c| c.len()); + let runtime_call: ::RuntimeCall = + ::RuntimeCall::from(self.1.clone()); + let who = self.0.clone(); + + let non_zero_sender_check = frame_system::CheckNonZeroSender::::new(); + let spec_version_check = frame_system::CheckSpecVersion::::new(); + let tx_version_check = frame_system::CheckTxVersion::::new(); + let genesis_hash_check = frame_system::CheckGenesis::::new(); + let era_check = frame_system::CheckEra::::from(Era::immortal()); + + let non_zero_sender_validity = + non_zero_sender_check.validate(&who, &runtime_call, info, len)?; + let spec_version_validity = spec_version_check.validate(&who, &runtime_call, info, len)?; + let tx_version_validity = tx_version_check.validate(&who, &runtime_call, info, len)?; + let genesis_hash_validity = genesis_hash_check.validate(&who, &runtime_call, info, len)?; + let era_validity = era_check.validate(&who, &runtime_call, info, len)?; + + Ok(non_zero_sender_validity + .combine_with(spec_version_validity) + .combine_with(tx_version_validity) + .combine_with(genesis_hash_validity) + .combine_with(era_validity)) + } +} + /// Block resource (weight) limit check. #[derive(Encode, Decode, Clone, TypeInfo)] #[scale_info(skip_type_params(T))] diff --git a/runtime/frequency/src/lib.rs b/runtime/frequency/src/lib.rs index 227fc1ffa4..811dd8f6c8 100644 --- a/runtime/frequency/src/lib.rs +++ b/runtime/frequency/src/lib.rs @@ -357,7 +357,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("frequency"), impl_name: create_runtime_str!("frequency"), authoring_version: 1, - spec_version: 92, + spec_version: 93, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -371,7 +371,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("frequency-testnet"), impl_name: create_runtime_str!("frequency"), authoring_version: 1, - spec_version: 92, + spec_version: 93, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1,