@@ -23,9 +23,7 @@ use crate::chain_config::ChainConfig;
23
23
use crate :: data_availability_checker:: {
24
24
Availability , AvailabilityCheckError , AvailableBlock , DataAvailabilityChecker ,
25
25
} ;
26
- use crate :: data_column_verification:: {
27
- DataColumnsSameBlock , GossipDataColumnError , GossipVerifiedDataColumn ,
28
- } ;
26
+ use crate :: data_column_verification:: { GossipDataColumnError , GossipVerifiedDataColumn } ;
29
27
use crate :: early_attester_cache:: EarlyAttesterCache ;
30
28
use crate :: errors:: { BeaconChainError as Error , BlockProductionError } ;
31
29
use crate :: eth1_chain:: { Eth1Chain , Eth1ChainBackend } ;
@@ -2970,13 +2968,23 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
2970
2968
2971
2969
/// Cache the data columns in the processing cache, process it, then evict it from the cache if it was
2972
2970
/// imported or errors.
2973
- pub async fn process_gossip_data_column (
2971
+ pub async fn process_gossip_data_columns (
2974
2972
self : & Arc < Self > ,
2975
- data_column : GossipVerifiedDataColumn < T > ,
2973
+ data_columns : Vec < GossipVerifiedDataColumn < T > > ,
2976
2974
) -> Result < AvailabilityProcessingStatus , BlockError < T :: EthSpec > > {
2975
+ let Ok ( ( slot, block_root) ) = data_columns
2976
+ . iter ( )
2977
+ . map ( |c| ( c. slot ( ) , c. block_root ( ) ) )
2978
+ . unique ( )
2979
+ . exactly_one ( )
2980
+ else {
2981
+ return Err ( BlockError :: InternalError (
2982
+ "Columns should be from the same block" . to_string ( ) ,
2983
+ ) ) ;
2984
+ } ;
2985
+
2977
2986
// If this block has already been imported to forkchoice it must have been available, so
2978
2987
// we don't need to process its samples again.
2979
- let block_root = data_column. block_root ( ) ;
2980
2988
if self
2981
2989
. canonical_head
2982
2990
. fork_choice_read_lock ( )
@@ -2986,7 +2994,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
2986
2994
}
2987
2995
2988
2996
let r = self
2989
- . check_gossip_data_columns_availability_and_import ( data_column )
2997
+ . check_gossip_data_columns_availability_and_import ( slot , block_root , data_columns )
2990
2998
. await ;
2991
2999
self . remove_notified_custody_columns ( & block_root, r)
2992
3000
}
@@ -3029,11 +3037,21 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
3029
3037
/// imported or errors.
3030
3038
pub async fn process_rpc_custody_columns (
3031
3039
self : & Arc < Self > ,
3032
- custody_columns : DataColumnsSameBlock < T :: EthSpec > ,
3040
+ custody_columns : DataColumnSidecarList < T :: EthSpec > ,
3033
3041
) -> Result < AvailabilityProcessingStatus , BlockError < T :: EthSpec > > {
3042
+ let Ok ( ( slot, block_root) ) = custody_columns
3043
+ . iter ( )
3044
+ . map ( |c| ( c. slot ( ) , c. block_root ( ) ) )
3045
+ . unique ( )
3046
+ . exactly_one ( )
3047
+ else {
3048
+ return Err ( BlockError :: InternalError (
3049
+ "Columns should be from the same block" . to_string ( ) ,
3050
+ ) ) ;
3051
+ } ;
3052
+
3034
3053
// If this block has already been imported to forkchoice it must have been available, so
3035
3054
// we don't need to process its columns again.
3036
- let block_root = custody_columns. block_root ( ) ;
3037
3055
if self
3038
3056
. canonical_head
3039
3057
. fork_choice_read_lock ( )
@@ -3045,7 +3063,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
3045
3063
// TODO(das): custody column SSE event
3046
3064
3047
3065
let r = self
3048
- . check_rpc_custody_columns_availability_and_import ( custody_columns)
3066
+ . check_rpc_custody_columns_availability_and_import ( slot , block_root , custody_columns)
3049
3067
. await ;
3050
3068
self . remove_notified ( & block_root, r)
3051
3069
}
@@ -3328,16 +3346,21 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
3328
3346
/// if so, otherwise caches the data column in the data availability checker.
3329
3347
async fn check_gossip_data_columns_availability_and_import (
3330
3348
self : & Arc < Self > ,
3331
- data_column : GossipVerifiedDataColumn < T > ,
3349
+ slot : Slot ,
3350
+ block_root : Hash256 ,
3351
+ data_columns : Vec < GossipVerifiedDataColumn < T > > ,
3332
3352
) -> Result < AvailabilityProcessingStatus , BlockError < T :: EthSpec > > {
3333
3353
if let Some ( slasher) = self . slasher . as_ref ( ) {
3334
- slasher. accept_block_header ( data_column. signed_block_header ( ) ) ;
3354
+ for data_colum in & data_columns {
3355
+ slasher. accept_block_header ( data_colum. signed_block_header ( ) ) ;
3356
+ }
3335
3357
}
3336
3358
3337
- let slot = data_column. slot ( ) ;
3338
- let availability = self
3339
- . data_availability_checker
3340
- . put_gossip_data_column ( data_column) ?;
3359
+ let availability = self . data_availability_checker . put_gossip_data_columns (
3360
+ slot,
3361
+ block_root,
3362
+ data_columns,
3363
+ ) ?;
3341
3364
3342
3365
self . process_availability ( slot, availability) . await
3343
3366
}
@@ -3385,34 +3408,39 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
3385
3408
/// if so, otherwise caches the columns in the data availability checker.
3386
3409
async fn check_rpc_custody_columns_availability_and_import (
3387
3410
self : & Arc < Self > ,
3388
- custody_columns : DataColumnsSameBlock < T :: EthSpec > ,
3411
+ slot : Slot ,
3412
+ block_root : Hash256 ,
3413
+ custody_columns : DataColumnSidecarList < T :: EthSpec > ,
3389
3414
) -> Result < AvailabilityProcessingStatus , BlockError < T :: EthSpec > > {
3390
3415
// Need to scope this to ensure the lock is dropped before calling `process_availability`
3391
3416
// Even an explicit drop is not enough to convince the borrow checker.
3392
3417
{
3393
3418
let mut slashable_cache = self . observed_slashable . write ( ) ;
3394
- let header = custody_columns. signed_block_header ( ) ;
3395
- let block_root = custody_columns. block_root ( ) ;
3396
- if verify_header_signature :: < T , BlockError < T :: EthSpec > > ( self , header) . is_ok ( ) {
3397
- slashable_cache
3398
- . observe_slashable (
3399
- header. message . slot ,
3400
- header. message . proposer_index ,
3401
- block_root,
3402
- )
3403
- . map_err ( |e| BlockError :: BeaconChainError ( e. into ( ) ) ) ?;
3404
- if let Some ( slasher) = self . slasher . as_ref ( ) {
3405
- slasher. accept_block_header ( header. clone ( ) ) ;
3419
+ // Assumes all items in custody_columns are for the same block_root
3420
+ if let Some ( column) = custody_columns. first ( ) {
3421
+ let header = & column. signed_block_header ;
3422
+ if verify_header_signature :: < T , BlockError < T :: EthSpec > > ( self , header) . is_ok ( ) {
3423
+ slashable_cache
3424
+ . observe_slashable (
3425
+ header. message . slot ,
3426
+ header. message . proposer_index ,
3427
+ block_root,
3428
+ )
3429
+ . map_err ( |e| BlockError :: BeaconChainError ( e. into ( ) ) ) ?;
3430
+ if let Some ( slasher) = self . slasher . as_ref ( ) {
3431
+ slasher. accept_block_header ( header. clone ( ) ) ;
3432
+ }
3406
3433
}
3407
3434
}
3408
3435
}
3409
3436
3410
3437
// This slot value is purely informative for the consumers of
3411
3438
// `AvailabilityProcessingStatus::MissingComponents` to log an error with a slot.
3412
- let slot = custody_columns. slot ( ) ;
3413
- let availability = self
3414
- . data_availability_checker
3415
- . put_rpc_custody_columns ( custody_columns) ?;
3439
+ let availability = self . data_availability_checker . put_rpc_custody_columns (
3440
+ block_root,
3441
+ slot. epoch ( T :: EthSpec :: slots_per_epoch ( ) ) ,
3442
+ custody_columns,
3443
+ ) ?;
3416
3444
3417
3445
self . process_availability ( slot, availability) . await
3418
3446
}
0 commit comments