Add Eth1Chain member to BeaconChain
This commit is contained in:
parent
ab2b8accd4
commit
31557704eb
@ -1,10 +1,10 @@
|
|||||||
use crate::checkpoint::CheckPoint;
|
use crate::checkpoint::CheckPoint;
|
||||||
use crate::errors::{BeaconChainError as Error, BlockProductionError};
|
use crate::errors::{BeaconChainError as Error, BlockProductionError};
|
||||||
|
use crate::eth1_chain::{Eth1Chain, Eth1ChainBackend};
|
||||||
use crate::fork_choice::{Error as ForkChoiceError, ForkChoice};
|
use crate::fork_choice::{Error as ForkChoiceError, ForkChoice};
|
||||||
use crate::iter::{ReverseBlockRootIterator, ReverseStateRootIterator};
|
use crate::iter::{ReverseBlockRootIterator, ReverseStateRootIterator};
|
||||||
use crate::metrics;
|
use crate::metrics;
|
||||||
use crate::persisted_beacon_chain::{PersistedBeaconChain, BEACON_CHAIN_DB_KEY};
|
use crate::persisted_beacon_chain::{PersistedBeaconChain, BEACON_CHAIN_DB_KEY};
|
||||||
use eth2_hashing::hash;
|
|
||||||
use lmd_ghost::LmdGhost;
|
use lmd_ghost::LmdGhost;
|
||||||
use operation_pool::DepositInsertStatus;
|
use operation_pool::DepositInsertStatus;
|
||||||
use operation_pool::{OperationPool, PersistedOperationPool};
|
use operation_pool::{OperationPool, PersistedOperationPool};
|
||||||
@ -113,6 +113,7 @@ pub trait BeaconChainTypes: Send + Sync + 'static {
|
|||||||
type Store: store::Store;
|
type Store: store::Store;
|
||||||
type SlotClock: slot_clock::SlotClock;
|
type SlotClock: slot_clock::SlotClock;
|
||||||
type LmdGhost: LmdGhost<Self::Store, Self::EthSpec>;
|
type LmdGhost: LmdGhost<Self::Store, Self::EthSpec>;
|
||||||
|
type Eth1Chain: Eth1ChainBackend<Self::EthSpec>;
|
||||||
type EthSpec: types::EthSpec;
|
type EthSpec: types::EthSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +128,8 @@ pub struct BeaconChain<T: BeaconChainTypes> {
|
|||||||
/// Stores all operations (e.g., `Attestation`, `Deposit`, etc) that are candidates for
|
/// Stores all operations (e.g., `Attestation`, `Deposit`, etc) that are candidates for
|
||||||
/// inclusion in a block.
|
/// inclusion in a block.
|
||||||
pub op_pool: OperationPool<T::EthSpec>,
|
pub op_pool: OperationPool<T::EthSpec>,
|
||||||
|
/// Provides information from the Ethereum 1 (PoW) chain.
|
||||||
|
pub eth1_chain: Eth1Chain<T>,
|
||||||
/// Stores a "snapshot" of the chain at the time the head-of-the-chain block was received.
|
/// Stores a "snapshot" of the chain at the time the head-of-the-chain block was received.
|
||||||
canonical_head: RwLock<CheckPoint<T::EthSpec>>,
|
canonical_head: RwLock<CheckPoint<T::EthSpec>>,
|
||||||
/// The root of the genesis block.
|
/// The root of the genesis block.
|
||||||
@ -142,6 +145,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
/// Instantiate a new Beacon Chain, from genesis.
|
/// Instantiate a new Beacon Chain, from genesis.
|
||||||
pub fn from_genesis(
|
pub fn from_genesis(
|
||||||
store: Arc<T::Store>,
|
store: Arc<T::Store>,
|
||||||
|
eth1_backend: T::Eth1Chain,
|
||||||
mut genesis_state: BeaconState<T::EthSpec>,
|
mut genesis_state: BeaconState<T::EthSpec>,
|
||||||
mut genesis_block: BeaconBlock<T::EthSpec>,
|
mut genesis_block: BeaconBlock<T::EthSpec>,
|
||||||
spec: ChainSpec,
|
spec: ChainSpec,
|
||||||
@ -186,6 +190,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
spec,
|
spec,
|
||||||
slot_clock,
|
slot_clock,
|
||||||
op_pool: OperationPool::new(),
|
op_pool: OperationPool::new(),
|
||||||
|
eth1_chain: Eth1Chain::new(eth1_backend),
|
||||||
canonical_head,
|
canonical_head,
|
||||||
genesis_block_root,
|
genesis_block_root,
|
||||||
fork_choice: ForkChoice::new(store.clone(), &genesis_block, genesis_block_root),
|
fork_choice: ForkChoice::new(store.clone(), &genesis_block, genesis_block_root),
|
||||||
@ -197,6 +202,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
/// Attempt to load an existing instance from the given `store`.
|
/// Attempt to load an existing instance from the given `store`.
|
||||||
pub fn from_store(
|
pub fn from_store(
|
||||||
store: Arc<T::Store>,
|
store: Arc<T::Store>,
|
||||||
|
eth1_backend: T::Eth1Chain,
|
||||||
spec: ChainSpec,
|
spec: ChainSpec,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
) -> Result<Option<BeaconChain<T>>, Error> {
|
) -> Result<Option<BeaconChain<T>>, Error> {
|
||||||
@ -233,6 +239,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
slot_clock,
|
slot_clock,
|
||||||
fork_choice: ForkChoice::new(store.clone(), last_finalized_block, last_finalized_root),
|
fork_choice: ForkChoice::new(store.clone(), last_finalized_block, last_finalized_root),
|
||||||
op_pool,
|
op_pool,
|
||||||
|
eth1_chain: Eth1Chain::new(eth1_backend),
|
||||||
canonical_head: RwLock::new(p.canonical_head),
|
canonical_head: RwLock::new(p.canonical_head),
|
||||||
genesis_block_root: p.genesis_block_root,
|
genesis_block_root: p.genesis_block_root,
|
||||||
store,
|
store,
|
||||||
@ -1205,12 +1212,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
body: BeaconBlockBody {
|
body: BeaconBlockBody {
|
||||||
randao_reveal,
|
randao_reveal,
|
||||||
// TODO: replace with real data.
|
// TODO: replace with real data.
|
||||||
eth1_data: Self::eth1_data_stub(&state),
|
eth1_data: self.eth1_chain.eth1_data_for_block_production(&state)?,
|
||||||
graffiti,
|
graffiti,
|
||||||
proposer_slashings: proposer_slashings.into(),
|
proposer_slashings: proposer_slashings.into(),
|
||||||
attester_slashings: attester_slashings.into(),
|
attester_slashings: attester_slashings.into(),
|
||||||
attestations: self.op_pool.get_attestations(&state, &self.spec).into(),
|
attestations: self.op_pool.get_attestations(&state, &self.spec).into(),
|
||||||
deposits: self.op_pool.get_deposits(&state).into(),
|
deposits: self.eth1_chain.deposits_for_block_inclusion(&state)?.into(),
|
||||||
voluntary_exits: self.op_pool.get_voluntary_exits(&state, &self.spec).into(),
|
voluntary_exits: self.op_pool.get_voluntary_exits(&state, &self.spec).into(),
|
||||||
transfers: self.op_pool.get_transfers(&state, &self.spec).into(),
|
transfers: self.op_pool.get_transfers(&state, &self.spec).into(),
|
||||||
},
|
},
|
||||||
@ -1234,22 +1241,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
Ok((block, state))
|
Ok((block, state))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eth1_data_stub(state: &BeaconState<T::EthSpec>) -> Eth1Data {
|
|
||||||
let current_epoch = state.current_epoch();
|
|
||||||
let slots_per_voting_period = T::EthSpec::slots_per_eth1_voting_period() as u64;
|
|
||||||
let current_voting_period: u64 = current_epoch.as_u64() / slots_per_voting_period;
|
|
||||||
|
|
||||||
// TODO: confirm that `int_to_bytes32` is correct.
|
|
||||||
let deposit_root = hash(&int_to_bytes32(current_voting_period));
|
|
||||||
let block_hash = hash(&deposit_root);
|
|
||||||
|
|
||||||
Eth1Data {
|
|
||||||
deposit_root: Hash256::from_slice(&deposit_root),
|
|
||||||
deposit_count: state.eth1_deposit_index,
|
|
||||||
block_hash: Hash256::from_slice(&block_hash),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute the fork choice algorithm and enthrone the result as the canonical head.
|
/// Execute the fork choice algorithm and enthrone the result as the canonical head.
|
||||||
pub fn fork_choice(&self) -> Result<(), Error> {
|
pub fn fork_choice(&self) -> Result<(), Error> {
|
||||||
metrics::inc_counter(&metrics::FORK_CHOICE_REQUESTS);
|
metrics::inc_counter(&metrics::FORK_CHOICE_REQUESTS);
|
||||||
@ -1445,13 +1436,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `int` as little-endian bytes with a length of 32.
|
|
||||||
fn int_to_bytes32(int: u64) -> Vec<u8> {
|
|
||||||
let mut vec = int.to_le_bytes().to_vec();
|
|
||||||
vec.resize(32, 0);
|
|
||||||
vec
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<DBError> for Error {
|
impl From<DBError> for Error {
|
||||||
fn from(e: DBError) -> Error {
|
fn from(e: DBError) -> Error {
|
||||||
Error::DBError(e)
|
Error::DBError(e)
|
||||||
|
@ -127,16 +127,23 @@ impl<T: BeaconChainTypes> BeaconChainBuilder<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self, store: Arc<T::Store>) -> Result<BeaconChain<T>, String> {
|
pub fn build(
|
||||||
|
self,
|
||||||
|
store: Arc<T::Store>,
|
||||||
|
eth1_backend: T::Eth1Chain,
|
||||||
|
) -> Result<BeaconChain<T>, String> {
|
||||||
Ok(match self.build_strategy {
|
Ok(match self.build_strategy {
|
||||||
BuildStrategy::LoadFromStore => BeaconChain::from_store(store, self.spec, self.log)
|
BuildStrategy::LoadFromStore => {
|
||||||
.map_err(|e| format!("Error loading BeaconChain from database: {:?}", e))?
|
BeaconChain::from_store(store, eth1_backend, self.spec, self.log)
|
||||||
.ok_or_else(|| format!("Unable to find exising BeaconChain in database."))?,
|
.map_err(|e| format!("Error loading BeaconChain from database: {:?}", e))?
|
||||||
|
.ok_or_else(|| format!("Unable to find exising BeaconChain in database."))?
|
||||||
|
}
|
||||||
BuildStrategy::FromGenesis {
|
BuildStrategy::FromGenesis {
|
||||||
genesis_block,
|
genesis_block,
|
||||||
genesis_state,
|
genesis_state,
|
||||||
} => BeaconChain::from_genesis(
|
} => BeaconChain::from_genesis(
|
||||||
store,
|
store,
|
||||||
|
eth1_backend,
|
||||||
genesis_state.as_ref().clone(),
|
genesis_state.as_ref().clone(),
|
||||||
genesis_block.as_ref().clone(),
|
genesis_block.as_ref().clone(),
|
||||||
self.spec,
|
self.spec,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::eth1_chain::Error as Eth1ChainError;
|
||||||
use crate::fork_choice::Error as ForkChoiceError;
|
use crate::fork_choice::Error as ForkChoiceError;
|
||||||
use state_processing::per_block_processing::errors::AttestationValidationError;
|
use state_processing::per_block_processing::errors::AttestationValidationError;
|
||||||
use state_processing::BlockProcessingError;
|
use state_processing::BlockProcessingError;
|
||||||
@ -42,6 +43,7 @@ pub enum BeaconChainError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
easy_from_to!(SlotProcessingError, BeaconChainError);
|
easy_from_to!(SlotProcessingError, BeaconChainError);
|
||||||
|
easy_from_to!(AttestationValidationError, BeaconChainError);
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum BlockProductionError {
|
pub enum BlockProductionError {
|
||||||
@ -50,10 +52,11 @@ pub enum BlockProductionError {
|
|||||||
UnableToProduceAtSlot(Slot),
|
UnableToProduceAtSlot(Slot),
|
||||||
SlotProcessingError(SlotProcessingError),
|
SlotProcessingError(SlotProcessingError),
|
||||||
BlockProcessingError(BlockProcessingError),
|
BlockProcessingError(BlockProcessingError),
|
||||||
|
Eth1ChainError(Eth1ChainError),
|
||||||
BeaconStateError(BeaconStateError),
|
BeaconStateError(BeaconStateError),
|
||||||
}
|
}
|
||||||
|
|
||||||
easy_from_to!(BlockProcessingError, BlockProductionError);
|
easy_from_to!(BlockProcessingError, BlockProductionError);
|
||||||
easy_from_to!(BeaconStateError, BlockProductionError);
|
easy_from_to!(BeaconStateError, BlockProductionError);
|
||||||
easy_from_to!(SlotProcessingError, BlockProductionError);
|
easy_from_to!(SlotProcessingError, BlockProductionError);
|
||||||
easy_from_to!(AttestationValidationError, BeaconChainError);
|
easy_from_to!(Eth1ChainError, BlockProductionError);
|
||||||
|
@ -5,6 +5,35 @@ use types::{BeaconState, Deposit, DepositData, Eth1Data, EthSpec, Hash256};
|
|||||||
|
|
||||||
type Result<T> = std::result::Result<T, Error>;
|
type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
pub struct Eth1Chain<T: BeaconChainTypes> {
|
||||||
|
backend: T::Eth1Chain,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: BeaconChainTypes> Eth1Chain<T> {
|
||||||
|
pub fn new(backend: T::Eth1Chain) -> Self {
|
||||||
|
Self { backend }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eth1_data_for_block_production(
|
||||||
|
&self,
|
||||||
|
state: &BeaconState<T::EthSpec>,
|
||||||
|
) -> Result<Eth1Data> {
|
||||||
|
self.backend.eth1_data(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deposits_for_block_inclusion(
|
||||||
|
&self,
|
||||||
|
state: &BeaconState<T::EthSpec>,
|
||||||
|
) -> Result<Vec<Deposit>> {
|
||||||
|
let deposits = self.backend.queued_deposits(state)?;
|
||||||
|
|
||||||
|
// TODO: truncate deposits if required.
|
||||||
|
|
||||||
|
Ok(deposits)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Unable to return an Eth1Data for the given epoch.
|
/// Unable to return an Eth1Data for the given epoch.
|
||||||
EpochUnavailable,
|
EpochUnavailable,
|
||||||
@ -12,10 +41,10 @@ pub enum Error {
|
|||||||
BackendError(String),
|
BackendError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Eth1Chain<T: BeaconChainTypes> {
|
pub trait Eth1ChainBackend<T: EthSpec> {
|
||||||
/// Returns the `Eth1Data` that should be included in a block being produced for the given
|
/// Returns the `Eth1Data` that should be included in a block being produced for the given
|
||||||
/// `state`.
|
/// `state`.
|
||||||
fn eth1_data_for_epoch(&self, beacon_state: &BeaconState<T::EthSpec>) -> Result<Eth1Data>;
|
fn eth1_data(&self, beacon_state: &BeaconState<T>) -> Result<Eth1Data>;
|
||||||
|
|
||||||
/// Returns all `Deposits` between `state.eth1_deposit_index` and
|
/// Returns all `Deposits` between `state.eth1_deposit_index` and
|
||||||
/// `state.eth1_data.deposit_count`.
|
/// `state.eth1_data.deposit_count`.
|
||||||
@ -24,20 +53,19 @@ pub trait Eth1Chain<T: BeaconChainTypes> {
|
|||||||
///
|
///
|
||||||
/// It is possible that not all returned `Deposits` can be included in a block. E.g., there may
|
/// It is possible that not all returned `Deposits` can be included in a block. E.g., there may
|
||||||
/// be more than `MAX_DEPOSIT_COUNT` or the churn may be too high.
|
/// be more than `MAX_DEPOSIT_COUNT` or the churn may be too high.
|
||||||
fn queued_deposits(&self, beacon_state: &BeaconState<T::EthSpec>) -> Result<Vec<Deposit>>;
|
fn queued_deposits(&self, beacon_state: &BeaconState<T>) -> Result<Vec<Deposit>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InteropEth1Chain<T: BeaconChainTypes> {
|
pub struct InteropEth1ChainBackend<T: EthSpec> {
|
||||||
_phantom: PhantomData<T>,
|
_phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: BeaconChainTypes> Eth1Chain<T> for InteropEth1Chain<T> {
|
impl<T: EthSpec> Eth1ChainBackend<T> for InteropEth1ChainBackend<T> {
|
||||||
fn eth1_data_for_epoch(&self, state: &BeaconState<T::EthSpec>) -> Result<Eth1Data> {
|
fn eth1_data(&self, state: &BeaconState<T>) -> Result<Eth1Data> {
|
||||||
let current_epoch = state.current_epoch();
|
let current_epoch = state.current_epoch();
|
||||||
let slots_per_voting_period = T::EthSpec::slots_per_eth1_voting_period() as u64;
|
let slots_per_voting_period = T::slots_per_eth1_voting_period() as u64;
|
||||||
let current_voting_period: u64 = current_epoch.as_u64() / slots_per_voting_period;
|
let current_voting_period: u64 = current_epoch.as_u64() / slots_per_voting_period;
|
||||||
|
|
||||||
// TODO: confirm that `int_to_bytes32` is correct.
|
|
||||||
let deposit_root = hash(&int_to_bytes32(current_voting_period));
|
let deposit_root = hash(&int_to_bytes32(current_voting_period));
|
||||||
let block_hash = hash(&deposit_root);
|
let block_hash = hash(&deposit_root);
|
||||||
|
|
||||||
@ -48,11 +76,19 @@ impl<T: BeaconChainTypes> Eth1Chain<T> for InteropEth1Chain<T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn queued_deposits(&self, beacon_state: &BeaconState<T::EthSpec>) -> Result<Vec<Deposit>> {
|
fn queued_deposits(&self, beacon_state: &BeaconState<T>) -> Result<Vec<Deposit>> {
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: EthSpec> Default for InteropEth1ChainBackend<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `int` as little-endian bytes with a length of 32.
|
/// Returns `int` as little-endian bytes with a length of 32.
|
||||||
fn int_to_bytes32(int: u64) -> Vec<u8> {
|
fn int_to_bytes32(int: u64) -> Vec<u8> {
|
||||||
let mut vec = int.to_le_bytes().to_vec();
|
let mut vec = int.to_le_bytes().to_vec();
|
||||||
|
@ -19,6 +19,7 @@ pub use self::beacon_chain::{
|
|||||||
pub use self::checkpoint::CheckPoint;
|
pub use self::checkpoint::CheckPoint;
|
||||||
pub use self::errors::{BeaconChainError, BlockProductionError};
|
pub use self::errors::{BeaconChainError, BlockProductionError};
|
||||||
pub use beacon_chain_builder::BeaconChainBuilder;
|
pub use beacon_chain_builder::BeaconChainBuilder;
|
||||||
|
pub use eth1_chain::InteropEth1ChainBackend;
|
||||||
pub use lmd_ghost;
|
pub use lmd_ghost;
|
||||||
pub use metrics::scrape_for_metrics;
|
pub use metrics::scrape_for_metrics;
|
||||||
pub use parking_lot;
|
pub use parking_lot;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{BeaconChain, BeaconChainTypes, BlockProcessingOutcome};
|
use crate::{BeaconChain, BeaconChainTypes, BlockProcessingOutcome, InteropEth1ChainBackend};
|
||||||
use lmd_ghost::LmdGhost;
|
use lmd_ghost::LmdGhost;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use sloggers::{null::NullLoggerBuilder, Build};
|
use sloggers::{null::NullLoggerBuilder, Build};
|
||||||
@ -60,6 +60,7 @@ where
|
|||||||
type Store = MemoryStore;
|
type Store = MemoryStore;
|
||||||
type SlotClock = TestingSlotClock;
|
type SlotClock = TestingSlotClock;
|
||||||
type LmdGhost = L;
|
type LmdGhost = L;
|
||||||
|
type Eth1Chain = InteropEth1ChainBackend<E>;
|
||||||
type EthSpec = E;
|
type EthSpec = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,9 +115,15 @@ where
|
|||||||
let builder = NullLoggerBuilder;
|
let builder = NullLoggerBuilder;
|
||||||
let log = builder.build().expect("logger should build");
|
let log = builder.build().expect("logger should build");
|
||||||
|
|
||||||
let chain =
|
let chain = BeaconChain::from_genesis(
|
||||||
BeaconChain::from_genesis(store, genesis_state, genesis_block, spec.clone(), log)
|
store,
|
||||||
.expect("Terminate if beacon chain generation fails");
|
InteropEth1ChainBackend::default(),
|
||||||
|
genesis_state,
|
||||||
|
genesis_block,
|
||||||
|
spec.clone(),
|
||||||
|
log,
|
||||||
|
)
|
||||||
|
.expect("Terminate if beacon chain generation fails");
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
chain,
|
chain,
|
||||||
|
Loading…
Reference in New Issue
Block a user