Refactor/stream vc vote publishing (#8880)

Changes four `ValidatorStore` batch signing methods to return `impl Stream` instead of `Future`. Services consume the stream and publish each batch as it arrives.  No behavioral change for lh since `LighthouseValidatorStore` wraps everything in `stream::once`

Also replaces anonymous tuples in method signatures with named structs


Co-Authored-By: shane-moore <skm1790@gmail.com>

Co-Authored-By: Michael Sproul <michaelsproul@users.noreply.github.com>

Co-Authored-By: Mac L <mjladson@pm.me>
This commit is contained in:
Shane K Moore
2026-03-12 02:53:32 -07:00
committed by GitHub
parent e1e97e6df0
commit 4b3a9d3d10
8 changed files with 740 additions and 543 deletions

View File

@@ -9,6 +9,7 @@ use eth2::lighthouse_vc::{
types::Web3SignerValidatorRequest,
};
use fixed_bytes::FixedBytesExtended;
use futures::StreamExt;
use itertools::Itertools;
use lighthouse_validator_store::DEFAULT_GAS_LIMIT;
use rand::rngs::StdRng;
@@ -19,6 +20,7 @@ use std::{collections::HashMap, path::Path};
use tokio::runtime::Handle;
use typenum::Unsigned;
use types::{Address, attestation::AttestationBase};
use validator_store::AttestationToSign;
use validator_store::ValidatorStore;
use zeroize::Zeroizing;
@@ -1101,11 +1103,16 @@ async fn generic_migration_test(
// Sign attestations on VC1.
for (validator_index, attestation) in first_vc_attestations {
let public_key = keystore_pubkey(&keystores[validator_index]);
let safe_attestations = tester1
let stream = tester1
.validator_store
.sign_attestations(vec![(0, public_key, 0, attestation.clone())])
.await
.unwrap();
.sign_attestations(vec![AttestationToSign {
validator_index: 0,
pubkey: public_key,
validator_committee_index: 0,
attestation: attestation.clone(),
}]);
tokio::pin!(stream);
let safe_attestations = stream.next().await.unwrap().unwrap();
assert_eq!(safe_attestations.len(), 1);
// Compare data only, ignoring signatures which are added during signing.
assert_eq!(safe_attestations[0].1.data(), attestation.data());
@@ -1184,10 +1191,16 @@ async fn generic_migration_test(
// Sign attestations on the second VC.
for (validator_index, attestation, should_succeed) in second_vc_attestations {
let public_key = keystore_pubkey(&keystores[validator_index]);
let result = tester2
let stream = tester2
.validator_store
.sign_attestations(vec![(0, public_key, 0, attestation.clone())])
.await;
.sign_attestations(vec![AttestationToSign {
validator_index: 0,
pubkey: public_key,
validator_committee_index: 0,
attestation: attestation.clone(),
}]);
tokio::pin!(stream);
let result = stream.next().await.unwrap();
match result {
Ok(safe_attestations) => {
if should_succeed {
@@ -1331,14 +1344,14 @@ async fn delete_concurrent_with_signing() {
for j in 0..num_attestations {
let att = make_attestation(j, j + 1);
for (validator_index, public_key) in thread_pubkeys.iter().enumerate() {
let _ = validator_store
.sign_attestations(vec![(
validator_index as u64,
*public_key,
0,
att.clone(),
)])
.await;
let stream = validator_store.sign_attestations(vec![AttestationToSign {
validator_index: validator_index as u64,
pubkey: *public_key,
validator_committee_index: 0,
attestation: att.clone(),
}]);
tokio::pin!(stream);
let _ = stream.next().await;
}
}
});