Add Parachain Template (#620)

* Add Canvas node as Parachain template

* Remove `pallet-contracts`

* Point to local Cumulus dependency

* Use double quotes instead of single quotes

* Get rid of GPL licensing

* Remove references to Canvas

* Get rid of warnings

* Remove GLP-3 License copy-pasta file

* Copy in README from `substrate-parachain-template`

* Add mention of `polkadot-launch` tool

* Add missing screenshot asset

* Remove Canvas hidden files and scripts

* Rename `template` to `parachain-template`

* Remove a few more Canvas references

* Add `pallet-template`

* Get `pallet-template` compiling

* Remove TODOs about Weights

* Sort some dependencies

* Remove contracts specific const

* Change binary name back to `parachain-collator`

* RustFmt

* Fix mock tests

* Purge sneaky whitespace

* Add template pallet index to runtime

Co-authored-by: Ricardo Rius <9488369+riusricardo@users.noreply.github.com>

* Add force authoring to collator `polkadot-launch` config

Co-authored-by: Ricardo Rius <9488369+riusricardo@users.noreply.github.com>

* Refer README readers to `substrate-parachain-template`

* Remove license header in `build.rs`

Co-authored-by: Michael Müller <michi@parity.io>

* Fix punctuation nitpick

Co-authored-by: Michael Müller <michi@parity.io>

* Remove unused `lib.rs` file

* Add note about Rococo network

Co-authored-by: Ricardo Rius <9488369+riusricardo@users.noreply.github.com>
Co-authored-by: Michael Müller <michi@parity.io>
This commit is contained in:
Hernando Castano
2021-09-23 13:47:47 -04:00
committed by GitHub
parent 1aab3349cc
commit 391d2f5241
22 changed files with 2863 additions and 3 deletions
@@ -0,0 +1,20 @@
//! Benchmarking setup for pallet-template
use super::*;
#[allow(unused)]
use crate::Module as Template;
use frame_benchmarking::{benchmarks, impl_benchmark_test_suite, whitelisted_caller};
use frame_system::RawOrigin;
benchmarks! {
do_something {
let s in 0 .. 100;
let caller: T::AccountId = whitelisted_caller();
}: _(RawOrigin::Signed(caller), s)
verify {
assert_eq!(Something::<T>::get(), Some(s));
}
}
impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test,);
@@ -0,0 +1,105 @@
#![cfg_attr(not(feature = "std"), no_std)]
/// Edit this file to define custom logic or remove it if it is not needed.
/// Learn more about FRAME and the core library of Substrate FRAME pallets:
/// <https://substrate.dev/docs/en/knowledgebase/runtime/frame>
pub use pallet::*;
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
#[frame_support::pallet]
pub mod pallet {
use frame_support::{dispatch::DispatchResultWithPostInfo, pallet_prelude::*};
use frame_system::pallet_prelude::*;
/// Configure the pallet by specifying the parameters and types on which it depends.
#[pallet::config]
pub trait Config: frame_system::Config {
/// Because this pallet emits events, it depends on the runtime's definition of an event.
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
}
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
// The pallet's runtime storage items.
// https://substrate.dev/docs/en/knowledgebase/runtime/storage
#[pallet::storage]
#[pallet::getter(fn something)]
// Learn more about declaring storage items:
// https://substrate.dev/docs/en/knowledgebase/runtime/storage#declaring-storage-items
pub type Something<T> = StorageValue<_, u32>;
// Pallets use events to inform users when important changes are made.
// https://substrate.dev/docs/en/knowledgebase/runtime/events
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Event documentation should end with an array that provides descriptive names for event
/// parameters. [something, who]
SomethingStored(u32, T::AccountId),
}
// Errors inform users that something went wrong.
#[pallet::error]
pub enum Error<T> {
/// Error names should be descriptive.
NoneValue,
/// Errors should have helpful documentation associated with them.
StorageOverflow,
}
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
// Dispatchable functions allows users to interact with the pallet and invoke state changes.
// These functions materialize as "extrinsics", which are often compared to transactions.
// Dispatchable functions must be annotated with a weight and must return a DispatchResult.
#[pallet::call]
impl<T: Config> Pallet<T> {
/// An example dispatchable that takes a singles value as a parameter, writes the value to
/// storage and emits an event. This function must be dispatched by a signed extrinsic.
#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
pub fn do_something(origin: OriginFor<T>, something: u32) -> DispatchResultWithPostInfo {
// Check that the extrinsic was signed and get the signer.
// This function will return an error if the extrinsic is not signed.
// https://substrate.dev/docs/en/knowledgebase/runtime/origin
let who = ensure_signed(origin)?;
// Update storage.
<Something<T>>::put(something);
// Emit an event.
Self::deposit_event(Event::SomethingStored(something, who));
// Return a successful DispatchResultWithPostInfo
Ok(().into())
}
/// An example dispatchable that may throw a custom error.
#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
pub fn cause_error(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
let _who = ensure_signed(origin)?;
// Read a value from storage.
match <Something<T>>::get() {
// Return an error if the value has not been set.
None => Err(Error::<T>::NoneValue)?,
Some(old) => {
// Increment the value read from storage; will error in the event of overflow.
let new = old.checked_add(1).ok_or(Error::<T>::StorageOverflow)?;
// Update the value in storage with the incremented result.
<Something<T>>::put(new);
Ok(().into())
},
}
}
}
}
@@ -0,0 +1,63 @@
use crate as pallet_template;
use frame_support::{parameter_types, traits::Everything};
use frame_system as system;
use sp_core::H256;
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
};
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
type Block = frame_system::mocking::MockBlock<Test>;
// Configure a mock runtime to test the pallet.
frame_support::construct_runtime!(
pub enum Test where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
TemplateModule: pallet_template::{Pallet, Call, Storage, Event<T>},
}
);
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const SS58Prefix: u8 = 42;
}
impl system::Config for Test {
type BaseCallFilter = Everything;
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type Origin = Origin;
type Call = Call;
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type Event = Event;
type BlockHashCount = BlockHashCount;
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = SS58Prefix;
type OnSetCode = ();
}
impl pallet_template::Config for Test {
type Event = Event;
}
// Build genesis storage according to the mock runtime.
pub fn new_test_ext() -> sp_io::TestExternalities {
system::GenesisConfig::default().build_storage::<Test>().unwrap().into()
}
@@ -0,0 +1,20 @@
use crate::{mock::*, Error};
use frame_support::{assert_noop, assert_ok};
#[test]
fn it_works_for_default_value() {
new_test_ext().execute_with(|| {
// Dispatch a signed extrinsic.
assert_ok!(TemplateModule::do_something(Origin::signed(1), 42));
// Read pallet storage and assert an expected result.
assert_eq!(TemplateModule::something(), Some(42));
});
}
#[test]
fn correct_error_for_none_value() {
new_test_ext().execute_with(|| {
// Ensure the expected error is thrown when no value is present.
assert_noop!(TemplateModule::cause_error(Origin::signed(1)), Error::<Test>::NoneValue);
});
}