Consensus Engines Implementation: Aura (#911)

* Generalize BlockImport

 - move ImportBlock, BlockOrigin, ImportResult into shared sr-primitives
 - let Consensus provide  and  traits again
 - update consensus traits to latest development
 - implement traits on client::Client, test_client::TestClient
 - update RHD to use the new import_block API

* Move ImportBlock into consensus-common
* Send import notification in aura tests
* Integrating aura into service
* Make Signatures more generic
* Aura Block Production with the given key
* run aura on the thread pool
* start at exact step start in aura
* Add needed wasm blob, in leiu of better solutions.
* Make API ids consistent with traits and bring upstream for sharing.
* Add decrease_free_balance to Balances module
* Encode `Metadata` once instead of two times
* Bitops include xor
* Upgrade key module.
* Default pages to somewhat bigger.
* Introduce upgrade key into node
* Add `Created` event
This commit is contained in:
Benjamin Kampmann
2018-10-27 15:59:18 +02:00
committed by GitHub
parent c0f7021427
commit 50adea6220
82 changed files with 3125 additions and 1902 deletions
+17
View File
@@ -423,6 +423,23 @@ impl<T: Trait> Module<T> {
Self::set_free_balance_creating(who, Self::free_balance(who) + value)
}
/// Substrates `value` from the free balance of `who`. If the whole amount cannot be
/// deducted, an error is returned.
///
/// NOTE: This assumes that the total stake remains unchanged after this operation. If
/// you mean to actually burn value out of existence, then use `slash` instead.
pub fn decrease_free_balance(
who: &T::AccountId,
value: T::Balance
) -> result::Result<UpdateBalanceOutcome, &'static str> {
T::EnsureAccountLiquid::ensure_account_liquid(who)?;
let b = Self::free_balance(who);
if b < value {
return Err("account has too few funds")
}
Ok(Self::set_free_balance(who, b - value))
}
/// Deducts up to `value` from the combined balance of `who`, preferring to deduct from the
/// free balance. This function cannot fail.
///
+11
View File
@@ -280,6 +280,17 @@ fn balance_transfer_works() {
});
}
#[test]
fn balance_reduction_works() {
with_externalities(&mut ExtBuilder::default().build(), || {
Balances::set_free_balance(&1, 111);
Balances::increase_total_stake_by(111);
assert_ok!(Balances::decrease_free_balance(&1, 69).map(|_| ()));
assert_eq!(Balances::total_balance(&1), 42);
assert_noop!(Balances::decrease_free_balance(&1, 69).map(|_| ()), "account has too few funds");
});
}
#[test]
fn reserving_balance_should_work() {
with_externalities(&mut ExtBuilder::default().build(), || {
+9 -1
View File
@@ -29,6 +29,7 @@ extern crate srml_support as runtime_support;
#[macro_use]
extern crate serde_derive;
extern crate parity_codec;
#[macro_use]
extern crate parity_codec_derive;
@@ -42,6 +43,7 @@ extern crate sr_io as runtime_io;
use rstd::prelude::*;
use rstd::result;
use parity_codec::Encode;
use runtime_support::{storage, Parameter};
use runtime_support::dispatch::Result;
use runtime_support::storage::StorageValue;
@@ -174,8 +176,14 @@ decl_module! {
Ok(())
}
/// Set the number of pages in the WebAssembly environment's heap.
fn set_heap_pages(pages: u64) -> Result {
storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode());
Ok(())
}
/// Set the new code.
fn set_code(new: Vec<u8>) -> Result {
pub fn set_code(new: Vec<u8>) -> Result {
storage::unhashed::put_raw(well_known_keys::CODE, &new);
Ok(())
}
+7 -1
View File
@@ -154,6 +154,7 @@ decl_module! {
fn deposit_event() = default;
// TODO: Change AccountId to staking::Address
/// Make a call to a specified account, optionally transferring some balance.
/// Make a call to a specified account, optionally transferring some balance.
fn call(
origin,
dest: T::AccountId,
@@ -232,12 +233,14 @@ decl_module! {
};
let result = ctx.create(origin.clone(), endowment, &mut gas_meter, &ctor_code, &data);
if let Ok(_) = result {
if let Ok(ref r) = result {
// Commit all changes that made it thus far into the persistant storage.
account_db::DirectAccountDb.commit(ctx.overlay.into_change_set());
// Then deposit all events produced.
ctx.events.into_iter().for_each(Self::deposit_event);
Self::deposit_event(RawEvent::Created(origin.clone(), r.address.clone()));
}
// Refund cost of the unused gas.
@@ -263,6 +266,9 @@ decl_event! {
{
/// Transfer happened `from` -> `to` with given `value` as part of a `message-call` or `create`.
Transfer(AccountId, AccountId, Balance),
/// Contract deployed by address at the specified address.
Created(AccountId, AccountId),
}
}
+4
View File
@@ -617,6 +617,10 @@ fn top_level_create() {
phase: Phase::ApplyExtrinsic(0),
event: MetaEvent::contract(RawEvent::Transfer(0, derived_address, 11)),
},
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: MetaEvent::contract(RawEvent::Created(0, 1)),
},
]);
});
}
+1 -1
View File
@@ -208,7 +208,7 @@ macro_rules! decl_module {
[
$($t)*
$(#[doc = $doc_attr])*
fn $fn_name(root $( , $param_name : $param )* ) -> $result { $( $impl )* }
$fn_vis fn $fn_name(root $( , $param_name : $param )* ) -> $result { $( $impl )* }
]
$($rest)*
);
+34
View File
@@ -0,0 +1,34 @@
[package]
name = "srml-upgrade-key"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
hex-literal = "0.1.0"
serde = { version = "1.0", default-features = false }
serde_derive = { version = "1.0", optional = true }
parity-codec = { version = "2.1", default-features = false }
parity-codec-derive = { version = "2.1", default-features = false }
substrate-primitives = { path = "../../core/primitives", default-features = false }
sr-std = { path = "../../core/sr-std", default-features = false }
sr-io = { path = "../../core/sr-io", default-features = false }
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
srml-support = { path = "../support", default-features = false }
srml-system = { path = "../system", default-features = false }
srml-consensus = { path = "../consensus", default-features = false }
[features]
default = ["std"]
std = [
"serde/std",
"serde_derive",
"parity-codec/std",
"parity-codec-derive/std",
"sr-std/std",
"sr-io/std",
"sr-primitives/std",
"substrate-primitives/std",
"srml-support/std",
"srml-system/std",
"srml-consensus/std",
]
+90
View File
@@ -0,0 +1,90 @@
// Copyright 2017-2018 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/>.
//! The Example: A simple example of a runtime module demonstrating
//! concepts, APIs and structures common to most runtime modules.
#![cfg_attr(not(feature = "std"), no_std)]
extern crate sr_std;
#[cfg(test)]
extern crate sr_io;
#[cfg(test)]
extern crate substrate_primitives;
extern crate sr_primitives;
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate parity_codec_derive;
extern crate parity_codec as codec;
#[macro_use]
extern crate srml_support as support;
extern crate srml_system as system;
extern crate srml_consensus as consensus;
use sr_std::prelude::*;
use support::{StorageValue, dispatch::Result};
use system::ensure_signed;
pub trait Trait: consensus::Trait + system::Trait {
/// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}
decl_module! {
// Simple declaration of the `Module` type. Lets the macro know what its working on.
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn deposit_event() = default;
fn upgrade(origin, new: Vec<u8>) -> Result {
// This is a public call, so we ensure that the origin is some signed account.
let _sender = ensure_signed(origin)?;
ensure!(_sender == Self::key(), "only the current upgrade key can use the upgrade_key module");
<consensus::Module<T>>::set_code(new)?;
Self::deposit_event(RawEvent::Upgraded);
Ok(())
}
fn set_key(origin, new: T::AccountId) -> Result {
// This is a public call, so we ensure that the origin is some signed account.
let _sender = ensure_signed(origin)?;
ensure!(_sender == Self::key(), "only the current upgrade key can use the upgrade_key module");
Self::deposit_event(RawEvent::KeyChanged(Self::key()));
<Key<T>>::put(new);
Ok(())
}
}
}
/// An event in this module.
decl_event!(
pub enum Event<T> where AccountId = <T as system::Trait>::AccountId {
/// An upgrade just happened.
Upgraded,
/// An upgrade just happened; old key is supplied as an argument.
KeyChanged(AccountId),
}
);
decl_storage! {
trait Store for Module<T: Trait> as UpgradeKey {
Key get(key) config(): T::AccountId;
}
}