Merge branch 'master' into sos

This commit is contained in:
Paul Hauner 2019-05-13 15:17:56 +10:00
commit 8222ac17cf
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
25 changed files with 127 additions and 264 deletions

View File

@ -1,6 +1,13 @@
# Lighthouse: an Ethereum Serenity client # Lighthouse: an Ethereum Serenity client
[![Build Status](https://travis-ci.org/sigp/lighthouse.svg?branch=master)](https://travis-ci.org/sigp/lighthouse) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sigp/lighthouse?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Build Status]][Build Link] [![Doc Status]][Doc Link] [![Gitter Badge]][Gitter Link]
[Build Status]: https://gitlab.sigmaprime.io/sigp/lighthouse/badges/master/build.svg
[Build Link]: https://gitlab.sigmaprime.io/sigp/lighthouse/pipelines
[Gitter Badge]: https://badges.gitter.im/Join%20Chat.svg
[Gitter Link]: https://gitter.im/sigp/lighthouse
[Doc Status]: https://img.shields.io/badge/docs-master-blue.svg
[Doc Link]: http://lighthouse-docs.sigmaprime.io/
A work-in-progress, open-source implementation of the Serenity Beacon A work-in-progress, open-source implementation of the Serenity Beacon
Chain, maintained by Sigma Prime. Chain, maintained by Sigma Prime.

View File

@ -83,31 +83,31 @@ impl BlockProcessingOutcome {
} }
} }
pub struct BeaconChain<T: ClientDB + Sized, U: SlotClock, F: ForkChoice, B: EthSpec> { pub struct BeaconChain<T: ClientDB + Sized, U: SlotClock, F: ForkChoice, E: EthSpec> {
pub block_store: Arc<BeaconBlockStore<T>>, pub block_store: Arc<BeaconBlockStore<T>>,
pub state_store: Arc<BeaconStateStore<T>>, pub state_store: Arc<BeaconStateStore<T>>,
pub slot_clock: U, pub slot_clock: U,
pub op_pool: OperationPool<B>, pub op_pool: OperationPool<E>,
canonical_head: RwLock<CheckPoint<B>>, canonical_head: RwLock<CheckPoint<E>>,
finalized_head: RwLock<CheckPoint<B>>, finalized_head: RwLock<CheckPoint<E>>,
pub state: RwLock<BeaconState<B>>, pub state: RwLock<BeaconState<E>>,
pub spec: ChainSpec, pub spec: ChainSpec,
pub fork_choice: RwLock<F>, pub fork_choice: RwLock<F>,
} }
impl<T, U, F, B> BeaconChain<T, U, F, B> impl<T, U, F, E> BeaconChain<T, U, F, E>
where where
T: ClientDB, T: ClientDB,
U: SlotClock, U: SlotClock,
F: ForkChoice, F: ForkChoice,
B: EthSpec, E: EthSpec,
{ {
/// Instantiate a new Beacon Chain, from genesis. /// Instantiate a new Beacon Chain, from genesis.
pub fn from_genesis( pub fn from_genesis(
state_store: Arc<BeaconStateStore<T>>, state_store: Arc<BeaconStateStore<T>>,
block_store: Arc<BeaconBlockStore<T>>, block_store: Arc<BeaconBlockStore<T>>,
slot_clock: U, slot_clock: U,
mut genesis_state: BeaconState<B>, mut genesis_state: BeaconState<E>,
genesis_block: BeaconBlock, genesis_block: BeaconBlock,
spec: ChainSpec, spec: ChainSpec,
fork_choice: F, fork_choice: F,
@ -230,7 +230,7 @@ where
Err(BeaconStateError::SlotOutOfBounds) => { Err(BeaconStateError::SlotOutOfBounds) => {
// Read the earliest historic state in the current slot. // Read the earliest historic state in the current slot.
let earliest_historic_slot = let earliest_historic_slot =
state.slot - Slot::from(B::SlotsPerHistoricalRoot::to_usize()); state.slot - Slot::from(E::SlotsPerHistoricalRoot::to_usize());
// Load the earlier state from disk. // Load the earlier state from disk.
let new_state_root = state.get_state_root(earliest_historic_slot)?; let new_state_root = state.get_state_root(earliest_historic_slot)?;
@ -270,7 +270,7 @@ where
&self, &self,
new_beacon_block: BeaconBlock, new_beacon_block: BeaconBlock,
new_beacon_block_root: Hash256, new_beacon_block_root: Hash256,
new_beacon_state: BeaconState<B>, new_beacon_state: BeaconState<E>,
new_beacon_state_root: Hash256, new_beacon_state_root: Hash256,
) { ) {
debug!( debug!(
@ -292,7 +292,7 @@ where
/// It is important to note that the `beacon_state` returned may not match the present slot. It /// It is important to note that the `beacon_state` returned may not match the present slot. It
/// is the state as it was when the head block was received, which could be some slots prior to /// is the state as it was when the head block was received, which could be some slots prior to
/// now. /// now.
pub fn head(&self) -> RwLockReadGuard<CheckPoint<B>> { pub fn head(&self) -> RwLockReadGuard<CheckPoint<E>> {
self.canonical_head.read() self.canonical_head.read()
} }
@ -302,7 +302,7 @@ where
/// state and calling `catchup_state` as it will not result in an old state being installed and /// state and calling `catchup_state` as it will not result in an old state being installed and
/// then having it iteratively updated -- in such a case it's possible for another thread to /// then having it iteratively updated -- in such a case it's possible for another thread to
/// find the state at an old slot. /// find the state at an old slot.
pub fn update_state(&self, mut state: BeaconState<B>) -> Result<(), Error> { pub fn update_state(&self, mut state: BeaconState<E>) -> Result<(), Error> {
let present_slot = match self.slot_clock.present_slot() { let present_slot = match self.slot_clock.present_slot() {
Ok(Some(slot)) => slot, Ok(Some(slot)) => slot,
_ => return Err(Error::UnableToReadSlot), _ => return Err(Error::UnableToReadSlot),
@ -357,7 +357,7 @@ where
&self, &self,
new_beacon_block: BeaconBlock, new_beacon_block: BeaconBlock,
new_beacon_block_root: Hash256, new_beacon_block_root: Hash256,
new_beacon_state: BeaconState<B>, new_beacon_state: BeaconState<E>,
new_beacon_state_root: Hash256, new_beacon_state_root: Hash256,
) { ) {
let mut finalized_head = self.finalized_head.write(); let mut finalized_head = self.finalized_head.write();
@ -371,7 +371,7 @@ where
/// Returns a read-lock guarded `CheckPoint` struct for reading the justified head (as chosen, /// Returns a read-lock guarded `CheckPoint` struct for reading the justified head (as chosen,
/// indirectly, by the fork-choice rule). /// indirectly, by the fork-choice rule).
pub fn finalized_head(&self) -> RwLockReadGuard<CheckPoint<B>> { pub fn finalized_head(&self) -> RwLockReadGuard<CheckPoint<E>> {
self.finalized_head.read() self.finalized_head.read()
} }
@ -664,7 +664,7 @@ where
pub fn produce_block( pub fn produce_block(
&self, &self,
randao_reveal: Signature, randao_reveal: Signature,
) -> Result<(BeaconBlock, BeaconState<B>), BlockProductionError> { ) -> Result<(BeaconBlock, BeaconState<E>), BlockProductionError> {
debug!("Producing block at slot {}...", self.state.read().slot); debug!("Producing block at slot {}...", self.state.read().slot);
let mut state = self.state.read().clone(); let mut state = self.state.read().clone();
@ -759,7 +759,7 @@ where
/// ///
/// This could be a very expensive operation and should only be done in testing/analysis /// This could be a very expensive operation and should only be done in testing/analysis
/// activities. /// activities.
pub fn chain_dump(&self) -> Result<Vec<CheckPoint<B>>, Error> { pub fn chain_dump(&self) -> Result<Vec<CheckPoint<E>>, Error> {
let mut dump = vec![]; let mut dump = vec![];
let mut last_slot = CheckPoint { let mut last_slot = CheckPoint {

View File

@ -4,19 +4,19 @@ use types::{BeaconBlock, BeaconState, EthSpec, Hash256};
/// Represents some block and it's associated state. Generally, this will be used for tracking the /// Represents some block and it's associated state. Generally, this will be used for tracking the
/// head, justified head and finalized head. /// head, justified head and finalized head.
#[derive(Clone, Serialize, PartialEq, Debug)] #[derive(Clone, Serialize, PartialEq, Debug)]
pub struct CheckPoint<B: EthSpec> { pub struct CheckPoint<E: EthSpec> {
pub beacon_block: BeaconBlock, pub beacon_block: BeaconBlock,
pub beacon_block_root: Hash256, pub beacon_block_root: Hash256,
pub beacon_state: BeaconState<B>, pub beacon_state: BeaconState<E>,
pub beacon_state_root: Hash256, pub beacon_state_root: Hash256,
} }
impl<B: EthSpec> CheckPoint<B> { impl<E: EthSpec> CheckPoint<E> {
/// Create a new checkpoint. /// Create a new checkpoint.
pub fn new( pub fn new(
beacon_block: BeaconBlock, beacon_block: BeaconBlock,
beacon_block_root: Hash256, beacon_block_root: Hash256,
beacon_state: BeaconState<B>, beacon_state: BeaconState<E>,
beacon_state_root: Hash256, beacon_state_root: Hash256,
) -> Self { ) -> Self {
Self { Self {
@ -32,7 +32,7 @@ impl<B: EthSpec> CheckPoint<B> {
&mut self, &mut self,
beacon_block: BeaconBlock, beacon_block: BeaconBlock,
beacon_block_root: Hash256, beacon_block_root: Hash256,
beacon_state: BeaconState<B>, beacon_state: BeaconState<E>,
beacon_state_root: Hash256, beacon_state_root: Hash256,
) { ) {
self.beacon_block = beacon_block; self.beacon_block = beacon_block;

View File

@ -10,15 +10,15 @@ use tree_hash::TreeHash;
use types::*; use types::*;
use types::{test_utils::TestingBeaconStateBuilder, EthSpec, FewValidatorsEthSpec}; use types::{test_utils::TestingBeaconStateBuilder, EthSpec, FewValidatorsEthSpec};
type TestingBeaconChain<B> = type TestingBeaconChain<E> =
BeaconChain<MemoryDB, TestingSlotClock, BitwiseLMDGhost<MemoryDB, FewValidatorsEthSpec>, B>; BeaconChain<MemoryDB, TestingSlotClock, BitwiseLMDGhost<MemoryDB, FewValidatorsEthSpec>, E>;
pub struct TestingBeaconChainBuilder<B: EthSpec> { pub struct TestingBeaconChainBuilder<E: EthSpec> {
state_builder: TestingBeaconStateBuilder<B>, state_builder: TestingBeaconStateBuilder<E>,
} }
impl<B: EthSpec> TestingBeaconChainBuilder<B> { impl<E: EthSpec> TestingBeaconChainBuilder<E> {
pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain<B> { pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain<E> {
let db = Arc::new(MemoryDB::open()); let db = Arc::new(MemoryDB::open());
let block_store = Arc::new(BeaconBlockStore::new(db.clone())); let block_store = Arc::new(BeaconBlockStore::new(db.clone()));
let state_store = Arc::new(BeaconStateStore::new(db.clone())); let state_store = Arc::new(BeaconStateStore::new(db.clone()));
@ -44,8 +44,8 @@ impl<B: EthSpec> TestingBeaconChainBuilder<B> {
} }
} }
impl<B: EthSpec> From<TestingBeaconStateBuilder<B>> for TestingBeaconChainBuilder<B> { impl<E: EthSpec> From<TestingBeaconStateBuilder<E>> for TestingBeaconChainBuilder<E> {
fn from(state_builder: TestingBeaconStateBuilder<B>) -> TestingBeaconChainBuilder<B> { fn from(state_builder: TestingBeaconStateBuilder<E>) -> TestingBeaconChainBuilder<E> {
TestingBeaconChainBuilder { state_builder } TestingBeaconChainBuilder { state_builder }
} }
} }

View File

@ -144,12 +144,12 @@ impl<TClientType: ClientTypes> Client<TClientType> {
} }
} }
fn do_state_catchup<T, U, F, B>(chain: &Arc<BeaconChain<T, U, F, B>>, log: &slog::Logger) fn do_state_catchup<T, U, F, E>(chain: &Arc<BeaconChain<T, U, F, E>>, log: &slog::Logger)
where where
T: ClientDB, T: ClientDB,
U: SlotClock, U: SlotClock,
F: ForkChoice, F: ForkChoice,
B: EthSpec, E: EthSpec,
{ {
if let Some(genesis_height) = chain.slots_since_genesis() { if let Some(genesis_height) = chain.slots_since_genesis() {
let result = chain.catchup_state(); let result = chain.catchup_state();

View File

@ -19,10 +19,10 @@ impl<T: ClientDB> BeaconStateStore<T> {
Self { db } Self { db }
} }
pub fn get_deserialized<B: EthSpec>( pub fn get_deserialized<E: EthSpec>(
&self, &self,
hash: &Hash256, hash: &Hash256,
) -> Result<Option<BeaconState<B>>, DBError> { ) -> Result<Option<BeaconState<E>>, DBError> {
match self.get(&hash)? { match self.get(&hash)? {
None => Ok(None), None => Ok(None),
Some(ssz) => { Some(ssz) => {

View File

@ -15,14 +15,14 @@ use types::{
pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome, InvalidBlock}; pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome, InvalidBlock};
/// The network's API to the beacon chain. /// The network's API to the beacon chain.
pub trait BeaconChain<B: EthSpec>: Send + Sync { pub trait BeaconChain<E: EthSpec>: Send + Sync {
fn get_spec(&self) -> &ChainSpec; fn get_spec(&self) -> &ChainSpec;
fn get_state(&self) -> RwLockReadGuard<BeaconState<B>>; fn get_state(&self) -> RwLockReadGuard<BeaconState<E>>;
fn slot(&self) -> Slot; fn slot(&self) -> Slot;
fn head(&self) -> RwLockReadGuard<CheckPoint<B>>; fn head(&self) -> RwLockReadGuard<CheckPoint<E>>;
fn get_block(&self, block_root: &Hash256) -> Result<Option<BeaconBlock>, BeaconChainError>; fn get_block(&self, block_root: &Hash256) -> Result<Option<BeaconBlock>, BeaconChainError>;
@ -30,7 +30,7 @@ pub trait BeaconChain<B: EthSpec>: Send + Sync {
fn best_block_root(&self) -> Hash256; fn best_block_root(&self) -> Hash256;
fn finalized_head(&self) -> RwLockReadGuard<CheckPoint<B>>; fn finalized_head(&self) -> RwLockReadGuard<CheckPoint<E>>;
fn finalized_epoch(&self) -> Epoch; fn finalized_epoch(&self) -> Epoch;
@ -64,18 +64,18 @@ pub trait BeaconChain<B: EthSpec>: Send + Sync {
fn is_new_block_root(&self, beacon_block_root: &Hash256) -> Result<bool, BeaconChainError>; fn is_new_block_root(&self, beacon_block_root: &Hash256) -> Result<bool, BeaconChainError>;
} }
impl<T, U, F, B> BeaconChain<B> for RawBeaconChain<T, U, F, B> impl<T, U, F, E> BeaconChain<E> for RawBeaconChain<T, U, F, E>
where where
T: ClientDB + Sized, T: ClientDB + Sized,
U: SlotClock, U: SlotClock,
F: ForkChoice, F: ForkChoice,
B: EthSpec, E: EthSpec,
{ {
fn get_spec(&self) -> &ChainSpec { fn get_spec(&self) -> &ChainSpec {
&self.spec &self.spec
} }
fn get_state(&self) -> RwLockReadGuard<BeaconState<B>> { fn get_state(&self) -> RwLockReadGuard<BeaconState<E>> {
self.state.read() self.state.read()
} }
@ -83,7 +83,7 @@ where
self.get_state().slot self.get_state().slot
} }
fn head(&self) -> RwLockReadGuard<CheckPoint<B>> { fn head(&self) -> RwLockReadGuard<CheckPoint<E>> {
self.head() self.head()
} }
@ -95,7 +95,7 @@ where
self.get_state().finalized_epoch self.get_state().finalized_epoch
} }
fn finalized_head(&self) -> RwLockReadGuard<CheckPoint<B>> { fn finalized_head(&self) -> RwLockReadGuard<CheckPoint<E>> {
self.finalized_head() self.finalized_head()
} }

View File

@ -21,11 +21,11 @@ use types::EthSpec;
// const HELLO_TIMEOUT: Duration = Duration::from_secs(30); // const HELLO_TIMEOUT: Duration = Duration::from_secs(30);
/// Handles messages received from the network and client and organises syncing. /// Handles messages received from the network and client and organises syncing.
pub struct MessageHandler<B: EthSpec> { pub struct MessageHandler<E: EthSpec> {
/// Currently loaded and initialised beacon chain. /// Currently loaded and initialised beacon chain.
_chain: Arc<BeaconChain<B>>, _chain: Arc<BeaconChain<E>>,
/// The syncing framework. /// The syncing framework.
sync: SimpleSync<B>, sync: SimpleSync<E>,
/// The context required to send messages to, and process messages from peers. /// The context required to send messages to, and process messages from peers.
network_context: NetworkContext, network_context: NetworkContext,
/// The `MessageHandler` logger. /// The `MessageHandler` logger.
@ -45,10 +45,10 @@ pub enum HandlerMessage {
PubsubMessage(PeerId, Box<PubsubMessage>), PubsubMessage(PeerId, Box<PubsubMessage>),
} }
impl<B: EthSpec> MessageHandler<B> { impl<E: EthSpec> MessageHandler<E> {
/// Initializes and runs the MessageHandler. /// Initializes and runs the MessageHandler.
pub fn spawn( pub fn spawn(
beacon_chain: Arc<BeaconChain<B>>, beacon_chain: Arc<BeaconChain<E>>,
network_send: crossbeam_channel::Sender<NetworkMessage>, network_send: crossbeam_channel::Sender<NetworkMessage>,
executor: &tokio::runtime::TaskExecutor, executor: &tokio::runtime::TaskExecutor,
log: slog::Logger, log: slog::Logger,

View File

@ -16,17 +16,17 @@ use tokio::runtime::TaskExecutor;
use types::{EthSpec, Topic}; use types::{EthSpec, Topic};
/// Service that handles communication between internal services and the eth2_libp2p network service. /// Service that handles communication between internal services and the eth2_libp2p network service.
pub struct Service<B: EthSpec> { pub struct Service<E: EthSpec> {
//libp2p_service: Arc<Mutex<LibP2PService>>, //libp2p_service: Arc<Mutex<LibP2PService>>,
_libp2p_exit: oneshot::Sender<()>, _libp2p_exit: oneshot::Sender<()>,
network_send: crossbeam_channel::Sender<NetworkMessage>, network_send: crossbeam_channel::Sender<NetworkMessage>,
_phantom: PhantomData<B>, //message_handler: MessageHandler, _phantom: PhantomData<E>, //message_handler: MessageHandler,
//message_handler_send: Sender<HandlerMessage> //message_handler_send: Sender<HandlerMessage>
} }
impl<B: EthSpec> Service<B> { impl<E: EthSpec> Service<E> {
pub fn new( pub fn new(
beacon_chain: Arc<BeaconChain<B>>, beacon_chain: Arc<BeaconChain<E>>,
config: &NetworkConfig, config: &NetworkConfig,
executor: &TaskExecutor, executor: &TaskExecutor,
log: slog::Logger, log: slog::Logger,

View File

@ -19,8 +19,8 @@ use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, EthSpec, Hash256, S
/// `BeaconBlockBody` as the key. /// `BeaconBlockBody` as the key.
/// - It is possible for multiple distinct blocks to have identical `BeaconBlockBodies`. Therefore /// - It is possible for multiple distinct blocks to have identical `BeaconBlockBodies`. Therefore
/// we cannot use a `HashMap` keyed by the root of `BeaconBlockBody`. /// we cannot use a `HashMap` keyed by the root of `BeaconBlockBody`.
pub struct ImportQueue<B: EthSpec> { pub struct ImportQueue<E: EthSpec> {
pub chain: Arc<BeaconChain<B>>, pub chain: Arc<BeaconChain<E>>,
/// Partially imported blocks, keyed by the root of `BeaconBlockBody`. /// Partially imported blocks, keyed by the root of `BeaconBlockBody`.
pub partials: Vec<PartialBeaconBlock>, pub partials: Vec<PartialBeaconBlock>,
/// Time before a queue entry is considered state. /// Time before a queue entry is considered state.
@ -29,9 +29,9 @@ pub struct ImportQueue<B: EthSpec> {
log: slog::Logger, log: slog::Logger,
} }
impl<B: EthSpec> ImportQueue<B> { impl<E: EthSpec> ImportQueue<E> {
/// Return a new, empty queue. /// Return a new, empty queue.
pub fn new(chain: Arc<BeaconChain<B>>, stale_time: Duration, log: slog::Logger) -> Self { pub fn new(chain: Arc<BeaconChain<E>>, stale_time: Duration, log: slog::Logger) -> Self {
Self { Self {
chain, chain,
partials: vec![], partials: vec![],

View File

@ -88,8 +88,8 @@ impl From<HelloMessage> for PeerSyncInfo {
} }
} }
impl<B: EthSpec> From<&Arc<BeaconChain<B>>> for PeerSyncInfo { impl<E: EthSpec> From<&Arc<BeaconChain<E>>> for PeerSyncInfo {
fn from(chain: &Arc<BeaconChain<B>>) -> PeerSyncInfo { fn from(chain: &Arc<BeaconChain<E>>) -> PeerSyncInfo {
Self::from(chain.hello_message()) Self::from(chain.hello_message())
} }
} }
@ -103,22 +103,22 @@ pub enum SyncState {
} }
/// Simple Syncing protocol. /// Simple Syncing protocol.
pub struct SimpleSync<B: EthSpec> { pub struct SimpleSync<E: EthSpec> {
/// A reference to the underlying beacon chain. /// A reference to the underlying beacon chain.
chain: Arc<BeaconChain<B>>, chain: Arc<BeaconChain<E>>,
/// A mapping of Peers to their respective PeerSyncInfo. /// A mapping of Peers to their respective PeerSyncInfo.
known_peers: HashMap<PeerId, PeerSyncInfo>, known_peers: HashMap<PeerId, PeerSyncInfo>,
/// A queue to allow importing of blocks /// A queue to allow importing of blocks
import_queue: ImportQueue<B>, import_queue: ImportQueue<E>,
/// The current state of the syncing protocol. /// The current state of the syncing protocol.
state: SyncState, state: SyncState,
/// Sync logger. /// Sync logger.
log: slog::Logger, log: slog::Logger,
} }
impl<B: EthSpec> SimpleSync<B> { impl<E: EthSpec> SimpleSync<E> {
/// Instantiate a `SimpleSync` instance, with no peers and an empty queue. /// Instantiate a `SimpleSync` instance, with no peers and an empty queue.
pub fn new(beacon_chain: Arc<BeaconChain<B>>, log: &slog::Logger) -> Self { pub fn new(beacon_chain: Arc<BeaconChain<E>>, log: &slog::Logger) -> Self {
let sync_logger = log.new(o!("Service"=> "Sync")); let sync_logger = log.new(o!("Service"=> "Sync"));
let queue_item_stale_time = Duration::from_secs(QUEUE_STALE_SECS); let queue_item_stale_time = Duration::from_secs(QUEUE_STALE_SECS);

View File

@ -12,12 +12,12 @@ use std::sync::Arc;
use types::{Attestation, EthSpec}; use types::{Attestation, EthSpec};
#[derive(Clone)] #[derive(Clone)]
pub struct AttestationServiceInstance<B: EthSpec> { pub struct AttestationServiceInstance<E: EthSpec> {
pub chain: Arc<BeaconChain<B>>, pub chain: Arc<BeaconChain<E>>,
pub log: slog::Logger, pub log: slog::Logger,
} }
impl<B: EthSpec> AttestationService for AttestationServiceInstance<B> { impl<E: EthSpec> AttestationService for AttestationServiceInstance<E> {
/// Produce the `AttestationData` for signing by a validator. /// Produce the `AttestationData` for signing by a validator.
fn produce_attestation_data( fn produce_attestation_data(
&mut self, &mut self,

View File

@ -16,13 +16,13 @@ use std::sync::Arc;
use types::{BeaconBlock, EthSpec, Signature, Slot}; use types::{BeaconBlock, EthSpec, Signature, Slot};
#[derive(Clone)] #[derive(Clone)]
pub struct BeaconBlockServiceInstance<B: EthSpec> { pub struct BeaconBlockServiceInstance<E: EthSpec> {
pub chain: Arc<BeaconChain<B>>, pub chain: Arc<BeaconChain<E>>,
pub network_chan: crossbeam_channel::Sender<NetworkMessage>, pub network_chan: crossbeam_channel::Sender<NetworkMessage>,
pub log: Logger, pub log: Logger,
} }
impl<B: EthSpec> BeaconBlockService for BeaconBlockServiceInstance<B> { impl<E: EthSpec> BeaconBlockService for BeaconBlockServiceInstance<E> {
/// Produce a `BeaconBlock` for signing by a validator. /// Produce a `BeaconBlock` for signing by a validator.
fn produce_beacon_block( fn produce_beacon_block(
&mut self, &mut self,

View File

@ -11,12 +11,12 @@ pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome};
use types::{Attestation, AttestationData, BeaconBlock, EthSpec}; use types::{Attestation, AttestationData, BeaconBlock, EthSpec};
/// The RPC's API to the beacon chain. /// The RPC's API to the beacon chain.
pub trait BeaconChain<B: EthSpec>: Send + Sync { pub trait BeaconChain<E: EthSpec>: Send + Sync {
fn get_spec(&self) -> &ChainSpec; fn get_spec(&self) -> &ChainSpec;
fn get_state(&self) -> RwLockReadGuard<BeaconState<B>>; fn get_state(&self) -> RwLockReadGuard<BeaconState<E>>;
fn get_mut_state(&self) -> RwLockWriteGuard<BeaconState<B>>; fn get_mut_state(&self) -> RwLockWriteGuard<BeaconState<E>>;
fn process_block(&self, block: BeaconBlock) fn process_block(&self, block: BeaconBlock)
-> Result<BlockProcessingOutcome, BeaconChainError>; -> Result<BlockProcessingOutcome, BeaconChainError>;
@ -24,7 +24,7 @@ pub trait BeaconChain<B: EthSpec>: Send + Sync {
fn produce_block( fn produce_block(
&self, &self,
randao_reveal: Signature, randao_reveal: Signature,
) -> Result<(BeaconBlock, BeaconState<B>), BlockProductionError>; ) -> Result<(BeaconBlock, BeaconState<E>), BlockProductionError>;
fn produce_attestation_data(&self, shard: u64) -> Result<AttestationData, BeaconChainError>; fn produce_attestation_data(&self, shard: u64) -> Result<AttestationData, BeaconChainError>;
@ -34,22 +34,22 @@ pub trait BeaconChain<B: EthSpec>: Send + Sync {
) -> Result<(), AttestationValidationError>; ) -> Result<(), AttestationValidationError>;
} }
impl<T, U, F, B> BeaconChain<B> for RawBeaconChain<T, U, F, B> impl<T, U, F, E> BeaconChain<E> for RawBeaconChain<T, U, F, E>
where where
T: ClientDB + Sized, T: ClientDB + Sized,
U: SlotClock, U: SlotClock,
F: ForkChoice, F: ForkChoice,
B: EthSpec, E: EthSpec,
{ {
fn get_spec(&self) -> &ChainSpec { fn get_spec(&self) -> &ChainSpec {
&self.spec &self.spec
} }
fn get_state(&self) -> RwLockReadGuard<BeaconState<B>> { fn get_state(&self) -> RwLockReadGuard<BeaconState<E>> {
self.state.read() self.state.read()
} }
fn get_mut_state(&self) -> RwLockWriteGuard<BeaconState<B>> { fn get_mut_state(&self) -> RwLockWriteGuard<BeaconState<E>> {
self.state.write() self.state.write()
} }
@ -63,7 +63,7 @@ where
fn produce_block( fn produce_block(
&self, &self,
randao_reveal: Signature, randao_reveal: Signature,
) -> Result<(BeaconBlock, BeaconState<B>), BlockProductionError> { ) -> Result<(BeaconBlock, BeaconState<E>), BlockProductionError> {
self.produce_block(randao_reveal) self.produce_block(randao_reveal)
} }

View File

@ -8,12 +8,12 @@ use std::sync::Arc;
use types::EthSpec; use types::EthSpec;
#[derive(Clone)] #[derive(Clone)]
pub struct BeaconNodeServiceInstance<B: EthSpec> { pub struct BeaconNodeServiceInstance<E: EthSpec> {
pub chain: Arc<BeaconChain<B>>, pub chain: Arc<BeaconChain<E>>,
pub log: slog::Logger, pub log: slog::Logger,
} }
impl<B: EthSpec> BeaconNodeService for BeaconNodeServiceInstance<B> { impl<E: EthSpec> BeaconNodeService for BeaconNodeServiceInstance<E> {
/// Provides basic node information. /// Provides basic node information.
fn info(&mut self, ctx: RpcContext, _req: Empty, sink: UnarySink<NodeInfoResponse>) { fn info(&mut self, ctx: RpcContext, _req: Empty, sink: UnarySink<NodeInfoResponse>) {
trace!(self.log, "Node info requested via RPC"); trace!(self.log, "Node info requested via RPC");

View File

@ -23,11 +23,11 @@ use std::sync::Arc;
use tokio::runtime::TaskExecutor; use tokio::runtime::TaskExecutor;
use types::EthSpec; use types::EthSpec;
pub fn start_server<B: EthSpec>( pub fn start_server<E: EthSpec>(
config: &RPCConfig, config: &RPCConfig,
executor: &TaskExecutor, executor: &TaskExecutor,
network_chan: crossbeam_channel::Sender<NetworkMessage>, network_chan: crossbeam_channel::Sender<NetworkMessage>,
beacon_chain: Arc<BeaconChain<B>>, beacon_chain: Arc<BeaconChain<E>>,
log: &slog::Logger, log: &slog::Logger,
) -> exit_future::Signal { ) -> exit_future::Signal {
let log = log.new(o!("Service"=>"RPC")); let log = log.new(o!("Service"=>"RPC"));

View File

@ -10,13 +10,13 @@ use std::sync::Arc;
use types::{Epoch, EthSpec, RelativeEpoch}; use types::{Epoch, EthSpec, RelativeEpoch};
#[derive(Clone)] #[derive(Clone)]
pub struct ValidatorServiceInstance<B: EthSpec> { pub struct ValidatorServiceInstance<E: EthSpec> {
pub chain: Arc<BeaconChain<B>>, pub chain: Arc<BeaconChain<E>>,
pub log: slog::Logger, pub log: slog::Logger,
} }
//TODO: Refactor Errors //TODO: Refactor Errors
impl<B: EthSpec> ValidatorService for ValidatorServiceInstance<B> { impl<E: EthSpec> ValidatorService for ValidatorServiceInstance<E> {
/// For a list of validator public keys, this function returns the slot at which each /// For a list of validator public keys, this function returns the slot at which each
/// validator must propose a block, attest to a shard, their shard committee and the shard they /// validator must propose a block, attest to a shard, their shard committee and the shard they
/// need to attest to. /// need to attest to.

View File

@ -34,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 {
} }
/// Stores the necessary data structures to run the optimised bitwise lmd ghost algorithm. /// Stores the necessary data structures to run the optimised bitwise lmd ghost algorithm.
pub struct BitwiseLMDGhost<T: ClientDB + Sized, B> { pub struct BitwiseLMDGhost<T: ClientDB + Sized, E> {
/// A cache of known ancestors at given heights for a specific block. /// A cache of known ancestors at given heights for a specific block.
//TODO: Consider FnvHashMap //TODO: Consider FnvHashMap
cache: HashMap<CacheKey<u64>, Hash256>, cache: HashMap<CacheKey<u64>, Hash256>,
@ -51,10 +51,10 @@ pub struct BitwiseLMDGhost<T: ClientDB + Sized, B> {
/// State storage access. /// State storage access.
state_store: Arc<BeaconStateStore<T>>, state_store: Arc<BeaconStateStore<T>>,
max_known_height: SlotHeight, max_known_height: SlotHeight,
_phantom: PhantomData<B>, _phantom: PhantomData<E>,
} }
impl<T, B: EthSpec> BitwiseLMDGhost<T, B> impl<T, E: EthSpec> BitwiseLMDGhost<T, E>
where where
T: ClientDB + Sized, T: ClientDB + Sized,
{ {
@ -88,7 +88,7 @@ where
// build a hashmap of block_hash to weighted votes // build a hashmap of block_hash to weighted votes
let mut latest_votes: HashMap<Hash256, u64> = HashMap::new(); let mut latest_votes: HashMap<Hash256, u64> = HashMap::new();
// gets the current weighted votes // gets the current weighted votes
let current_state: BeaconState<B> = self let current_state: BeaconState<E> = self
.state_store .state_store
.get_deserialized(&state_root)? .get_deserialized(&state_root)?
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
@ -243,7 +243,7 @@ where
} }
} }
impl<T: ClientDB + Sized, B: EthSpec> ForkChoice for BitwiseLMDGhost<T, B> { impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for BitwiseLMDGhost<T, E> {
fn add_block( fn add_block(
&mut self, &mut self,
block: &BeaconBlock, block: &BeaconBlock,

View File

@ -34,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 {
} }
/// Stores the necessary data structures to run the optimised lmd ghost algorithm. /// Stores the necessary data structures to run the optimised lmd ghost algorithm.
pub struct OptimizedLMDGhost<T: ClientDB + Sized, B> { pub struct OptimizedLMDGhost<T: ClientDB + Sized, E> {
/// A cache of known ancestors at given heights for a specific block. /// A cache of known ancestors at given heights for a specific block.
//TODO: Consider FnvHashMap //TODO: Consider FnvHashMap
cache: HashMap<CacheKey<u64>, Hash256>, cache: HashMap<CacheKey<u64>, Hash256>,
@ -51,10 +51,10 @@ pub struct OptimizedLMDGhost<T: ClientDB + Sized, B> {
/// State storage access. /// State storage access.
state_store: Arc<BeaconStateStore<T>>, state_store: Arc<BeaconStateStore<T>>,
max_known_height: SlotHeight, max_known_height: SlotHeight,
_phantom: PhantomData<B>, _phantom: PhantomData<E>,
} }
impl<T, B: EthSpec> OptimizedLMDGhost<T, B> impl<T, E: EthSpec> OptimizedLMDGhost<T, E>
where where
T: ClientDB + Sized, T: ClientDB + Sized,
{ {
@ -88,7 +88,7 @@ where
// build a hashmap of block_hash to weighted votes // build a hashmap of block_hash to weighted votes
let mut latest_votes: HashMap<Hash256, u64> = HashMap::new(); let mut latest_votes: HashMap<Hash256, u64> = HashMap::new();
// gets the current weighted votes // gets the current weighted votes
let current_state: BeaconState<B> = self let current_state: BeaconState<E> = self
.state_store .state_store
.get_deserialized(&state_root)? .get_deserialized(&state_root)?
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
@ -214,7 +214,7 @@ where
} }
} }
impl<T: ClientDB + Sized, B: EthSpec> ForkChoice for OptimizedLMDGhost<T, B> { impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for OptimizedLMDGhost<T, E> {
fn add_block( fn add_block(
&mut self, &mut self,
block: &BeaconBlock, block: &BeaconBlock,

View File

@ -13,7 +13,7 @@ use types::{BeaconBlock, BeaconState, ChainSpec, EthSpec, Hash256, Slot};
//TODO: Pruning and syncing //TODO: Pruning and syncing
pub struct SlowLMDGhost<T: ClientDB + Sized, B> { pub struct SlowLMDGhost<T: ClientDB + Sized, E> {
/// The latest attestation targets as a map of validator index to block hash. /// The latest attestation targets as a map of validator index to block hash.
//TODO: Could this be a fixed size vec //TODO: Could this be a fixed size vec
latest_attestation_targets: HashMap<u64, Hash256>, latest_attestation_targets: HashMap<u64, Hash256>,
@ -23,10 +23,10 @@ pub struct SlowLMDGhost<T: ClientDB + Sized, B> {
block_store: Arc<BeaconBlockStore<T>>, block_store: Arc<BeaconBlockStore<T>>,
/// State storage access. /// State storage access.
state_store: Arc<BeaconStateStore<T>>, state_store: Arc<BeaconStateStore<T>>,
_phantom: PhantomData<B>, _phantom: PhantomData<E>,
} }
impl<T, B: EthSpec> SlowLMDGhost<T, B> impl<T, E: EthSpec> SlowLMDGhost<T, E>
where where
T: ClientDB + Sized, T: ClientDB + Sized,
{ {
@ -57,7 +57,7 @@ where
// build a hashmap of block_hash to weighted votes // build a hashmap of block_hash to weighted votes
let mut latest_votes: HashMap<Hash256, u64> = HashMap::new(); let mut latest_votes: HashMap<Hash256, u64> = HashMap::new();
// gets the current weighted votes // gets the current weighted votes
let current_state: BeaconState<B> = self let current_state: BeaconState<E> = self
.state_store .state_store
.get_deserialized(&state_root)? .get_deserialized(&state_root)?
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
@ -108,7 +108,7 @@ where
} }
} }
impl<T: ClientDB + Sized, B: EthSpec> ForkChoice for SlowLMDGhost<T, B> { impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for SlowLMDGhost<T, E> {
/// Process when a block is added /// Process when a block is added
fn add_block( fn add_block(
&mut self, &mut self,

View File

@ -539,10 +539,10 @@ where
/// The keys in the map should be validator indices, which will be looked up /// The keys in the map should be validator indices, which will be looked up
/// in the state's validator registry and then passed to `prune_if`. /// in the state's validator registry and then passed to `prune_if`.
/// Entries for unknown validators will be kept. /// Entries for unknown validators will be kept.
fn prune_validator_hash_map<T, F, B: EthSpec>( fn prune_validator_hash_map<T, F, E: EthSpec>(
map: &mut HashMap<u64, T>, map: &mut HashMap<u64, T>,
prune_if: F, prune_if: F,
finalized_state: &BeaconState<B>, finalized_state: &BeaconState<E>,
) where ) where
F: Fn(&Validator) -> bool, F: Fn(&Validator) -> bool,
{ {
@ -722,12 +722,12 @@ mod tests {
/// Create a signed attestation for use in tests. /// Create a signed attestation for use in tests.
/// Signed by all validators in `committee[signing_range]` and `committee[extra_signer]`. /// Signed by all validators in `committee[signing_range]` and `committee[extra_signer]`.
fn signed_attestation<R: std::slice::SliceIndex<[usize], Output = [usize]>, B: EthSpec>( fn signed_attestation<R: std::slice::SliceIndex<[usize], Output = [usize]>, E: EthSpec>(
committee: &CrosslinkCommittee, committee: &CrosslinkCommittee,
keypairs: &[Keypair], keypairs: &[Keypair],
signing_range: R, signing_range: R,
slot: Slot, slot: Slot,
state: &BeaconState<B>, state: &BeaconState<E>,
spec: &ChainSpec, spec: &ChainSpec,
extra_signer: Option<usize>, extra_signer: Option<usize>,
) -> Attestation { ) -> Attestation {
@ -754,10 +754,10 @@ mod tests {
} }
/// Test state for attestation-related tests. /// Test state for attestation-related tests.
fn attestation_test_state<B: EthSpec>( fn attestation_test_state<E: EthSpec>(
num_committees: usize, num_committees: usize,
) -> (BeaconState<B>, Vec<Keypair>, ChainSpec) { ) -> (BeaconState<E>, Vec<Keypair>, ChainSpec) {
let spec = B::spec(); let spec = E::spec();
let num_validators = let num_validators =
num_committees * (spec.slots_per_epoch * spec.target_committee_size) as usize; num_committees * (spec.slots_per_epoch * spec.target_committee_size) as usize;
@ -775,9 +775,9 @@ mod tests {
} }
/// Set the latest crosslink in the state to match the attestation. /// Set the latest crosslink in the state to match the attestation.
fn fake_latest_crosslink<B: EthSpec>( fn fake_latest_crosslink<E: EthSpec>(
att: &Attestation, att: &Attestation,
state: &mut BeaconState<B>, state: &mut BeaconState<E>,
spec: &ChainSpec, spec: &ChainSpec,
) { ) {
state.latest_crosslinks[att.data.shard as usize] = Crosslink { state.latest_crosslinks[att.data.shard as usize] = Crosslink {

View File

@ -27,7 +27,6 @@ pub mod pending_attestation;
pub mod proposer_slashing; pub mod proposer_slashing;
pub mod slashable_attestation; pub mod slashable_attestation;
pub mod transfer; pub mod transfer;
// pub mod tree_hash_vector;
pub mod voluntary_exit; pub mod voluntary_exit;
#[macro_use] #[macro_use]
pub mod slot_epoch_macros; pub mod slot_epoch_macros;
@ -66,7 +65,6 @@ pub use crate::slashable_attestation::SlashableAttestation;
pub use crate::slot_epoch::{Epoch, Slot}; pub use crate::slot_epoch::{Epoch, Slot};
pub use crate::slot_height::SlotHeight; pub use crate::slot_height::SlotHeight;
pub use crate::transfer::Transfer; pub use crate::transfer::Transfer;
// pub use crate::tree_hash_vector::TreeHashVector;
pub use crate::validator::Validator; pub use crate::validator::Validator;
pub use crate::voluntary_exit::VoluntaryExit; pub use crate::voluntary_exit::VoluntaryExit;

View File

@ -1,142 +0,0 @@
use crate::test_utils::{RngCore, TestRandom};
use cached_tree_hash::CachedTreeHash;
use serde_derive::{Deserialize, Serialize};
use ssz::{Decode, DecodeError, Encode};
use std::ops::{Deref, DerefMut};
use tree_hash::TreeHash;
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct TreeHashVector<T>(Vec<T>);
impl<T> From<Vec<T>> for TreeHashVector<T> {
fn from(vec: Vec<T>) -> TreeHashVector<T> {
TreeHashVector(vec)
}
}
impl<T> Into<Vec<T>> for TreeHashVector<T> {
fn into(self) -> Vec<T> {
self.0
}
}
impl<T> Deref for TreeHashVector<T> {
type Target = Vec<T>;
fn deref(&self) -> &Vec<T> {
&self.0
}
}
impl<T> DerefMut for TreeHashVector<T> {
fn deref_mut(&mut self) -> &mut Vec<T> {
&mut self.0
}
}
impl<T> tree_hash::TreeHash for TreeHashVector<T>
where
T: TreeHash,
{
fn tree_hash_type() -> tree_hash::TreeHashType {
tree_hash::TreeHashType::Vector
}
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
unreachable!("Vector should never be packed.")
}
fn tree_hash_packing_factor() -> usize {
unreachable!("Vector should never be packed.")
}
fn tree_hash_root(&self) -> Vec<u8> {
tree_hash::impls::vec_tree_hash_root(self)
}
}
impl<T> CachedTreeHash for TreeHashVector<T>
where
T: CachedTreeHash + TreeHash,
{
fn new_tree_hash_cache(
&self,
depth: usize,
) -> Result<cached_tree_hash::TreeHashCache, cached_tree_hash::Error> {
let (cache, _overlay) = cached_tree_hash::vec::new_tree_hash_cache(self, depth)?;
Ok(cache)
}
fn tree_hash_cache_schema(&self, depth: usize) -> cached_tree_hash::BTreeSchema {
cached_tree_hash::vec::produce_schema(self, depth)
}
fn update_tree_hash_cache(
&self,
cache: &mut cached_tree_hash::TreeHashCache,
) -> Result<(), cached_tree_hash::Error> {
cached_tree_hash::vec::update_tree_hash_cache(self, cache)?;
Ok(())
}
}
impl<T> Encode for TreeHashVector<T>
where
T: Encode,
{
fn ssz_append(&self, s: &mut SszStream) {
s.append_vec(self)
}
}
impl<T> Decode for TreeHashVector<T>
where
T: Decode,
{
fn ssz_decode(bytes: &[u8], index: usize) -> Result<(Self, usize), DecodeError> {
ssz::decode_ssz_list(bytes, index).and_then(|(vec, i)| Ok((vec.into(), i)))
}
}
impl<U> TestRandom for TreeHashVector<U>
where
U: TestRandom,
{
fn random_for_test(rng: &mut impl RngCore) -> Self {
TreeHashVector::from(vec![
U::random_for_test(rng),
U::random_for_test(rng),
U::random_for_test(rng),
])
}
}
#[cfg(test)]
mod test {
use super::*;
use tree_hash::TreeHash;
#[test]
pub fn test_cached_tree_hash() {
let original = TreeHashVector::from(vec![1_u64, 2, 3, 4]);
let mut cache = cached_tree_hash::TreeHashCache::new(&original).unwrap();
assert_eq!(
cache.tree_hash_root().unwrap().to_vec(),
original.tree_hash_root()
);
let modified = TreeHashVector::from(vec![1_u64, 1, 1, 1]);
cache.update(&modified).unwrap();
assert_eq!(
cache.tree_hash_root().unwrap().to_vec(),
modified.tree_hash_root()
);
}
}

View File

@ -2,8 +2,8 @@ use super::*;
/// A schema defining a binary tree over a `TreeHashCache`. /// A schema defining a binary tree over a `TreeHashCache`.
/// ///
/// This structure is used for succinct storage, run-time functionality is gained by converting the /// This structure is used for succinct storage; run-time functionality is gained by converting a
/// schema into a `BTreeOverlay`. /// `BTreeSchema` into a `BTreeOverlay`.
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct BTreeSchema { pub struct BTreeSchema {
/// The depth of a schema defines how far it is nested within other fixed-length items. /// The depth of a schema defines how far it is nested within other fixed-length items.
@ -48,8 +48,8 @@ pub enum LeafNode {
Padding, Padding,
} }
/// Instantiated from a `BTreeSchema`, allows for interpreting some chunks of a `TreeHashCache` as /// Instantiated from a `BTreeSchema`, a `BTreeOverlay` allows for interpreting some
/// a perfect binary tree. /// non-consecutive chunks of a `TreeHashCache` as a perfect binary tree.
/// ///
/// The primary purpose of this struct is to map from binary tree "nodes" to `TreeHashCache` /// The primary purpose of this struct is to map from binary tree "nodes" to `TreeHashCache`
/// "chunks". Each tree has nodes `0..n` where `n` is the number of nodes and `0` is the root node. /// "chunks". Each tree has nodes `0..n` where `n` is the number of nodes and `0` is the root node.

View File

@ -1,8 +1,8 @@
//! Performs cached merkle-hashing adhering to the Ethereum 2.0 specification defined //! Performs cached merkle-hashing adhering to the Ethereum 2.0 specification defined
//! [here](https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/simple-serialize.md#merkleization). //! [here](https://github.com/ethereum/eth2.0-specs/blob/v0.5.1/specs/simple-serialize.md#merkleization).
//! //!
//! Caching allows for reduced hashing when some object has only been partially modified. This //! Caching allows for reduced hashing when some object has only been partially modified, which
//! allows for significant CPU-time savings (at the cost of additional storage). For example, //! consumes less CPU-time at the cost of additional storage. For example,
//! determining the root of a list of 1024 items with a single modification has been observed to //! determining the root of a list of 1024 items with a single modification has been observed to
//! run in 1/25th of the time of a full merkle hash. //! run in 1/25th of the time of a full merkle hash.
//! //!
@ -61,8 +61,8 @@ pub trait CachedTreeHash: TreeHash {
fn update_tree_hash_cache(&self, cache: &mut TreeHashCache) -> Result<(), Error>; fn update_tree_hash_cache(&self, cache: &mut TreeHashCache) -> Result<(), Error>;
} }
/// Implements `CachedTreeHash` on `$type` as a fixed-length tree-hash vector of the ssz encoding /// Implements `CachedTreeHash` on `$type`, where `$type` is a fixed-length vector and each item in
/// of `$type`. /// the `$type` is encoded as bytes using `ssz_encode`.
#[macro_export] #[macro_export]
macro_rules! cached_tree_hash_ssz_encoding_as_vector { macro_rules! cached_tree_hash_ssz_encoding_as_vector {
($type: ident, $num_bytes: expr) => { ($type: ident, $num_bytes: expr) => {
@ -95,8 +95,8 @@ macro_rules! cached_tree_hash_ssz_encoding_as_vector {
}; };
} }
/// Implements `CachedTreeHash` on `$type` as a variable-length tree-hash list of the result of /// Implements `CachedTreeHash` on `$type`, where `$type` is a variable-length list and each item
/// calling `.as_bytes()` on `$type`. /// in `$type` is encoded as bytes by calling `item.to_bytes()`.
#[macro_export] #[macro_export]
macro_rules! cached_tree_hash_bytes_as_list { macro_rules! cached_tree_hash_bytes_as_list {
($type: ident) => { ($type: ident) => {