Refactor key management (#3296)

* Add Call type to extensible transactions.

Cleanup some naming

* Merge Resource and BlockExhausted into just Exhausted

* Fix

* Another fix

* Call

* Some fixes

* Fix srml tests.

* Fix all tests.

* Refactor crypto so each application of it has its own type.

* Introduce new AuthorityProvider API into Aura

This will eventually allow for dynamic determination of authority
keys and avoid having to set them directly on CLI.

* Introduce authority determinator for Babe.

Experiment with modular consensus API.

* Work in progress to introduce KeyTypeId and avoid polluting API
with validator IDs

* Finish up drafting imonline

* Rework offchain workers API.

* Rework API implementation.

* Make it compile for wasm, simplify app_crypto.

* Fix compilation of im-online.

* Fix compilation of im-online.

* Fix more compilation errors.

* Make it compile.

* Fixing tests.

* Rewrite `keystore`

* Fix session tests

* Bring back `TryFrom`'s'

* Fix `srml-grandpa`

* Fix `srml-aura`

* Fix consensus babe

* More fixes

* Make service generate keys from dev_seed

* Build fixes

* Remove offchain tests

* More fixes and cleanups

* Fixes finality grandpa

* Fix `consensus-aura`

* Fix cli

* Fix `node-cli`

* Fix chain_spec builder

* Fix doc tests

* Add authority getter for grandpa.

* Test fix

* Fixes

* Make keystore accessible from the runtime

* Move app crypto to its own crate

* Update `Cargo.lock`

* Make the crypto stuff usable from the runtime

* Adds some runtime crypto tests

* Use last finalized block for grandpa authority

* Fix warning

* Adds `SessionKeys` runtime api

* Remove `FinalityPair` and `ConsensusPair`

* Minor governance tweaks to get it inline with docs.

* Make the governance be up to date with the docs.

* Build fixes.

* Generate the inital session keys

* Failing keystore is a hard error

* Make babe work again

* Fix grandpa

* Fix tests

* Disable `keystore` in consensus critical stuff

* Build fix.

* ImOnline supports multiple authorities at once.

* Update core/application-crypto/src/ed25519.rs

* Merge branch 'master' into gav-in-progress

* Remove unneeded code for now.

* Some `session` testing

* Support querying the public keys

* Cleanup offchain

* Remove warnings

* More cleanup

* Apply suggestions from code review

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

* More cleanups

* JSONRPC API for setting keys.

Also, rename traits::KeyStore* -> traits::BareCryptoStore*

* Bad merge

* Fix integration tests

* Fix test build

* Test fix

* Fixes

* Warnings

* Another warning

* Bump version.
This commit is contained in:
Gavin Wood
2019-08-07 20:47:48 +02:00
committed by GitHub
parent a6a6779f01
commit 1a524b8207
160 changed files with 4467 additions and 2769 deletions
+64 -107
View File
@@ -61,6 +61,8 @@ pub enum Conviction {
Locked4x,
/// 5x votes, locked for 16x...
Locked5x,
/// 6x votes, locked for 32x...
Locked6x,
}
impl Default for Conviction {
@@ -78,6 +80,7 @@ impl From<Conviction> for u8 {
Conviction::Locked3x => 3,
Conviction::Locked4x => 4,
Conviction::Locked5x => 5,
Conviction::Locked6x => 6,
}
}
}
@@ -92,6 +95,7 @@ impl TryFrom<u8> for Conviction {
3 => Conviction::Locked3x,
4 => Conviction::Locked4x,
5 => Conviction::Locked5x,
6 => Conviction::Locked6x,
_ => return Err(()),
})
}
@@ -108,6 +112,7 @@ impl Conviction {
Conviction::Locked3x => 4,
Conviction::Locked4x => 8,
Conviction::Locked5x => 16,
Conviction::Locked6x => 32,
}
}
@@ -134,7 +139,7 @@ impl Bounded for Conviction {
}
fn max_value() -> Self {
Conviction::Locked5x
Conviction::Locked6x
}
}
@@ -208,18 +213,19 @@ pub trait Trait: system::Trait + Sized {
/// a majority-carries referendum.
type ExternalMajorityOrigin: EnsureOrigin<Self::Origin>;
/// Origin from which the next tabled referendum may be forced; this allows for the tabling of
/// a negative-turnout-bias (default-carries) referendum.
type ExternalDefaultOrigin: EnsureOrigin<Self::Origin>;
/// Origin from which the next referendum proposed by the external majority may be immediately
/// tabled to vote asynchronously in a similar manner to the emergency origin. It remains a
/// majority-carries vote.
type ExternalPushOrigin: EnsureOrigin<Self::Origin>;
type FastTrackOrigin: EnsureOrigin<Self::Origin>;
/// Origin from which emergency referenda may be scheduled.
type EmergencyOrigin: EnsureOrigin<Self::Origin>;
/// Minimum voting period allowed for an emergency referendum.
/// Minimum voting period allowed for an fast-track/emergency referendum.
type EmergencyVotingPeriod: Get<Self::BlockNumber>;
/// Origin from which any referenda may be cancelled in an emergency.
/// Origin from which any referendum may be cancelled in an emergency.
type CancellationOrigin: EnsureOrigin<Self::Origin>;
/// Origin for anyone able to veto proposals.
@@ -434,32 +440,6 @@ decl_module! {
Self::do_vote(who, ref_index, vote)
}
/// Schedule an emergency referendum.
///
/// This will create a new referendum for the `proposal`, approved as long as counted votes
/// exceed `threshold` and, if approved, enacted after the given `delay`.
///
/// It may be called from either the Root or the Emergency origin.
#[weight = SimpleDispatchInfo::FixedOperational(500_000)]
fn emergency_propose(origin,
proposal: Box<T::Proposal>,
threshold: VoteThreshold,
voting_period: T::BlockNumber,
delay: T::BlockNumber
) {
T::EmergencyOrigin::try_origin(origin)
.map(|_| ())
.or_else(|origin| ensure_root(origin))?;
let now = <system::Module<T>>::block_number();
// We don't consider it an error if `vote_period` is too low, but we do enforce the
// minimum. This is primarily due to practicality. If it's an emergency, we don't want
// to introduce more delays than is strictly needed by requiring a potentially costly
// resubmission in the case of a mistakenly low `vote_period`; better to just let the
// referendum take place with the lowest valid value.
let period = voting_period.max(T::EmergencyVotingPeriod::get());
Self::inject_referendum(now + period, *proposal, threshold, delay).map(|_| ())?;
}
/// Schedule an emergency cancellation of a referendum. Cannot happen twice to the same
/// referendum.
#[weight = SimpleDispatchInfo::FixedOperational(500_000)]
@@ -489,17 +469,26 @@ decl_module! {
/// Schedule a majority-carries referendum to be tabled next once it is legal to schedule
/// an external referendum.
///
/// Unlike `external_propose`, blacklisting has no effect on this and it may replace a
/// pre-scheduled `external_propose` call.
#[weight = SimpleDispatchInfo::FixedNormal(5_000_000)]
fn external_propose_majority(origin, proposal: Box<T::Proposal>) {
T::ExternalMajorityOrigin::ensure_origin(origin)?;
ensure!(!<NextExternal<T>>::exists(), "proposal already made");
let proposal_hash = T::Hashing::hash_of(&proposal);
if let Some((until, _)) = <Blacklist<T>>::get(proposal_hash) {
ensure!(<system::Module<T>>::block_number() >= until, "proposal still blacklisted");
}
<NextExternal<T>>::put((*proposal, VoteThreshold::SimpleMajority));
}
/// Schedule a negative-turnout-bias referendum to be tabled next once it is legal to
/// schedule an external referendum.
///
/// Unlike `external_propose`, blacklisting has no effect on this and it may replace a
/// pre-scheduled `external_propose` call.
#[weight = SimpleDispatchInfo::FixedNormal(5_000_000)]
fn external_propose_default(origin, proposal: Box<T::Proposal>) {
T::ExternalDefaultOrigin::ensure_origin(origin)?;
<NextExternal<T>>::put((*proposal, VoteThreshold::SuperMajorityAgainst));
}
/// Schedule the currently externally-proposed majority-carries referendum to be tabled
/// immediately. If there is no externally-proposed referendum currently, or if there is one
/// but it is not a majority-carries referendum then it fails.
@@ -509,14 +498,14 @@ decl_module! {
/// - `delay`: The number of block after voting has ended in approval and this should be
/// enacted. Increased to `EmergencyVotingPeriod` if too low.
#[weight = SimpleDispatchInfo::FixedNormal(200_000)]
fn external_push(origin,
fn fast_track(origin,
proposal_hash: T::Hash,
voting_period: T::BlockNumber,
delay: T::BlockNumber
) {
T::ExternalPushOrigin::ensure_origin(origin)?;
T::FastTrackOrigin::ensure_origin(origin)?;
let (proposal, threshold) = <NextExternal<T>>::get().ok_or("no proposal made")?;
ensure!(threshold == VoteThreshold::SimpleMajority, "next external proposal not simple majority");
ensure!(threshold != VoteThreshold::SuperMajorityApprove, "next external proposal not simple majority");
ensure!(proposal_hash == T::Hashing::hash_of(&proposal), "invalid hash");
<NextExternal<T>>::kill();
@@ -1028,6 +1017,7 @@ mod tests {
type Origin = Origin;
type Index = u64;
type BlockNumber = u64;
type Call = ();
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = u64;
@@ -1090,10 +1080,10 @@ mod tests {
type VotingPeriod = VotingPeriod;
type EmergencyVotingPeriod = EmergencyVotingPeriod;
type MinimumDeposit = MinimumDeposit;
type EmergencyOrigin = EnsureSignedBy<One, u64>;
type ExternalOrigin = EnsureSignedBy<Two, u64>;
type ExternalMajorityOrigin = EnsureSignedBy<Three, u64>;
type ExternalPushOrigin = EnsureSignedBy<Five, u64>;
type ExternalDefaultOrigin = EnsureSignedBy<One, u64>;
type FastTrackOrigin = EnsureSignedBy<Five, u64>;
type CancellationOrigin = EnsureSignedBy<Four, u64>;
type VetoOrigin = EnsureSignedBy<OneToFive, u64>;
type CooloffPeriod = CooloffPeriod;
@@ -1347,64 +1337,6 @@ mod tests {
});
}
#[test]
fn emergency_referendum_works() {
with_externalities(&mut new_test_ext(), || {
System::set_block_number(0);
assert_noop!(Democracy::emergency_propose(
Origin::signed(6), // invalid
Box::new(set_balance_proposal(2)),
VoteThreshold::SuperMajorityAgainst,
0,
0,
), "bad origin: expected to be a root origin");
assert_ok!(Democracy::emergency_propose(
Origin::signed(1),
Box::new(set_balance_proposal(2)),
VoteThreshold::SuperMajorityAgainst,
0,
0,
));
assert_eq!(
Democracy::referendum_info(0),
Some(ReferendumInfo {
end: 1,
proposal: set_balance_proposal(2),
threshold: VoteThreshold::SuperMajorityAgainst,
delay: 0
})
);
assert_ok!(Democracy::vote(Origin::signed(1), 0, AYE));
fast_forward_to(1);
assert_eq!(Balances::free_balance(&42), 0);
fast_forward_to(2);
assert_eq!(Balances::free_balance(&42), 2);
assert_ok!(Democracy::emergency_propose(
Origin::signed(1),
Box::new(set_balance_proposal(4)),
VoteThreshold::SuperMajorityAgainst,
3,
3
));
assert_eq!(
Democracy::referendum_info(1),
Some(ReferendumInfo {
end: 5,
proposal: set_balance_proposal(4),
threshold: VoteThreshold::SuperMajorityAgainst,
delay: 3
})
);
assert_ok!(Democracy::vote(Origin::signed(1), 1, AYE));
fast_forward_to(8);
assert_eq!(Balances::free_balance(&42), 2);
fast_forward_to(9);
assert_eq!(Balances::free_balance(&42), 4);
});
}
#[test]
fn external_referendum_works() {
with_externalities(&mut new_test_ext(), || {
@@ -1460,17 +1392,42 @@ mod tests {
}
#[test]
fn external_push_referendum_works() {
fn external_default_referendum_works() {
with_externalities(&mut new_test_ext(), || {
System::set_block_number(0);
assert_noop!(Democracy::external_propose_default(
Origin::signed(3),
Box::new(set_balance_proposal(2))
), "Invalid origin");
assert_ok!(Democracy::external_propose_default(
Origin::signed(1),
Box::new(set_balance_proposal(2))
));
fast_forward_to(1);
assert_eq!(
Democracy::referendum_info(0),
Some(ReferendumInfo {
end: 2,
proposal: set_balance_proposal(2),
threshold: VoteThreshold::SuperMajorityAgainst,
delay: 2,
})
);
});
}
#[test]
fn fast_track_referendum_works() {
with_externalities(&mut new_test_ext(), || {
System::set_block_number(0);
let h = BlakeTwo256::hash_of(&set_balance_proposal(2));
assert_noop!(Democracy::external_push(Origin::signed(5), h, 3, 2), "no proposal made");
assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), "no proposal made");
assert_ok!(Democracy::external_propose_majority(
Origin::signed(3),
Box::new(set_balance_proposal(2))
));
assert_noop!(Democracy::external_push(Origin::signed(1), h, 3, 2), "Invalid origin");
assert_ok!(Democracy::external_push(Origin::signed(5), h, 0, 0));
assert_noop!(Democracy::fast_track(Origin::signed(1), h, 3, 2), "Invalid origin");
assert_ok!(Democracy::fast_track(Origin::signed(5), h, 0, 0));
assert_eq!(
Democracy::referendum_info(0),
Some(ReferendumInfo {
@@ -1484,7 +1441,7 @@ mod tests {
}
#[test]
fn external_push_referendum_fails_when_no_simple_majority() {
fn fast_track_referendum_fails_when_no_simple_majority() {
with_externalities(&mut new_test_ext(), || {
System::set_block_number(0);
let h = BlakeTwo256::hash_of(&set_balance_proposal(2));
@@ -1493,7 +1450,7 @@ mod tests {
Box::new(set_balance_proposal(2))
));
assert_noop!(
Democracy::external_push(Origin::signed(5), h, 3, 2),
Democracy::fast_track(Origin::signed(5), h, 3, 2),
"next external proposal not simple majority"
);
});