mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 10:01:17 +00:00
Make Polkadot use the Substrate traity libraries (#105)
* Initial stuff. * Various fixes. * Fix tests. * Fix another test * Fix another test. * Docs in polkadot runtime. * Fix up ser/de tests. * Update god keys * Syntax * Fix * Merge remote-tracking branch 'origin/master' into gav-merge-runtime * Permissions on init.sh * Port-over the whitespace from @rphmeier * Rename * Merge branch 'master' into gav-merge-runtime * Fix typo. * Fix grumbles. * Make more idiomatic. * Move `Ed25519Signature` out of traits.
This commit is contained in:
committed by
Robert Habermeier
parent
6b83f11a11
commit
1d8a9a6dd3
@@ -7,18 +7,22 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
hex-literal = "0.1.0"
|
||||
serde = { version = "1.0", default_features = false }
|
||||
substrate-codec = { path = "../../codec", default_features = false }
|
||||
substrate-primitives = { path = "../../primitives", default_features = false }
|
||||
substrate-runtime-std = { path = "../../runtime-std", default_features = false }
|
||||
substrate-runtime-io = { path = "../../runtime-io", default_features = false }
|
||||
substrate-runtime-support = { path = "../../runtime-support", default_features = false }
|
||||
substrate-runtime-primitives = { path = "../primitives", default_features = false }
|
||||
substrate-runtime-system = { path = "../system", default_features = false }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"serde/std",
|
||||
"substrate-codec/std",
|
||||
"substrate-primitives/std",
|
||||
"substrate-runtime-std/std",
|
||||
"substrate-runtime-io/std",
|
||||
"substrate-runtime-support/std",
|
||||
"substrate-runtime-primitives/std",
|
||||
"substrate-runtime-system/std",
|
||||
]
|
||||
|
||||
@@ -28,10 +28,15 @@ extern crate substrate_runtime_support as runtime_support;
|
||||
extern crate substrate_runtime_io as runtime_io;
|
||||
extern crate substrate_runtime_primitives as primitives;
|
||||
extern crate substrate_codec as codec;
|
||||
extern crate substrate_runtime_system as system;
|
||||
extern crate substrate_primitives;
|
||||
|
||||
use rstd::prelude::*;
|
||||
use runtime_support::{storage, Parameter};
|
||||
use runtime_support::storage::unhashed::StorageVec;
|
||||
use primitives::traits::RefInto;
|
||||
use substrate_primitives::bft::MisbehaviorReport;
|
||||
|
||||
|
||||
pub const AUTHORITY_AT: &'static[u8] = b":auth:";
|
||||
pub const AUTHORITY_COUNT: &'static[u8] = b":auth:len";
|
||||
@@ -44,15 +49,18 @@ impl<S: codec::Slicable + Default> StorageVec for AuthorityStorageVec<S> {
|
||||
|
||||
pub const CODE: &'static [u8] = b":code";
|
||||
|
||||
pub trait Trait {
|
||||
type SessionKey: Parameter + Default;
|
||||
pub trait Trait: system::Trait {
|
||||
type PublicAux: RefInto<Self::AccountId>;
|
||||
type SessionKey: Parameter + Default;
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
pub struct Module<T: Trait>;
|
||||
pub enum Call where aux: T::PublicAux {
|
||||
fn report_misbehavior(aux, report: MisbehaviorReport) = 0;
|
||||
}
|
||||
pub enum PrivCall {
|
||||
fn set_code(new: Vec<u8>) = 0;
|
||||
fn dummy() = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +75,10 @@ impl<T: Trait> Module<T> {
|
||||
storage::unhashed::put_raw(CODE, &new);
|
||||
}
|
||||
|
||||
fn dummy() {}
|
||||
/// Report some misbehaviour.
|
||||
fn report_misbehavior(_aux: &T::PublicAux, _report: MisbehaviorReport) {
|
||||
// TODO.
|
||||
}
|
||||
|
||||
/// Set the current set of authorities' session keys.
|
||||
///
|
||||
@@ -85,6 +96,7 @@ impl<T: Trait> Module<T> {
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
pub authorities: Vec<T::SessionKey>,
|
||||
pub code: Vec<u8>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
@@ -92,6 +104,7 @@ impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
authorities: vec![],
|
||||
code: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,9 +116,10 @@ impl<T: Trait> primitives::BuildExternalities for GenesisConfig<T>
|
||||
use codec::{Slicable, KeyedVec};
|
||||
let auth_count = self.authorities.len() as u32;
|
||||
let mut r: runtime_io::TestExternalities = self.authorities.into_iter().enumerate().map(|(i, v)|
|
||||
((i as u32).to_keyed_vec(b":auth:"), v.encode())
|
||||
((i as u32).to_keyed_vec(AUTHORITY_AT), v.encode())
|
||||
).collect();
|
||||
r.insert(b":auth:len".to_vec(), auth_count.encode());
|
||||
r.insert(AUTHORITY_COUNT.to_vec(), auth_count.encode());
|
||||
r.insert(CODE.to_vec(), self.code);
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
@@ -584,6 +584,7 @@ mod tests {
|
||||
type PublicAux = u64;
|
||||
}
|
||||
impl consensus::Trait for Test {
|
||||
type PublicAux = <Self as HasPublicAux>::PublicAux;
|
||||
type SessionKey = u64;
|
||||
}
|
||||
impl system::Trait for Test {
|
||||
@@ -596,7 +597,6 @@ mod tests {
|
||||
type Header = Header;
|
||||
}
|
||||
impl session::Trait for Test {
|
||||
type PublicAux = <Self as HasPublicAux>::PublicAux;
|
||||
type ConvertAccountIdToSessionKey = Identity;
|
||||
}
|
||||
impl staking::Trait for Test {
|
||||
@@ -611,6 +611,7 @@ mod tests {
|
||||
pub fn new_test_ext(with_council: bool) -> runtime_io::TestExternalities {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
|
||||
t.extend(consensus::GenesisConfig::<Test>{
|
||||
code: vec![],
|
||||
authorities: vec![],
|
||||
}.build_externalities());
|
||||
t.extend(session::GenesisConfig::<Test>{
|
||||
|
||||
@@ -345,6 +345,7 @@ mod tests {
|
||||
type PublicAux = u64;
|
||||
}
|
||||
impl consensus::Trait for Test {
|
||||
type PublicAux = <Self as HasPublicAux>::PublicAux;
|
||||
type SessionKey = u64;
|
||||
}
|
||||
impl system::Trait for Test {
|
||||
@@ -357,7 +358,6 @@ mod tests {
|
||||
type Header = Header;
|
||||
}
|
||||
impl session::Trait for Test {
|
||||
type PublicAux = <Self as HasPublicAux>::PublicAux;
|
||||
type ConvertAccountIdToSessionKey = Identity;
|
||||
}
|
||||
impl staking::Trait for Test {
|
||||
@@ -371,6 +371,7 @@ mod tests {
|
||||
fn new_test_ext() -> runtime_io::TestExternalities {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
|
||||
t.extend(consensus::GenesisConfig::<Test>{
|
||||
code: vec![],
|
||||
authorities: vec![],
|
||||
}.build_externalities());
|
||||
t.extend(session::GenesisConfig::<Test>{
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[cfg(feature = "std")] extern crate serde;
|
||||
|
||||
extern crate substrate_runtime_std as rstd;
|
||||
extern crate substrate_runtime_support as runtime_support;
|
||||
extern crate substrate_runtime_io as runtime_io;
|
||||
@@ -41,11 +43,10 @@ extern crate substrate_runtime_session as session;
|
||||
#[cfg(test)]
|
||||
extern crate substrate_runtime_staking as staking;
|
||||
|
||||
#[cfg(feature = "std")] extern crate serde;
|
||||
|
||||
use rstd::prelude::*;
|
||||
use rstd::marker::PhantomData;
|
||||
use runtime_io::Hashing;
|
||||
use runtime_support::StorageValue;
|
||||
use primitives::traits::{self, Header, Zero, One, Checkable, Applyable, CheckEqual, Executable, MakePayment};
|
||||
use codec::Slicable;
|
||||
|
||||
@@ -122,27 +123,29 @@ impl<
|
||||
|
||||
/// Apply outside of the block execution function.
|
||||
/// This doesn't attempt to validate anything regarding the block.
|
||||
pub fn apply_extrinsic(utx: Block::Extrinsic) {
|
||||
pub fn apply_extrinsic(uxt: Block::Extrinsic) {
|
||||
// Verify the signature is good.
|
||||
let tx = match utx.check() {
|
||||
Ok(tx) => tx,
|
||||
let xt = match uxt.check() {
|
||||
Ok(xt) => xt,
|
||||
Err(_) => panic!("All transactions should be properly signed"),
|
||||
};
|
||||
|
||||
{
|
||||
if xt.sender() != &Default::default() {
|
||||
// check index
|
||||
let expected_index = <system::Module<System>>::account_index(tx.sender());
|
||||
assert!(tx.index() == &expected_index, "All transactions should have the correct nonce");
|
||||
let expected_index = <system::Module<System>>::account_index(xt.sender());
|
||||
assert!(xt.index() == &expected_index, "All transactions should have the correct nonce");
|
||||
|
||||
// increment nonce in storage
|
||||
<system::Module<System>>::inc_account_index(tx.sender());
|
||||
<system::Module<System>>::inc_account_index(xt.sender());
|
||||
|
||||
// pay any fees.
|
||||
Payment::make_payment(xt.sender());
|
||||
}
|
||||
|
||||
// pay any fees.
|
||||
Payment::make_payment(tx.sender());
|
||||
|
||||
// decode parameters and dispatch
|
||||
tx.apply();
|
||||
xt.apply();
|
||||
|
||||
<system::ExtrinsicIndex<System>>::put(<system::ExtrinsicIndex<System>>::get() + 1u32);
|
||||
}
|
||||
|
||||
fn final_checks(header: &System::Header) {
|
||||
@@ -180,6 +183,7 @@ mod tests {
|
||||
type PublicAux = u64;
|
||||
}
|
||||
impl consensus::Trait for Test {
|
||||
type PublicAux = <Self as HasPublicAux>::PublicAux;
|
||||
type SessionKey = u64;
|
||||
}
|
||||
impl system::Trait for Test {
|
||||
@@ -192,7 +196,6 @@ mod tests {
|
||||
type Header = Header;
|
||||
}
|
||||
impl session::Trait for Test {
|
||||
type PublicAux = <Self as HasPublicAux>::PublicAux;
|
||||
type ConvertAccountIdToSessionKey = Identity;
|
||||
}
|
||||
impl staking::Trait for Test {
|
||||
@@ -239,7 +242,7 @@ mod tests {
|
||||
header: Header {
|
||||
parent_hash: [69u8; 32].into(),
|
||||
number: 1,
|
||||
state_root: hex!("9228e363883f4f5a01981985b5598d1a767e987eb3ccea017a0e14cac7acc79d").into(),
|
||||
state_root: hex!("aa0cff04242e55fc780861b890aa8deba555f6ed95bd8fa575dfd80864f3b93e").into(),
|
||||
extrinsics_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
|
||||
digest: Digest { logs: vec![], },
|
||||
},
|
||||
@@ -273,7 +276,7 @@ mod tests {
|
||||
header: Header {
|
||||
parent_hash: [69u8; 32].into(),
|
||||
number: 1,
|
||||
state_root: hex!("93dde1251278e65430baf291337ba219bacfa9ad583c52513b12cf1974109a97").into(),
|
||||
state_root: hex!("aa0cff04242e55fc780861b890aa8deba555f6ed95bd8fa575dfd80864f3b93e").into(),
|
||||
extrinsics_root: [0u8; 32].into(),
|
||||
digest: Digest { logs: vec![], },
|
||||
},
|
||||
|
||||
@@ -86,7 +86,7 @@ pub struct UncheckedExtrinsic<AccountId, Index, Call, Signature> where
|
||||
AccountId: Member,
|
||||
Index: Member,
|
||||
Call: Member,
|
||||
Signature: Member
|
||||
Signature: Member, // TODO: should be Option<Signature>
|
||||
{
|
||||
/// The actual extrinsic information.
|
||||
pub extrinsic: Extrinsic<AccountId, Index, Call>,
|
||||
@@ -94,6 +94,19 @@ pub struct UncheckedExtrinsic<AccountId, Index, Call, Signature> where
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
impl<AccountId, Index, Call, Signature> UncheckedExtrinsic<AccountId, Index, Call, Signature> where
|
||||
AccountId: Member + Default,
|
||||
Index: Member,
|
||||
Call: Member,
|
||||
Signature: Member + Default,
|
||||
{
|
||||
/// Is this extrinsic signed?
|
||||
pub fn is_signed(&self) -> bool {
|
||||
// TODO: should be Option<Signature> and Option<AccountId>
|
||||
self.signature != Signature::default() || self.extrinsic.signed != AccountId::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl<AccountId, Index, Call, Signature> Slicable for UncheckedExtrinsic<AccountId, Index, Call, Signature> where
|
||||
AccountId: Member + Slicable,
|
||||
Index: Member + Slicable,
|
||||
@@ -145,21 +158,25 @@ impl<AccountId, Index, Call, Signature> fmt::Debug for UncheckedExtrinsic<Accoun
|
||||
}
|
||||
|
||||
impl<AccountId, Index, Call, Signature> traits::Checkable for UncheckedExtrinsic<AccountId, Index, Call, Signature> where
|
||||
AccountId: Member,
|
||||
AccountId: Member + Default,
|
||||
Index: Member,
|
||||
Call: Member,
|
||||
Signature: Member + traits::Verify<Signer = AccountId>,
|
||||
Signature: Member + Default + traits::Verify<Signer = AccountId>,
|
||||
Extrinsic<AccountId, Index, Call>: Slicable
|
||||
{
|
||||
type Checked = CheckedExtrinsic<AccountId, Index, Call, Signature>;
|
||||
|
||||
fn check(self) -> Result<Self::Checked, Self> {
|
||||
if ::codec::Slicable::using_encoded(&self.extrinsic, |msg|
|
||||
self.signature.verify(msg, &self.extrinsic.signed)
|
||||
) {
|
||||
if !self.is_signed() {
|
||||
Ok(CheckedExtrinsic(self))
|
||||
} else {
|
||||
Err(self)
|
||||
if ::codec::Slicable::using_encoded(&self.extrinsic, |msg|
|
||||
self.signature.verify(msg, &self.extrinsic.signed)
|
||||
) {
|
||||
Ok(CheckedExtrinsic(self))
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,6 +203,16 @@ where
|
||||
pub fn signature(&self) -> &Signature {
|
||||
&self.0.signature
|
||||
}
|
||||
|
||||
/// Get a reference to the checked signature.
|
||||
pub fn as_unchecked(&self) -> &UncheckedExtrinsic<AccountId, Index, Call, Signature> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Get a reference to the checked signature.
|
||||
pub fn into_unchecked(self) -> UncheckedExtrinsic<AccountId, Index, Call, Signature> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<AccountId, Index, Call, Signature> ops::Deref
|
||||
|
||||
@@ -34,7 +34,10 @@ extern crate substrate_runtime_support as runtime_support;
|
||||
extern crate substrate_codec as codec;
|
||||
extern crate substrate_primitives;
|
||||
|
||||
#[cfg(feature = "std")] use std::collections::HashMap;
|
||||
#[cfg(feature = "std")]
|
||||
use std::collections::HashMap;
|
||||
|
||||
use substrate_primitives::hash::H512;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub mod testing;
|
||||
@@ -50,6 +53,26 @@ pub trait BuildExternalities {
|
||||
fn build_externalities(self) -> BuiltExternalities;
|
||||
}
|
||||
|
||||
/// Ed25519 signature verify.
|
||||
#[derive(Eq, PartialEq, Clone, Default)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
|
||||
pub struct Ed25519Signature(H512);
|
||||
impl traits::Verify for Ed25519Signature {
|
||||
type Signer = [u8; 32];
|
||||
fn verify(&self, msg: &[u8], signer: &Self::Signer) -> bool {
|
||||
runtime_io::ed25519_verify(&(self.0).0, msg, &signer[..])
|
||||
}
|
||||
}
|
||||
impl codec::Slicable for Ed25519Signature {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> { Some(Ed25519Signature(codec::Slicable::decode(input)?,)) }
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R { self.0.using_encoded(f) }
|
||||
}
|
||||
impl From<H512> for Ed25519Signature {
|
||||
fn from(h: H512) -> Ed25519Signature {
|
||||
Ed25519Signature(h)
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! __impl_outer_config_types {
|
||||
($concrete:ident $config:ident $snake:ident $($rest:ident)*) => {
|
||||
|
||||
@@ -20,8 +20,7 @@ use rstd::prelude::*;
|
||||
use rstd;
|
||||
#[cfg(not(feature = "std"))] use runtime_io;
|
||||
use substrate_primitives;
|
||||
use codec::{Input, Slicable};
|
||||
use substrate_primitives::hash::H512;
|
||||
use codec::Slicable;
|
||||
pub use integer_sqrt::IntegerSquareRoot;
|
||||
pub use num_traits::{Zero, One, Bounded};
|
||||
use rstd::ops::{Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
||||
@@ -34,26 +33,6 @@ pub trait Verify {
|
||||
fn verify(&self, msg: &[u8], signer: &Self::Signer) -> bool;
|
||||
}
|
||||
|
||||
/// Ed25519 signature verify.
|
||||
#[derive(Eq, PartialEq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
|
||||
pub struct Ed25519Signature(H512);
|
||||
impl Verify for Ed25519Signature {
|
||||
type Signer = [u8; 32];
|
||||
fn verify(&self, msg: &[u8], signer: &Self::Signer) -> bool {
|
||||
::runtime_io::ed25519_verify(&(self.0).0, msg, &signer[..])
|
||||
}
|
||||
}
|
||||
impl Slicable for Ed25519Signature {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> { Some(Ed25519Signature(Slicable::decode(input)?,)) }
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R { self.0.using_encoded(f) }
|
||||
}
|
||||
impl From<H512> for Ed25519Signature {
|
||||
fn from(h: H512) -> Ed25519Signature {
|
||||
Ed25519Signature(h)
|
||||
}
|
||||
}
|
||||
|
||||
/// Simple payment making trait, operating on a single generic `AccountId` type.
|
||||
pub trait MakePayment<AccountId> {
|
||||
/// Make some sort of payment concerning `who`.
|
||||
@@ -102,8 +81,18 @@ impl<T> Convert<T, T> for Identity {
|
||||
fn convert(a: T) -> T { a }
|
||||
}
|
||||
|
||||
pub trait MaybeEmpty {
|
||||
fn is_empty(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<T: Default + PartialEq> MaybeEmpty for T {
|
||||
fn is_empty(&self) -> bool {
|
||||
*self == T::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HasPublicAux {
|
||||
type PublicAux;
|
||||
type PublicAux: MaybeEmpty;
|
||||
}
|
||||
|
||||
pub trait RefInto<T> {
|
||||
|
||||
@@ -44,8 +44,7 @@ use rstd::prelude::*;
|
||||
use primitives::traits::{Zero, One, RefInto, Executable, Convert};
|
||||
use runtime_support::{StorageValue, StorageMap};
|
||||
|
||||
pub trait Trait: consensus::Trait + system::Trait {
|
||||
type PublicAux: RefInto<Self::AccountId>;
|
||||
pub trait Trait: consensus::Trait {
|
||||
type ConvertAccountIdToSessionKey: Convert<Self::AccountId, Self::SessionKey>;
|
||||
}
|
||||
|
||||
@@ -162,28 +161,6 @@ pub struct GenesisConfig<T: Trait> {
|
||||
pub validators: Vec<T::AccountId>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> GenesisConfig<T> where T::AccountId: From<keyring::Keyring> {
|
||||
pub fn simple() -> Self where T::AccountId: From<[u8; 32]> {
|
||||
use primitives::traits::As;
|
||||
use keyring::Keyring::*;
|
||||
let three = [3u8; 32];
|
||||
GenesisConfig {
|
||||
session_length: T::BlockNumber::sa(2),
|
||||
validators: vec![T::AccountId::from(One), T::AccountId::from(Two), T::AccountId::from(three)],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extended() -> Self {
|
||||
use primitives::traits::As;
|
||||
use keyring::Keyring::*;
|
||||
GenesisConfig {
|
||||
session_length: T::BlockNumber::sa(1),
|
||||
validators: vec![T::AccountId::from(Alice), T::AccountId::from(Bob), T::AccountId::from(Charlie)],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
@@ -224,6 +201,7 @@ mod tests {
|
||||
type PublicAux = u64;
|
||||
}
|
||||
impl consensus::Trait for Test {
|
||||
type PublicAux = <Self as HasPublicAux>::PublicAux;
|
||||
type SessionKey = u64;
|
||||
}
|
||||
impl system::Trait for Test {
|
||||
@@ -236,7 +214,6 @@ mod tests {
|
||||
type Header = Header;
|
||||
}
|
||||
impl Trait for Test {
|
||||
type PublicAux = <Self as HasPublicAux>::PublicAux;
|
||||
type ConvertAccountIdToSessionKey = Identity;
|
||||
}
|
||||
|
||||
@@ -247,6 +224,7 @@ mod tests {
|
||||
fn new_test_ext() -> runtime_io::TestExternalities {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
|
||||
t.extend(consensus::GenesisConfig::<Test>{
|
||||
code: vec![],
|
||||
authorities: vec![1, 2, 3],
|
||||
}.build_externalities());
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
|
||||
@@ -685,6 +685,7 @@ mod tests {
|
||||
type PublicAux = u64;
|
||||
}
|
||||
impl consensus::Trait for Test {
|
||||
type PublicAux = <Self as HasPublicAux>::PublicAux;
|
||||
type SessionKey = u64;
|
||||
}
|
||||
impl system::Trait for Test {
|
||||
@@ -697,7 +698,6 @@ mod tests {
|
||||
type Header = Header;
|
||||
}
|
||||
impl session::Trait for Test {
|
||||
type PublicAux = <Self as HasPublicAux>::PublicAux;
|
||||
type ConvertAccountIdToSessionKey = Identity;
|
||||
}
|
||||
impl Trait for Test {
|
||||
@@ -708,6 +708,7 @@ mod tests {
|
||||
fn new_test_ext(session_length: u64, sessions_per_era: u64, current_era: u64, monied: bool) -> runtime_io::TestExternalities {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
|
||||
t.extend(consensus::GenesisConfig::<Test>{
|
||||
code: vec![],
|
||||
authorities: vec![],
|
||||
}.build_externalities());
|
||||
t.extend(session::GenesisConfig::<Test>{
|
||||
|
||||
@@ -67,6 +67,7 @@ decl_storage! {
|
||||
pub AccountIndex get(account_index): b"sys:non" => default map [ T::AccountId => T::Index ];
|
||||
pub BlockHash get(block_hash): b"sys:old" => required map [ T::BlockNumber => T::Hash ];
|
||||
|
||||
pub ExtrinsicIndex get(extrinsic_index): b"sys:xti" => required u32;
|
||||
RandomSeed get(random_seed): b"sys:rnd" => required T::Hash;
|
||||
// The current block number being processed. Set by `execute_block`.
|
||||
Number get(block_number): b"sys:num" => required T::BlockNumber;
|
||||
@@ -83,11 +84,13 @@ impl<T: Trait> Module<T> {
|
||||
<ParentHash<T>>::put(parent_hash);
|
||||
<ExtrinsicsRoot<T>>::put(txs_root);
|
||||
<RandomSeed<T>>::put(Self::calculate_random());
|
||||
<ExtrinsicIndex<T>>::put(0);
|
||||
}
|
||||
|
||||
/// Remove temporary "environment" entries in storage.
|
||||
pub fn finalise() -> T::Header {
|
||||
<RandomSeed<T>>::kill();
|
||||
<ExtrinsicIndex<T>>::kill();
|
||||
|
||||
let number = <Number<T>>::take();
|
||||
let parent_hash = <ParentHash<T>>::take();
|
||||
@@ -145,6 +148,20 @@ impl<T: Trait> Module<T> {
|
||||
<Number<T>>::put(n);
|
||||
}
|
||||
|
||||
/// Set the parent hash number to something in particular. Can be used as an alternative to
|
||||
/// `initialise` for tests that don't need to bother with the other environment entries.
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub fn set_parent_hash(n: T::Hash) {
|
||||
<ParentHash<T>>::put(n);
|
||||
}
|
||||
|
||||
/// Set the random seed to something in particular. Can be used as an alternative to
|
||||
/// `initialise` for tests that don't need to bother with the other environment entries.
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub fn set_random_seed(n: T::Hash) {
|
||||
<RandomSeed<T>>::put(n);
|
||||
}
|
||||
|
||||
/// Increment a particular account's nonce by 1.
|
||||
pub fn inc_account_index(who: &T::AccountId) {
|
||||
<AccountIndex<T>>::insert(who, Self::account_index(who) + T::Index::one());
|
||||
@@ -172,7 +189,8 @@ impl<T: Trait> primitives::BuildExternalities for GenesisConfig<T>
|
||||
twox_128(&<BlockHash<T>>::key_for(T::BlockNumber::zero())).to_vec() => [69u8; 32].encode(),
|
||||
twox_128(<Number<T>>::key()).to_vec() => 1u64.encode(),
|
||||
twox_128(<ParentHash<T>>::key()).to_vec() => [69u8; 32].encode(),
|
||||
twox_128(<RandomSeed<T>>::key()).to_vec() => [0u8; 32].encode()
|
||||
twox_128(<RandomSeed<T>>::key()).to_vec() => [0u8; 32].encode(),
|
||||
twox_128(<ExtrinsicIndex<T>>::key()).to_vec() => [0u8; 4].encode()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,12 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
hex-literal = "0.1.0"
|
||||
serde = { version = "1.0", default_features = false }
|
||||
substrate-runtime-std = { path = "../../runtime-std", default_features = false }
|
||||
substrate-runtime-io = { path = "../../runtime-io", default_features = false }
|
||||
substrate-runtime-support = { path = "../../runtime-support", default_features = false }
|
||||
substrate-runtime-primitives = { path = "../primitives", default_features = false }
|
||||
substrate-codec = { path = "../../codec", default_features = false }
|
||||
substrate-primitives = { path = "../../primitives", default_features = false }
|
||||
substrate-runtime-system = { path = "../system", default_features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
substrate-runtime-io = { path = "../../runtime-io", default_features = true }
|
||||
@@ -18,8 +21,11 @@ substrate-runtime-io = { path = "../../runtime-io", default_features = true }
|
||||
default = ["std"]
|
||||
std = [
|
||||
"substrate-runtime-std/std",
|
||||
"substrate-runtime-io/std",
|
||||
"substrate-runtime-support/std",
|
||||
"substrate-runtime-primitives/std",
|
||||
"serde/std",
|
||||
"substrate-codec/std",
|
||||
"substrate-primitives/std",
|
||||
"substrate-runtime-system/std",
|
||||
]
|
||||
|
||||
@@ -18,22 +18,25 @@
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[cfg_attr(test, macro_use)]
|
||||
#[cfg_attr(any(feature = "std", test), macro_use)]
|
||||
extern crate substrate_runtime_std as rstd;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_support as runtime_support;
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(any(feature = "std", test))]
|
||||
extern crate substrate_runtime_io as runtime_io;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate substrate_primitives;
|
||||
extern crate substrate_runtime_primitives as runtime_primitives;
|
||||
extern crate substrate_runtime_system as system;
|
||||
extern crate substrate_codec as codec;
|
||||
|
||||
use runtime_support::{StorageValue, Parameter};
|
||||
use runtime_primitives::traits::HasPublicAux;
|
||||
use runtime_primitives::traits::{HasPublicAux, Executable, MaybeEmpty};
|
||||
|
||||
pub trait Trait: HasPublicAux {
|
||||
pub trait Trait: HasPublicAux + system::Trait {
|
||||
type Value: Parameter + Default;
|
||||
}
|
||||
|
||||
@@ -45,8 +48,11 @@ decl_module! {
|
||||
}
|
||||
|
||||
decl_storage! {
|
||||
pub trait Store for Module<T: Trait>;
|
||||
trait Store for Module<T: Trait>;
|
||||
pub Now get(now): b"tim:val" => required T::Value;
|
||||
|
||||
// Did the timestamp get updated in this block?
|
||||
DidUpdate: b"tim:did" => default bool;
|
||||
}
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
@@ -55,8 +61,36 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
|
||||
/// Set the current time.
|
||||
fn set(_aux: &T::PublicAux, now: T::Value) {
|
||||
fn set(aux: &T::PublicAux, now: T::Value) {
|
||||
assert!(aux.is_empty());
|
||||
assert!(!<Self as Store>::DidUpdate::exists(), "Timestamp must be updated only once in the block");
|
||||
assert!(<system::Module<T>>::extrinsic_index() == 0, "Timestamp must be first extrinsic in the block");
|
||||
<Self as Store>::Now::put(now);
|
||||
<Self as Store>::DidUpdate::put(true);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> Executable for Module<T> {
|
||||
fn execute() {
|
||||
assert!(<Self as Store>::DidUpdate::take(), "Timestamp must be updated once in the block");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
#[derive(Default)]
|
||||
pub struct GenesisConfig<T: Trait> {
|
||||
pub now: T::Value,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Trait> runtime_primitives::BuildExternalities for GenesisConfig<T>
|
||||
{
|
||||
fn build_externalities(self) -> runtime_primitives::BuiltExternalities {
|
||||
use runtime_io::twox_128;
|
||||
use codec::Slicable;
|
||||
map![
|
||||
twox_128(<Now<T>>::key()).to_vec() => self.now.encode()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,25 +98,35 @@ impl<T: Trait> Module<T> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use runtime_io::{with_externalities, twox_128, TestExternalities};
|
||||
use codec::Joiner;
|
||||
use runtime_io::with_externalities;
|
||||
use runtime_support::storage::StorageValue;
|
||||
use substrate_primitives::H256;
|
||||
use runtime_primitives::BuildExternalities;
|
||||
use runtime_primitives::traits::{HasPublicAux};
|
||||
use runtime_primitives::testing::{Digest, Header};
|
||||
|
||||
struct TraitImpl;
|
||||
impl HasPublicAux for TraitImpl {
|
||||
pub struct Test;
|
||||
impl HasPublicAux for Test {
|
||||
type PublicAux = u64;
|
||||
}
|
||||
impl Trait for TraitImpl {
|
||||
impl system::Trait for Test {
|
||||
type Index = u64;
|
||||
type BlockNumber = u64;
|
||||
type Hash = H256;
|
||||
type Hashing = runtime_io::BlakeTwo256;
|
||||
type Digest = Digest;
|
||||
type AccountId = u64;
|
||||
type Header = Header;
|
||||
}
|
||||
impl Trait for Test {
|
||||
type Value = u64;
|
||||
}
|
||||
type Timestamp = Module<TraitImpl>;
|
||||
type Timestamp = Module<Test>;
|
||||
|
||||
#[test]
|
||||
fn timestamp_works() {
|
||||
|
||||
let mut t: TestExternalities = map![
|
||||
twox_128(<Timestamp as Store>::Now::key()).to_vec() => vec![].and(&42u64)
|
||||
];
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_externalities();
|
||||
t.extend(GenesisConfig::<Test> { now: 42 }.build_externalities());
|
||||
|
||||
with_externalities(&mut t, || {
|
||||
assert_eq!(<Timestamp as Store>::Now::get(), 42);
|
||||
|
||||
Reference in New Issue
Block a user