Rename Palette to FRAME (#4182)

* palette -> frame

* PALETTE, Palette -> FRAME

* Move folder pallete -> frame

* Update docs/Structure.adoc

Co-Authored-By: Benjamin Kampmann <ben.kampmann@googlemail.com>

* Update docs/README.adoc

Co-Authored-By: Benjamin Kampmann <ben.kampmann@googlemail.com>

* Update README.adoc
This commit is contained in:
Shawn Tabrizi
2019-11-22 19:21:25 +01:00
committed by GitHub
parent 68351da29b
commit c9175b59ff
206 changed files with 485 additions and 483 deletions
@@ -0,0 +1,641 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
#[cfg(test)]
// Do not complain about unused `dispatch` and `dispatch_aux`.
#[allow(dead_code)]
mod tests {
use support::metadata::*;
use std::marker::PhantomData;
use codec::{Encode, Decode, EncodeLike};
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
pub trait Trait {
type Origin: Encode + Decode + EncodeLike + std::default::Default;
type BlockNumber;
}
support::decl_storage! {
trait Store for Module<T: Trait> as TestStorage {
// non-getters: pub / $default
/// Hello, this is doc!
U32 : Option<u32>;
pub PUBU32 : Option<u32>;
U32MYDEF : Option<u32>;
pub PUBU32MYDEF : Option<u32>;
// getters: pub / $default
// we need at least one type which uses T, otherwise GenesisConfig will complain.
GETU32 get(fn u32_getter): T::Origin;
pub PUBGETU32 get(fn pub_u32_getter) build(|config: &GenesisConfig| config.u32_getter_with_config): u32;
GETU32WITHCONFIG get(fn u32_getter_with_config) config(): u32;
pub PUBGETU32WITHCONFIG get(fn pub_u32_getter_with_config) config(): u32;
GETU32MYDEF get(fn u32_getter_mydef): Option<u32>;
pub PUBGETU32MYDEF get(fn pub_u32_getter_mydef) config(): u32 = 3;
GETU32WITHCONFIGMYDEF get(fn u32_getter_with_config_mydef) config(): u32 = 2;
pub PUBGETU32WITHCONFIGMYDEF get(fn pub_u32_getter_with_config_mydef) config(): u32 = 1;
PUBGETU32WITHCONFIGMYDEFOPT get(fn pub_u32_getter_with_config_mydef_opt) config(): Option<u32>;
// map non-getters: pub / $default
MAPU32 : map u32 => Option<String>;
pub PUBMAPU32 : map u32 => Option<String>;
MAPU32MYDEF : map u32 => Option<String>;
pub PUBMAPU32MYDEF : map u32 => Option<String>;
// map getters: pub / $default
GETMAPU32 get(fn map_u32_getter): map u32 => String;
pub PUBGETMAPU32 get(fn pub_map_u32_getter): map u32 => String;
GETMAPU32MYDEF get(fn map_u32_getter_mydef): map u32 => String = "map".into();
pub PUBGETMAPU32MYDEF get(fn pub_map_u32_getter_mydef): map u32 => String = "pubmap".into();
// linked map
LINKEDMAPU32 : linked_map u32 => Option<String>;
pub PUBLINKEDMAPU32MYDEF : linked_map u32 => Option<String>;
GETLINKEDMAPU32 get(fn linked_map_u32_getter): linked_map u32 => String;
pub PUBGETLINKEDMAPU32MYDEF get(fn pub_linked_map_u32_getter_mydef): linked_map u32 => String = "pubmap".into();
COMPLEXTYPE1: ::std::vec::Vec<<T as Trait>::Origin>;
COMPLEXTYPE2: (Vec<Vec<(u16,Box<( )>)>>, u32);
COMPLEXTYPE3: ([u32;25]);
}
add_extra_genesis {
build(|_| {});
}
}
struct TraitImpl {}
impl Trait for TraitImpl {
type Origin = u32;
type BlockNumber = u32;
}
const EXPECTED_METADATA: StorageMetadata = StorageMetadata {
prefix: DecodeDifferent::Encode("TestStorage"),
entries: DecodeDifferent::Encode(
&[
StorageEntryMetadata {
name: DecodeDifferent::Encode("U32"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructU32(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[ " Hello, this is doc!" ]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBU32"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBU32(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("U32MYDEF"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructU32MYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBU32MYDEF"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBU32MYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("GETU32"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("T::Origin")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructGETU32(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBGETU32"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBGETU32(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("GETU32WITHCONFIG"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructGETU32WITHCONFIG(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBGETU32WITHCONFIG"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBGETU32WITHCONFIG(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("GETU32MYDEF"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructGETU32MYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBGETU32MYDEF"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBGETU32MYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("GETU32WITHCONFIGMYDEF"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructGETU32WITHCONFIGMYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBGETU32WITHCONFIGMYDEF"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBGETU32WITHCONFIGMYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBGETU32WITHCONFIGMYDEFOPT"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBGETU32WITHCONFIGMYDEFOPT(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("MAPU32"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: false,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructMAPU32(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBMAPU32"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: false,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBMAPU32(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("MAPU32MYDEF"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: false,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructMAPU32MYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBMAPU32MYDEF"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: false,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBMAPU32MYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("GETMAPU32"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: false,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructGETMAPU32(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBGETMAPU32"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: false,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBGETMAPU32(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("GETMAPU32MYDEF"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: false,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructGETMAPU32MYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBGETMAPU32MYDEF"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: false,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBGETMAPU32MYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("LINKEDMAPU32"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: true,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructLINKEDMAPU32(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBLINKEDMAPU32MYDEF"),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: true,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBLINKEDMAPU32MYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("GETLINKEDMAPU32"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: true,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructGETLINKEDMAPU32(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("PUBGETLINKEDMAPU32MYDEF"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u32"),
value: DecodeDifferent::Encode("String"),
is_linked: true,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructPUBGETLINKEDMAPU32MYDEF(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("COMPLEXTYPE1"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("::std::vec::Vec<<T as Trait>::Origin>")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructCOMPLEXTYPE1(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("COMPLEXTYPE2"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("(Vec<Vec<(u16, Box<()>)>>, u32)")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructCOMPLEXTYPE2(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("COMPLEXTYPE3"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("([u32; 25])")),
default: DecodeDifferent::Encode(
DefaultByteGetter(&__GetByteStructCOMPLEXTYPE3(PhantomData::<TraitImpl>))
),
documentation: DecodeDifferent::Encode(&[]),
},
]
),
};
#[test]
fn store_metadata() {
let metadata = Module::<TraitImpl>::storage_metadata();
assert_eq!(EXPECTED_METADATA, metadata);
}
#[test]
fn check_genesis_config() {
let config = GenesisConfig::default();
assert_eq!(config.u32_getter_with_config, 0u32);
assert_eq!(config.pub_u32_getter_with_config, 0u32);
assert_eq!(config.pub_u32_getter_mydef, 3u32);
assert_eq!(config.u32_getter_with_config_mydef, 2u32);
assert_eq!(config.pub_u32_getter_with_config_mydef, 1u32);
assert_eq!(config.pub_u32_getter_with_config_mydef_opt, 0u32);
}
}
#[cfg(test)]
#[allow(dead_code)]
mod test2 {
pub trait Trait {
type Origin;
type BlockNumber;
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
type PairOf<T> = (T, T);
support::decl_storage! {
trait Store for Module<T: Trait> as TestStorage {
SingleDef : u32;
PairDef : PairOf<u32>;
Single : Option<u32>;
Pair : (u32, u32);
}
add_extra_genesis {
config(_marker) : ::std::marker::PhantomData<T>;
config(extra_field) : u32 = 32;
build(|_| {});
}
}
struct TraitImpl {}
impl Trait for TraitImpl {
type Origin = u32;
type BlockNumber = u32;
}
}
#[cfg(test)]
#[allow(dead_code)]
mod test3 {
pub trait Trait {
type Origin;
type BlockNumber;
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
support::decl_storage! {
trait Store for Module<T: Trait> as Test {
Foo get(fn foo) config(initial_foo): u32;
}
}
type PairOf<T> = (T, T);
struct TraitImpl {}
impl Trait for TraitImpl {
type Origin = u32;
type BlockNumber = u32;
}
}
#[cfg(test)]
#[allow(dead_code)]
mod test_append_and_len {
use runtime_io::TestExternalities;
use codec::{Encode, Decode};
pub trait Trait {
type Origin;
type BlockNumber;
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
struct NoDef(u32);
support::decl_storage! {
trait Store for Module<T: Trait> as Test {
NoDefault: Option<NoDef>;
JustVec: Vec<u32>;
JustVecWithDefault: Vec<u32> = vec![6, 9];
OptionVec: Option<Vec<u32>>;
MapVec: map u32 => Vec<u32>;
MapVecWithDefault: map u32 => Vec<u32> = vec![6, 9];
OptionMapVec: map u32 => Option<Vec<u32>>;
LinkedMapVec: linked_map u32 => Vec<u32>;
LinkedMapVecWithDefault: linked_map u32 => Vec<u32> = vec![6, 9];
OptionLinkedMapVec: linked_map u32 => Option<Vec<u32>>;
}
}
struct Test {}
impl Trait for Test {
type Origin = u32;
type BlockNumber = u32;
}
#[test]
fn default_for_option() {
TestExternalities::default().execute_with(|| {
assert_eq!(OptionVec::get(), None);
assert_eq!(JustVec::get(), vec![]);
});
}
#[test]
fn append_works() {
TestExternalities::default().execute_with(|| {
let _ = MapVec::append(1, [1, 2, 3].iter());
let _ = MapVec::append(1, [4, 5].iter());
assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]);
let _ = JustVec::append([1, 2, 3].iter());
let _ = JustVec::append([4, 5].iter());
assert_eq!(JustVec::get(), vec![1, 2, 3, 4, 5]);
});
}
#[test]
fn append_works_for_default() {
TestExternalities::default().execute_with(|| {
assert_eq!(JustVecWithDefault::get(), vec![6, 9]);
let _ = JustVecWithDefault::append([1].iter());
assert_eq!(JustVecWithDefault::get(), vec![6, 9, 1]);
assert_eq!(MapVecWithDefault::get(0), vec![6, 9]);
let _ = MapVecWithDefault::append(0, [1].iter());
assert_eq!(MapVecWithDefault::get(0), vec![6, 9, 1]);
assert_eq!(OptionVec::get(), None);
let _ = OptionVec::append([1].iter());
assert_eq!(OptionVec::get(), Some(vec![1]));
});
}
#[test]
fn append_or_put_works() {
TestExternalities::default().execute_with(|| {
let _ = MapVec::append_or_insert(1, &[1, 2, 3][..]);
let _ = MapVec::append_or_insert(1, &[4, 5][..]);
assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]);
let _ = JustVec::append_or_put(&[1, 2, 3][..]);
let _ = JustVec::append_or_put(&[4, 5][..]);
assert_eq!(JustVec::get(), vec![1, 2, 3, 4, 5]);
let _ = OptionVec::append_or_put(&[1, 2, 3][..]);
let _ = OptionVec::append_or_put(&[4, 5][..]);
assert_eq!(OptionVec::get(), Some(vec![1, 2, 3, 4, 5]));
});
}
#[test]
fn len_works() {
TestExternalities::default().execute_with(|| {
JustVec::put(&vec![1, 2, 3, 4]);
OptionVec::put(&vec![1, 2, 3, 4, 5]);
MapVec::insert(1, &vec![1, 2, 3, 4, 5, 6]);
LinkedMapVec::insert(2, &vec![1, 2, 3]);
assert_eq!(JustVec::decode_len().unwrap(), 4);
assert_eq!(OptionVec::decode_len().unwrap(), 5);
assert_eq!(MapVec::decode_len(1).unwrap(), 6);
assert_eq!(LinkedMapVec::decode_len(2).unwrap(), 3);
});
}
#[test]
fn len_works_for_default() {
TestExternalities::default().execute_with(|| {
// vec
assert_eq!(JustVec::get(), vec![]);
assert_eq!(JustVec::decode_len(), Ok(0));
assert_eq!(JustVecWithDefault::get(), vec![6, 9]);
assert_eq!(JustVecWithDefault::decode_len(), Ok(2));
assert_eq!(OptionVec::get(), None);
assert_eq!(OptionVec::decode_len(), Ok(0));
// map
assert_eq!(MapVec::get(0), vec![]);
assert_eq!(MapVec::decode_len(0), Ok(0));
assert_eq!(MapVecWithDefault::get(0), vec![6, 9]);
assert_eq!(MapVecWithDefault::decode_len(0), Ok(2));
assert_eq!(OptionMapVec::get(0), None);
assert_eq!(OptionMapVec::decode_len(0), Ok(0));
// linked map
assert_eq!(LinkedMapVec::get(0), vec![]);
assert_eq!(LinkedMapVec::decode_len(0), Ok(0));
assert_eq!(LinkedMapVecWithDefault::get(0), vec![6, 9]);
assert_eq!(LinkedMapVecWithDefault::decode_len(0), Ok(2));
assert_eq!(OptionLinkedMapVec::get(0), None);
assert_eq!(OptionLinkedMapVec::decode_len(0), Ok(0));
});
}
}
@@ -0,0 +1,24 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
#[test]
fn decl_storage_ui() {
// As trybuild is using `cargo check`, we don't need the real WASM binaries.
std::env::set_var("BUILD_DUMMY_WASM_BINARY", "1");
let t = trybuild::TestCases::new();
t.compile_fail("tests/decl_storage_ui/*.rs");
}
@@ -0,0 +1,33 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
pub trait Trait {
type Origin;
type BlockNumber: codec::Codec + codec::EncodeLike + Default + Clone;
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
support::decl_storage!{
trait Store for Module<T: Trait> as FinalKeysNone {
pub Value config(value): u32;
pub Value2 config(value): u32;
}
}
fn main() {}
@@ -0,0 +1,5 @@
error: `config()`/`get()` with the same name already defined.
--> $DIR/config_duplicate.rs:29:21
|
29 | pub Value2 config(value): u32;
| ^^^^^
@@ -0,0 +1,33 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
pub trait Trait {
type Origin;
type BlockNumber: codec::Codec + codec::EncodeLike + Default + Clone;
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
support::decl_storage!{
trait Store for Module<T: Trait> as FinalKeysNone {
pub Value get(fn value) config(): u32;
pub Value2 config(value): u32;
}
}
fn main() {}
@@ -0,0 +1,5 @@
error: `config()`/`get()` with the same name already defined.
--> $DIR/config_get_duplicate.rs:29:21
|
29 | pub Value2 config(value): u32;
| ^^^^^
@@ -0,0 +1,33 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
pub trait Trait {
type Origin;
type BlockNumber: codec::Codec + codec::EncodeLike + Default + Clone;
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
support::decl_storage!{
trait Store for Module<T: Trait> as FinalKeysNone {
pub Value get(fn value) config(): u32;
pub Value2 get(fn value) config(): u32;
}
}
fn main() {}
@@ -0,0 +1,5 @@
error: `config()`/`get()` with the same name already defined.
--> $DIR/get_duplicate.rs:29:21
|
29 | pub Value2 get(fn value) config(): u32;
| ^^^^^
@@ -0,0 +1,227 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
use support::storage::unhashed;
use codec::Encode;
use support::{StorageDoubleMap, StorageLinkedMap, StorageMap, StorageValue};
use runtime_io::{TestExternalities, hashing};
mod no_instance {
use codec::{Encode, Decode, EncodeLike};
pub trait Trait {
type Origin;
type BlockNumber: Encode + Decode + EncodeLike + Default + Clone;
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
support::decl_storage!{
trait Store for Module<T: Trait> as FinalKeysNone {
pub Value config(value): u32;
pub Map: map u32 => u32;
pub Map2: map hasher(twox_128) u32 => u32;
pub LinkedMap: linked_map u32 => u32;
pub LinkedMap2: linked_map hasher(twox_128) u32 => u32;
pub DoubleMap: double_map u32, blake2_256(u32) => u32;
pub DoubleMap2: double_map hasher(twox_128) u32, blake2_128(u32) => u32;
pub TestGenericValue get(fn test_generic_value) config(): Option<T::BlockNumber>;
pub TestGenericDoubleMap get(fn foo2) config(test_generic_double_map):
double_map u32, blake2_256(T::BlockNumber) => Option<u32>;
}
}
}
mod instance {
pub trait Trait<I = DefaultInstance>: super::no_instance::Trait {}
support::decl_module! {
pub struct Module<T: Trait<I>, I: Instantiable = DefaultInstance>
for enum Call where origin: T::Origin {}
}
support::decl_storage!{
trait Store for Module<T: Trait<I>, I: Instantiable = DefaultInstance>
as FinalKeysSome
{
pub Value config(value): u32;
pub Map: map u32 => u32;
pub Map2: map hasher(twox_128) u32 => u32;
pub LinkedMap: linked_map u32 => u32;
pub LinkedMap2: linked_map hasher(twox_128) u32 => u32;
pub DoubleMap: double_map u32, blake2_256(u32) => u32;
pub DoubleMap2: double_map hasher(twox_128) u32, blake2_128(u32) => u32;
pub TestGenericValue get(fn test_generic_value) config(): Option<T::BlockNumber>;
pub TestGenericDoubleMap get(fn foo2) config(test_generic_double_map):
double_map u32, blake2_256(T::BlockNumber) => Option<u32>;
}
add_extra_genesis {
// See `decl_storage` limitation.
config(phantom): core::marker::PhantomData<I>;
}
}
}
#[test]
fn final_keys_no_instance() {
TestExternalities::default().execute_with(|| {
no_instance::Value::put(1);
assert_eq!(unhashed::get::<u32>(&hashing::twox_128(b"FinalKeysNone Value")), Some(1u32));
no_instance::Map::insert(1, 2);
let mut k = b"FinalKeysNone Map".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
no_instance::Map2::insert(1, 2);
let mut k = b"FinalKeysNone Map2".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
let head = b"head of FinalKeysNone LinkedMap".to_vec();
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), None);
no_instance::LinkedMap::insert(1, 2);
let mut k = b"FinalKeysNone LinkedMap".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), Some(1u32));
no_instance::LinkedMap2::insert(1, 2);
let mut k = b"FinalKeysNone LinkedMap2".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
no_instance::DoubleMap::insert(&1, &2, &3);
let mut k = b"FinalKeysNone DoubleMap".to_vec();
k.extend(1u32.encode());
let mut k = hashing::blake2_256(&k).to_vec();
k.extend(&hashing::blake2_256(&2u32.encode()));
assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
no_instance::DoubleMap2::insert(&1, &2, &3);
let mut k = b"FinalKeysNone DoubleMap2".to_vec();
k.extend(1u32.encode());
let mut k = hashing::twox_128(&k).to_vec();
k.extend(&hashing::blake2_128(&2u32.encode()));
assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
});
}
#[test]
fn final_keys_default_instance() {
TestExternalities::default().execute_with(|| {
<instance::Value<instance::DefaultInstance>>::put(1);
assert_eq!(unhashed::get::<u32>(&hashing::twox_128(b"FinalKeysSome Value")), Some(1u32));
<instance::Map<instance::DefaultInstance>>::insert(1, 2);
let mut k = b"FinalKeysSome Map".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
<instance::Map2<instance::DefaultInstance>>::insert(1, 2);
let mut k = b"FinalKeysSome Map2".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
let head = b"head of FinalKeysSome LinkedMap".to_vec();
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), None);
<instance::LinkedMap<instance::DefaultInstance>>::insert(1, 2);
let mut k = b"FinalKeysSome LinkedMap".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), Some(1u32));
<instance::LinkedMap2<instance::DefaultInstance>>::insert(1, 2);
let mut k = b"FinalKeysSome LinkedMap2".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
<instance::DoubleMap<instance::DefaultInstance>>::insert(&1, &2, &3);
let mut k = b"FinalKeysSome DoubleMap".to_vec();
k.extend(1u32.encode());
let mut k = hashing::blake2_256(&k).to_vec();
k.extend(&hashing::blake2_256(&2u32.encode()));
assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
<instance::DoubleMap2<instance::DefaultInstance>>::insert(&1, &2, &3);
let mut k = b"FinalKeysSome DoubleMap2".to_vec();
k.extend(1u32.encode());
let mut k = hashing::twox_128(&k).to_vec();
k.extend(&hashing::blake2_128(&2u32.encode()));
assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
});
}
#[test]
fn final_keys_instance_2() {
TestExternalities::default().execute_with(|| {
<instance::Value<instance::Instance2>>::put(1);
assert_eq!(
unhashed::get::<u32>(&hashing::twox_128(b"Instance2FinalKeysSome Value")),
Some(1u32)
);
<instance::Map<instance::Instance2>>::insert(1, 2);
let mut k = b"Instance2FinalKeysSome Map".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
<instance::Map2<instance::Instance2>>::insert(1, 2);
let mut k = b"Instance2FinalKeysSome Map2".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
let head = b"head of Instance2FinalKeysSome LinkedMap".to_vec();
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), None);
<instance::LinkedMap<instance::Instance2>>::insert(1, 2);
let mut k = b"Instance2FinalKeysSome LinkedMap".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), Some(1u32));
<instance::LinkedMap2<instance::Instance2>>::insert(1, 2);
let mut k = b"Instance2FinalKeysSome LinkedMap2".to_vec();
k.extend(1u32.encode());
assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
<instance::DoubleMap<instance::Instance2>>::insert(&1, &2, &3);
let mut k = b"Instance2FinalKeysSome DoubleMap".to_vec();
k.extend(1u32.encode());
let mut k = hashing::blake2_256(&k).to_vec();
k.extend(&hashing::blake2_256(&2u32.encode()));
assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
<instance::DoubleMap2<instance::Instance2>>::insert(&1, &2, &3);
let mut k = b"Instance2FinalKeysSome DoubleMap2".to_vec();
k.extend(1u32.encode());
let mut k = hashing::twox_128(&k).to_vec();
k.extend(&hashing::blake2_128(&2u32.encode()));
assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
});
}
@@ -0,0 +1,44 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
pub trait Trait {
type BlockNumber: codec::Codec + codec::EncodeLike + Default;
type Origin;
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
support::decl_storage! {
trait Store for Module<T: Trait> as Example {
pub AppendableDM config(t): double_map u32, blake2_256(T::BlockNumber) => Vec<u32>;
}
}
struct Test;
impl Trait for Test {
type BlockNumber = u32;
type Origin = ();
}
#[test]
fn init_genesis_config() {
GenesisConfig::<Test> {
t: Default::default(),
};
}
@@ -0,0 +1,485 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
#![recursion_limit="128"]
use sr_primitives::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}};
use support::{
Parameter, traits::Get, parameter_types,
metadata::{
DecodeDifferent, StorageMetadata, StorageEntryModifier, StorageEntryType, DefaultByteGetter,
StorageEntryMetadata, StorageHasher,
},
StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap,
};
use inherents::{ProvideInherent, InherentData, InherentIdentifier, MakeFatalError};
use primitives::{H256, sr25519};
mod system;
pub trait Currency {}
// Test for:
// * No default instance
// * Custom InstantiableTrait
// * Origin, Inherent, Event
mod module1 {
use super::*;
pub trait Trait<I>: system::Trait where <Self as system::Trait>::BlockNumber: From<u32> {
type Event: From<Event<Self, I>> + Into<<Self as system::Trait>::Event>;
type Origin: From<Origin<Self, I>>;
type SomeParameter: Get<u32>;
type GenericType: Default + Clone + codec::Codec + codec::EncodeLike;
}
support::decl_module! {
pub struct Module<T: Trait<I>, I: InstantiableThing> for enum Call where
origin: <T as system::Trait>::Origin,
T::BlockNumber: From<u32>
{
fn offchain_worker() {}
fn deposit_event() = default;
fn one(origin) {
system::ensure_root(origin)?;
Self::deposit_event(RawEvent::AnotherVariant(3));
}
}
}
support::decl_storage! {
trait Store for Module<T: Trait<I>, I: InstantiableThing> as Module1 where
T::BlockNumber: From<u32> + std::fmt::Display
{
pub Value config(value): T::GenericType;
pub Map: map u32 => u64;
pub LinkedMap: linked_map u32 => u64;
}
add_extra_genesis {
config(test) : T::BlockNumber;
build(|config: &Self| {
println!("{}", config.test);
});
}
}
support::decl_event! {
pub enum Event<T, I> where Phantom = std::marker::PhantomData<T> {
_Phantom(Phantom),
AnotherVariant(u32),
}
}
#[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)]
pub enum Origin<T: Trait<I>, I> where T::BlockNumber: From<u32> {
Members(u32),
_Phantom(std::marker::PhantomData<(T, I)>),
}
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"12345678";
impl<T: Trait<I>, I: InstantiableThing> ProvideInherent for Module<T, I> where
T::BlockNumber: From<u32>
{
type Call = Call<T, I>;
type Error = MakeFatalError<inherents::Error>;
const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
fn create_inherent(_data: &InherentData) -> Option<Self::Call> {
unimplemented!();
}
fn check_inherent(_: &Self::Call, _: &InherentData) -> std::result::Result<(), Self::Error> {
unimplemented!();
}
}
}
// Test for:
// * default instance
// * use of no_genesis_config_phantom_data
mod module2 {
use super::*;
pub trait Trait<I=DefaultInstance>: system::Trait {
type Amount: Parameter + Default;
type Event: From<Event<Self, I>> + Into<<Self as system::Trait>::Event>;
type Origin: From<Origin<Self, I>>;
}
impl<T: Trait<I>, I: Instance> Currency for Module<T, I> {}
support::decl_module! {
pub struct Module<T: Trait<I>, I: Instance=DefaultInstance> for enum Call where
origin: <T as system::Trait>::Origin
{
fn deposit_event() = default;
}
}
support::decl_storage! {
trait Store for Module<T: Trait<I>, I: Instance=DefaultInstance> as Module2 {
pub Value config(value): T::Amount;
pub Map config(map): map u64 => u64;
pub LinkedMap config(linked_map): linked_map u64 => Vec<u8>;
pub DoubleMap config(double_map): double_map u64, blake2_256(u64) => u64;
}
}
support::decl_event! {
pub enum Event<T, I=DefaultInstance> where Amount = <T as Trait<I>>::Amount {
Variant(Amount),
}
}
#[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)]
pub enum Origin<T: Trait<I>, I=DefaultInstance> {
Members(u32),
_Phantom(std::marker::PhantomData<(T, I)>),
}
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"12345678";
impl<T: Trait<I>, I: Instance> ProvideInherent for Module<T, I> {
type Call = Call<T, I>;
type Error = MakeFatalError<inherents::Error>;
const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
fn create_inherent(_data: &InherentData) -> Option<Self::Call> {
unimplemented!();
}
fn check_inherent(_call: &Self::Call, _data: &InherentData) -> std::result::Result<(), Self::Error> {
unimplemented!();
}
}
}
// Test for:
// * Depends on multiple instances of a module with instances
mod module3 {
use super::*;
pub trait Trait: module2::Trait + module2::Trait<module2::Instance1> + system::Trait {
type Currency: Currency;
type Currency2: Currency;
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: <T as system::Trait>::Origin {}
}
}
parameter_types! {
pub const SomeValue: u32 = 100;
}
impl module1::Trait<module1::Instance1> for Runtime {
type Event = Event;
type Origin = Origin;
type SomeParameter = SomeValue;
type GenericType = u32;
}
impl module1::Trait<module1::Instance2> for Runtime {
type Event = Event;
type Origin = Origin;
type SomeParameter = SomeValue;
type GenericType = u32;
}
impl module2::Trait for Runtime {
type Amount = u16;
type Event = Event;
type Origin = Origin;
}
impl module2::Trait<module2::Instance1> for Runtime {
type Amount = u32;
type Event = Event;
type Origin = Origin;
}
impl module2::Trait<module2::Instance2> for Runtime {
type Amount = u32;
type Event = Event;
type Origin = Origin;
}
impl module2::Trait<module2::Instance3> for Runtime {
type Amount = u64;
type Event = Event;
type Origin = Origin;
}
impl module3::Trait for Runtime {
type Currency = Module2_2;
type Currency2 = Module2_3;
}
pub type Signature = sr25519::Signature;
pub type AccountId = <Signature as Verify>::Signer;
pub type BlockNumber = u64;
pub type Index = u64;
impl system::Trait for Runtime {
type Hash = H256;
type Origin = Origin;
type BlockNumber = BlockNumber;
type AccountId = AccountId;
type Event = Event;
}
support::construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: system::{Module, Call, Event},
Module1_1: module1::<Instance1>::{
Module, Call, Storage, Event<T>, Config<T>, Origin<T>, Inherent
},
Module1_2: module1::<Instance2>::{
Module, Call, Storage, Event<T>, Config<T>, Origin<T>, Inherent
},
Module2: module2::{Module, Call, Storage, Event<T>, Config<T>, Origin<T>, Inherent},
Module2_1: module2::<Instance1>::{
Module, Call, Storage, Event<T>, Config<T>, Origin<T>, Inherent
},
Module2_2: module2::<Instance2>::{
Module, Call, Storage, Event<T>, Config<T>, Origin<T>, Inherent
},
Module2_3: module2::<Instance3>::{
Module, Call, Storage, Event<T>, Config<T>, Origin<T>, Inherent
},
Module3: module3::{Module, Call},
}
);
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<u32, Call, Signature, ()>;
fn new_test_ext() -> runtime_io::TestExternalities {
GenesisConfig{
module1_Instance1: Some(module1::GenesisConfig {
value: 3,
test: 2,
}),
module1_Instance2: Some(module1::GenesisConfig {
value: 4,
test: 5,
}),
module2: Some(module2::GenesisConfig {
value: 4,
map: vec![(0, 0)],
linked_map: vec![(0, vec![0])],
double_map: vec![(0, 0, 0)],
}),
module2_Instance1: Some(module2::GenesisConfig {
value: 4,
map: vec![(0, 0)],
linked_map: vec![(0, vec![0])],
double_map: vec![(0, 0, 0)],
}),
module2_Instance2: None,
module2_Instance3: None,
}.build_storage().unwrap().into()
}
#[test]
fn storage_instance_independance() {
let mut storage = (std::collections::HashMap::new(), std::collections::HashMap::new());
state_machine::BasicExternalities::execute_with_storage(&mut storage, || {
module2::Value::<Runtime>::put(0);
module2::Value::<Runtime, module2::Instance1>::put(0);
module2::Value::<Runtime, module2::Instance2>::put(0);
module2::Value::<Runtime, module2::Instance3>::put(0);
module2::Map::<module2::DefaultInstance>::insert(0, 0);
module2::Map::<module2::Instance1>::insert(0, 0);
module2::Map::<module2::Instance2>::insert(0, 0);
module2::Map::<module2::Instance3>::insert(0, 0);
module2::LinkedMap::<module2::DefaultInstance>::insert::<_, Vec<u8>>(0, vec![]);
module2::LinkedMap::<module2::Instance1>::insert::<_, Vec<u8>>(0, vec![]);
module2::LinkedMap::<module2::Instance2>::insert::<_, Vec<u8>>(0, vec![]);
module2::LinkedMap::<module2::Instance3>::insert::<_, Vec<u8>>(0, vec![]);
module2::DoubleMap::<module2::DefaultInstance>::insert(&0, &0, &0);
module2::DoubleMap::<module2::Instance1>::insert(&0, &0, &0);
module2::DoubleMap::<module2::Instance2>::insert(&0, &0, &0);
module2::DoubleMap::<module2::Instance3>::insert(&0, &0, &0);
});
// 16 storage values + 4 linked_map head.
assert_eq!(storage.0.len(), 16 + 4);
}
#[test]
fn storage_with_instance_basic_operation() {
new_test_ext().execute_with(|| {
type Value = module2::Value<Runtime, module2::Instance1>;
type Map = module2::Map<module2::Instance1>;
type LinkedMap = module2::LinkedMap<module2::Instance1>;
type DoubleMap = module2::DoubleMap<module2::Instance1>;
assert_eq!(Value::exists(), true);
assert_eq!(Value::get(), 4);
Value::put(1);
assert_eq!(Value::get(), 1);
assert_eq!(Value::take(), 1);
assert_eq!(Value::get(), 0);
Value::mutate(|a| *a=2);
assert_eq!(Value::get(), 2);
Value::kill();
assert_eq!(Value::exists(), false);
assert_eq!(Value::get(), 0);
let key = 1;
assert_eq!(Map::exists(0), true);
assert_eq!(Map::exists(key), false);
Map::insert(key, 1);
assert_eq!(Map::get(key), 1);
assert_eq!(Map::take(key), 1);
assert_eq!(Map::get(key), 0);
Map::mutate(key, |a| *a=2);
assert_eq!(Map::get(key), 2);
Map::remove(key);
assert_eq!(Map::exists(key), false);
assert_eq!(Map::get(key), 0);
assert_eq!(LinkedMap::exists(0), true);
assert_eq!(LinkedMap::exists(key), false);
LinkedMap::insert(key, vec![1]);
assert_eq!(LinkedMap::enumerate().count(), 2);
assert_eq!(LinkedMap::get(key), vec![1]);
assert_eq!(LinkedMap::take(key), vec![1]);
assert_eq!(LinkedMap::enumerate().count(), 1);
assert_eq!(LinkedMap::get(key), vec![]);
LinkedMap::mutate(key, |a| *a=vec![2]);
assert_eq!(LinkedMap::enumerate().count(), 2);
assert_eq!(LinkedMap::get(key), vec![2]);
LinkedMap::remove(key);
assert_eq!(LinkedMap::enumerate().count(), 1);
assert_eq!(LinkedMap::exists(key), false);
assert_eq!(LinkedMap::get(key), vec![]);
assert_eq!(LinkedMap::exists(key), false);
assert_eq!(LinkedMap::enumerate().count(), 1);
LinkedMap::insert(key, &vec![1]);
assert_eq!(LinkedMap::enumerate().count(), 2);
let key1 = 1;
let key2 = 1;
assert_eq!(DoubleMap::exists(&0, &0), true);
assert_eq!(DoubleMap::exists(&key1, &key2), false);
DoubleMap::insert(&key1, &key2, &1);
assert_eq!(DoubleMap::get(&key1, &key2), 1);
assert_eq!(DoubleMap::take(&key1, &key2), 1);
assert_eq!(DoubleMap::get(&key1, &key2), 0);
DoubleMap::mutate(&key1, &key2, |a| *a=2);
assert_eq!(DoubleMap::get(&key1, &key2), 2);
DoubleMap::remove(&key1, &key2);
assert_eq!(DoubleMap::get(&key1, &key2), 0);
});
}
const EXPECTED_METADATA: StorageMetadata = StorageMetadata {
prefix: DecodeDifferent::Encode("Instance2Module2"),
entries: DecodeDifferent::Encode(
&[
StorageEntryMetadata {
name: DecodeDifferent::Encode("Value"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Plain(DecodeDifferent::Encode("T::Amount")),
default: DecodeDifferent::Encode(
DefaultByteGetter(
&module2::__GetByteStructValue(
std::marker::PhantomData::<(Runtime, module2::Instance2)>
)
)
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("Map"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u64"),
value: DecodeDifferent::Encode("u64"),
is_linked: false,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(
&module2::__GetByteStructMap(
std::marker::PhantomData::<(Runtime, module2::Instance2)>
)
)
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("LinkedMap"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::Map {
hasher: StorageHasher::Blake2_256,
key: DecodeDifferent::Encode("u64"),
value: DecodeDifferent::Encode("Vec<u8>"),
is_linked: true,
},
default: DecodeDifferent::Encode(
DefaultByteGetter(
&module2::__GetByteStructLinkedMap(
std::marker::PhantomData::<(Runtime, module2::Instance2)>
)
)
),
documentation: DecodeDifferent::Encode(&[]),
},
StorageEntryMetadata {
name: DecodeDifferent::Encode("DoubleMap"),
modifier: StorageEntryModifier::Default,
ty: StorageEntryType::DoubleMap {
hasher: StorageHasher::Blake2_256,
key2_hasher: StorageHasher::Blake2_256,
key1: DecodeDifferent::Encode("u64"),
key2: DecodeDifferent::Encode("u64"),
value: DecodeDifferent::Encode("u64"),
},
default: DecodeDifferent::Encode(
DefaultByteGetter(
&module2::__GetByteStructDoubleMap(
std::marker::PhantomData::<(Runtime, module2::Instance2)>
)
)
),
documentation: DecodeDifferent::Encode(&[]),
}
]
)
};
#[test]
fn test_instance_storage_metadata() {
let metadata = Module2_2::storage_metadata();
pretty_assertions::assert_eq!(EXPECTED_METADATA, metadata);
}
#[test]
fn instance_prefix_is_prefix_of_entries() {
use module2::Instance;
let prefix = module2::Instance2::PREFIX;
assert!(module2::Instance2::PREFIX_FOR_Value.starts_with(prefix));
assert!(module2::Instance2::PREFIX_FOR_Map.starts_with(prefix));
assert!(module2::Instance2::PREFIX_FOR_LinkedMap.starts_with(prefix));
assert!(module2::Instance2::PREFIX_FOR_DoubleMap.starts_with(prefix));
}
@@ -0,0 +1,186 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
use support::sr_primitives::generic;
use support::sr_primitives::traits::{BlakeTwo256, Block as _, Verify};
use support::codec::{Encode, Decode};
use primitives::{H256, sr25519};
use serde::{Serialize, Deserialize};
mod system;
mod module {
use super::*;
pub type Request<T> = (
<T as system::Trait>::AccountId,
Role,
<T as system::Trait>::BlockNumber,
);
pub type Requests<T> = Vec<Request<T>>;
#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Debug)]
pub enum Role {
Storage,
}
#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Debug)]
pub struct RoleParameters<T: Trait> {
// minimum actors to maintain - if role is unstaking
// and remaining actors would be less that this value - prevent or punish for unstaking
pub min_actors: u32,
// the maximum number of spots available to fill for a role
pub max_actors: u32,
// payouts are made at this block interval
pub reward_period: T::BlockNumber,
// minimum amount of time before being able to unstake
pub bonding_period: T::BlockNumber,
// how long tokens remain locked for after unstaking
pub unbonding_period: T::BlockNumber,
// minimum period required to be in service. unbonding before this time is highly penalized
pub min_service_period: T::BlockNumber,
// "startup" time allowed for roles that need to sync their infrastructure
// with other providers before they are considered in service and punishable for
// not delivering required level of service.
pub startup_grace_period: T::BlockNumber,
}
impl<T: Trait> Default for RoleParameters<T> {
fn default() -> Self {
Self {
max_actors: 10,
reward_period: T::BlockNumber::default(),
unbonding_period: T::BlockNumber::default(),
// not currently used
min_actors: 5,
bonding_period: T::BlockNumber::default(),
min_service_period: T::BlockNumber::default(),
startup_grace_period: T::BlockNumber::default(),
}
}
}
pub trait Trait: system::Trait {}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
#[derive(Encode, Decode, Copy, Clone, Serialize, Deserialize)]
pub struct Data<T: Trait> {
pub data: T::BlockNumber,
}
impl<T: Trait> Default for Data<T> {
fn default() -> Self {
Self {
data: T::BlockNumber::default(),
}
}
}
support::decl_storage! {
trait Store for Module<T: Trait> as Actors {
/// requirements to enter and maintain status in roles
pub Parameters get(fn parameters) build(|config: &GenesisConfig| {
if config.enable_storage_role {
let storage_params: RoleParameters<T> = Default::default();
vec![(Role::Storage, storage_params)]
} else {
vec![]
}
}): map Role => Option<RoleParameters<T>>;
/// the roles members can enter into
pub AvailableRoles get(fn available_roles) build(|config: &GenesisConfig| {
if config.enable_storage_role {
vec![(Role::Storage)]
} else {
vec![]
}
}): Vec<Role>;
/// Actors list
pub ActorAccountIds get(fn actor_account_ids) : Vec<T::AccountId>;
/// actor accounts associated with a role
pub AccountIdsByRole get(fn account_ids_by_role) : map Role => Vec<T::AccountId>;
/// tokens locked until given block number
pub Bondage get(fn bondage) : map T::AccountId => T::BlockNumber;
/// First step before enter a role is registering intent with a new account/key.
/// This is done by sending a role_entry_request() from the new account.
/// The member must then send a stake() transaction to approve the request and enter the desired role.
/// The account making the request will be bonded and must have
/// sufficient balance to cover the minimum stake for the role.
/// Bonding only occurs after successful entry into a role.
pub RoleEntryRequests get(fn role_entry_requests) : Requests<T>;
/// Entry request expires after this number of blocks
pub RequestLifeTime get(fn request_life_time) config(request_life_time) : u64 = 0;
}
add_extra_genesis {
config(enable_storage_role): bool;
}
}
}
pub type Signature = sr25519::Signature;
pub type AccountId = <Signature as Verify>::Signer;
pub type BlockNumber = u64;
pub type Index = u64;
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<u32, Call, Signature, ()>;
impl system::Trait for Runtime {
type Hash = H256;
type Origin = Origin;
type BlockNumber = BlockNumber;
type AccountId = AccountId;
type Event = Event;
}
impl module::Trait for Runtime {}
support::construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: system::{Module, Call, Event},
Module: module::{Module, Call, Storage, Config},
}
);
#[test]
fn create_genesis_config() {
GenesisConfig {
module: Some(module::GenesisConfig {
request_life_time: 0,
enable_storage_role: true,
})
};
}
@@ -0,0 +1,24 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
#[test]
fn reserved_keyword() {
// As trybuild is using `cargo check`, we don't need the real WASM binaries.
std::env::set_var("BUILD_DUMMY_WASM_BINARY", "1");
let t = trybuild::TestCases::new();
t.compile_fail("tests/reserved_keyword/*.rs");
}
@@ -0,0 +1,32 @@
macro_rules! reserved {
($($reserved:ident)*) => {
$(
mod $reserved {
pub use support::dispatch::Result;
pub trait Trait {
type Origin;
type BlockNumber: Into<u32>;
}
pub mod system {
use support::dispatch::Result;
pub fn ensure_root<R>(_: R) -> Result {
Ok(())
}
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn $reserved(_origin) -> Result { unreachable!() }
}
}
}
)*
}
}
reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event);
fn main() {}
@@ -0,0 +1,47 @@
error: Invalid call fn name: `on_finalize`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword.
--> $DIR/on_initialize.rs:30:1
|
30 | reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: Invalid call fn name: `on_initialize`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword.
--> $DIR/on_initialize.rs:30:1
|
30 | reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: `on_finalise` was renamed to `on_finalize`. Please rename your function accordingly.
--> $DIR/on_initialize.rs:30:1
|
30 | reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: `on_initialise` was renamed to `on_initialize`. Please rename your function accordingly.
--> $DIR/on_initialize.rs:30:1
|
30 | reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: Invalid call fn name: `offchain_worker`, name is reserved and doesn't match expected signature, please refer to `decl_module!` documentation to see the appropriate usage, or rename it to an unreserved keyword.
--> $DIR/on_initialize.rs:30:1
|
30 | reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: `deposit_event` function is reserved and must follow the syntax: `$vis:vis fn deposit_event() = default;`
--> $DIR/on_initialize.rs:30:1
|
30 | reserved!(on_finalize on_initialize on_finalise on_initialise offchain_worker deposit_event);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
@@ -0,0 +1,64 @@
use support::codec::{Encode, Decode, EncodeLike};
pub trait Trait: 'static + Eq + Clone {
type Origin: Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>
+ From<RawOrigin<Self::AccountId>>;
type BlockNumber: Decode + Encode + EncodeLike + Clone + Default;
type Hash;
type AccountId: Encode + EncodeLike + Decode;
type Event: From<Event>;
}
support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
}
}
impl<T: Trait> Module<T> {
pub fn deposit_event(_event: impl Into<T::Event>) {
}
}
support::decl_event!(
pub enum Event {
ExtrinsicSuccess,
ExtrinsicFailed,
}
);
support::decl_error! {
pub enum Error {
/// Test error documentation
TestError,
/// Error documentation
/// with multiple lines
AnotherError
}
}
/// Origin for the system module.
#[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)]
pub enum RawOrigin<AccountId> {
Root,
Signed(AccountId),
None,
}
impl<AccountId> From<Option<AccountId>> for RawOrigin<AccountId> {
fn from(s: Option<AccountId>) -> RawOrigin<AccountId> {
match s {
Some(who) => RawOrigin::Signed(who),
None => RawOrigin::None,
}
}
}
pub type Origin<T> = RawOrigin<<T as Trait>::AccountId>;
#[allow(dead_code)]
pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), &'static str>
where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
{
o.into().map(|_| ()).map_err(|_| "bad origin: expected to be a root origin")
}