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() {
|
while let Some((_root, block)) = filtered_chain_segment.first() {
|
||||||
// Determine the epoch of the first block in the remaining segment.
|
// 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
|
// 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
|
// 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`.
|
// the same `BeaconState`.
|
||||||
let last_index = filtered_chain_segment
|
let last_index = filtered_chain_segment
|
||||||
.iter()
|
.iter()
|
||||||
.position(|(_root, block)| {
|
.position(|(_root, block)| block.epoch() > start_epoch)
|
||||||
block.slot().epoch(T::EthSpec::slots_per_epoch()) > start_epoch
|
|
||||||
})
|
|
||||||
.unwrap_or(filtered_chain_segment.len());
|
.unwrap_or(filtered_chain_segment.len());
|
||||||
|
|
||||||
let mut blocks = filtered_chain_segment.split_off(last_index);
|
let mut blocks = filtered_chain_segment.split_off(last_index);
|
||||||
@ -3162,7 +3160,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
// Sync aggregate.
|
// Sync aggregate.
|
||||||
if let Ok(sync_aggregate) = block.body().sync_aggregate() {
|
if let Ok(sync_aggregate) = block.body().sync_aggregate() {
|
||||||
// `SyncCommittee` for the sync_aggregate should correspond to the duty slot
|
// `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) {
|
match self.sync_committee_at_epoch(duty_epoch) {
|
||||||
Ok(sync_committee) => {
|
Ok(sync_committee) => {
|
||||||
@ -3429,7 +3427,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
parent_block_slot: Slot,
|
parent_block_slot: Slot,
|
||||||
) {
|
) {
|
||||||
// Do not write to eth1 finalization cache for blocks older than 5 epochs.
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5860,6 +5858,29 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
.flatten()
|
.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
|
/// Returns `true` if we are at or past the `Eip4844` fork. This will always return `false` if
|
||||||
/// the `Eip4844` fork is disabled.
|
/// the `Eip4844` fork is disabled.
|
||||||
pub fn is_data_availability_check_required(&self) -> Result<bool, Error> {
|
pub fn is_data_availability_check_required(&self) -> Result<bool, Error> {
|
||||||
|
@ -246,19 +246,39 @@ impl<T: BeaconChainTypes> Worker<T> {
|
|||||||
"request_root" => ?root
|
"request_root" => ?root
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok((Some(_), None)) => {
|
Ok((Some(block), None)) => {
|
||||||
debug!(
|
let data_availability_boundary_by_root = self.chain.data_availability_boundary_by_root_rpc_request();
|
||||||
self.log,
|
let block_epoch = block.epoch();
|
||||||
"Peer requested block and blob, but no blob found";
|
|
||||||
"peer" => %peer_id,
|
if Some(block_epoch) >= data_availability_boundary_by_root {
|
||||||
"request_root" => ?root
|
debug!(
|
||||||
);
|
self.log,
|
||||||
self.send_error_response(
|
"Peer requested block and blob that should be available, but no blob found";
|
||||||
peer_id,
|
"peer" => %peer_id,
|
||||||
RPCResponseErrorCode::ResourceUnavailable,
|
"request_root" => ?root,
|
||||||
"No blob for requested block".into(),
|
"data_availability_boundary_by_root" => data_availability_boundary_by_root,
|
||||||
request_id,
|
);
|
||||||
);
|
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;
|
send_response = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -592,15 +612,33 @@ impl<T: BeaconChainTypes> Worker<T> {
|
|||||||
"start_slot" => req.start_slot,
|
"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
|
// Should not send more than max request blocks
|
||||||
if req.count > MAX_REQUEST_BLOBS_SIDECARS {
|
if req.count > MAX_REQUEST_BLOBS_SIDECARS {
|
||||||
req.count = MAX_REQUEST_BLOBS_SIDECARS;
|
req.count = MAX_REQUEST_BLOBS_SIDECARS;
|
||||||
}
|
}
|
||||||
|
|
||||||
let forwards_block_root_iter = match self
|
let forwards_block_root_iter = match self.chain.forwards_iter_block_roots(start_slot) {
|
||||||
.chain
|
|
||||||
.forwards_iter_block_roots(Slot::from(req.start_slot))
|
|
||||||
{
|
|
||||||
Ok(iter) => iter,
|
Ok(iter) => iter,
|
||||||
Err(BeaconChainError::HistoricalBlockError(
|
Err(BeaconChainError::HistoricalBlockError(
|
||||||
HistoricalBlockError::BlockOutOfRange {
|
HistoricalBlockError::BlockOutOfRange {
|
||||||
|
@ -195,7 +195,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBeaconBlock<E, Payload>
|
|||||||
}
|
}
|
||||||
|
|
||||||
let domain = spec.get_domain(
|
let domain = spec.get_domain(
|
||||||
self.slot().epoch(E::slots_per_epoch()),
|
self.epoch(),
|
||||||
Domain::BeaconProposer,
|
Domain::BeaconProposer,
|
||||||
fork,
|
fork,
|
||||||
genesis_validators_root,
|
genesis_validators_root,
|
||||||
@ -227,6 +227,11 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBeaconBlock<E, Payload>
|
|||||||
self.message().slot()
|
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.
|
/// Convenience accessor for the block's parent root.
|
||||||
pub fn parent_root(&self) -> Hash256 {
|
pub fn parent_root(&self) -> Hash256 {
|
||||||
self.message().parent_root()
|
self.message().parent_root()
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use crate::signed_beacon_block::BlobReconstructionError;
|
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 derivative::Derivative;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use ssz::{Decode, DecodeError};
|
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> {
|
pub fn block(&self) -> &SignedBeaconBlock<T> {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
BlockWrapperInner::Block(block) => &block,
|
BlockWrapperInner::Block(block) => &block,
|
||||||
|
Loading…
Reference in New Issue
Block a user