---
# System prepended metadata

title: FRAME @ Parachain Summit 2023

---

---
type: slide
---

# FRAME @ Parachain Summit 2023

> 💭 Collective FRAME Imagination Exercise

note: 

In this presentation I will try and paint a picture of what FRAME/Substrate development could look like, with some of the features that we are adding. 

All features should have an associated gh issue. 

Not all issues are being actively worked on. Not all are confirmed to be worthwhile.

But no harm in dreaming. 

----

## Presentation Framework

- For each item, please rate: 
    - how cool/valuable you see this feature to the whole ecosystem?
    - how likely you see it to be integrated into your own project?

---

### ☂️ Umbrella Crate

```toml
[dependencies]
frame = { 
    version = "3.0.0", 
    default-features = false,
    features = ["runtime", "experimental"]
}

[features]
default = [ "std" ]
std = [ "frame/std" ]
```

----

### ☂️ Umbrella Crate

```rust
#![cfg_attr(not(feature = "std"), no_std)]
use frame::prelude::*;

#[frame::pallet]
pub mod pallet {
	use super::*;

	#[pallet::config]
	pub trait Config: frame_system::Config {
		type RuntimeEvent: IsType<<Self as frame_system::Config>::RuntimeEvent> + From<Event<Self>>;
	}

	#[pallet::pallet]
	pub struct Pallet<T>(PhantomData<T>);

	#[pallet::event]
	pub enum Event<T: Config> {}
}
```

---

### 👷‍♂️ Runtime Construction

```rust
#[cfg(test)]
mod tests {
    use super::pallet as my_pallet;
    use frame::{prelude::*, testing_prelude::*};
    
    construct_runtime!(
        pub struct Runtime {
            System: frame_system,
            MyPallet: my_pallet,
            ...
        }
    );

	#[derive_impl(frame_system::TestDefaultConfig)]
	impl frame_system::Config for Runtime {}
	impl my_pallet::Config for Runtime {
		..
	}
}
```

note:

neater construct_runtime: https://github.com/paritytech/substrate/issues/14126
derive impls: https://github.com/paritytech/substrate/issues/14234

---

### 🦸 Super Pallets 

```rust
#[cfg(test)]
mod tests {
    use frame::{prelude::*, testing_prelude::*};

	construct_runtime!(
        pub struct Runtime {
            System: frame_system, 
            // contains gov-1 pallets, all as one item. 
            GovernanceBundle: frame_basic_governance,
        }
    );

	#[derive_impl(frame_basic_governance::TestDefaultConfig)]
	impl frame_basic_governance::Config for Runtime {}
}
```

note: 

not tracked in an issue yet, just an idea. 
opposite is here: https://github.com/paritytech/substrate/pull/13950/files (uses the same tech)


---

### 🔨 Pallet Tasks 

```rust
/// Some running total.
#[pallet::storage]
pub type Total<T: Config> = StorageValue<_, (u32, u32), ValueQuery>;

/// Numbers to be added into the total.
#[pallet::storage]
pub type Numbers<T> = StorageMap<_, Twox64Concat, u32, u32, OptionQuery>;

#[pallet::tasks]
impl<T: Config<I>, I: 'static> Pallet<T, I> {
	/// Add a pair of numbers into the totals and remove them.
	#[pallet::tasks(Numbers::<T, I>::iter_keys())]
	#[pallet::condition(|i| Numbers::<T, I>::contains_key(i))]
	#[pallet::task_index(0)]
	pub fn add_number_into_total(i: u32) -> DispatchResult {
		let v = Numbers::<T, I>::take(i).ok_or(Error::<T, I>::NotFound)?;
		Total::<T, I>::mutate(|(total_keys, total_values)| {
			*total_keys += i;
			*total_values += v;
		});
		Ok(())
	}
}
```

note: 

https://github.com/paritytech/substrate/issues/13530
Same task scheduler for tasks that don't have hard deadlines. 

---

### 💰 Automatic Storage Deposit 

```rust
trait Config {
-    /// Used only for deposits 🤮
-    type Currency: ReservableCurrency<_, _>;
    
+    /// Abstract storage deposit manager ✨
+    type Consideration: Consideration;
}
```

note: 

https://github.com/paritytech/substrate/issues/13529

---

### 🌁 View Functions

```rust
#[pallet::view_function]
impl<T: Config> Pallet<T> {
    pub fn account_balances(account: T::AccountId) -> Vec<T::Balance> {
        todo!();
    }
}
```

note: 
https://github.com/paritytech/substrate/issues/13358


---

### 🏋️‍♂️ Weight Clawback

- `proof_size` 📐
- `ref_time` 🤷 

note: 

- https://github.com/paritytech/substrate/issues/13501
- https://forum.polkadot.network/t/eliminating-pre-dispatch-weight/400
- https://www.youtube.com/watch?v=hSoSA6laK3Q&t=1230s

---

### 🔬 Benchmarking Syntax

```
#[benchmarks]
mod benchmarks {
	use super::*;

	#[benchmark]
	fn set_dummy_benchmark() {
		// This is the benchmark setup phase.
		// `set_dummy` is a constant time function, hence we hard-code some random value here.
		let value = 1000u32.into();
		#[extrinsic_call]
		set_dummy(RawOrigin::Root, value); // The execution phase is just running `set_dummy` extrinsic call

		// This is the optional benchmark verification phase, asserting certain states.
		assert_eq!(Pallet::<T>::dummy(), Some(value))
	}

```

----

### 🔬 Benchmarking Syntax

```
#[pallet::call]
#[pallet::weight_info(T::WeightInfo)]
impl<T: Config> Pallet<T> {
	#[pallet::call_index(1)]
	pub fn foo(_) -> DispatchResult {
		/* snip */
	}
    
    #[pallet::call_index(1)]
	pub fn bar(_) -> DispatchResult {
		/* snip */
	}
```

note: 

https://github.com/paritytech/substrate/issues/13132


---

### 🔄 MBMs

```rust
pub trait SteppedMigration {
	fn step(
		&self,
		cursor: &_,
		meter: &mut WeightMeter,
	) -> Result<Option<_>, _>;
}
```

---

### 📝 Versioned Migration

```
pub struct VersionedRuntimeUpgrade<
    const FROM: u16, 
    const TO: u16, 
    Inner: OnRuntimeUpgrade
>(_);
```

note: 

https://github.com/paritytech/substrate/pull/14311/files
