Compare commits

...

8 Commits

Author SHA1 Message Date
james-prysm
f321948bf3 wip fixing tests 2024-03-05 12:58:43 -06:00
james-prysm
32fb74954b gaz 2024-03-05 10:17:07 -06:00
james-prysm
a3f95caf41 Merge branch 'develop' into validate-sync-aggregate 2024-03-05 10:02:24 -06:00
james-prysm
b4f1d43684 Merge branch 'develop' into validate-sync-aggregate 2024-03-05 09:48:30 -06:00
james-prysm
9526b432aa adding interface to avoid import of blockchain package 2024-03-05 09:46:02 -06:00
james-prysm
e4db78ab46 refactoring to reuse functions 2024-03-04 17:02:29 -06:00
james-prysm
7d068a3d61 gaz 2024-03-04 14:24:42 -06:00
james-prysm
e0f2b4c259 wip 2024-03-04 14:24:22 -06:00
6 changed files with 99 additions and 38 deletions

View File

@@ -26,6 +26,7 @@ go_library(
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/sync:go_default_library",
"//beacon-chain/verification:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types/primitives:go_default_library",

View File

@@ -18,6 +18,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
forkchoicetypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/types"
beaconState "github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/verification"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
@@ -222,6 +223,18 @@ func (s *Service) SubmitSignedContributionAndProof(
errs, ctx := errgroup.WithContext(ctx)
sigRoot, aggKey, msgErr := verification.SignedContributionAndProofValidationSetup(ctx, s.HeadFetcher, req)
if msgErr != nil {
return &RpcError{Err: msgErr.Err, Reason: BadRequest}
}
valid, err := bls.VerifySignature(req.Signature, sigRoot, aggKey)
if err != nil {
return &RpcError{Err: err, Reason: Internal}
}
if !valid {
return &RpcError{Err: errors.New("request signature invalid based on request message"), Reason: BadRequest}
}
// Broadcasting and saving contribution into the pool in parallel. As one fail should not affect another.
errs.Go(func() error {
return s.Broadcaster.Broadcast(ctx, req)
@@ -232,7 +245,7 @@ func (s *Service) SubmitSignedContributionAndProof(
}
// Wait for p2p broadcast to complete and return the first error (if any)
err := errs.Wait()
err = errs.Wait()
if err != nil {
return &RpcError{Err: err, Reason: Internal}
}

View File

@@ -336,11 +336,13 @@ func TestGetAggregateAttestation_SameSlotAndRoot_ReturnMostAggregationBits(t *te
}
func TestSubmitContributionAndProofs(t *testing.T) {
headFetcher := &mockChain.ChainService{}
c := &core.Service{
HeadFetcher: headFetcher,
OperationNotifier: (&mockChain.ChainService{}).OperationNotifier(),
}
s := &Server{CoreService: c}
s := &Server{CoreService: c, HeadFetcher: headFetcher}
t.Run("single", func(t *testing.T) {
broadcaster := &p2pmock.MockBroadcaster{}

View File

@@ -10,7 +10,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/feed"
opfeed "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/feed/operation"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
p2ptypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/types"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/verification"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
@@ -249,41 +249,9 @@ func (s *Service) rejectInvalidSyncAggregateSignature(m *ethpb.SignedContributio
return func(ctx context.Context) (pubsub.ValidationResult, error) {
ctx, span := trace.StartSpan(ctx, "sync.rejectInvalidSyncAggregateSignature")
defer span.End()
// The aggregate signature is valid for the message `beacon_block_root` and aggregate pubkey
// derived from the participation info in `aggregation_bits` for the subcommittee specified by the `contribution.subcommittee_index`.
var activeRawPubkeys [][]byte
syncPubkeys, err := s.cfg.chain.HeadSyncCommitteePubKeys(ctx, m.Message.Contribution.Slot, primitives.CommitteeIndex(m.Message.Contribution.SubcommitteeIndex))
if err != nil {
return pubsub.ValidationIgnore, err
}
bVector := m.Message.Contribution.AggregationBits
// In the event no bit is set for the
// sync contribution, we reject the message.
if bVector.Count() == 0 {
return pubsub.ValidationReject, errors.New("bitvector count is 0")
}
for i, pk := range syncPubkeys {
if bVector.BitAt(uint64(i)) {
activeRawPubkeys = append(activeRawPubkeys, pk)
}
}
d, err := s.cfg.chain.HeadSyncCommitteeDomain(ctx, m.Message.Contribution.Slot)
if err != nil {
tracing.AnnotateError(span, err)
return pubsub.ValidationIgnore, err
}
rawBytes := p2ptypes.SSZBytes(m.Message.Contribution.BlockRoot)
sigRoot, err := signing.ComputeSigningRoot(&rawBytes, d)
if err != nil {
tracing.AnnotateError(span, err)
return pubsub.ValidationIgnore, err
}
// Aggregate pubkeys separately again to allow
// for signature sets to be created for batch verification.
aggKey, err := bls.AggregatePublicKeys(activeRawPubkeys)
if err != nil {
tracing.AnnotateError(span, err)
return pubsub.ValidationIgnore, err
sigRoot, aggKey, msgErr := verification.SignedContributionAndProofValidationSetup(ctx, s.cfg.chain, m)
if msgErr != nil {
return msgErr.PubsubResult, msgErr.Err
}
set := &bls.SignatureBatch{
Messages: [][32]byte{sigRoot},

View File

@@ -9,6 +9,7 @@ go_library(
"fake.go",
"initializer.go",
"interface.go",
"message.go",
"mock.go",
"result.go",
],
@@ -20,6 +21,7 @@ go_library(
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/core/transition:go_default_library",
"//beacon-chain/forkchoice/types:go_default_library",
"//beacon-chain/p2p/types:go_default_library",
"//beacon-chain/startup:go_default_library",
"//beacon-chain/state:go_default_library",
"//cache/lru:go_default_library",
@@ -29,13 +31,16 @@ go_library(
"//consensus-types/primitives:go_default_library",
"//crypto/bls:go_default_library",
"//encoding/bytesutil:go_default_library",
"//monitoring/tracing:go_default_library",
"//network/forks:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/logging:go_default_library",
"//time/slots:go_default_library",
"@com_github_hashicorp_golang_lru//:go_default_library",
"@com_github_libp2p_go_libp2p_pubsub//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
],
)

View File

@@ -0,0 +1,72 @@
package verification
import (
"context"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
p2ptypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/types"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"go.opencensus.io/trace"
)
// MsgVerifError is an error wrapper for the validation setup responses
type MsgVerifError struct {
PubsubResult pubsub.ValidationResult
Err error
}
type syncSigPrerequisiteFetcher interface {
HeadSyncCommitteePubKeys(ctx context.Context, slot primitives.Slot, committeeIndex primitives.CommitteeIndex) ([][]byte, error)
HeadSyncCommitteeDomain(ctx context.Context, slot primitives.Slot) ([]byte, error)
}
// SignedContributionAndProofValidationSetup returns components used for a bls signature valuation
func SignedContributionAndProofValidationSetup(ctx context.Context, headFetcher syncSigPrerequisiteFetcher, req *ethpb.SignedContributionAndProof) ([fieldparams.RootLength]byte, bls.PublicKey, *MsgVerifError) {
ctx, span := trace.StartSpan(ctx, "verification.SignedContributionAndProofValidationSetup")
defer span.End()
// The aggregate signature is valid for the message `beacon_block_root` and aggregate pubkey
// derived from the participation info in `aggregation_bits` for the subcommittee specified by the `contribution.subcommittee_index`.
var activeRawPubkeys [][]byte
syncPubkeys, err := headFetcher.HeadSyncCommitteePubKeys(ctx, req.Message.Contribution.Slot, primitives.CommitteeIndex(req.Message.Contribution.SubcommitteeIndex))
if err != nil {
tracing.AnnotateError(span, err)
return [fieldparams.RootLength]byte{}, nil, &MsgVerifError{PubsubResult: pubsub.ValidationIgnore, Err: err}
}
bVector := req.Message.Contribution.AggregationBits
// In the event no bit is set for the
// sync contribution, we reject the message.
if bVector.Count() == 0 {
tracing.AnnotateError(span, err)
return [fieldparams.RootLength]byte{}, nil, &MsgVerifError{PubsubResult: pubsub.ValidationReject, Err: errors.New("bitvector count is 0")}
}
for i, pk := range syncPubkeys {
if bVector.BitAt(uint64(i)) {
activeRawPubkeys = append(activeRawPubkeys, pk)
}
}
d, err := headFetcher.HeadSyncCommitteeDomain(ctx, req.Message.Contribution.Slot)
if err != nil {
tracing.AnnotateError(span, err)
return [fieldparams.RootLength]byte{}, nil, &MsgVerifError{PubsubResult: pubsub.ValidationIgnore, Err: err}
}
rawBytes := p2ptypes.SSZBytes(req.Message.Contribution.BlockRoot)
sigRoot, err := signing.ComputeSigningRoot(&rawBytes, d)
if err != nil {
tracing.AnnotateError(span, err)
return [fieldparams.RootLength]byte{}, nil, &MsgVerifError{PubsubResult: pubsub.ValidationIgnore, Err: err}
}
// Aggregate pubkeys separately again to allow
// for signature sets to be created for batch verification.
aggKey, err := bls.AggregatePublicKeys(activeRawPubkeys)
if err != nil {
tracing.AnnotateError(span, err)
return [fieldparams.RootLength]byte{}, nil, &MsgVerifError{PubsubResult: pubsub.ValidationIgnore, Err: err}
}
return sigRoot, aggKey, nil
}