mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 06:57:58 +00:00
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:
@@ -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")
|
||||
}
|
||||
Reference in New Issue
Block a user