Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b7d4a2a
draft
Jun 2, 2020
d2bb3b8
steps
Jun 2, 2020
7a4426c
chore: fmt
Jun 2, 2020
8eb7a4c
step by step
Jun 3, 2020
fe0682b
more details
Jun 3, 2020
c24b0a3
make test public
Jun 4, 2020
5aec81e
refactor: split into on and offchain
Jun 4, 2020
f1e9367
test stab
Jun 5, 2020
f29babe
tabs my friend
Jun 5, 2020
388970b
offchain overlay: split key into prefix and true key
Jun 9, 2020
1c41dfb
test: share state
Jun 9, 2020
3249272
fix & test
Jun 9, 2020
2600769
docs improv
Jun 9, 2020
5383907
address review comments
Jun 9, 2020
d6a78ca
cleanup test chore
Jun 9, 2020
3e5d00c
refactor, abbrev link text
Jun 9, 2020
dbbb282
chore: linewidth
Jun 10, 2020
2032b6a
fix prefix key split fallout
Jun 10, 2020
1bb092f
minor fallout
Jun 10, 2020
4abd969
minor changes
Jun 10, 2020
1fdc7c1
addresses review comments
Jun 10, 2020
1d271db
rename historical.rs -> historical/mod.rs
Jun 10, 2020
acb67fd
avoid shared::* wildcard import
Jun 10, 2020
359dec9
fix/compile: missing shared:: prefix
Jun 11, 2020
126f6ea
fix: add missing call to store_session_validator_set_to_offchain
Jun 11, 2020
7a7c0b2
fix/test: flow
Jun 12, 2020
87c1696
Merge remote-tracking branch 'origin/master' into bernhard/historical…
Jun 15, 2020
23cc9cf
fix/review: Apply suggestions from code review
drahnr Jun 15, 2020
68ad304
fix/review: more review comment fixes
Jun 15, 2020
bf34c2c
fix/review: make ValidatorSet private
Jun 15, 2020
55f4271
fix/include: core -> sp_core
Jun 15, 2020
6c6c484
fix/review: fallout
Jun 15, 2020
7052484
fix/visbility: make them public API
Jun 15, 2020
6069f35
Merge remote-tracking branch 'origin/master' into bernhard/historical…
Jun 15, 2020
5231d06
fix/review: review changes fallout - again
Jun 16, 2020
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
steps
  • Loading branch information
Bernhard Schuster committed Jun 10, 2020
commit d2bb3b8d482eb1b207ef4e5a0bf06b459bede8b3
71 changes: 48 additions & 23 deletions frame/session/src/historical/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@
//! the offchain indexing API.

use sp_std::prelude::*;

use sp_io::offchain_index;

use super::Trait;
use super::super::{SessionIndex, Module as SessionModule};

const PREFIX: &[u8] = b"historical";
const LAST_PRUNE: &[u8] = b"historical_last_prune";
const HEAD: &[u8] = b"historical_head";

pub struct ValidatorSet<T: Trait> {
validator_set: Vec<(T::ValidatorId, T::FullIdentification)>
Expand Down Expand Up @@ -58,59 +59,83 @@ impl<T: Trait> ValidatorSet<T> {
validator_set
}

/// Access the underlying `ValidatorId` and `FullIdentification` tuples as slice.
fn as_slice(&self) -> &[(T::ValidatorId, T::FullIdentification)] {
self.validator_set.as_slice()
}

/// Convert `self` to a vector and consume `self`.
fn to_vec(self) -> Vec<(T::ValidatorId, T::FullIdentification)> {
self.validator_set
}

fn prune_item(everything_up_to: SessionIndex) {
StorageValueRef::persistent(derived_key.as_ref()).clear()
}

/// Prune anything older than the current session index.
///
/// For behaviour details refer to [`fn prune_older_than`](Self::prune_older_than).
///
/// **Must** be called from the offchain worker.
fn prune() {
let move_pruning_marker = SessionModule::current_index();
Self::prune_older_than(move_pruning_marker);
}

/// Attempt to prune anything that is older than `first_to_keep`.
/// Attempt to prune anything that is older than `first_to_keep` session index.
///
/// Due to re-ogranisation it could be that the `first_to_keep` might be less
/// than the stored one, in which case the conservative choice is made to keep records
/// up to the one that is the lesser.
///
/// **Must** be called from the offchain worker.
fn prune_older_than(first_to_keep: SessionIndex) {
let pruning_marker_key = derive_key(STATIC_LAST_PRUNE);
match StorageValueRef::persistent(derived_key.as_ref())
.mutate(|x| {
Ok(x.encode())
let mut entry = StorageValueRef::persistent(derived_key.as_ref());
match entry.mutate(|current: Option<Option<SessionIndex>>| {
match current {
Some(Some(current)) if current < first_to_keep => Ok(first_to_keep),
// do not move the cursor, if the new one would be behind ours
Some(Some(current)) => Ok(current),
None => Ok(first_to_keep),
// if the storage contains undecodable data, overwrite with current anyways
// which might leak some entries being never purged
Some(None) => Ok(first_to_keep),
}
}) {
Ok(Ok(previous)) => {
for session_index in previous..first_to_keep {
let derived_key = derive_key(STATIC_PREFIX, session_index.encode());
let _ = StorageValueRef::persistent(derived_key.as_ref()).clear();
Ok(Ok(new_value)) => {
// on a re-org this is not necessarily true, with the above they might be equal
if previous < first_to_keep {
for session_index in previous..first_to_keep {
let derived_key = derive_key(STATIC_PREFIX, session_index.encode());
let _ = StorageValueRef::persistent(derived_key.as_ref()).clear();
}
}
},
Ok(Err(e)) => {}, // failed to store the value calculated by the closure
Ok(Err(e)) => {}, // failed to store the value calculated with the given closure
Err(e) => {}, // failed to calculate the value to store with the given closure
}
}


/// Must be called from on chain.
fn store_current<P: AsRef<[u8]>>(prefix: P, session: SessionIndex) {
let session_index = SessionModule::current_index();
/// **Must** be called from on chain.
fn store_to_offchain(session: SessionIndex) {
let session_index = <SessionModule<T>>::current_index();
let derived_key = derive_key(prefix.as_ref(), session.encode());
StorageValueRef::persistent(derived_key.as_ref()).set();
//let value = SessionModule::historical_root(session_index);
let value = <SessionModule<T>>::validators().encode();
offchain_index::set(value.as_slice())
}

/// **Must** be called from on chain, i.e. `on_block_imported`
fn store() {

/// **Must** be called from on chain, i.e. `on_import`
fn store_current_to_offchain() {
Self::store_to_offchain(SessionModule::current_index());
}
}



/// Implement conversion into iterator for usage
/// with [ProvingTrie](super::ProvingTrie::generate_for).
impl<T: Trait> IntoIter for ValidatorSet<T> {
type Item=(T::ValidatorId, T::FullIdentification);
fn into_iter(self) -> impl Iterator<Item=Self::Item> {
self.validator_set.into_iter()
}
}
}