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

Batch verify aggregated attestation signatures #7744

Merged
merged 8 commits into from
Nov 10, 2020

Conversation

terencechain
Copy link
Member

@terencechain terencechain commented Nov 7, 2020

This PR batches verify all 3 signatures within aggregated attestation, the 3 signatures in aggregated attestation: selection signature, aggregator signature, and attestation signature.

It combines the following 3 verifications into 1:
image

image

With the following benchmark: https://gist.github.com/terencechain/412ef767ff37562a2735237c7ffc8b71
We gathered the following results:

Before:
BenchmarkValidateAggregateAndProof
BenchmarkValidateAggregateAndProof-12             295       3931547 ns/op
PASS

After:
BenchmarkValidateAggregateAndProof
BenchmarkValidateAggregateAndProof-12             414       2812799 ns/op

The result showed 40% improvements, roughly 1200000ns of saving on per attestation. There's currently 260 aggregated attestation per slot in medalla. That’s about 300ms we could save on per slot.

@terencechain terencechain requested a review from a team as a code owner November 7, 2020 23:34
@terencechain terencechain self-assigned this Nov 7, 2020
@codecov
Copy link

codecov bot commented Nov 7, 2020

Codecov Report

Merging #7744 (c230f96) into master (d4c9546) will decrease coverage by 0.01%.
The diff coverage is 48.21%.

@@            Coverage Diff             @@
##           master    #7744      +/-   ##
==========================================
- Coverage   62.15%   62.14%   -0.02%     
==========================================
  Files         429      429              
  Lines       30248    30292      +44     
==========================================
+ Hits        18802    18824      +22     
- Misses       8521     8539      +18     
- Partials     2925     2929       +4     

return helpers.ComputeDomainVerifySigningRoot(s, a.Message.AggregatorIndex,
helpers.SlotToEpoch(a.Message.Aggregate.Data.Slot), a.Message, params.BeaconConfig().DomainAggregateAndProof, a.Signature)
// This returns aggregator signature set which can be used to batch verify.
func aggSigSet(s *stateTrie.BeaconState, a *ethpb.SignedAggregateAttestationAndProof) (*bls.SignatureSet, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use our core methods here if possible, the logic here seems duplicated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which core method? this is for DomainAggregateAndProof over the entire message

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't we just be using this ?

func validateAggregatorSignature(s *stateTrie.BeaconState, a *ethpb.SignedAggregateAttestationAndProof) error {
	return helpers.ComputeDomainVerifySigningRoot(s, a.Message.AggregatorIndex,
		helpers.SlotToEpoch(a.Message.Aggregate.Data.Slot), a.Message, params.BeaconConfig().DomainAggregateAndProof, a.Signature)
}

any way to refactor that method to return a signature set instead ? Goal would be to avoid having 2 different methods
for signature verification.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll open a subsequent PR to address this. We should just refactor for all. There's some duplications from BLS helpers to signing helpers to block processing and to this. Better to improve all at once

traceutil.AnnotateError(span, errors.Wrapf(err, "Could not validate selection for validator %d", signed.Message.AggregatorIndex))
return pubsub.ValidationReject
return pubsub.ValidationIgnore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this an ignore ?

traceutil.AnnotateError(span, errors.Wrapf(err, "Could not verify aggregator signature %d", signed.Message.AggregatorIndex))
return pubsub.ValidationReject
return pubsub.ValidationIgnore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Failing to construct attestation signature set is a self-error and we shouldn't stop broadcasting it to our peers

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That depends on what kind of error, ex:
https://github.com/prysmaticlabs/prysm/blob/86e4c90fd999d9045e60cb76d2284d86ba0081da/beacon-chain/core/blocks/signature.go#L127:6

Most of the errors there would only be possible because of an invalid attestation aggregate. Ignoring rather than rejecting something like this seems risky.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily. These errors could come from:

  • Bad implementation of caching (e.g. BeaconCommitteeFromState)
  • Bad implementation of hash tree root (e.g. ComputeSigningRoot)
  • Bad implementation of helper functions (e.g. ConvertToIndexed, IsValidAttestationIndices)

These are likely client independent bug that varies from releases and languages. Example, if prysm has a bug on a specific version, it'll kill liveness for lh and nimbus as well. We don't want to stop broadcast and descore peers due to reasons above.

Likewise, if the aggregation is really bad, the signature validation will fail which will cause a reject. It feels safer on the liveness to be lenient on the first check

@terencechain terencechain dismissed a stale review via 628e145 November 9, 2020 05:16
@terencechain terencechain added the Ready For Review A pull request ready for code review label Nov 9, 2020
@prylabs-bulldozer prylabs-bulldozer bot merged commit 1b9911c into master Nov 10, 2020
@delete-merged-branch delete-merged-branch bot deleted the batch-veriy-aggre branch November 10, 2020 00:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Ready For Review A pull request ready for code review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants