Implement sessions.

This commit is contained in:
Gav
2018-01-19 10:34:55 +01:00
parent 400008028b
commit 81cd156d2a
7 changed files with 83 additions and 38 deletions
@@ -1,35 +1,26 @@
use runtime_support::Vec;
use keyedvec::KeyedVec;
use storage::Storage;
use primitives::{AccountID, SessionKey, BlockNumber};
use runtime::{system, staking};
use storagevec::StorageVec;
use primitives::SessionKey;
pub fn set_authority(index: u32, authority: AccountID) {
authority.store(&index.to_keyed_vec(b"con\0aut\0"));
}
fn authority(index: u32) -> AccountID {
Storage::into(&index.to_keyed_vec(b"con\0aut\0"))
}
pub fn set_authority_count(count: u32) {
(count..authority_count()).for_each(|i| set_authority(i, SessionKey::default()));
count.store(b"con\0aut\0len");
}
fn authority_count() -> u32 {
Storage::into(b"con\0aut\0len")
struct AuthorityStorageVec {}
impl StorageVec for AuthorityStorageVec {
type Item = SessionKey;
const PREFIX: &'static[u8] = b"con\0aut\0";
}
/// Get the current set of authorities. These are the session keys.
pub fn authorities() -> Vec<AccountID> {
(0..authority_count()).into_iter().map(authority).collect()
pub fn authorities() -> Vec<SessionKey> {
AuthorityStorageVec::items()
}
/// Set the current set of authorities' session keys.
///
/// Called by `next_session` only.
pub fn set_authorities(authorities: &[AccountID]) {
set_authority_count(authorities.len() as u32);
authorities.iter().enumerate().for_each(|(v, &i)| set_authority(v as u32, i));
pub fn set_authorities(authorities: &[SessionKey]) {
AuthorityStorageVec::set_items(authorities);
}
/// Set a single authority by index.
pub fn set_authority(index: u32, key: &SessionKey) {
AuthorityStorageVec::set_item(index, key);
}
@@ -8,3 +8,5 @@ pub mod staking;
pub mod timestamp;
#[allow(unused)]
pub mod session;
// TODO: governance, polkadao
@@ -1,31 +1,38 @@
use runtime_support::Vec;
use keyedvec::KeyedVec;
use storage::Storage;
use storagevec::StorageVec;
use primitives::{AccountID, SessionKey, BlockNumber};
use runtime::{system, staking, consensus};
struct ValidatorStorageVec {}
impl StorageVec for ValidatorStorageVec {
type Item = AccountID;
const PREFIX: &'static[u8] = b"ses\0key\0";
}
// TRANSACTION API (available to all transactors)
/// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next
/// Sets the session key of `_validator` to `_key`. This doesn't take effect until the next
/// session.
pub fn set_key(_transactor: &AccountID, _session: &AccountID) {
// TODO: record the new session key for `_transactor`, ready for the next session.
pub fn set_key(validator: &AccountID, key: &SessionKey) {
// set new value for next session
key.store(&validator.to_keyed_vec(b"ses\0nxt\0"));
}
// PUBLIC API (available to other runtime modules)
/// Get the current set of validators. These are the long-term identifiers for the validators
/// and will be mapped to a session key with the most recent `set_next_session_key`.
pub fn validators() -> Vec<AccountID> {
// TODO: derive from the actual validator set
consensus::authorities()
/// Get the current set of authorities. These are the session keys.
fn validators() -> Vec<AccountID> {
ValidatorStorageVec::items()
}
/// Set the current set of validators.
///
/// Called by staking::next_era() only.
/// Called by staking::next_era() only. `next_session` should be called after this in order to
/// update the session keys to the next validator set.
pub fn set_validators(new: &[AccountID]) {
// TODO: set the actual validators
ValidatorStorageVec::set_items(new);
consensus::set_authorities(new);
}
@@ -56,4 +63,10 @@ pub fn post_transactions() {
/// Move onto next session: register the new authority set.
fn next_session() {
// TODO: Call set_authorities() with any new authorities.
validators().iter().enumerate().for_each(|(i, v)| {
let k = v.to_keyed_vec(b"ses\0nxt\0");
if let Some(n) = Storage::try_into(&k) {
consensus::set_authority(i as u32, &n);
}
})
}