starting memoized validatorset
This commit is contained in:
parent
a254b2098f
commit
7723d6281b
@ -206,7 +206,7 @@ pub trait Engine : Sync + Send {
|
|||||||
///
|
///
|
||||||
/// Engines which do draw consensus information from the state may only do so
|
/// Engines which do draw consensus information from the state may only do so
|
||||||
/// here.
|
/// here.
|
||||||
fn generate_validation_proof(&self, _call: &Call) -> ValidationProof {
|
fn generate_validation_proof(&self, header: &Header, _call: &Call) -> ValidationProof {
|
||||||
ValidationProof::default()
|
ValidationProof::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,11 +25,15 @@ use std::sync::Weak;
|
|||||||
use util::{Address, H256};
|
use util::{Address, H256};
|
||||||
use ethjson::spec::ValidatorSet as ValidatorSpec;
|
use ethjson::spec::ValidatorSet as ValidatorSpec;
|
||||||
use client::Client;
|
use client::Client;
|
||||||
|
use receipt::Receipt;
|
||||||
|
|
||||||
use self::simple_list::SimpleList;
|
use self::simple_list::SimpleList;
|
||||||
use self::contract::ValidatorContract;
|
use self::contract::ValidatorContract;
|
||||||
use self::safe_contract::ValidatorSafeContract;
|
use self::safe_contract::ValidatorSafeContract;
|
||||||
use self::multi::Multi;
|
use self::multi::Multi;
|
||||||
|
|
||||||
|
pub type Call = Fn(Address, Vec<u8>) -> Result<Vec<u8>, String>;
|
||||||
|
|
||||||
/// Creates a validator set from spec.
|
/// Creates a validator set from spec.
|
||||||
pub fn new_validator_set(spec: ValidatorSpec) -> Box<ValidatorSet> {
|
pub fn new_validator_set(spec: ValidatorSpec) -> Box<ValidatorSet> {
|
||||||
match spec {
|
match spec {
|
||||||
@ -42,7 +46,12 @@ pub fn new_validator_set(spec: ValidatorSpec) -> Box<ValidatorSet> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A validator set.
|
||||||
pub trait ValidatorSet: Send + Sync {
|
pub trait ValidatorSet: Send + Sync {
|
||||||
|
/// Get this validator set as a flexible validator set.
|
||||||
|
/// Returning `None` indicates this is only usable for
|
||||||
|
/// full nodes.
|
||||||
|
fn as_memoized(&self) -> Option<&Memoized> { None }
|
||||||
/// Checks if a given address is a validator.
|
/// Checks if a given address is a validator.
|
||||||
fn contains(&self, parent_block_hash: &H256, address: &Address) -> bool;
|
fn contains(&self, parent_block_hash: &H256, address: &Address) -> bool;
|
||||||
/// Draws an validator nonce modulo number of validators.
|
/// Draws an validator nonce modulo number of validators.
|
||||||
@ -56,3 +65,35 @@ pub trait ValidatorSet: Send + Sync {
|
|||||||
/// Allows blockchain state access.
|
/// Allows blockchain state access.
|
||||||
fn register_contract(&self, _client: Weak<Client>) {}
|
fn register_contract(&self, _client: Weak<Client>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A flexible validator set can track its changes.
|
||||||
|
pub trait FlexibleValidatorSet: Send + Sync {
|
||||||
|
/// Whether a validator set may have changed at this header.
|
||||||
|
fn has_possibly_changed(&self, header: &Header) -> bool;
|
||||||
|
|
||||||
|
/// Whether a validator set has changed at this header, given the block receipts.
|
||||||
|
/// Called after `has_possibly_changed`.
|
||||||
|
/// `Some` indicates the validator set has changed at this header and the new
|
||||||
|
/// expected validator set.
|
||||||
|
/// `None` indicates no change.
|
||||||
|
fn has_changed(&self, header: &Header, receipts: &[Receipt]) -> Option<SimpleList>;
|
||||||
|
|
||||||
|
/// Fetch validators at a block synchronously.
|
||||||
|
fn fetch_validators(&self, header: &Header, call: &Call) -> Result<SimpleList, String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A memoized flexible validator set
|
||||||
|
pub struct Memoized {
|
||||||
|
inner: Box<FlexibleValidatorSet>,
|
||||||
|
memo: Mutex<(SimpleList, (H256, u64))>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Memoized {
|
||||||
|
/// Denote that the
|
||||||
|
pub fn use_memo_at(&self, list: SimpleList)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ValidatorSet for Memoized {
|
||||||
|
fn as_memoized(&self) -> Option<&Memoized> { Some(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ impl Multi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn correct_set(&self, bh: &H256) -> Option<&Box<ValidatorSet>> {
|
fn correct_set(&self, bh: &H256) -> Option<&ValidatorSet> {
|
||||||
match self
|
match self
|
||||||
.block_number
|
.block_number
|
||||||
.read()(bh)
|
.read()(bh)
|
||||||
@ -55,7 +55,7 @@ impl Multi {
|
|||||||
) {
|
) {
|
||||||
Ok((block, set)) => {
|
Ok((block, set)) => {
|
||||||
trace!(target: "engine", "Multi ValidatorSet retrieved for block {}.", block);
|
trace!(target: "engine", "Multi ValidatorSet retrieved for block {}.", block);
|
||||||
Some(set)
|
Some(&*set)
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!(target: "engine", "ValidatorSet could not be recovered: {}", e);
|
debug!(target: "engine", "ValidatorSet could not be recovered: {}", e);
|
||||||
@ -66,6 +66,21 @@ impl Multi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ValidatorSet for Multi {
|
impl ValidatorSet for Multi {
|
||||||
|
fn has_possibly_changed(&self, header: &Header) -> bool {
|
||||||
|
// if the sets are the same for each header, compare those.
|
||||||
|
// otherwise, the sets have almost certainly changed.
|
||||||
|
match (self.correct_set(&header.hash()), self.correct_set(header.parent_hash())) {
|
||||||
|
(Some(a), Some(b)) if a as *const _ == b as *const _ => { a.has_possibly_changed(header) },
|
||||||
|
_ => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_changed(&self, header: &Header, receipts: &[Receipt]) -> Option<Vec<Address>> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch(&self) ->
|
||||||
|
|
||||||
fn contains(&self, bh: &H256, address: &Address) -> bool {
|
fn contains(&self, bh: &H256, address: &Address) -> bool {
|
||||||
self.correct_set(bh).map_or(false, |set| set.contains(bh, address))
|
self.correct_set(bh).map_or(false, |set| set.contains(bh, address))
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,11 @@ use super::ValidatorSet;
|
|||||||
#[derive(Debug, PartialEq, Eq, Default)]
|
#[derive(Debug, PartialEq, Eq, Default)]
|
||||||
pub struct SimpleList {
|
pub struct SimpleList {
|
||||||
validators: Vec<Address>,
|
validators: Vec<Address>,
|
||||||
validator_n: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimpleList {
|
impl SimpleList {
|
||||||
pub fn new(validators: Vec<Address>) -> Self {
|
pub fn new(validators: Vec<Address>) -> Self {
|
||||||
SimpleList {
|
SimpleList {
|
||||||
validator_n: validators.len(),
|
|
||||||
validators: validators,
|
validators: validators,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,7 +34,7 @@ impl SimpleList {
|
|||||||
|
|
||||||
impl HeapSizeOf for SimpleList {
|
impl HeapSizeOf for SimpleList {
|
||||||
fn heap_size_of_children(&self) -> usize {
|
fn heap_size_of_children(&self) -> usize {
|
||||||
self.validators.heap_size_of_children() + self.validator_n.heap_size_of_children()
|
self.validators.heap_size_of_children()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,11 +44,12 @@ impl ValidatorSet for SimpleList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get(&self, _bh: &H256, nonce: usize) -> Address {
|
fn get(&self, _bh: &H256, nonce: usize) -> Address {
|
||||||
self.validators.get(nonce % self.validator_n).expect("There are validator_n authorities; taking number modulo validator_n gives number in validator_n range; qed").clone()
|
let validator_n = self.validators.len();
|
||||||
|
self.validators.get(nonce % validator_n).expect("There are validator_n authorities; taking number modulo validator_n gives number in validator_n range; qed").clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count(&self, _bh: &H256) -> usize {
|
fn count(&self, _bh: &H256) -> usize {
|
||||||
self.validator_n
|
self.validators.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user