Skip to content

Commit 18df701

Browse files
authored
Persist data columns to store (#6255)
* Persist data columns (from das PR #5196)
1 parent 3a996fb commit 18df701

File tree

5 files changed

+67
-23
lines changed

5 files changed

+67
-23
lines changed

beacon_node/beacon_chain/src/beacon_chain.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -3661,16 +3661,15 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
36613661
}
36623662
}
36633663

3664-
if let Some(_data_columns) = data_columns {
3665-
// TODO(das): depends on https://github.com/sigp/lighthouse/pull/6073
3666-
// if !data_columns.is_empty() {
3667-
// debug!(
3668-
// self.log, "Writing data_columns to store";
3669-
// "block_root" => %block_root,
3670-
// "count" => data_columns.len(),
3671-
// );
3672-
// ops.push(StoreOp::PutDataColumns(block_root, data_columns));
3673-
// }
3664+
if let Some(data_columns) = data_columns {
3665+
if !data_columns.is_empty() {
3666+
debug!(
3667+
self.log, "Writing data_columns to store";
3668+
"block_root" => %block_root,
3669+
"count" => data_columns.len(),
3670+
);
3671+
ops.push(StoreOp::PutDataColumns(block_root, data_columns));
3672+
}
36743673
}
36753674

36763675
let txn_lock = self.store.hot_db.begin_rw_transaction();

beacon_node/beacon_chain/src/data_availability_checker.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -108,21 +108,27 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
108108
let custody_column_count =
109109
custody_subnet_count.saturating_mul(spec.data_columns_per_subnet());
110110

111-
let overflow_cache = DataAvailabilityCheckerInner::new(
111+
let inner = DataAvailabilityCheckerInner::new(
112112
OVERFLOW_LRU_CAPACITY,
113113
store,
114114
custody_column_count,
115115
spec.clone(),
116116
)?;
117117
Ok(Self {
118-
availability_cache: Arc::new(overflow_cache),
118+
availability_cache: Arc::new(inner),
119119
slot_clock,
120120
kzg,
121121
log: log.clone(),
122122
spec,
123123
})
124124
}
125125

126+
pub fn get_custody_columns_count(&self) -> usize {
127+
self.availability_cache
128+
.custody_subnet_count()
129+
.saturating_mul(self.spec.data_columns_per_subnet())
130+
}
131+
126132
/// Checks if the block root is currenlty in the availability cache awaiting import because
127133
/// of missing components.
128134
pub fn get_execution_valid_block(

beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use crate::data_column_verification::KzgVerifiedCustodyDataColumn;
99
use crate::BeaconChainTypes;
1010
use lru::LruCache;
1111
use parking_lot::RwLock;
12-
use ssz_derive::{Decode, Encode};
1312
use ssz_types::{FixedVector, VariableList};
1413
use std::num::NonZeroUsize;
1514
use std::sync::Arc;
@@ -20,7 +19,7 @@ use types::{BlobSidecar, ChainSpec, Epoch, EthSpec, Hash256, SignedBeaconBlock};
2019
///
2120
/// The blobs are all gossip and kzg verified.
2221
/// The block has completed all verifications except the availability check.
23-
#[derive(Encode, Decode, Clone)]
22+
#[derive(Clone)]
2423
pub struct PendingComponents<E: EthSpec> {
2524
pub block_root: Hash256,
2625
pub verified_blobs: FixedVector<Option<KzgVerifiedBlob<E>>, E::MaxBlobsPerBlock>,
@@ -303,6 +302,15 @@ impl<E: EthSpec> PendingComponents<E> {
303302
});
304303
}
305304
}
305+
306+
if let Some(kzg_verified_data_column) = self.verified_data_columns.first() {
307+
let epoch = kzg_verified_data_column
308+
.as_data_column()
309+
.slot()
310+
.epoch(E::slots_per_epoch());
311+
return Some(epoch);
312+
}
313+
306314
None
307315
})
308316
}
@@ -336,6 +344,10 @@ impl<T: BeaconChainTypes> DataAvailabilityCheckerInner<T> {
336344
})
337345
}
338346

347+
pub fn custody_subnet_count(&self) -> usize {
348+
self.custody_column_count
349+
}
350+
339351
/// Returns true if the block root is known, without altering the LRU ordering
340352
pub fn get_execution_valid_block(
341353
&self,

beacon_node/beacon_chain/src/data_column_verification.rs

+4
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ impl<E: EthSpec> KzgVerifiedCustodyDataColumn<E> {
250250
pub fn into_inner(self) -> Arc<DataColumnSidecar<E>> {
251251
self.data
252252
}
253+
254+
pub fn as_data_column(&self) -> &DataColumnSidecar<E> {
255+
&self.data
256+
}
253257
}
254258

255259
/// Complete kzg verification for a `DataColumnSidecar`.

beacon_node/beacon_chain/src/historical_blocks.rs

+32-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use state_processing::{
99
use std::borrow::Cow;
1010
use std::iter;
1111
use std::time::Duration;
12+
use store::metadata::DataColumnInfo;
1213
use store::{chunked_vector::BlockRoots, AnchorInfo, BlobInfo, ChunkWriter, KeyValueStore};
1314
use types::{Hash256, Slot};
1415

@@ -66,6 +67,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
6667
.get_anchor_info()
6768
.ok_or(HistoricalBlockError::NoAnchorInfo)?;
6869
let blob_info = self.store.get_blob_info();
70+
let data_column_info = self.store.get_data_column_info();
6971

7072
// Take all blocks with slots less than the oldest block slot.
7173
let num_relevant = blocks.partition_point(|available_block| {
@@ -90,18 +92,27 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
9092
return Ok(0);
9193
}
9294

93-
let n_blobs_lists_to_import = blocks_to_import
95+
// Blobs are stored per block, and data columns are each stored individually
96+
let n_blob_ops_per_block = if self.spec.is_peer_das_scheduled() {
97+
self.data_availability_checker.get_custody_columns_count()
98+
} else {
99+
1
100+
};
101+
102+
let blob_batch_size = blocks_to_import
94103
.iter()
95104
.filter(|available_block| available_block.blobs().is_some())
96-
.count();
105+
.count()
106+
.saturating_mul(n_blob_ops_per_block);
97107

98108
let mut expected_block_root = anchor_info.oldest_block_parent;
99109
let mut prev_block_slot = anchor_info.oldest_block_slot;
100110
let mut chunk_writer =
101111
ChunkWriter::<BlockRoots, _, _>::new(&self.store.cold_db, prev_block_slot.as_usize())?;
102112
let mut new_oldest_blob_slot = blob_info.oldest_blob_slot;
113+
let mut new_oldest_data_column_slot = data_column_info.oldest_data_column_slot;
103114

104-
let mut blob_batch = Vec::with_capacity(n_blobs_lists_to_import);
115+
let mut blob_batch = Vec::with_capacity(blob_batch_size);
105116
let mut cold_batch = Vec::with_capacity(blocks_to_import.len());
106117
let mut hot_batch = Vec::with_capacity(blocks_to_import.len());
107118
let mut signed_blocks = Vec::with_capacity(blocks_to_import.len());
@@ -129,11 +140,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
129140
.blobs_as_kv_store_ops(&block_root, blobs, &mut blob_batch);
130141
}
131142
// Store the data columns too
132-
if let Some(_data_columns) = maybe_data_columns {
133-
// TODO(das): depends on https://github.com/sigp/lighthouse/pull/6073
134-
// new_oldest_data_column_slot = Some(block.slot());
135-
// self.store
136-
// .data_columns_as_kv_store_ops(&block_root, data_columns, &mut blob_batch);
143+
if let Some(data_columns) = maybe_data_columns {
144+
new_oldest_data_column_slot = Some(block.slot());
145+
self.store
146+
.data_columns_as_kv_store_ops(&block_root, data_columns, &mut blob_batch);
137147
}
138148

139149
// Store block roots, including at all skip slots in the freezer DB.
@@ -212,7 +222,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
212222
self.store.hot_db.do_atomically(hot_batch)?;
213223
self.store.cold_db.do_atomically(cold_batch)?;
214224

215-
let mut anchor_and_blob_batch = Vec::with_capacity(2);
225+
let mut anchor_and_blob_batch = Vec::with_capacity(3);
216226

217227
// Update the blob info.
218228
if new_oldest_blob_slot != blob_info.oldest_blob_slot {
@@ -228,6 +238,19 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
228238
}
229239
}
230240

241+
// Update the data column info.
242+
if new_oldest_data_column_slot != data_column_info.oldest_data_column_slot {
243+
if let Some(oldest_data_column_slot) = new_oldest_data_column_slot {
244+
let new_data_column_info = DataColumnInfo {
245+
oldest_data_column_slot: Some(oldest_data_column_slot),
246+
};
247+
anchor_and_blob_batch.push(
248+
self.store
249+
.compare_and_set_data_column_info(data_column_info, new_data_column_info)?,
250+
);
251+
}
252+
}
253+
231254
// Update the anchor.
232255
let new_anchor = AnchorInfo {
233256
oldest_block_slot: prev_block_slot,

0 commit comments

Comments
 (0)