Skip to content

Commit

Permalink
impl authorize
Browse files Browse the repository at this point in the history
  • Loading branch information
gui1117 committed Nov 1, 2024
1 parent cfe8667 commit f84192b
Show file tree
Hide file tree
Showing 49 changed files with 2,255 additions and 122 deletions.
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.

19 changes: 19 additions & 0 deletions polkadot/runtime/rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,25 @@ where
}
}

impl<LocalCall> frame_system::offchain::CreateAuthorizedTransaction<LocalCall> for Runtime
where
RuntimeCall: From<LocalCall>,
{
fn create_extension() -> Self::Extension {
(
frame_system::CheckNonZeroSender::<Runtime>::new(),
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckMortality::<Runtime>::from(generic::Era::Immortal),
frame_system::CheckNonce::<Runtime>::from(0),
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
frame_metadata_hash_extension::CheckMetadataHash::new(false),
)
}
}

parameter_types! {
pub Prefix: &'static [u8] = b"Pay ROCs to the Rococo account:";
}
Expand Down
18 changes: 18 additions & 0 deletions polkadot/runtime/test-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,24 @@ where
}
}

impl<C> frame_system::offchain::CreateAuthorizedTransaction<C> for Runtime
where
RuntimeCall: From<C>,
{
fn create_extension() -> Self::Extension {
(
frame_system::CheckNonZeroSender::<Runtime>::new(),
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckMortality::<Runtime>::from(generic::Era::Immortal),
frame_system::CheckNonce::<Runtime>::from(0),
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
)
}
}

parameter_types! {
pub storage EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
pub storage ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
Expand Down
19 changes: 19 additions & 0 deletions polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,25 @@ where
}
}

impl<LocalCall> frame_system::offchain::CreateAuthorizedTransaction<LocalCall> for Runtime
where
RuntimeCall: From<LocalCall>,
{
fn create_extension() -> Self::Extension {
(
frame_system::CheckNonZeroSender::<Runtime>::new(),
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckMortality::<Runtime>::from(generic::Era::Immortal),
frame_system::CheckNonce::<Runtime>::from(0),
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(false),
)
}
}

parameter_types! {
// Minimum 100 bytes/KSM deposited (1 CENT/byte)
pub const BasicDeposit: Balance = 1000 * CENTS; // 258 bytes on-chain
Expand Down
21 changes: 21 additions & 0 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1528,6 +1528,27 @@ where
type RuntimeCall = RuntimeCall;
}

impl<C> frame_system::offchain::CreateAuthorizedTransaction<C> for Runtime
where
RuntimeCall: From<C>,
{
fn create_extension() -> Self::Extension {
(
frame_system::CheckNonZeroSender::<Runtime>::new(),
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckEra::<Runtime>::from(Era::Immortal),
frame_system::CheckNonce::<Runtime>::from(0),
frame_system::CheckWeight::<Runtime>::new(),
pallet_skip_feeless_payment::SkipCheckIfFeeless::from(
pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::<Runtime>::from(0, None),
),
frame_metadata_hash_extension::CheckMetadataHash::new(false),
)
}
}

impl pallet_im_online::Config for Runtime {
type AuthorityId = ImOnlineId;
type RuntimeEvent = RuntimeEvent;
Expand Down
10 changes: 9 additions & 1 deletion substrate/frame/benchmarking/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_io::hashing::blake2_256;
use sp_runtime::{traits::TrailingZeroInput, DispatchError};
use sp_runtime::{
traits::TrailingZeroInput, transaction_validity::TransactionValidityError, DispatchError,
};
use sp_storage::TrackedStorageKey;

/// An alphabet of possible parameters to use for benchmarking.
Expand Down Expand Up @@ -195,6 +197,12 @@ impl From<DispatchError> for BenchmarkError {
}
}

impl From<TransactionValidityError> for BenchmarkError {
fn from(e: TransactionValidityError) -> Self {
Self::Stop(e.into())
}
}

/// Configuration used to setup and run runtime benchmarks.
#[derive(Encode, Decode, Default, Clone, PartialEq, Debug, TypeInfo)]
pub struct BenchmarkConfig {
Expand Down
40 changes: 37 additions & 3 deletions substrate/frame/examples/kitchensink/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,45 @@ mod benchmarks {
assert_eq!(Foo::<T>::get(), Some(value))
}

// This will measure the execution time of `set_foo_using_authorize`.
#[benchmark]
fn set_foo_using_authorize() {
// This is the benchmark setup phase.

// `set_foo_using_authorize` is only authorized when value is 42 so we will use it.
let value = 42u32;
// We dispatch with authorized origin, it is the origin resulting from authorization.
let origin = RawOrigin::Authorized;

#[extrinsic_call]
_(origin, value); // The execution phase is just running `set_foo_using_authorize` extrinsic call

// This is the optional benchmark verification phase, asserting certain states.
assert_eq!(Foo::<T>::get(), Some(42))
}

// This will measure the weight for the closure in `[pallet::authorize(...)]`.
#[benchmark]
fn authorize_set_foo_using_authorize() {
// This is the benchmark setup phase.

let call = Call::<T>::set_foo_using_authorize { new_foo: 42 };
let source = TransactionSource::External;

// We use a block with specific code to benchmark the closure.
#[block]
{
use frame_support::traits::Authorize;
call.authorize(source)
.expect("Call give some authorization")
.expect("Authorization is successful");
}
}

// This line generates test cases for benchmarking, and could be run by:
// `cargo test -p pallet-example-kitchensink --all-features`, you will see one line per case:
// `test benchmarking::bench_sort_vector ... ok`
// `test benchmarking::bench_accumulate_dummy ... ok`
// `test benchmarking::bench_set_dummy_benchmark ... ok` in the result.
// `test benchmarking::bench_set_foo_benchmark ... ok`
// `test benchmarking::bench_set_foo_using_authorize_benchmark ... ok` in the result.
//
// The line generates three steps per benchmark, with repeat=1 and the three steps are
// [low, mid, high] of the range.
Expand Down
43 changes: 29 additions & 14 deletions substrate/frame/examples/kitchensink/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,35 @@ pub mod pallet {

Ok(())
}

/// A call that is specially authorized.
/// Authorized call can be dispatched by anybody without requiring any signature or fee.
#[pallet::call_index(1)]
#[pallet::authorize(|
_source: TransactionSource,
new_foo: &u32,
| -> TransactionValidityWithRefund {
if *new_foo == 42 {
let refund = Weight::zero();
let validity = ValidTransaction::default();
Ok((validity, refund))
} else {
Err(InvalidTransaction::Call.into())
}
})]
#[pallet::weight(T::WeightInfo::set_foo_using_authorize())]
#[pallet::weight_of_authorize(T::WeightInfo::authorize_set_foo_using_authorize())]
pub fn set_foo_using_authorize(
origin: OriginFor<T>,
new_foo: u32,
) -> DispatchResult {
// We only dispatch if it comes from the authorized origin. Meaning that the closure
// passed in `pallet::authorize` has successfully authorized the call.
ensure_authorized(origin)?;
Foo::<T>::set(Some(new_foo));

Ok(())
}
}

/// The event type. This exactly like a normal Rust enum.
Expand Down Expand Up @@ -300,20 +329,6 @@ pub mod pallet {
Staking,
}

/// Allows the pallet to validate some unsigned transaction. See
/// [`sp_runtime::traits::ValidateUnsigned`] for more info.
#[pallet::validate_unsigned]
impl<T: Config> ValidateUnsigned for Pallet<T> {
type Call = Call<T>;
fn validate_unsigned(_: TransactionSource, _: &Self::Call) -> TransactionValidity {
unimplemented!()
}

fn pre_dispatch(_: &Self::Call) -> Result<(), TransactionValidityError> {
unimplemented!()
}
}

/// Allows the pallet to provide some inherent. See [`frame_support::inherent::ProvideInherent`]
/// for more info.
#[pallet::inherent]
Expand Down
18 changes: 18 additions & 0 deletions substrate/frame/examples/kitchensink/src/weights.rs

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

13 changes: 8 additions & 5 deletions substrate/frame/support/procedural/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,18 @@ codec = { features = [
"max-encoded-len",
], workspace = true }
regex = { workspace = true }
sp-metadata-ir = { workspace = true }
sp-metadata-ir = { workspace = true, features = ["std"] }
scale-info = { features = ["derive"], workspace = true }
sp-core = { workspace = true }
sp-io = { workspace = true }
sp-core = { workspace = true, features = ["std"] }
sp-io = { workspace = true, features = ["std"] }
sp-runtime = { features = [
"serde",
"runtime-benchmarks",
"std",
], workspace = true }
frame-system = { workspace = true }
frame-support = { workspace = true }
frame-system = { workspace = true, features = ["runtime-benchmarks", "std"] }
frame-support = { workspace = true, features = ["runtime-benchmarks", "std"] }
frame-benchmarking = { workspace = true, features = ["std"] }
pretty_assertions = { workspace = true }
static_assertions = { workspace = true }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub fn expand_outer_dispatch(
) -> TokenStream {
let mut variant_defs = TokenStream::new();
let mut variant_patterns = Vec::new();
let mut variant_usages = Vec::new();
let mut query_call_part_macros = Vec::new();
let mut pallet_names = Vec::new();
let mut pallet_attrs = Vec::new();
Expand All @@ -55,6 +56,7 @@ pub fn expand_outer_dispatch(
#[codec(index = #index)]
#name( #scrate::dispatch::CallableCallFor<#name, #runtime> ),
});
variant_usages.push(quote!( #scrate::dispatch::CallableCallFor<#name, #runtime> ));
variant_patterns.push(quote!(RuntimeCall::#name(call)));
pallet_names.push(name);
pallet_attrs.push(attr);
Expand Down Expand Up @@ -220,5 +222,37 @@ pub fn expand_outer_dispatch(
}
}
)*

impl #scrate::traits::Authorize for RuntimeCall {
fn authorize(
&self,
source: #scrate::pallet_prelude::TransactionSource,
) -> ::core::option::Option<
::core::result::Result<
(
#scrate::pallet_prelude::ValidTransaction,
#scrate::pallet_prelude::Weight,
),
#scrate::pallet_prelude::TransactionValidityError
>
> {
match self {
#(
#pallet_attrs
#variant_patterns => #scrate::traits::Authorize::authorize(call, source),
)*
}
}

fn weight_of_authorize(&self) -> #scrate::pallet_prelude::Weight {
match self {
#(
#pallet_attrs
#variant_patterns =>
#scrate::traits::Authorize::weight_of_authorize(call),
)*
}
}
}
}
}
Loading

0 comments on commit f84192b

Please sign in to comment.