mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Avoid unnecessary database lookups in data column RPC requests (#7897)
This PR is an optimisation to avoid unnecessary database lookups when peer requests data columns that the node doesn't custody (advertised via `cgc`). e.g. an extreme but realistic example - a full node only store 4 custody columns by default, but it may receive a range request of 32 slots with all 128 columns, and this would result in 4096 database lookups but the node is only able to get 128 (4 * 32) of them. - Filter data column RPC requests (`DataColumnsByRoot`, `DataColumnsByRange`) to only lookup columns the node custodies - Prevents unnecessary database queries that would always fail for non-custody columns
This commit is contained in:
@@ -364,11 +364,19 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
request: DataColumnsByRootRequest<T::EthSpec>,
|
||||
) -> Result<(), (RpcErrorResponse, &'static str)> {
|
||||
let mut send_data_column_count = 0;
|
||||
// Only attempt lookups for columns the node has advertised and is responsible for maintaining custody of.
|
||||
let available_columns = self.chain.custody_columns_for_epoch(None);
|
||||
|
||||
for data_column_ids_by_root in request.data_column_ids.as_slice() {
|
||||
let indices_to_retrieve = data_column_ids_by_root
|
||||
.columns
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|c| available_columns.contains(c))
|
||||
.collect::<Vec<_>>();
|
||||
match self.chain.get_data_columns_checking_all_caches(
|
||||
data_column_ids_by_root.block_root,
|
||||
data_column_ids_by_root.columns.iter().as_slice(),
|
||||
&indices_to_retrieve,
|
||||
) {
|
||||
Ok(data_columns) => {
|
||||
send_data_column_count += data_columns.len();
|
||||
@@ -1070,8 +1078,14 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
self.get_block_roots_for_slot_range(req.start_slot, req.count, "DataColumnsByRange")?;
|
||||
let mut data_columns_sent = 0;
|
||||
|
||||
// Only attempt lookups for columns the node has advertised and is responsible for maintaining custody of.
|
||||
let request_start_epoch = request_start_slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
let available_columns = self
|
||||
.chain
|
||||
.custody_columns_for_epoch(Some(request_start_epoch));
|
||||
|
||||
for root in block_roots {
|
||||
for index in &req.columns {
|
||||
for index in available_columns {
|
||||
match self.chain.get_data_column(&root, index) {
|
||||
Ok(Some(data_column_sidecar)) => {
|
||||
// Due to skip slots, data columns could be out of the range, we ensure they
|
||||
|
||||
Reference in New Issue
Block a user