lib.rs 68.1 KiB
Newer Older
/// 	decl_storage provide an upgrade template (see 3.). All storages, genesis config, genesis
/// 	build and default implementation of genesis config can be taken from it directly.
///
/// 	Otherwise here is the manual process:
///
/// 	first migrate the genesis logic. write:
/// 	```ignore
/// 	#[pallet::genesis_config]
/// 	struct GenesisConfig {
/// 		// fields of add_extra_genesis
/// 	}
/// 	impl Default for GenesisConfig {
/// 		// type default or default provided for fields
/// 	}
/// 	#[pallet::genesis_build]
/// 	impl<T: Config> GenesisBuild<T> for GenesisConfig {
/// 	// impl<T: Config, I: 'static> GenesisBuild<T, I> for GenesisConfig { for instantiable pallet
/// 		fn build() {
/// 			// The add_extra_genesis build logic
/// 		}
/// 	}
/// 	```
/// 	for each storages, if it contains config(..) then add a fields, and make its default to the
/// 	value in `= ..;` or the type default if none, if it contains no build then also add the
/// 	logic to build the value.
/// 	for each storages if it contains build(..) then add the logic to genesis_build.
///
/// 	NOTE: in decl_storage: is executed first the individual config and build and at the end the
/// 	add_extra_genesis build
///
/// 	Once this is done you can migrate storage individually, a few notes:
/// 	- for private storage use `pub(crate) type ` or `pub(super) type` or nothing,
/// 	- for storage with `get(fn ..)` use `#[pallet::getter(fn ...)]`
/// 	- for storage with value being `Option<$something>` make generic `Value` being `$something`
/// 		and generic `QueryKind` being `OptionQuery` (note: this is default). Otherwise make
/// 		`Value` the complete value type and `QueryKind` being `ValueQuery`.
/// 	- for storage with default value: `= $expr;` provide some specific OnEmpty generic. To do so
/// 		use of `#[pallet::type_value]` to generate the wanted struct to put.
/// 		example: `MyStorage: u32 = 3u32` would be written:
/// 		```ignore
/// 		#[pallet::type_value] fn MyStorageOnEmpty() -> u32 { 3u32 }
/// 		#[pallet::storage]
/// 		pub(super) type MyStorage<T> = StorageValue<u32, ValueQuery, MyStorageOnEmpty>;
/// 		```
///
/// 	NOTE: `decl_storage` also generates functions `assimilate_storage` and `build_storage`
/// 	directly on GenesisConfig, those are sometimes used in tests. In order not to break they
/// 	can be implemented manually, one can implement those functions by calling `GenesisBuild`
/// 10. **migrate origin**: move the origin to the pallet module under `#[pallet::origin]`
/// 11. **migrate validate_unsigned**: move the `ValidateUnsigned` implementation to the pallet
/// 	module under `#[pallet::validate_unsigned]`
/// 12. **migrate provide_inherent**: move the `ProvideInherent` implementation to the pallet
/// 	module under `#[pallet::inherent]`
/// 13. rename the usage of `Module` to `Pallet` inside the crate.
/// 14. migration is done, now double check migration with the checking migration guidelines.
///
/// ## Checking upgrade guidelines:
///
/// * compare metadata. Use [subsee](https://github.com/ascjones/subsee) to fetch the metadata
/// and do a diff of the resulting json before and after migration. This checks for:
/// 	* call, names, signature, docs
/// 	* event names, docs
/// 	* error names, docs
/// 	* storage names, hasher, prefixes, default value
/// 	* error , error, constant,
/// * manually check that:
/// 	* `Origin` is moved inside the macro under `#[pallet::origin]` if it exists
/// 	* `ValidateUnsigned` is moved inside the macro under `#[pallet::validate_unsigned)]` if it exists
/// 	* `ProvideInherent` is moved inside macro under `#[pallet::inherent)]` if it exists
/// 	* `on_initialize`/`on_finalize`/`on_runtime_upgrade`/`offchain_worker` are moved to `Hooks`
/// 	* storages with `config(..)` are converted to `GenesisConfig` field, and their default is
/// 		`= $expr;` if the storage have default value
/// 	* storages with `build($expr)` or `config(..)` are built in `GenesisBuild::build`
/// 	* `add_extra_genesis` fields are converted to `GenesisConfig` field with their correct
/// 		default if specified
/// 	* `add_extra_genesis` build is written into `GenesisBuild::build`
/// * storage items defined with [`pallet`] use the name of the pallet provided by
/// 	[`traits::PalletInfo::name`] as `pallet_prefix` (in `decl_storage`, storage items used the
/// 	`pallet_prefix` given as input of `decl_storage` with the syntax `as Example`).
/// 	Thus a runtime using the pallet must be careful with this change.
/// 	To handle this change:
/// 	* either ensure that the name of the pallet given to `construct_runtime!` is the same
/// 		as the name the pallet was giving to `decl_storage`,
/// 	* or do a storage migration from the old prefix used to the new prefix used.
///
/// 	NOTE: The prefixes used by storage items are in the metadata. Thus, ensuring the metadata hasn't
/// 	changed does ensure that the `pallet_prefix`s used by the storage items haven't changed.
///
/// # Notes when macro fails to show proper error message spans:
///
/// Rustc loses span for some macro input. Some tips to fix it:
/// * do not use inner attribute:
/// 	```ignore
/// 	#[pallet]
/// 	pub mod pallet {
/// 		//! This inner attribute will make span fail
/// 		..
/// 	}
/// 	```
/// * use the newest nightly possible.
///
pub use frame_support_procedural::pallet;