mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 18:11:10 +00:00
Reorganising the repository - external renames and moves (#4074)
* Adding first rough ouline of the repository structure * Remove old CI stuff * add title * formatting fixes * move node-exits job's script to scripts dir * Move docs into subdir * move to bin * move maintainence scripts, configs and helpers into its own dir * add .local to ignore * move core->client * start up 'test' area * move test client * move test runtime * make test move compile * Add dependencies rule enforcement. * Fix indexing. * Update docs to reflect latest changes * Moving /srml->/paint * update docs * move client/sr-* -> primitives/ * clean old readme * remove old broken code in rhd * update lock * Step 1. * starting to untangle client * Fix after merge. * start splitting out client interfaces * move children and blockchain interfaces * Move trie and state-machine to primitives. * Fix WASM builds. * fixing broken imports * more interface moves * move backend and light to interfaces * move CallExecutor * move cli off client * moving around more interfaces * re-add consensus crates into the mix * fix subkey path * relieve client from executor * starting to pull out client from grandpa * move is_decendent_of out of client * grandpa still depends on client directly * lemme tests pass * rename srml->paint * Make it compile. * rename interfaces->client-api * Move keyring to primitives. * fixup libp2p dep * fix broken use * allow dependency enforcement to fail * move fork-tree * Moving wasm-builder * make env * move build-script-utils * fixup broken crate depdencies and names * fix imports for authority discovery * fix typo * update cargo.lock * fixing imports * Fix paths and add missing crates * re-add missing crates
This commit is contained in:
committed by
Bastian Köcher
parent
becc3b0a4f
commit
60e5011c72
@@ -0,0 +1,431 @@
|
||||
// Copyright 2017-2019 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Substrate is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Structures and functions to return blocks whose changes are to be included
|
||||
//! in given block's changes trie.
|
||||
|
||||
use num_traits::Zero;
|
||||
use crate::changes_trie::{ConfigurationRange, BlockNumber};
|
||||
|
||||
/// Returns iterator of OTHER blocks that are required for inclusion into
|
||||
/// changes trie of given block. Blocks are guaranteed to be returned in
|
||||
/// ascending order.
|
||||
///
|
||||
/// Skewed digest is built IF block >= config.end.
|
||||
pub fn digest_build_iterator<'a, Number: BlockNumber>(
|
||||
config: ConfigurationRange<'a, Number>,
|
||||
block: Number,
|
||||
) -> DigestBuildIterator<Number> {
|
||||
// prepare digest build parameters
|
||||
let (_, _, digest_step) = match config.config.digest_level_at_block(config.zero, block.clone()) {
|
||||
Some((current_level, digest_interval, digest_step)) =>
|
||||
(current_level, digest_interval, digest_step),
|
||||
None => return DigestBuildIterator::empty(),
|
||||
};
|
||||
|
||||
DigestBuildIterator::new(block.clone(), config.end.unwrap_or(block), config.config.digest_interval, digest_step)
|
||||
}
|
||||
|
||||
/// Changes trie build iterator that returns numbers of OTHER blocks that are
|
||||
/// required for inclusion into changes trie of given block.
|
||||
#[derive(Debug)]
|
||||
pub struct DigestBuildIterator<Number: BlockNumber> {
|
||||
/// Block we're building changes trie for. It could (logically) be a post-end block if we are creating
|
||||
/// skewed digest.
|
||||
block: Number,
|
||||
/// Block that is a last block where current configuration is active. We have never yet created anything
|
||||
/// after this block => digest that we're creating can't reference any blocks that are >= end.
|
||||
end: Number,
|
||||
/// Interval of L1 digest blocks.
|
||||
digest_interval: u32,
|
||||
/// Max step that could be used when digest is created.
|
||||
max_step: u32,
|
||||
|
||||
// Mutable data below:
|
||||
|
||||
/// Step of current blocks range.
|
||||
current_step: u32,
|
||||
/// Reverse step of current blocks range.
|
||||
current_step_reverse: u32,
|
||||
/// Current blocks range.
|
||||
current_range: Option<BlocksRange<Number>>,
|
||||
/// Last block that we have returned.
|
||||
last_block: Option<Number>,
|
||||
}
|
||||
|
||||
impl<Number: BlockNumber> DigestBuildIterator<Number> {
|
||||
/// Create new digest build iterator.
|
||||
pub fn new(block: Number, end: Number, digest_interval: u32, max_step: u32) -> Self {
|
||||
DigestBuildIterator {
|
||||
block,
|
||||
end,
|
||||
digest_interval,
|
||||
max_step,
|
||||
current_step: max_step,
|
||||
current_step_reverse: 0,
|
||||
current_range: None,
|
||||
last_block: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create empty digest build iterator.
|
||||
pub fn empty() -> Self {
|
||||
Self::new(Zero::zero(), Zero::zero(), 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Number: BlockNumber> Iterator for DigestBuildIterator<Number> {
|
||||
type Item = Number;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// when we're building skewed digest, we might want to skip some blocks if
|
||||
// they're not covered by current configuration
|
||||
loop {
|
||||
if let Some(next) = self.current_range.as_mut().and_then(|iter| iter.next()) {
|
||||
if next < self.end {
|
||||
self.last_block = Some(next.clone());
|
||||
return Some(next);
|
||||
}
|
||||
}
|
||||
|
||||
// we are safe to use non-checking mul/sub versions here because:
|
||||
// DigestBuildIterator is created only by internal function that is checking
|
||||
// that all multiplications/subtractions are safe within max_step limit
|
||||
|
||||
let next_step_reverse = if self.current_step_reverse == 0 {
|
||||
1
|
||||
} else {
|
||||
self.current_step_reverse * self.digest_interval
|
||||
};
|
||||
if next_step_reverse > self.max_step {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.current_step_reverse = next_step_reverse;
|
||||
self.current_range = Some(BlocksRange::new(
|
||||
match self.last_block.clone() {
|
||||
Some(last_block) => last_block + self.current_step.into(),
|
||||
None => self.block.clone() - (self.current_step * self.digest_interval - self.current_step).into(),
|
||||
},
|
||||
self.block.clone(),
|
||||
self.current_step.into(),
|
||||
));
|
||||
|
||||
self.current_step = self.current_step / self.digest_interval;
|
||||
if self.current_step == 0 {
|
||||
self.current_step = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Blocks range iterator with builtin step_by support.
|
||||
#[derive(Debug)]
|
||||
struct BlocksRange<Number: BlockNumber> {
|
||||
current: Number,
|
||||
end: Number,
|
||||
step: Number,
|
||||
}
|
||||
|
||||
impl<Number: BlockNumber> BlocksRange<Number> {
|
||||
pub fn new(begin: Number, end: Number, step: Number) -> Self {
|
||||
BlocksRange {
|
||||
current: begin,
|
||||
end,
|
||||
step,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Number: BlockNumber> Iterator for BlocksRange<Number> {
|
||||
type Item = Number;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.current >= self.end {
|
||||
return None;
|
||||
}
|
||||
|
||||
let current = Some(self.current.clone());
|
||||
self.current += self.step.clone();
|
||||
current
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::changes_trie::Configuration;
|
||||
use super::*;
|
||||
|
||||
fn digest_build_iterator(
|
||||
digest_interval: u32,
|
||||
digest_levels: u32,
|
||||
zero: u64,
|
||||
block: u64,
|
||||
end: Option<u64>,
|
||||
) -> DigestBuildIterator<u64> {
|
||||
super::digest_build_iterator(
|
||||
ConfigurationRange {
|
||||
config: &Configuration {
|
||||
digest_interval,
|
||||
digest_levels,
|
||||
},
|
||||
zero,
|
||||
end,
|
||||
},
|
||||
block,
|
||||
)
|
||||
}
|
||||
|
||||
fn digest_build_iterator_basic(
|
||||
digest_interval: u32,
|
||||
digest_levels: u32,
|
||||
zero: u64,
|
||||
block: u64,
|
||||
) -> (u64, u32, u32) {
|
||||
let iter = digest_build_iterator(digest_interval, digest_levels, zero, block, None);
|
||||
(iter.block, iter.digest_interval, iter.max_step)
|
||||
}
|
||||
|
||||
fn digest_build_iterator_blocks(
|
||||
digest_interval: u32,
|
||||
digest_levels: u32,
|
||||
zero: u64,
|
||||
block: u64,
|
||||
end: Option<u64>,
|
||||
) -> Vec<u64> {
|
||||
digest_build_iterator(digest_interval, digest_levels, zero, block, end).collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suggest_digest_inclusion_returns_empty_iterator() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
let empty = (0, 0, 0);
|
||||
assert_eq!(digest_build_iterator_basic(4, 16, zero, zero + 0), empty, "block is 0");
|
||||
assert_eq!(digest_build_iterator_basic(0, 16, zero, zero + 64), empty, "digest_interval is 0");
|
||||
assert_eq!(digest_build_iterator_basic(1, 16, zero, zero + 64), empty, "digest_interval is 1");
|
||||
assert_eq!(digest_build_iterator_basic(4, 0, zero, zero + 64), empty, "digest_levels is 0");
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(4, 16, zero, zero + 1),
|
||||
empty,
|
||||
"digest is not required for this block",
|
||||
);
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(4, 16, zero, zero + 2),
|
||||
empty,
|
||||
"digest is not required for this block",
|
||||
);
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(4, 16, zero, zero + 15),
|
||||
empty,
|
||||
"digest is not required for this block",
|
||||
);
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(4, 16, zero, zero + 17),
|
||||
empty,
|
||||
"digest is not required for this block",
|
||||
);
|
||||
assert_eq!(digest_build_iterator_basic(
|
||||
::std::u32::MAX / 2 + 1,
|
||||
16,
|
||||
zero,
|
||||
::std::u64::MAX,
|
||||
), empty, "digest_interval * 2 is greater than u64::MAX");
|
||||
}
|
||||
|
||||
test_with_zero(0);
|
||||
test_with_zero(1);
|
||||
test_with_zero(2);
|
||||
test_with_zero(4);
|
||||
test_with_zero(17);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suggest_digest_inclusion_returns_level1_iterator() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(16, 1, zero, zero + 16),
|
||||
(zero + 16, 16, 1),
|
||||
"!(block % interval) && first digest level == block",
|
||||
);
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(16, 1, zero, zero + 256),
|
||||
(zero + 256, 16, 1),
|
||||
"!(block % interval^2), but there's only 1 digest level",
|
||||
);
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(16, 2, zero, zero + 32),
|
||||
(zero + 32, 16, 1),
|
||||
"second level digest is not required for this block",
|
||||
);
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(16, 3, zero, zero + 4080),
|
||||
(zero + 4080, 16, 1),
|
||||
"second && third level digest are not required for this block",
|
||||
);
|
||||
}
|
||||
|
||||
test_with_zero(0);
|
||||
test_with_zero(16);
|
||||
test_with_zero(17);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suggest_digest_inclusion_returns_level2_iterator() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(16, 2, zero, zero + 256),
|
||||
(zero + 256, 16, 16),
|
||||
"second level digest",
|
||||
);
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(16, 2, zero, zero + 4096),
|
||||
(zero + 4096, 16, 16),
|
||||
"!(block % interval^3), but there's only 2 digest levels",
|
||||
);
|
||||
}
|
||||
|
||||
test_with_zero(0);
|
||||
test_with_zero(16);
|
||||
test_with_zero(17);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suggest_digest_inclusion_returns_level3_iterator() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(16, 3, zero, zero + 4096),
|
||||
(zero + 4096, 16, 256),
|
||||
"third level digest: beginning",
|
||||
);
|
||||
assert_eq!(
|
||||
digest_build_iterator_basic(16, 3, zero, zero + 8192),
|
||||
(zero + 8192, 16, 256),
|
||||
"third level digest: next",
|
||||
);
|
||||
}
|
||||
|
||||
test_with_zero(0);
|
||||
test_with_zero(16);
|
||||
test_with_zero(17);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn digest_iterator_returns_level1_blocks() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
assert_eq!(digest_build_iterator_blocks(16, 1, zero, zero + 16, None),
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
|
||||
.iter().map(|item| zero + item).collect::<Vec<_>>());
|
||||
assert_eq!(digest_build_iterator_blocks(16, 1, zero, zero + 256, None),
|
||||
[241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]
|
||||
.iter().map(|item| zero + item).collect::<Vec<_>>());
|
||||
assert_eq!(digest_build_iterator_blocks(16, 2, zero, zero + 32, None),
|
||||
[17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
|
||||
.iter().map(|item| zero + item).collect::<Vec<_>>());
|
||||
assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4080, None),
|
||||
[4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079]
|
||||
.iter().map(|item| zero + item).collect::<Vec<_>>());
|
||||
}
|
||||
|
||||
test_with_zero(0);
|
||||
test_with_zero(16);
|
||||
test_with_zero(17);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn digest_iterator_returns_level1_and_level2_blocks() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
assert_eq!(digest_build_iterator_blocks(16, 2, zero, zero + 256, None),
|
||||
[
|
||||
// level2 points to previous 16-1 level1 digests:
|
||||
16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240,
|
||||
// level2 is a level1 digest of 16-1 previous blocks:
|
||||
241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
|
||||
].iter().map(|item| zero + item).collect::<Vec<_>>(),
|
||||
);
|
||||
assert_eq!(digest_build_iterator_blocks(16, 2, zero, zero + 4096, None),
|
||||
[
|
||||
// level2 points to previous 16-1 level1 digests:
|
||||
3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080,
|
||||
// level2 is a level1 digest of 16-1 previous blocks:
|
||||
4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095,
|
||||
].iter().map(|item| zero + item).collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
|
||||
test_with_zero(0);
|
||||
test_with_zero(16);
|
||||
test_with_zero(17);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn digest_iterator_returns_level1_and_level2_and_level3_blocks() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4096, None),
|
||||
[
|
||||
// level3 points to previous 16-1 level2 digests:
|
||||
256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840,
|
||||
// level3 points to previous 16-1 level1 digests:
|
||||
3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080,
|
||||
// level3 is a level1 digest of 16-1 previous blocks:
|
||||
4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095,
|
||||
].iter().map(|item| zero + item).collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
|
||||
test_with_zero(0);
|
||||
test_with_zero(16);
|
||||
test_with_zero(17);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn digest_iterator_returns_skewed_digest_blocks() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4096, Some(zero + 1338)),
|
||||
[
|
||||
// level3 MUST point to previous 16-1 level2 digests, BUT there are only 5:
|
||||
256, 512, 768, 1024, 1280,
|
||||
// level3 MUST point to previous 16-1 level1 digests, BUT there are only 3:
|
||||
1296, 1312, 1328,
|
||||
// level3 MUST be a level1 digest of 16-1 previous blocks, BUT there are only 9:
|
||||
1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337,
|
||||
].iter().map(|item| zero + item).collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
|
||||
test_with_zero(0);
|
||||
test_with_zero(16);
|
||||
test_with_zero(17);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn digest_iterator_returns_skewed_digest_blocks_skipping_level() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
assert_eq!(digest_build_iterator_blocks(16, 3, zero, zero + 4096, Some(zero + 1284)),
|
||||
[
|
||||
// level3 MUST point to previous 16-1 level2 digests, BUT there are only 5:
|
||||
256, 512, 768, 1024, 1280,
|
||||
// level3 MUST point to previous 16-1 level1 digests, BUT there are NO ANY L1-digests:
|
||||
// level3 MUST be a level1 digest of 16-1 previous blocks, BUT there are only 3:
|
||||
1281, 1282, 1283,
|
||||
].iter().map(|item| zero + item).collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
|
||||
test_with_zero(0);
|
||||
test_with_zero(16);
|
||||
test_with_zero(17);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user