Check data availability boundary in rpc request
This commit is contained in:
parent
e046657b4f
commit
9445ac70d8
@ -2486,7 +2486,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
|
||||
while let Some((_root, block)) = filtered_chain_segment.first() {
|
||||
// Determine the epoch of the first block in the remaining segment.
|
||||
let start_epoch = block.slot().epoch(T::EthSpec::slots_per_epoch());
|
||||
let start_epoch = block.epoch();
|
||||
|
||||
// The `last_index` indicates the position of the first block in an epoch greater
|
||||
// than the current epoch: partitioning the blocks into a run of blocks in the same
|
||||
@ -2494,9 +2494,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
// the same `BeaconState`.
|
||||
let last_index = filtered_chain_segment
|
||||
.iter()
|
||||
.position(|(_root, block)| {
|
||||
block.slot().epoch(T::EthSpec::slots_per_epoch()) > start_epoch
|
||||
})
|
||||
.position(|(_root, block)| block.epoch() > start_epoch)
|
||||
.unwrap_or(filtered_chain_segment.len());
|
||||
|
||||
let mut blocks = filtered_chain_segment.split_off(last_index);
|
||||
@ -3162,7 +3160,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
// Sync aggregate.
|
||||
if let Ok(sync_aggregate) = block.body().sync_aggregate() {
|
||||
// `SyncCommittee` for the sync_aggregate should correspond to the duty slot
|
||||
let duty_epoch = block.slot().epoch(T::EthSpec::slots_per_epoch());
|
||||
let duty_epoch = block.epoch();
|
||||
|
||||
match self.sync_committee_at_epoch(duty_epoch) {
|
||||
Ok(sync_committee) => {
|
||||
@ -3429,7 +3427,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
parent_block_slot: Slot,
|
||||
) {
|
||||
// Do not write to eth1 finalization cache for blocks older than 5 epochs.
|
||||
if block.slot().epoch(T::EthSpec::slots_per_epoch()) + 5 < current_epoch {
|
||||
if block.epoch() + 5 < current_epoch {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5860,6 +5858,29 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
.flatten()
|
||||
}
|
||||
|
||||
/// The epoch since which we cater blob data upon a request 'ByRoot'.
|
||||
/// `None` if the `Eip4844` fork is disabled.
|
||||
pub fn data_availability_boundary_by_root_rpc_request(&self) -> Option<Epoch> {
|
||||
self.spec
|
||||
.eip4844_fork_epoch
|
||||
.map(|fork_epoch| {
|
||||
self.epoch().ok().map(|current_epoch| {
|
||||
vec![
|
||||
fork_epoch,
|
||||
current_epoch.saturating_sub(*MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS),
|
||||
self.canonical_head
|
||||
.cached_head()
|
||||
.finalized_checkpoint()
|
||||
.epoch,
|
||||
]
|
||||
.into_iter()
|
||||
.max()
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
.flatten()
|
||||
}
|
||||
|
||||
/// Returns `true` if we are at or past the `Eip4844` fork. This will always return `false` if
|
||||
/// the `Eip4844` fork is disabled.
|
||||
pub fn is_data_availability_check_required(&self) -> Result<bool, Error> {
|
||||
|
@ -246,19 +246,39 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"request_root" => ?root
|
||||
);
|
||||
}
|
||||
Ok((Some(_), None)) => {
|
||||
debug!(
|
||||
self.log,
|
||||
"Peer requested block and blob, but no blob found";
|
||||
"peer" => %peer_id,
|
||||
"request_root" => ?root
|
||||
);
|
||||
self.send_error_response(
|
||||
peer_id,
|
||||
RPCResponseErrorCode::ResourceUnavailable,
|
||||
"No blob for requested block".into(),
|
||||
request_id,
|
||||
);
|
||||
Ok((Some(block), None)) => {
|
||||
let data_availability_boundary_by_root = self.chain.data_availability_boundary_by_root_rpc_request();
|
||||
let block_epoch = block.epoch();
|
||||
|
||||
if Some(block_epoch) >= data_availability_boundary_by_root {
|
||||
debug!(
|
||||
self.log,
|
||||
"Peer requested block and blob that should be available, but no blob found";
|
||||
"peer" => %peer_id,
|
||||
"request_root" => ?root,
|
||||
"data_availability_boundary_by_root" => data_availability_boundary_by_root,
|
||||
);
|
||||
self.send_error_response(
|
||||
peer_id,
|
||||
RPCResponseErrorCode::ResourceUnavailable,
|
||||
"No blob for requested block.".into(),
|
||||
request_id,
|
||||
);
|
||||
} else {
|
||||
debug!(
|
||||
self.log,
|
||||
"Peer requested block and blob older than the data availability boundary for ByRoot request, no blob found";
|
||||
"peer" => %peer_id,
|
||||
"request_root" => ?root,
|
||||
"data_availability_boundary_by_root" => data_availability_boundary_by_root,
|
||||
);
|
||||
self.send_error_response(
|
||||
peer_id,
|
||||
RPCResponseErrorCode::ResourceUnavailable,
|
||||
format!("No blob for requested block. Requested blob is older than the data availability boundary for a ByRoot request, currently at epoch {:?}", data_availability_boundary_by_root),
|
||||
request_id,
|
||||
);
|
||||
}
|
||||
send_response = false;
|
||||
break;
|
||||
}
|
||||
@ -592,15 +612,33 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"start_slot" => req.start_slot,
|
||||
);
|
||||
|
||||
let start_slot = Slot::from(req.start_slot);
|
||||
let start_epoch = start_slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
let data_availability_boundary = self.chain.data_availability_boundary();
|
||||
|
||||
if Some(start_epoch) < data_availability_boundary {
|
||||
let oldest_blob_slot = self
|
||||
.chain
|
||||
.store
|
||||
.get_blob_info()
|
||||
.map(|blob_info| blob_info.oldest_blob_slot);
|
||||
|
||||
debug!(self.log, "Range request start slot is older than data availability boundary"; "requested_slot" => req.start_slot, "oldest_known_slot" => ?oldest_blob_slot, "data_availability_boundary" => data_availability_boundary);
|
||||
|
||||
return self.send_error_response(
|
||||
peer_id,
|
||||
RPCResponseErrorCode::ResourceUnavailable,
|
||||
format!("Requested start slot in epoch {}. Data availability boundary is currently at epoch {:?}", start_epoch, data_availability_boundary),
|
||||
request_id,
|
||||
);
|
||||
}
|
||||
|
||||
// Should not send more than max request blocks
|
||||
if req.count > MAX_REQUEST_BLOBS_SIDECARS {
|
||||
req.count = MAX_REQUEST_BLOBS_SIDECARS;
|
||||
}
|
||||
|
||||
let forwards_block_root_iter = match self
|
||||
.chain
|
||||
.forwards_iter_block_roots(Slot::from(req.start_slot))
|
||||
{
|
||||
let forwards_block_root_iter = match self.chain.forwards_iter_block_roots(start_slot) {
|
||||
Ok(iter) => iter,
|
||||
Err(BeaconChainError::HistoricalBlockError(
|
||||
HistoricalBlockError::BlockOutOfRange {
|
||||
|
@ -195,7 +195,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBeaconBlock<E, Payload>
|
||||
}
|
||||
|
||||
let domain = spec.get_domain(
|
||||
self.slot().epoch(E::slots_per_epoch()),
|
||||
self.epoch(),
|
||||
Domain::BeaconProposer,
|
||||
fork,
|
||||
genesis_validators_root,
|
||||
@ -227,6 +227,11 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBeaconBlock<E, Payload>
|
||||
self.message().slot()
|
||||
}
|
||||
|
||||
/// Convenience accessor for the block's epoch.
|
||||
pub fn epoch(&self) -> Epoch {
|
||||
self.message().slot().epoch(E::slots_per_epoch())
|
||||
}
|
||||
|
||||
/// Convenience accessor for the block's parent root.
|
||||
pub fn parent_root(&self) -> Hash256 {
|
||||
self.message().parent_root()
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::signed_beacon_block::BlobReconstructionError;
|
||||
use crate::{BlobsSidecar, EthSpec, Hash256, SignedBeaconBlock, SignedBeaconBlockEip4844, Slot};
|
||||
use crate::{
|
||||
BlobsSidecar, Epoch, EthSpec, Hash256, SignedBeaconBlock, SignedBeaconBlockEip4844, Slot,
|
||||
};
|
||||
use derivative::Derivative;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::{Decode, DecodeError};
|
||||
@ -74,6 +76,14 @@ impl<T: EthSpec> BlockWrapper<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn epoch(&self) -> Epoch {
|
||||
match &self.0 {
|
||||
BlockWrapperInner::Block(block) => block.epoch(),
|
||||
BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => {
|
||||
block_sidecar_pair.beacon_block.epoch()
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn block(&self) -> &SignedBeaconBlock<T> {
|
||||
match &self.0 {
|
||||
BlockWrapperInner::Block(block) => &block,
|
||||
|
Loading…
Reference in New Issue
Block a user