Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
store prior session
  • Loading branch information
rphmeier committed Feb 26, 2018
commit 7cb524b0cd1a5f48a8c0c932cd1faff40fe8d071
26 changes: 18 additions & 8 deletions polkadot/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,33 @@
#![cfg_attr(not(feature = "std"), no_std)]

extern crate substrate_runtime_std as rstd;
#[macro_use] extern crate substrate_runtime_io as runtime_io;
extern crate substrate_runtime_support as runtime_support;
#[cfg(all(feature = "std", test))] extern crate substrate_keyring as keyring;

#[cfg(feature = "std")] extern crate rustc_hex;

extern crate substrate_codec as codec;
#[cfg(feature = "std")] #[macro_use] extern crate substrate_primitives as primitives;
extern crate polkadot_primitives;

#[cfg(test)] #[macro_use] extern crate hex_literal;
#[cfg(all(feature = "std", test))]
extern crate substrate_keyring as keyring;

#[cfg(feature = "std")]
extern crate rustc_hex;

#[cfg(feature = "std")]
#[macro_use]
extern crate substrate_primitives as primitives;

#[macro_use]
extern crate substrate_runtime_io as runtime_io;

#[cfg(test)]
#[macro_use]
extern crate hex_literal;

pub mod environment;
pub mod runtime;
pub mod api;

#[cfg(feature = "std")] pub mod genesismap;
#[cfg(feature = "std")]
pub mod genesismap;

/// Type definitions and helpers for transactions.
pub mod transaction {
Expand Down
6 changes: 3 additions & 3 deletions polkadot/runtime/src/runtime/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use polkadot_primitives::SessionKey;
struct AuthorityStorageVec {}
impl StorageVec for AuthorityStorageVec {
type Item = SessionKey;
const PREFIX: &'static[u8] = b":auth:";
const PREFIX: &'static [u8] = b":auth:";
}

/// Get the current set of authorities. These are the session keys.
Expand All @@ -37,8 +37,8 @@ pub mod internal {
/// Set the current set of authorities' session keys.
///
/// Called by `next_session` only.
pub fn set_authorities(authorities: &[SessionKey]) {
AuthorityStorageVec::set_items(authorities);
pub fn set_authorities<'a, I: IntoIterator<Item=&'a SessionKey>>(authorities: I) {
AuthorityStorageVec::set_items::<I>(authorities);
}

/// Set a single authority by index.
Expand Down
47 changes: 42 additions & 5 deletions polkadot/runtime/src/runtime/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,23 @@ use runtime::{system, staking, consensus};

const SESSION_LENGTH: &[u8] = b"ses:len";
const CURRENT_INDEX: &[u8] = b"ses:ind";
const CURRENT_SESSION_START: &[u8] = b"ses:sta";
const LAST_SESSION_START: &[u8] = b"ses:lst";
const LAST_LENGTH_CHANGE: &[u8] = b"ses:llc";
const NEXT_KEY_FOR: &[u8] = b"ses:nxt:";
const NEXT_SESSION_LENGTH: &[u8] = b"ses:nln";

struct ValidatorStorageVec {}
struct ValidatorStorageVec;
impl StorageVec for ValidatorStorageVec {
type Item = AccountId;
const PREFIX: &'static[u8] = b"ses:val:";
const PREFIX: &'static [u8] = b"ses:val:";
}

// the session keys before the previous.
struct LastSessionKeys;
impl StorageVec for LastSessionKeys {
type Item = SessionKey;
const PREFIX: &'static [u8] = b"ses:old:";
}

/// Get the current set of validators.
Expand All @@ -50,11 +59,31 @@ pub fn validator_count() -> u32 {
ValidatorStorageVec::count() as u32
}

/// The current era index.
/// The current session index.
pub fn current_index() -> BlockNumber {
storage::get_or(CURRENT_INDEX, 0)
}

/// Get the starting block of the current session.
pub fn current_start_block() -> BlockNumber {
// this seems like it's computable just by examining the current block number, session length,
// and last length change, but it's not simple to tell whether we are before or after
// a session rotation on a block which will have one.
storage::get_or(CURRENT_SESSION_START, 0)
}

/// Get the last session's authority keys.
pub fn last_session_keys() -> Vec<SessionKey> {
LastSessionKeys::items()
}

/// Get the start block of the last session.
/// In general this is computable from the session length,
/// but when the current session is the first with a new length it is uncomputable.
pub fn last_session_start() -> Option<BlockNumber> {
storage::get(LAST_SESSION_START)
}

/// The block number at which the era length last changed.
pub fn last_length_change() -> BlockNumber {
storage::get_or(LAST_LENGTH_CHANGE, 0)
Expand Down Expand Up @@ -90,12 +119,15 @@ pub mod privileged {
pub mod internal {
use super::*;

/// Set the current set of validators.
/// Transition to a new era, with a new set of valiators.
///
/// 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]) {
println!("new era: {:?}", new);

ValidatorStorageVec::set_items(new);
LastSessionKeys::set_items(&consensus::authorities());
consensus::internal::set_authorities(new);
}

Expand All @@ -114,18 +146,23 @@ pub mod internal {
fn rotate_session() {
// Increment current session index.
storage::put(CURRENT_INDEX, &(current_index() + 1));

// Enact era length change.
if let Some(next_len) = storage::get::<u64>(NEXT_SESSION_LENGTH) {
storage::put(SESSION_LENGTH, &next_len);
storage::put(LAST_LENGTH_CHANGE, &system::block_number());
storage::kill(NEXT_SESSION_LENGTH);
}

storage::put(LAST_SESSION_START, &current_start_block());
storage::put(CURRENT_SESSION_START, &system::block_number());
LastSessionKeys::set_items(&consensus::authorities());

// Update any changes in session keys.
validators().iter().enumerate().for_each(|(i, v)| {
let k = v.to_keyed_vec(NEXT_KEY_FOR);
if let Some(n) = storage::take(&k) {
// this is fine because the authorities vector currently
// matches the validators length perfectly.
consensus::internal::set_authority(i as u32, &n);
}
});
Expand Down
10 changes: 9 additions & 1 deletion polkadot/runtime/src/runtime/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use runtime_io::print;
use codec::KeyedVec;
use runtime_support::{storage, StorageVec};
use polkadot_primitives::{BlockNumber, AccountId};
use primitives::bft::{MisbehaviorReport, MisbehaviorKind};
use runtime::{system, session, governance};

/// The balance of an account.
Expand All @@ -33,7 +34,7 @@ pub type Bondage = u64;
struct IntentionStorageVec {}
impl StorageVec for IntentionStorageVec {
type Item = AccountId;
const PREFIX: &'static[u8] = b"sta:wil:";
const PREFIX: &'static [u8] = b"sta:wil:";
}

const BONDING_DURATION: &[u8] = b"sta:loc";
Expand Down Expand Up @@ -132,6 +133,13 @@ pub mod public {
IntentionStorageVec::set_items(&intentions);
storage::put(&transactor.to_keyed_vec(BONDAGE_OF), &(current_era() + bonding_duration()));
}

/// Report misbehavior. Only validators may do this.
pub fn report_misbehavior(misbehavior: &MisbehaviorReport) {
// 1. check that the target was a validator at the current block.
// 2. check the report.

}
}

pub mod privileged {
Expand Down
3 changes: 3 additions & 0 deletions polkadot/runtime/src/runtime/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ fn dispatch_function(function: &Function, transactor: &AccountId) {
Function::StakingTransfer(dest, value) => {
::runtime::staking::public::transfer(transactor, &dest, value);
}
Function::ReportMisbehavior(ref report) => {
::runtime::staking::public::report_misbehavior(report)
}
Function::SessionSetKey(session) => {
::runtime::session::public::set_key(transactor, &session);
}
Expand Down
1 change: 1 addition & 0 deletions substrate/bft/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ impl<P: Proposer, I: BlockImport> Future for BftFuture<P, I> {
impl<P: Proposer, I> Drop for BftFuture<P, I> {
fn drop(&mut self) {
// TODO: have a trait member to pass misbehavior reports into.
// map authority IDs onto validator IDs.
let _misbehavior = self.inner.drain_misbehavior();
}
}
Expand Down
7 changes: 7 additions & 0 deletions substrate/primitives/src/bft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ pub struct MisbehaviorReport {
pub round_number: u32,
/// The parent hash of the block where the misbehavior occurred.
pub parent_hash: HeaderHash,
/// The parent number of the block where the misbehavior occurred.
pub parent_number: ::block::Number,
/// The authority who misbehavior.
pub target: AuthorityId,
/// The misbehavior kind.
Expand All @@ -202,6 +204,7 @@ impl Slicable for MisbehaviorReport {
let mut v = Vec::new();
self.round_number.using_encoded(|s| v.extend(s));
self.parent_hash.using_encoded(|s| v.extend(s));
self.parent_number.using_encoded(|s| v.extend(s));
self.target.using_encoded(|s| v.extend(s));

match self.misbehavior {
Expand All @@ -227,6 +230,7 @@ impl Slicable for MisbehaviorReport {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
let round_number = u32::decode(input)?;
let parent_hash = HeaderHash::decode(input)?;
let parent_number = ::block::Number::decode(input)?;
let target = AuthorityId::decode(input)?;

let misbehavior = match u8::decode(input).and_then(MisbehaviorCode::from_u8)? {
Expand All @@ -247,6 +251,7 @@ impl Slicable for MisbehaviorReport {
Some(MisbehaviorReport {
round_number,
parent_hash,
parent_number,
target,
misbehavior,
})
Expand All @@ -262,6 +267,7 @@ mod test {
let report = MisbehaviorReport {
round_number: 511,
parent_hash: [0; 32].into(),
parent_number: 999,
target: [1; 32].into(),
misbehavior: MisbehaviorKind::BftDoubleCommit(
([2; 32].into(), [3; 64].into()),
Expand All @@ -275,6 +281,7 @@ mod test {
let report = MisbehaviorReport {
round_number: 511,
parent_hash: [0; 32].into(),
parent_number: 999,
target: [1; 32].into(),
misbehavior: MisbehaviorKind::BftDoublePrepare(
([2; 32].into(), [3; 64].into()),
Expand Down
46 changes: 35 additions & 11 deletions substrate/runtime-support/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,26 @@ pub trait StorageVec {
}

/// 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_items<'a, I>(items: I)
where
I: IntoIterator<Item=&'a Self::Item>,
Self::Item: 'a,
{
let mut count: u32 = 0;

for (v, i) in items.into_iter().enumerate() {
count = count.checked_add(1).expect("exceeded runtime storage capacity");
put(&v.to_keyed_vec(Self::PREFIX), i);
}

Self::set_count(count);
}

/// Push an item.
fn push(item: &Self::Item) {
let len = Self::count();
put(&len.to_keyed_vec(Self::PREFIX), item);
Self::set_count(len + 1);
}

fn set_item(index: u32, item: &Self::Item) {
Expand Down Expand Up @@ -258,9 +275,19 @@ pub mod unhashed {
}

/// 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_items<'a, I>(items: I)
where
I: IntoIterator<Item=&'a Self::Item>,
Self::Item: 'a,
{
let mut count: u32 = 0;

for (v, i) in items.into_iter().enumerate() {
count = count.checked_add(1).expect("exceeded runtime storage capacity");
put(&v.to_keyed_vec(Self::PREFIX), i);
}

Self::set_count(count);
}

fn set_item(index: u32, item: &Self::Item) {
Expand Down Expand Up @@ -293,8 +320,8 @@ pub mod unhashed {
#[cfg(test)]
mod tests {
use super::*;
use primitives::hexdisplay::HexDisplay;
use runtime_io::{storage, twox_128, TestExternalities, with_externalities};
use primitives::hexdisplay;
use runtime_io::{twox_128, TestExternalities, with_externalities};

#[test]
fn integers_can_be_stored() {
Expand Down Expand Up @@ -337,7 +364,6 @@ mod tests {
with_externalities(&mut t, || {
runtime_io::set_storage(&twox_128(b":test"), b"\x0b\0\0\0Hello world");
let x = b"Hello world".to_vec();
println!("Hex: {}", HexDisplay::from(&storage(&twox_128(b":test")).unwrap()));
let y = get::<Vec<u8>>(b":test").unwrap();
assert_eq!(x, y);

Expand All @@ -353,9 +379,7 @@ mod tests {
put(b":test", &x);
});

println!("Ext is {:?}", t);
with_externalities(&mut t, || {
println!("Hex: {}", HexDisplay::from(&storage(&twox_128(b":test")).unwrap()));
let y: Vec<u8> = get(b":test").unwrap();
assert_eq!(x, y);
});
Expand Down