Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Maintain attestations that reference unknown blocks #2319

Closed
wants to merge 48 commits into from
Closed
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
5166a3a
wip
divagant-martian Apr 5, 2021
c48fafa
wip compiles
divagant-martian Apr 5, 2021
157e5db
move file names
divagant-martian Apr 6, 2021
ced9b1a
make ethspec unpin
divagant-martian Apr 9, 2021
bbd8a87
add queued types
divagant-martian Apr 12, 2021
316a0e2
wip
divagant-martian Apr 13, 2021
c5b9861
solving unpin problems
divagant-martian Apr 14, 2021
9c0c982
wip
divagant-martian Apr 14, 2021
c6ed553
do not lose the attestation info on error
divagant-martian Apr 15, 2021
32bd149
add glue
divagant-martian Apr 16, 2021
587c634
add more glue
divagant-martian Apr 17, 2021
e859725
almost there
divagant-martian Apr 20, 2021
1432a5c
Merge branch 'unstable' into att-queueing
divagant-martian Apr 20, 2021
d366868
wip
divagant-martian Apr 21, 2021
1bad064
update docs and constants
divagant-martian Apr 22, 2021
1b88a1b
add metrics
divagant-martian Apr 23, 2021
4213847
fix delay
divagant-martian Apr 27, 2021
3b5b253
add initial test
divagant-martian Apr 27, 2021
a62bbdf
better first test
divagant-martian Apr 27, 2021
117af5d
second test
divagant-martian Apr 27, 2021
23d3a6e
clippy lints
divagant-martian Apr 28, 2021
cbd74a9
cleanup
divagant-martian Apr 28, 2021
0edffed
ignore attestation message for unknown block only after retry
divagant-martian Apr 28, 2021
aea9c3b
Comment style
divagant-martian Apr 28, 2021
587a214
Merge branch 'unstable' into att-queueing
divagant-martian Apr 28, 2021
07b8b16
fmt and spelling
divagant-martian Apr 28, 2021
5e9c6b0
update delay
divagant-martian Apr 28, 2021
c3e1e28
update delay
divagant-martian Apr 28, 2021
67bc791
update tests
divagant-martian Apr 28, 2021
a18a04b
update tests
divagant-martian Apr 28, 2021
82408fd
clippy lints
divagant-martian Apr 28, 2021
1861f0a
spelling
divagant-martian Apr 29, 2021
49a0e8e
spelling
divagant-martian Apr 29, 2021
681d1e7
docs update
divagant-martian Apr 29, 2021
c09c364
review suggestions
divagant-martian Apr 29, 2021
7823704
remove unpin contrains
divagant-martian Apr 29, 2021
ca66900
comment style
divagant-martian Apr 29, 2021
f6c3a3e
Merge branch 'unstable' into att-queueing
divagant-martian Jun 18, 2021
e762f17
our savior clippy
divagant-martian Jun 18, 2021
d9b69be
Add some requeue tests for aggregates
paulhauner Jun 21, 2021
6744e2a
Try reprocess attns after RPC block import
paulhauner Jun 21, 2021
8fae905
Rename root -> beacon_block_root
paulhauner Jun 21, 2021
863d286
Add metrics for reprocessing queue size
paulhauner Jun 21, 2021
dca09d0
Add metrics to reprocessing queue
paulhauner Jun 21, 2021
c33d3cf
improve logs
divagant-martian Jul 5, 2021
4ba921e
adjust attestations delay before re-processing
divagant-martian Jul 6, 2021
cb7c56c
Merge branch 'unstable' into att-queueing
divagant-martian Jul 13, 2021
f117888
Merge branch 'att-queueing' of github.com:divagant-martian/lighthouse…
divagant-martian Jul 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 46 additions & 15 deletions beacon_node/beacon_chain/src/attestation_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,15 +375,17 @@ impl<T: BeaconChainTypes> VerifiedAggregatedAttestation<T> {
pub fn verify(
signed_aggregate: SignedAggregateAndProof<T::EthSpec>,
chain: &BeaconChain<T>,
) -> Result<Self, Error> {
) -> Result<Self, (Error, SignedAggregateAndProof<T::EthSpec>)> {
Self::verify_slashable(signed_aggregate, chain)
.map(|verified_aggregate| {
if let Some(slasher) = chain.slasher.as_ref() {
slasher.accept_attestation(verified_aggregate.indexed_attestation.clone());
}
verified_aggregate
})
.map_err(|slash_info| process_slash_info(slash_info, chain))
.map_err(|(slash_info, original_aggregate)| {
(process_slash_info(slash_info, chain), original_aggregate)
})
}

/// Run the checks that happen before an indexed attestation is constructed.
Expand Down Expand Up @@ -509,17 +511,31 @@ impl<T: BeaconChainTypes> VerifiedAggregatedAttestation<T> {
}

/// Verify the attestation, producing extra information about whether it might be slashable.
// NOTE: Clippy considers the return too complex. This tuple is not used elsewhere so it is not
// worth creating an alias.
#[allow(clippy::type_complexity)]
pub fn verify_slashable(
signed_aggregate: SignedAggregateAndProof<T::EthSpec>,
chain: &BeaconChain<T>,
) -> Result<Self, AttestationSlashInfo<T, Error>> {
) -> Result<
Self,
(
AttestationSlashInfo<T, Error>,
SignedAggregateAndProof<T::EthSpec>,
),
> {
use AttestationSlashInfo::*;

let attestation = &signed_aggregate.message.aggregate;
let aggregator_index = signed_aggregate.message.aggregator_index;
let attestation_root = match Self::verify_early_checks(&signed_aggregate, chain) {
Ok(root) => root,
Err(e) => return Err(SignatureNotChecked(signed_aggregate.message.aggregate, e)),
Err(e) => {
return Err((
SignatureNotChecked(signed_aggregate.message.aggregate.clone(), e),
signed_aggregate,
))
}
};

let indexed_attestation =
Expand All @@ -546,7 +562,12 @@ impl<T: BeaconChainTypes> VerifiedAggregatedAttestation<T> {
.map_err(|e| BeaconChainError::from(e).into())
}) {
Ok(indexed_attestation) => indexed_attestation,
Err(e) => return Err(SignatureNotChecked(signed_aggregate.message.aggregate, e)),
Err(e) => {
return Err((
SignatureNotChecked(signed_aggregate.message.aggregate.clone(), e),
signed_aggregate,
))
}
};

// Ensure that all signatures are valid.
Expand All @@ -560,11 +581,11 @@ impl<T: BeaconChainTypes> VerifiedAggregatedAttestation<T> {
}
})
{
return Err(SignatureInvalid(e));
return Err((SignatureInvalid(e), signed_aggregate));
}

if let Err(e) = Self::verify_late_checks(&signed_aggregate, attestation_root, chain) {
return Err(SignatureValid(indexed_attestation, e));
return Err((SignatureValid(indexed_attestation, e), signed_aggregate));
}

Ok(VerifiedAggregatedAttestation {
Expand Down Expand Up @@ -715,34 +736,39 @@ impl<T: BeaconChainTypes> VerifiedUnaggregatedAttestation<T> {
attestation: Attestation<T::EthSpec>,
subnet_id: Option<SubnetId>,
chain: &BeaconChain<T>,
) -> Result<Self, Error> {
) -> Result<Self, (Error, Attestation<T::EthSpec>)> {
Self::verify_slashable(attestation, subnet_id, chain)
.map(|verified_unaggregated| {
if let Some(slasher) = chain.slasher.as_ref() {
slasher.accept_attestation(verified_unaggregated.indexed_attestation.clone());
}
verified_unaggregated
})
.map_err(|slash_info| process_slash_info(slash_info, chain))
.map_err(|(slash_info, original_attestation)| {
(process_slash_info(slash_info, chain), original_attestation)
})
}

/// Verify the attestation, producing extra information about whether it might be slashable.
// NOTE: Clippy considers the return too complex. This tuple is not used elsewhere so it is not
// worth creating an alias.
#[allow(clippy::type_complexity)]
pub fn verify_slashable(
attestation: Attestation<T::EthSpec>,
subnet_id: Option<SubnetId>,
chain: &BeaconChain<T>,
) -> Result<Self, AttestationSlashInfo<T, Error>> {
) -> Result<Self, (AttestationSlashInfo<T, Error>, Attestation<T::EthSpec>)> {
use AttestationSlashInfo::*;

if let Err(e) = Self::verify_early_checks(&attestation, chain) {
return Err(SignatureNotChecked(attestation, e));
return Err((SignatureNotChecked(attestation.clone(), e), attestation));
}

let (indexed_attestation, committees_per_slot) =
match obtain_indexed_attestation_and_committees_per_slot(chain, &attestation) {
Ok(x) => x,
Err(e) => {
return Err(SignatureNotChecked(attestation, e));
return Err((SignatureNotChecked(attestation.clone(), e), attestation));
}
};

Expand All @@ -754,16 +780,21 @@ impl<T: BeaconChainTypes> VerifiedUnaggregatedAttestation<T> {
chain,
) {
Ok(t) => t,
Err(e) => return Err(SignatureNotCheckedIndexed(indexed_attestation, e)),
Err(e) => {
return Err((
SignatureNotCheckedIndexed(indexed_attestation, e),
attestation,
))
}
};

// The aggregate signature of the attestation is valid.
if let Err(e) = verify_attestation_signature(chain, &indexed_attestation) {
return Err(SignatureInvalid(e));
return Err((SignatureInvalid(e), attestation));
}

if let Err(e) = Self::verify_late_checks(&attestation, validator_index, chain) {
return Err(SignatureValid(indexed_attestation, e));
return Err((SignatureValid(indexed_attestation, e), attestation));
}

Ok(Self {
Expand Down
8 changes: 6 additions & 2 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
&self,
unaggregated_attestation: Attestation<T::EthSpec>,
subnet_id: Option<SubnetId>,
) -> Result<VerifiedUnaggregatedAttestation<T>, AttestationError> {
) -> Result<VerifiedUnaggregatedAttestation<T>, (AttestationError, Attestation<T::EthSpec>)>
{
metrics::inc_counter(&metrics::UNAGGREGATED_ATTESTATION_PROCESSING_REQUESTS);
let _timer =
metrics::start_timer(&metrics::UNAGGREGATED_ATTESTATION_GOSSIP_VERIFICATION_TIMES);
Expand All @@ -1221,7 +1222,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
pub fn verify_aggregated_attestation_for_gossip(
&self,
signed_aggregate: SignedAggregateAndProof<T::EthSpec>,
) -> Result<VerifiedAggregatedAttestation<T>, AttestationError> {
) -> Result<
VerifiedAggregatedAttestation<T>,
(AttestationError, SignedAggregateAndProof<T::EthSpec>),
> {
metrics::inc_counter(&metrics::AGGREGATED_ATTESTATION_PROCESSING_REQUESTS);
let _timer =
metrics::start_timer(&metrics::AGGREGATED_ATTESTATION_GOSSIP_VERIFICATION_TIMES);
Expand Down
4 changes: 2 additions & 2 deletions beacon_node/beacon_chain/tests/attestation_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ fn aggregated_gossip_verification() {
.expect(&format!(
"{} should error during verify_aggregated_attestation_for_gossip",
$desc
)),
)).0,
$( $error ) |+ $( if $guard )?
),
"case: {}",
Expand Down Expand Up @@ -605,7 +605,7 @@ fn unaggregated_gossip_verification() {
.expect(&format!(
"{} should error during verify_unaggregated_attestation_for_gossip",
$desc
)),
)).0,
$( $error ) |+ $( if $guard )?
),
"case: {}",
Expand Down
2 changes: 1 addition & 1 deletion beacon_node/beacon_chain/tests/store_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ fn epoch_boundary_state_attestation_processing() {
{
checked_pre_fin = true;
assert!(matches!(
res.err().unwrap(),
res.err().unwrap().0,
AttnError::PastSlot {
attestation_slot,
earliest_permissible_slot,
Expand Down
2 changes: 1 addition & 1 deletion beacon_node/beacon_chain/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ fn attestations_with_increasing_slots() {

if expected_attestation_slot < expected_earliest_permissible_slot {
assert!(matches!(
res.err().unwrap(),
res.err().unwrap().0,
AttnError::PastSlot {
attestation_slot,
earliest_permissible_slot,
Expand Down
8 changes: 4 additions & 4 deletions beacon_node/http_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1783,8 +1783,8 @@ pub fn serve<T: BeaconChainTypes>(
let mut failures = Vec::new();

// Verify that all messages in the post are valid before processing further
for (index, aggregate) in aggregates.as_slice().iter().enumerate() {
match chain.verify_aggregated_attestation_for_gossip(aggregate.clone()) {
for (index, aggregate) in aggregates.into_iter().enumerate() {
match chain.verify_aggregated_attestation_for_gossip(aggregate) {
Ok(verified_aggregate) => {
messages.push(PubsubMessage::AggregateAndProofAttestation(Box::new(
verified_aggregate.aggregate().clone(),
Expand All @@ -1809,8 +1809,8 @@ pub fn serve<T: BeaconChainTypes>(
// It's reasonably likely that two different validators produce
// identical aggregates, especially if they're using the same beacon
// node.
Err(AttnError::AttestationAlreadyKnown(_)) => continue,
Err(e) => {
Err((AttnError::AttestationAlreadyKnown(_), _)) => continue,
Err((e, aggregate)) => {
error!(log,
"Failure verifying aggregate and proofs";
"error" => format!("{:?}", e),
Expand Down
Loading