should_forward function

This commit is contained in:
Grant Wuerker
2019-11-06 19:46:03 +09:00
parent 1d40a723b0
commit 410c8aa2bd
3 changed files with 53 additions and 7 deletions

View File

@@ -1093,7 +1093,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// processing.
let db_read_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_DB_READ);
// Load the blocks parent block from the database, returning invalid if that block is not
// Load the blocks parent block from the database, returning ParentUnknown if that block is not
// found.
let parent_block: BeaconBlock<T::EthSpec> = match self.store.get(&block.parent_root)? {
Some(block) => block,

View File

@@ -21,3 +21,5 @@ error-chain = "0.12.0"
tokio = "0.1.16"
parking_lot = "0.9.0"
smallvec = "0.6.10"
state_processing = { path = "../../eth2/state_processing" }
bls = { path = "../../eth2/utils/bls" }

View File

@@ -12,7 +12,9 @@ use std::sync::Arc;
use store::Store;
use tokio::sync::{mpsc, oneshot};
use tree_hash::SignedRoot;
use types::{Attestation, BeaconBlock, Epoch, EthSpec, Hash256, Slot};
use types::{Attestation, BeaconBlock, Epoch, EthSpec, Hash256, Slot, BeaconState, RelativeEpoch, Domain};
use state_processing::per_block_processing::verify_block_signature;
use bls::SignatureSet;
//TODO: Put a maximum limit on the number of block that can be requested.
//TODO: Rate limit requests
@@ -385,7 +387,7 @@ impl<T: BeaconChainTypes> MessageProcessor<T> {
/// Process a gossip message declaring a new block.
///
/// Attempts to apply to block to the beacon chain. May queue the block for later processing.
/// Attempts to apply a block to the beacon chain. May queue the block for later processing.
///
/// Returns a `bool` which, if `true`, indicates we should forward the block to our peers. 524
/// Old blocks or blocks on a different fork. Will need to recalc proposer shuffle.
@@ -394,7 +396,7 @@ impl<T: BeaconChainTypes> MessageProcessor<T> {
/// Do we know the block's parent?
/// 1.) It's a recent block on the same chain. We can use the current cache in the BeaconChain. (cheap)
/// 2.) Old block on a different fork. (may have to recalc shuffling)
/// If we don't know the block's parent, we don't who is supposed to sign it, therefore we can
/// If we don't know the block's parent, we don't know who is supposed to sign it, therefore we can
/// not validate the signature.
/// 1.) We can try to look up the block's parent using the syncing thread. (it's expensive not sure how to reprop from sync thread)
pub fn on_block_gossip(&mut self, peer_id: PeerId, block: BeaconBlock<T::EthSpec>) -> bool {
@@ -410,16 +412,18 @@ impl<T: BeaconChainTypes> MessageProcessor<T> {
trace!(self.log, "Block with unknown parent received";
"peer_id" => format!("{:?}",peer_id));
self.send_to_sync(SyncMessage::UnknownBlock(peer_id, block.clone()));
SHOULD_FORWARD_GOSSIP_BLOCK
SHOULD_NOT_FORWARD_GOSSIP_BLOCK
}
BlockProcessingOutcome::FutureSlot {
present_slot,
block_slot,
} if present_slot + FUTURE_SLOT_TOLERANCE >= block_slot => {
//TODO: Decide the logic here
SHOULD_FORWARD_GOSSIP_BLOCK
SHOULD_NOT_FORWARD_GOSSIP_BLOCK
}
BlockProcessingOutcome::BlockIsAlreadyKnown => SHOULD_FORWARD_GOSSIP_BLOCK,
BlockProcessingOutcome::BlockIsAlreadyKnown => {
self.should_forward_block(block)
},
other => {
warn!(
self.log,
@@ -453,6 +457,46 @@ impl<T: BeaconChainTypes> MessageProcessor<T> {
}
}
fn should_forward_block(&mut self, block: BeaconBlock<T::EthSpec>) -> bool {
let parent_block: BeaconBlock<T::EthSpec> = self.chain.store.get(&block.parent_root).unwrap().unwrap();
let parent_state_root = parent_block.state_root;
let parent_state: BeaconState<T::EthSpec> = self
.chain
.store
.get(&parent_state_root)
.unwrap().unwrap();
let relative_epoch = RelativeEpoch::from_slot(
parent_block.slot,
block.slot,
T::EthSpec::slots_per_epoch()
).unwrap();
let proposer_index = parent_state
.get_beacon_proposer_index(
block.slot,
relative_epoch,
&self.chain.spec
).unwrap();
let proposer = &parent_state.validators.get(proposer_index).unwrap();
let domain = self.chain.spec.get_domain(
block.slot.epoch(T::EthSpec::slots_per_epoch()),
Domain::BeaconProposer,
&parent_state.fork,
);
let set = SignatureSet::single(
&block.signature,
&proposer.pubkey,
block.signed_root(),
domain
);
set.is_valid()
}
/// Process a gossip message declaring a new attestation.
///
/// Not currently implemented.