Merge branch 'release-v7.0.0' into v7-backmerge

This commit is contained in:
Mac L
2025-04-04 13:32:58 +11:00
29 changed files with 65 additions and 54 deletions

View File

@@ -738,7 +738,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
///
/// - `slot` always increases by `1`.
/// - Skipped slots contain the root of the closest prior
/// non-skipped slot (identical to the way they are stored in `state.block_roots`).
/// non-skipped slot (identical to the way they are stored in `state.block_roots`).
/// - Iterator returns `(Hash256, Slot)`.
///
/// Will return a `BlockOutOfRange` error if the requested start slot is before the period of
@@ -802,7 +802,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
///
/// - `slot` always decreases by `1`.
/// - Skipped slots contain the root of the closest prior
/// non-skipped slot (identical to the way they are stored in `state.block_roots`) .
/// non-skipped slot (identical to the way they are stored in `state.block_roots`) .
/// - Iterator returns `(Hash256, Slot)`.
/// - The provided `block_root` is included as the first item in the iterator.
pub fn rev_iter_block_roots_from(
@@ -831,7 +831,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// - `slot` always decreases by `1`.
/// - Iterator returns `(Hash256, Slot)`.
/// - As this iterator starts at the `head` of the chain (viz., the best block), the first slot
/// returned may be earlier than the wall-clock slot.
/// returned may be earlier than the wall-clock slot.
pub fn rev_iter_state_roots_from<'a>(
&'a self,
state_root: Hash256,

View File

@@ -178,7 +178,7 @@ pub fn compute_proposer_duties_from_head<T: BeaconChainTypes>(
/// - Returns an error if `state.current_epoch() > target_epoch`.
/// - No-op if `state.current_epoch() == target_epoch`.
/// - It must be the case that `state.canonical_root() == state_root`, but this function will not
/// check that.
/// check that.
pub fn ensure_state_is_in_epoch<E: EthSpec>(
state: &mut BeaconState<E>,
state_root: Hash256,

View File

@@ -5,7 +5,7 @@
//! - Verification for gossip blocks (i.e., should we gossip some block from the network).
//! - Verification for normal blocks (e.g., some block received on the RPC during a parent lookup).
//! - Verification for chain segments (e.g., some chain of blocks received on the RPC during a
//! sync).
//! sync).
//!
//! The primary source of complexity here is that we wish to avoid doing duplicate work as a block
//! moves through the verification process. For example, if some block is verified for gossip, we

View File

@@ -33,7 +33,7 @@ pub struct CacheItem<E: EthSpec> {
///
/// - Produce an attestation without using `chain.canonical_head`.
/// - Verify that a block root exists (i.e., will be imported in the future) during attestation
/// verification.
/// verification.
/// - Provide a block which can be sent to peers via RPC.
#[derive(Default)]
pub struct EarlyAttesterCache<E: EthSpec> {

View File

@@ -461,7 +461,7 @@ pub mod tests {
let last_finalized_eth1 = eth1s_by_count
.range(0..(finalized_deposits + 1))
.map(|(_, eth1)| eth1)
.last()
.next_back()
.cloned();
assert_eq!(
eth1cache.finalize(finalized_checkpoint),

View File

@@ -1282,7 +1282,7 @@ impl InvalidHeadSetup {
///
/// 1. A chain where the only viable head block has an invalid execution payload.
/// 2. A block (`fork_block`) which will become the head of the chain when
/// it is imported.
/// it is imported.
async fn new() -> InvalidHeadSetup {
let slots_per_epoch = E::slots_per_epoch();
let mut rig = InvalidPayloadRig::new().enable_attestations();

View File

@@ -1682,7 +1682,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
///
/// - `Some(true)` if the given `block_hash` is the terminal proof-of-work block.
/// - `Some(false)` if the given `block_hash` is certainly *not* the terminal proof-of-work
/// block.
/// block.
/// - `None` if the `block_hash` or its parent were not present on the execution engine.
/// - `Err(_)` if there was an error connecting to the execution engine.
///

View File

@@ -991,23 +991,23 @@ impl<E: EthSpec> PeerManager<E> {
/// - Do not prune outbound peers to exceed our outbound target.
/// - Do not prune more peers than our target peer count.
/// - If we have an option to remove a number of peers, remove ones that have the least
/// long-lived subnets.
/// long-lived subnets.
/// - When pruning peers based on subnet count. If multiple peers can be chosen, choose a peer
/// that is not subscribed to a long-lived sync committee subnet.
/// that is not subscribed to a long-lived sync committee subnet.
/// - When pruning peers based on subnet count, do not prune a peer that would lower us below the
/// MIN_SYNC_COMMITTEE_PEERS peer count. To keep it simple, we favour a minimum number of sync-committee-peers over
/// uniformity subnet peers. NOTE: We could apply more sophisticated logic, but the code is
/// simpler and easier to maintain if we take this approach. If we are pruning subnet peers
/// below the MIN_SYNC_COMMITTEE_PEERS and maintaining the sync committee peers, this should be
/// fine as subnet peers are more likely to be found than sync-committee-peers. Also, we're
/// in a bit of trouble anyway if we have so few peers on subnets. The
/// MIN_SYNC_COMMITTEE_PEERS
/// number should be set low as an absolute lower bound to maintain peers on the sync
/// committees.
/// MIN_SYNC_COMMITTEE_PEERS peer count. To keep it simple, we favour a minimum number of sync-committee-peers over
/// uniformity subnet peers. NOTE: We could apply more sophisticated logic, but the code is
/// simpler and easier to maintain if we take this approach. If we are pruning subnet peers
/// below the MIN_SYNC_COMMITTEE_PEERS and maintaining the sync committee peers, this should be
/// fine as subnet peers are more likely to be found than sync-committee-peers. Also, we're
/// in a bit of trouble anyway if we have so few peers on subnets. The
/// MIN_SYNC_COMMITTEE_PEERS
/// number should be set low as an absolute lower bound to maintain peers on the sync
/// committees.
/// - Do not prune trusted peers. NOTE: This means if a user has more trusted peers than the
/// excess peer limit, all of the following logic is subverted as we will not prune any peers.
/// Also, the more trusted peers a user has, the less room Lighthouse has to efficiently manage
/// its peers across the subnets.
/// excess peer limit, all of the following logic is subverted as we will not prune any peers.
/// Also, the more trusted peers a user has, the less room Lighthouse has to efficiently manage
/// its peers across the subnets.
///
/// Prune peers in the following order:
/// 1. Remove worst scoring peers

View File

@@ -153,7 +153,7 @@ impl<E: EthSpec> PeerDB<E> {
matches!(
self.connection_status(peer_id),
Some(PeerConnectionStatus::Disconnected { .. })
| Some(PeerConnectionStatus::Unknown { .. })
| Some(PeerConnectionStatus::Unknown)
| None
) && !self.score_state_banned_or_disconnected(peer_id)
}
@@ -771,8 +771,8 @@ impl<E: EthSpec> PeerDB<E> {
NewConnectionState::Connected { .. } // We have established a new connection (peer may not have been seen before)
| NewConnectionState::Disconnecting { .. }// We are disconnecting from a peer that may not have been registered before
| NewConnectionState::Dialing { .. } // We are dialing a potentially new peer
| NewConnectionState::Disconnected { .. } // Dialing a peer that responds by a different ID can be immediately
// disconnected without having being stored in the db before
| NewConnectionState::Disconnected // Dialing a peer that responds by a different ID can be immediately
// disconnected without having being stored in the db before
) {
warn!(%peer_id, ?new_state, "Updating state of unknown peer");
}

View File

@@ -1010,7 +1010,7 @@ mod tests {
BeaconBlockBellatrix::empty(&Spec::default_spec());
let tx = VariableList::from(vec![0; 1024]);
let txs = VariableList::from(std::iter::repeat(tx).take(5000).collect::<Vec<_>>());
let txs = VariableList::from(std::iter::repeat_n(tx, 5000).collect::<Vec<_>>());
block.body.execution_payload.execution_payload.transactions = txs;
@@ -1030,7 +1030,7 @@ mod tests {
BeaconBlockBellatrix::empty(&Spec::default_spec());
let tx = VariableList::from(vec![0; 1024]);
let txs = VariableList::from(std::iter::repeat(tx).take(100000).collect::<Vec<_>>());
let txs = VariableList::from(std::iter::repeat_n(tx, 100000).collect::<Vec<_>>());
block.body.execution_payload.execution_payload.transactions = txs;

View File

@@ -25,7 +25,7 @@ type E = MinimalEthSpec;
fn bellatrix_block_small(fork_context: &ForkContext, spec: &ChainSpec) -> BeaconBlock<E> {
let mut block = BeaconBlockBellatrix::<E>::empty(spec);
let tx = VariableList::from(vec![0; 1024]);
let txs = VariableList::from(std::iter::repeat(tx).take(5000).collect::<Vec<_>>());
let txs = VariableList::from(std::iter::repeat_n(tx, 5000).collect::<Vec<_>>());
block.body.execution_payload.execution_payload.transactions = txs;
@@ -40,7 +40,7 @@ fn bellatrix_block_small(fork_context: &ForkContext, spec: &ChainSpec) -> Beacon
fn bellatrix_block_large(fork_context: &ForkContext, spec: &ChainSpec) -> BeaconBlock<E> {
let mut block = BeaconBlockBellatrix::<E>::empty(spec);
let tx = VariableList::from(vec![0; 1024]);
let txs = VariableList::from(std::iter::repeat(tx).take(100000).collect::<Vec<_>>());
let txs = VariableList::from(std::iter::repeat_n(tx, 100000).collect::<Vec<_>>());
block.body.execution_payload.execution_payload.transactions = txs;

View File

@@ -821,7 +821,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
| GossipDataColumnError::ProposerIndexMismatch { .. }
| GossipDataColumnError::IsNotLaterThanParent { .. }
| GossipDataColumnError::InvalidSubnetId { .. }
| GossipDataColumnError::InvalidInclusionProof { .. }
| GossipDataColumnError::InvalidInclusionProof
| GossipDataColumnError::InvalidKzgProof { .. }
| GossipDataColumnError::UnexpectedDataColumn
| GossipDataColumnError::InvalidColumnIndex(_)

View File

@@ -685,7 +685,7 @@ impl<T: BeaconChainTypes> SyncManager<T> {
if new_state.is_synced()
&& !matches!(
old_state,
SyncState::Synced { .. } | SyncState::BackFillSyncing { .. }
SyncState::Synced | SyncState::BackFillSyncing { .. }
)
{
self.network.subscribe_core_topics();

View File

@@ -1297,7 +1297,7 @@ impl TestRig {
.sync_manager
.get_sampling_request_status(block_root, index)
.unwrap_or_else(|| panic!("No request state for {index}"));
if !matches!(status, crate::sync::peer_sampling::Status::NoPeers { .. }) {
if !matches!(status, crate::sync::peer_sampling::Status::NoPeers) {
panic!("expected {block_root} {index} request to be no peers: {status:?}");
}
}

View File

@@ -104,8 +104,8 @@ impl std::fmt::Display for SyncState {
match self {
SyncState::SyncingFinalized { .. } => write!(f, "Syncing Finalized Chain"),
SyncState::SyncingHead { .. } => write!(f, "Syncing Head Chain"),
SyncState::Synced { .. } => write!(f, "Synced"),
SyncState::Stalled { .. } => write!(f, "Stalled"),
SyncState::Synced => write!(f, "Synced"),
SyncState::Stalled => write!(f, "Stalled"),
SyncState::SyncTransition => write!(f, "Evaluating known peers"),
SyncState::BackFillSyncing { .. } => write!(f, "Syncing Historical Blocks"),
}

View File

@@ -11,3 +11,6 @@
- enr:-Ku4QIC89sMC0o-irosD4_23lJJ4qCGOvdUz7SmoShWx0k6AaxCFTKviEHa-sa7-EzsiXpDp0qP0xzX6nKdXJX3X-IQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBd9cEGEAAJEP__________gmlkgnY0gmlwhIbRilSJc2VjcDI1NmsxoQK_m0f1DzDc9Cjrspm36zuRa7072HSiMGYWLsKiVSbP34N1ZHCCIyk
- enr:-Ku4QNkWjw5tNzo8DtWqKm7CnDdIq_y7xppD6c1EZSwjB8rMOkSFA1wJPLoKrq5UvA7wcxIotH6Usx3PAugEN2JMncIBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBd9cEGEAAJEP__________gmlkgnY0gmlwhIbHuBeJc2VjcDI1NmsxoQP3FwrhFYB60djwRjAoOjttq6du94DtkQuaN99wvgqaIYN1ZHCCIyk
- enr:-OS4QMJGE13xEROqvKN1xnnt7U-noc51VXyM6wFMuL9LMhQDfo1p1dF_zFdS4OsnXz_vIYk-nQWnqJMWRDKvkSK6_CwDh2F0dG5ldHOIAAAAADAAAACGY2xpZW502IpMaWdodGhvdXNljDcuMC4wLWJldGEuM4RldGgykNLxmX9gAAkQAAgAAAAAAACCaWSCdjSCaXCEhse4F4RxdWljgiMqiXNlY3AyNTZrMaECef77P8k5l3PC_raLw42OAzdXfxeQ-58BJriNaqiRGJSIc3luY25ldHMAg3RjcIIjKIN1ZHCCIyg
# Teku
- enr:-LK4QDwhXMitMbC8xRiNL-XGMhRyMSOnxej-zGifjv9Nm5G8EF285phTU-CAsMHRRefZimNI7eNpAluijMQP7NDC8kEMh2F0dG5ldHOIAAAAAAAABgCEZXRoMpDS8Zl_YAAJEAAIAAAAAAAAgmlkgnY0gmlwhAOIT_SJc2VjcDI1NmsxoQMoHWNL4MAvh6YpQeM2SUjhUrLIPsAVPB8nyxbmckC6KIN0Y3CCIyiDdWRwgiMo
- enr:-LK4QPYl2HnMPQ7b1es6Nf_tFYkyya5bj9IqAKOEj2cmoqVkN8ANbJJJK40MX4kciL7pZszPHw6vLNyeC-O3HUrLQv8Mh2F0dG5ldHOIAAAAAAAAAMCEZXRoMpDS8Zl_YAAJEAAIAAAAAAAAgmlkgnY0gmlwhAMYRG-Jc2VjcDI1NmsxoQPQ35tjr6q1qUqwAnegQmYQyfqxC_6437CObkZneI9n34N0Y3CCIyiDdWRwgiMo

View File

@@ -1,6 +1,12 @@
# EF bootnodes
# EF
- enr:-Ku4QDZ_rCowZFsozeWr60WwLgOfHzv1Fz2cuMvJqN5iJzLxKtVjoIURY42X_YTokMi3IGstW5v32uSYZyGUXj9Q_IECh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCo_ujukAAAaf__________gmlkgnY0gmlwhIpEe5iJc2VjcDI1NmsxoQNHTpFdaNSCEWiN_QqT396nb0PzcUpLe3OVtLph-AciBYN1ZHCCIy0
- enr:-Ku4QHRyRwEPT7s0XLYzJ_EeeWvZTXBQb4UCGy1F_3m-YtCNTtDlGsCMr4UTgo4uR89pv11uM-xq4w6GKfKhqU31hTgCh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCo_ujukAAAaf__________gmlkgnY0gmlwhIrFM7WJc2VjcDI1NmsxoQI4diTwChN3zAAkarf7smOHCdFb1q3DSwdiQ_Lc_FdzFIN1ZHCCIy0
- enr:-Ku4QOkvvf0u5Hg4-HhY-SJmEyft77G5h3rUM8VF_e-Hag5cAma3jtmFoX4WElLAqdILCA-UWFRN1ZCDJJVuEHrFeLkDh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCo_ujukAAAaf__________gmlkgnY0gmlwhJK-AWeJc2VjcDI1NmsxoQLFcT5VE_NMiIC8Ll7GypWDnQ4UEmuzD7hF_Hf4veDJwIN1ZHCCIy0
- enr:-Ku4QH6tYsHKITYeHUu5kdfXgEZWI18EWk_2RtGOn1jBPlx2UlS_uF3Pm5Dx7tnjOvla_zs-wwlPgjnEOcQDWXey51QCh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCo_ujukAAAaf__________gmlkgnY0gmlwhIs7Mc6Jc2VjcDI1NmsxoQIET4Mlv9YzhrYhX_H9D7aWMemUrvki6W4J2Qo0YmFMp4N1ZHCCIy0
- enr:-Ku4QDmz-4c1InchGitsgNk4qzorWMiFUoaPJT4G0IiF8r2UaevrekND1o7fdoftNucirj7sFFTTn2-JdC2Ej0p1Mn8Ch2F0dG5ldHOIAAAAAAAAAACEZXRoMpCo_ujukAAAaf__________gmlkgnY0gmlwhKpA-liJc2VjcDI1NmsxoQMpHP5U1DK8O_JQU6FadmWbE42qEdcGlllR8HcSkkfWq4N1ZHCCIy0
# Teku bootnode
- enr:-KO4QP7MmB3juk8rUjJHcUoxZDU9Np4FlW0HyDEGIjSO7GD9PbSsabu7713cWSUWKDkxIypIXg1A-6lG7ySRGOMZHeGCAmuEZXRoMpDTH2GRkAAAc___________gmlkgnY0gmlwhBSoyGOJc2VjcDI1NmsxoQNta5b_bexSSwwrGW2Re24MjfMntzFd0f2SAxQtMj3ueYN0Y3CCIyiDdWRwgiMo
# Lodestar
- enr:-KG4QJejf8KVtMeAPWFhN_P0c4efuwu1pZHELTveiXUeim6nKYcYcMIQpGxxdgT2Xp9h-M5pr9gn2NbbwEAtxzu50Y8BgmlkgnY0gmlwhEEVkQCDaXA2kCoBBPnAEJg4AAAAAAAAAAGJc2VjcDI1NmsxoQLEh_eVvk07AQABvLkTGBQTrrIOQkzouMgSBtNHIRUxOIN1ZHCCIyiEdWRwNoIjKA

View File

@@ -22,7 +22,7 @@ pub const LOCK_FILE: &str = ".lock";
///
/// - Control over the `.lock` file to prevent concurrent access.
/// - A `next_validator` function which wraps `Wallet::next_validator`, ensuring that the wallet is
/// persisted to disk (as JSON) between each consecutive call.
/// persisted to disk (as JSON) between each consecutive call.
pub struct LockedWallet {
wallet_dir: PathBuf,
wallet: Wallet,

View File

@@ -760,7 +760,7 @@ impl ProtoArray {
///
/// - The child is already the best child but it's now invalid due to a FFG change and should be removed.
/// - The child is already the best child and the parent is updated with the new
/// best-descendant.
/// best-descendant.
/// - The child is not the best child but becomes the best child.
/// - The child is not the best child and does not become the best child.
fn maybe_update_best_child_and_descendant<E: EthSpec>(

View File

@@ -1121,7 +1121,7 @@ mod test_compute_deltas {
///
/// - `A` (slot 31) is the common descendant.
/// - `B` (slot 33) descends from `A`, but there is a single skip slot
/// between it and `A`.
/// between it and `A`.
/// - `C` (slot 32) descends from `A` and conflicts with `B`.
///
/// Imagine that the `B` chain is finalized at epoch 1. This means that the

View File

@@ -42,8 +42,8 @@ impl<E: EthSpec> SyncCommitteeContribution<E> {
///
/// - `message`: A single `SyncCommitteeMessage`.
/// - `subcommittee_index`: The subcommittee this contribution pertains to out of the broader
/// sync committee. This can be determined from the `SyncSubnetId` of the gossip subnet
/// this message was seen on.
/// sync committee. This can be determined from the `SyncSubnetId` of the gossip subnet
/// this message was seen on.
/// - `validator_sync_committee_index`: The index of the validator **within** the subcommittee.
pub fn from_message(
message: &SyncCommitteeMessage,

View File

@@ -3,7 +3,7 @@ use smallvec::smallvec;
impl<N: Unsigned + Clone> TestRandom for BitList<N> {
fn random_for_test(rng: &mut impl RngCore) -> Self {
let initial_len = std::cmp::max(1, (N::to_usize() + 7) / 8);
let initial_len = std::cmp::max(1, N::to_usize().div_ceil(8));
let mut raw_bytes = smallvec![0; initial_len];
rng.fill_bytes(&mut raw_bytes);
@@ -24,7 +24,7 @@ impl<N: Unsigned + Clone> TestRandom for BitList<N> {
impl<N: Unsigned + Clone> TestRandom for BitVector<N> {
fn random_for_test(rng: &mut impl RngCore) -> Self {
let mut raw_bytes = smallvec![0; std::cmp::max(1, (N::to_usize() + 7) / 8)];
let mut raw_bytes = smallvec![0; std::cmp::max(1, N::to_usize().div_ceil(8))];
rng.fill_bytes(&mut raw_bytes);
// If N isn't divisible by 8
// zero out bits greater than N

View File

@@ -10,7 +10,7 @@
//!
//! - `supranational`: the pure-assembly, highly optimized version from the `blst` crate.
//! - `fake_crypto`: an always-returns-valid implementation that is only useful for testing
//! scenarios which intend to *ignore* real cryptography.
//! scenarios which intend to *ignore* real cryptography.
//!
//! This crate uses traits to reduce code-duplication between the two implementations. For example,
//! the `GenericPublicKey` struct exported from this crate is generic across the `TPublicKey` trait

View File

@@ -1,4 +1,4 @@
TESTS_TAG := v1.5.0-beta.2
TESTS_TAG := v1.5.0-beta.4
TESTS = general minimal mainnet
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))

View File

@@ -50,6 +50,8 @@ excluded_paths = [
# TODO(das): Fulu tests are ignored for now
"tests/.*/fulu",
"tests/.*/fulu/ssz_static/MatrixEntry",
"tests/.*/eip7441",
"tests/.*/eip7732",
]

View File

@@ -84,11 +84,11 @@ pub use transition::TransitionTest;
///
/// The feature tests can be run with one of the following methods:
/// 1. `handler.run_for_feature(feature_name)` for new tests that are not on existing fork, i.e. a
/// new handler. This will be temporary and the test will need to be updated to use
/// `handle.run()` once the feature is incorporated into a fork.
/// new handler. This will be temporary and the test will need to be updated to use
/// `handle.run()` once the feature is incorporated into a fork.
/// 2. `handler.run()` for tests that are already on existing forks, but with new test vectors for
/// the feature. In this case the `handler.is_enabled_for_feature` will need to be implemented
/// to return `true` for the feature in order for the feature test vector to be tested.
/// the feature. In this case the `handler.is_enabled_for_feature` will need to be implemented
/// to return `true` for the feature in order for the feature test vector to be tested.
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum FeatureName {
// TODO(fulu): to be removed once we start using Fulu types for test vectors.

View File

@@ -143,7 +143,7 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
fn load_from_dir(path: &Path, fork_name: ForkName) -> Result<Self, Error> {
let description = path
.iter()
.last()
.next_back()
.expect("path must be non-empty")
.to_str()
.expect("path must be valid OsStr")

View File

@@ -92,7 +92,7 @@ fn keystore_pubkey(keystore: &Keystore) -> PublicKeyBytes {
}
fn all_with_status<T: Clone>(count: usize, status: T) -> impl Iterator<Item = T> {
std::iter::repeat(status).take(count)
std::iter::repeat_n(status, count)
}
fn all_imported(count: usize) -> impl Iterator<Item = ImportKeystoreStatus> {
@@ -1059,7 +1059,7 @@ async fn migrate_some_extra_slashing_protection() {
/// - `first_vc_attestations`: attestations to sign on the first VC as `(validator_idx, att)`
/// - `delete_indices`: validators to delete from the first VC
/// - `slashing_protection_indices`: validators to transfer slashing protection data for. It should
/// be a subset of `delete_indices` or the test will panic.
/// be a subset of `delete_indices` or the test will panic.
/// - `import_indices`: validators to transfer. It needn't be a subset of `delete_indices`.
/// - `second_vc_attestations`: attestations to sign on the second VC after the transfer. The bool
/// indicates whether the signing should be successful.

View File

@@ -263,9 +263,9 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
/// are two primary functions used here:
///
/// - `DoppelgangerStatus::only_safe`: only returns pubkeys which have passed doppelganger
/// protection and are safe-enough to sign messages.
/// protection and are safe-enough to sign messages.
/// - `DoppelgangerStatus::ignored`: returns all the pubkeys from `only_safe` *plus* those still
/// undergoing protection. This is useful for collecting duties or other non-signing tasks.
/// undergoing protection. This is useful for collecting duties or other non-signing tasks.
#[allow(clippy::needless_collect)] // Collect is required to avoid holding a lock.
pub fn voting_pubkeys<I, F>(&self, filter_func: F) -> I
where