Custody backfill sync (#7907)

#7603


  #### Custody backfill sync service
Similar in many ways to the current backfill service. There may be ways to unify the two services. The difficulty there is that the current backfill service tightly couples blocks and their associated blobs/data columns. Any attempts to unify the two services should be left to a separate PR in my opinion.

#### `SyncNeworkContext`
`SyncNetworkContext` manages custody sync data columns by range requests separetly from other sync RPC requests. I think this is a nice separation considering that custody backfill is its own service.

#### Data column import logic
The import logic verifies KZG committments and that the data columns block root matches the block root in the nodes store before importing columns

#### New channel to send messages to `SyncManager`
Now external services can communicate with the `SyncManager`. In this PR this channel is used to trigger a custody sync. Alternatively we may be able to use the existing `mpsc` channel that the `SyncNetworkContext` uses to communicate with the `SyncManager`. I will spend some time reviewing this.


Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>

Co-Authored-By: Eitan Seri- Levi <eserilev@gmail.com>

Co-Authored-By: dapplion <35266934+dapplion@users.noreply.github.com>
This commit is contained in:
Eitan Seri-Levi
2025-10-21 20:51:34 -07:00
committed by GitHub
parent 46dde9afee
commit 33e21634cb
30 changed files with 2958 additions and 200 deletions

View File

@@ -60,8 +60,8 @@ pub struct BlobsByRangeRequestId {
pub struct DataColumnsByRangeRequestId {
/// Id to identify this attempt at a data_columns_by_range request for `parent_request_id`
pub id: Id,
/// The Id of the overall By Range request for block components.
pub parent_request_id: ComponentsByRangeRequestId,
/// The Id of the overall By Range request for either a components by range request or a custody backfill request.
pub parent_request_id: DataColumnsByRangeRequester,
/// The peer id associated with the request.
///
/// This is useful to penalize the peer at a later point if it returned data columns that
@@ -69,6 +69,12 @@ pub struct DataColumnsByRangeRequestId {
pub peer: PeerId,
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub enum DataColumnsByRangeRequester {
ComponentsByRange(ComponentsByRangeRequestId),
CustodyBackfillSync(CustodyBackFillBatchRequestId),
}
/// Block components by range request for range sync. Includes an ID for downstream consumers to
/// handle retries and tie all their sub requests together.
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
@@ -80,6 +86,24 @@ pub struct ComponentsByRangeRequestId {
pub requester: RangeRequestId,
}
/// A batch of data columns by range request for custody sync. Includes an ID for downstream consumers to
/// handle retries and tie all the range requests for the given epoch together.
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub struct CustodyBackFillBatchRequestId {
/// For each `epoch` we may request the same data in a later retry. This Id identifies the
/// current attempt.
pub id: Id,
pub batch_id: CustodyBackfillBatchId,
}
/// Custody backfill may be restarted and sync each epoch multiple times in different runs. Identify
/// each batch by epoch and run_id for uniqueness.
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub struct CustodyBackfillBatchId {
pub epoch: Epoch,
pub run_id: u64,
}
/// Range sync chain or backfill batch
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub enum RangeRequestId {
@@ -217,6 +241,8 @@ impl_display!(ComponentsByRangeRequestId, "{}/{}", id, requester);
impl_display!(DataColumnsByRootRequestId, "{}/{}", id, requester);
impl_display!(SingleLookupReqId, "{}/Lookup/{}", req_id, lookup_id);
impl_display!(CustodyId, "{}", requester);
impl_display!(CustodyBackFillBatchRequestId, "{}/{}", id, batch_id);
impl_display!(CustodyBackfillBatchId, "{}/{}", epoch, run_id);
impl Display for DataColumnsByRootRequester {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
@@ -241,6 +267,15 @@ impl Display for RangeRequestId {
}
}
impl Display for DataColumnsByRangeRequester {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::ComponentsByRange(id) => write!(f, "ByRange/{id}"),
Self::CustodyBackfillSync(id) => write!(f, "CustodyBackfill/{id}"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -263,15 +298,17 @@ mod tests {
fn display_id_data_columns_by_range() {
let id = DataColumnsByRangeRequestId {
id: 123,
parent_request_id: ComponentsByRangeRequestId {
id: 122,
requester: RangeRequestId::RangeSync {
chain_id: 54,
batch_id: Epoch::new(0),
parent_request_id: DataColumnsByRangeRequester::ComponentsByRange(
ComponentsByRangeRequestId {
id: 122,
requester: RangeRequestId::RangeSync {
chain_id: 54,
batch_id: Epoch::new(0),
},
},
},
),
peer: PeerId::random(),
};
assert_eq!(format!("{id}"), "123/122/RangeSync/0/54");
assert_eq!(format!("{id}"), "123/ByRange/122/RangeSync/0/54");
}
}