mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 22:11:06 +00:00
Implement sessions.
This commit is contained in:
@@ -12,7 +12,7 @@ mod codec;
|
||||
mod support;
|
||||
mod runtime;
|
||||
pub use codec::{endiansensitive, streamreader, joiner, slicable, keyedvec};
|
||||
pub use support::{primitives, function, environment, storage};
|
||||
pub use support::{primitives, function, environment, storage, storagevec};
|
||||
#[cfg(test)]
|
||||
pub use support::{testing, statichex};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ pub mod primitives;
|
||||
pub mod function;
|
||||
pub mod environment;
|
||||
pub mod storage;
|
||||
pub mod storagevec;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod statichex;
|
||||
|
||||
@@ -3,14 +3,14 @@ use endiansensitive::EndianSensitive;
|
||||
use runtime_support;
|
||||
|
||||
pub trait Storage {
|
||||
fn into(_key: &[u8]) -> Self where Self: Sized { unimplemented!() }
|
||||
fn into(key: &[u8]) -> Self where Self: Sized + Default { Self::try_into(key).unwrap_or_else(Default::default) }
|
||||
fn try_into(_key: &[u8]) -> Option<Self> where Self: Sized { unimplemented!() }
|
||||
fn store(&self, key: &[u8]);
|
||||
}
|
||||
|
||||
impl<T: Default + Sized + EndianSensitive> Storage for T {
|
||||
fn into(key: &[u8]) -> Self {
|
||||
fn try_into(key: &[u8]) -> Option<Self> {
|
||||
Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len())
|
||||
.unwrap_or_else(Default::default)
|
||||
}
|
||||
fn store(&self, key: &[u8]) {
|
||||
self.as_slice_then(|slice| runtime_support::set_storage(key, slice));
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
use runtime_support::Vec;
|
||||
use keyedvec::KeyedVec;
|
||||
use storage::Storage;
|
||||
|
||||
/// A trait to conveniently store a vector of storable data.
|
||||
// TODO: add iterator support
|
||||
pub trait StorageVec {
|
||||
type Item: Default + Sized + Storage;
|
||||
const PREFIX: &'static [u8];
|
||||
|
||||
/// Get the current set of items.
|
||||
fn items() -> Vec<Self::Item> {
|
||||
(0..Self::count()).into_iter().map(Self::item).collect()
|
||||
}
|
||||
|
||||
/// Set the current set of items.
|
||||
fn set_items(items: &[Self::Item]) {
|
||||
Self::set_count(items.len() as u32);
|
||||
items.iter().enumerate().for_each(|(v, ref i)| Self::set_item(v as u32, i));
|
||||
}
|
||||
|
||||
fn set_item(index: u32, item: &Self::Item) {
|
||||
item.store(&index.to_keyed_vec(Self::PREFIX));
|
||||
}
|
||||
|
||||
fn item(index: u32) -> Self::Item {
|
||||
Storage::into(&index.to_keyed_vec(Self::PREFIX))
|
||||
}
|
||||
|
||||
fn set_count(count: u32) {
|
||||
(count..Self::count()).for_each(|i| Self::set_item(i, &Self::Item::default()));
|
||||
count.store(&b"len".to_keyed_vec(Self::PREFIX));
|
||||
}
|
||||
|
||||
fn count() -> u32 {
|
||||
Storage::into(&b"len".to_keyed_vec(Self::PREFIX))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user