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
more details
  • Loading branch information
Bernhard Schuster committed Jun 10, 2020
commit fe0682b0d25b5e40253f14b8e69e2675965bd118
58 changes: 33 additions & 25 deletions frame/session/src/historical/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Validator Set Extracting an iterator from an offchain worker stored list containing historical validatorsets.
//! Validator Set Extracting an iterator from an off-chain worker stored list containing historical validatorsets.
//!
//! This is used in conjunction with [`ProvingTrie`](super::ProvingTrie) and
//! the offchain indexing API.
//! the off-chain indexing API.

use codec::{Codec, Decode, Encode};
use sp_runtime::offchain::storage::StorageValueRef;
Expand All @@ -29,43 +29,43 @@ use super::Trait;

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)>,
}

/// Derive the key used to store the list of validators
fn derive_key<P: AsRef<[u8]>>(prefix: P, session_index: &[u8]) -> Vec<u8> {
assert!(session_index.len() > 0);
fn derive_key<P: AsRef<[u8]>>(prefix: P, session_index: SessionIndex) -> Vec<u8> {
let prefix: &[u8] = prefix.as_ref();
let mut concatenated = Vec::with_capacity(prefix.len() + 1 + session_index.len());
let encoded_session_index = session_index.encode();
assert!(encoded_session_index.len() > 0);
let mut concatenated = Vec::with_capacity(prefix.len() + 1 + encoded_session_index.len());
concatenated.extend_from_slice(prefix);
concatenated.push('/' as u8);
concatenated.extend_from_slice(session_index);
concatenated.extend_from_slice(encoded_session_index.as_slice());
concatenated
}

impl<T: Trait> ValidatorSet<T> {
/// Load the set of validators for a paritcular session index from the offchain storage.
/// Load the set of validators for a paritcular session index from the off-chain storage.
///
/// If none is found or decodable given `prefix` and `session`, it will return `None`.
/// Empty validator sets should only ever exist for genesis blocks.
fn load_from_offchain(session_index: SessionIndex) -> Option<Self> {
let derived_key = derive_key(PREFIX, session_index.encode().as_slice());
pub fn load_from_offchain(session_index: SessionIndex) -> Option<Self> {
let derived_key = derive_key(PREFIX, session_index);
let validator_set = StorageValueRef::persistent(derived_key.as_ref())
.get::<Vec<(T::ValidatorId, T::FullIdentification)>>()
.flatten();
validator_set.map(|validator_set| Self { validator_set })
}

/// Access the underlying `ValidatorId` and `FullIdentification` tuples as slice.
fn as_slice(&self) -> &[(T::ValidatorId, T::FullIdentification)] {
pub 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)> {
/// Convert `self` into a vector and consume `self`.
pub fn into_vec(self) -> Vec<(T::ValidatorId, T::FullIdentification)> {
self.validator_set
}

Expand All @@ -75,10 +75,10 @@ impl<T: Trait> ValidatorSet<T> {
/// 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 derived_key = derive_key(LAST_PRUNE, b"---");
let mut entry = StorageValueRef::persistent(derived_key.as_ref());
/// **Must** be called from the off-chain worker.
pub fn prune_older_than(first_to_keep: SessionIndex) {
let derived_key = LAST_PRUNE.to_vec();
let entry = StorageValueRef::persistent(derived_key.as_ref());
match entry.mutate(|current: Option<Option<SessionIndex>>| -> Result<_, ()> {
match current {
Some(Some(current)) if current < first_to_keep => Ok(first_to_keep),
Expand All @@ -95,7 +95,7 @@ impl<T: Trait> ValidatorSet<T> {
// on a re-org this is not necessarily true, with the above they might be equal
if new_value < first_to_keep {
for session_index in new_value..first_to_keep {
let derived_key = derive_key(PREFIX, session_index.encode().as_slice());
let derived_key = derive_key(PREFIX, session_index);
let _ = StorageValueRef::persistent(derived_key.as_ref()).clear();
}
}
Expand All @@ -105,17 +105,25 @@ impl<T: Trait> ValidatorSet<T> {
}
}

/// **Must** be called from on chain.
fn store_to_offchain(session: SessionIndex) {
pub fn keep_newest(number_of_sessions_to_keep: usize) {
let session_index = <SessionModule<T>>::current_index();
let derived_key = derive_key(PREFIX, session.encode().as_slice());
let number_of_sessions_to_keep = number_of_sessions_to_keep as SessionIndex;
if number_of_sessions_to_keep < session_index {
Self::prune_older_than(session_index - number_of_sessions_to_keep)
}
// otherwise we want to keep all of them
}

/// **Must** be called from on-chain, i.e. `on_initialize` or `on_finalization`.
pub fn store_to_offchain(session_index: SessionIndex) {
let derived_key = derive_key(PREFIX, session_index);
//let value = SessionModule::historical_root(session_index);
let value = <SessionModule<T>>::validators().encode();
sp_io::offchain_index::set(derived_key.as_slice(), value.as_slice())
let encoded_validator_list = <SessionModule<T>>::validators().encode();
sp_io::offchain_index::set(derived_key.as_slice(), encoded_validator_list.as_slice())
}

/// **Must** be called from on chain, i.e. `on_initialize` or `on_finalization`.
fn store_current_to_offchain() {
/// **Must** be called from on-chain, i.e. `on_initialize` or `on_finalization`.
pub fn store_current_to_offchain() {
Self::store_to_offchain(<SessionModule<T>>::current_index());
}
}
Expand Down