mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-31 08:08:18 -05:00
Compare commits
8 Commits
e2e-debugg
...
validate-s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f321948bf3 | ||
|
|
32fb74954b | ||
|
|
a3f95caf41 | ||
|
|
b4f1d43684 | ||
|
|
9526b432aa | ||
|
|
e4db78ab46 | ||
|
|
7d068a3d61 | ||
|
|
e0f2b4c259 |
@@ -26,6 +26,7 @@ go_library(
|
|||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/stategen:go_default_library",
|
"//beacon-chain/state/stategen:go_default_library",
|
||||||
"//beacon-chain/sync:go_default_library",
|
"//beacon-chain/sync:go_default_library",
|
||||||
|
"//beacon-chain/verification:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
"//consensus-types/primitives:go_default_library",
|
"//consensus-types/primitives:go_default_library",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
|
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
|
||||||
forkchoicetypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/types"
|
forkchoicetypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/types"
|
||||||
beaconState "github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
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"
|
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||||
@@ -222,6 +223,18 @@ func (s *Service) SubmitSignedContributionAndProof(
|
|||||||
|
|
||||||
errs, ctx := errgroup.WithContext(ctx)
|
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.
|
// Broadcasting and saving contribution into the pool in parallel. As one fail should not affect another.
|
||||||
errs.Go(func() error {
|
errs.Go(func() error {
|
||||||
return s.Broadcaster.Broadcast(ctx, req)
|
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)
|
// Wait for p2p broadcast to complete and return the first error (if any)
|
||||||
err := errs.Wait()
|
err = errs.Wait()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &RpcError{Err: err, Reason: Internal}
|
return &RpcError{Err: err, Reason: Internal}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,11 +336,13 @@ func TestGetAggregateAttestation_SameSlotAndRoot_ReturnMostAggregationBits(t *te
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSubmitContributionAndProofs(t *testing.T) {
|
func TestSubmitContributionAndProofs(t *testing.T) {
|
||||||
|
headFetcher := &mockChain.ChainService{}
|
||||||
c := &core.Service{
|
c := &core.Service{
|
||||||
|
HeadFetcher: headFetcher,
|
||||||
OperationNotifier: (&mockChain.ChainService{}).OperationNotifier(),
|
OperationNotifier: (&mockChain.ChainService{}).OperationNotifier(),
|
||||||
}
|
}
|
||||||
|
|
||||||
s := &Server{CoreService: c}
|
s := &Server{CoreService: c, HeadFetcher: headFetcher}
|
||||||
|
|
||||||
t.Run("single", func(t *testing.T) {
|
t.Run("single", func(t *testing.T) {
|
||||||
broadcaster := &p2pmock.MockBroadcaster{}
|
broadcaster := &p2pmock.MockBroadcaster{}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/feed"
|
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/feed"
|
||||||
opfeed "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/feed/operation"
|
opfeed "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/feed/operation"
|
||||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
|
"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/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
"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) {
|
return func(ctx context.Context) (pubsub.ValidationResult, error) {
|
||||||
ctx, span := trace.StartSpan(ctx, "sync.rejectInvalidSyncAggregateSignature")
|
ctx, span := trace.StartSpan(ctx, "sync.rejectInvalidSyncAggregateSignature")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
// The aggregate signature is valid for the message `beacon_block_root` and aggregate pubkey
|
sigRoot, aggKey, msgErr := verification.SignedContributionAndProofValidationSetup(ctx, s.cfg.chain, m)
|
||||||
// derived from the participation info in `aggregation_bits` for the subcommittee specified by the `contribution.subcommittee_index`.
|
if msgErr != nil {
|
||||||
var activeRawPubkeys [][]byte
|
return msgErr.PubsubResult, msgErr.Err
|
||||||
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
|
|
||||||
}
|
}
|
||||||
set := &bls.SignatureBatch{
|
set := &bls.SignatureBatch{
|
||||||
Messages: [][32]byte{sigRoot},
|
Messages: [][32]byte{sigRoot},
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ go_library(
|
|||||||
"fake.go",
|
"fake.go",
|
||||||
"initializer.go",
|
"initializer.go",
|
||||||
"interface.go",
|
"interface.go",
|
||||||
|
"message.go",
|
||||||
"mock.go",
|
"mock.go",
|
||||||
"result.go",
|
"result.go",
|
||||||
],
|
],
|
||||||
@@ -20,6 +21,7 @@ go_library(
|
|||||||
"//beacon-chain/core/signing:go_default_library",
|
"//beacon-chain/core/signing:go_default_library",
|
||||||
"//beacon-chain/core/transition:go_default_library",
|
"//beacon-chain/core/transition:go_default_library",
|
||||||
"//beacon-chain/forkchoice/types: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/startup:go_default_library",
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//cache/lru:go_default_library",
|
"//cache/lru:go_default_library",
|
||||||
@@ -29,13 +31,16 @@ go_library(
|
|||||||
"//consensus-types/primitives:go_default_library",
|
"//consensus-types/primitives:go_default_library",
|
||||||
"//crypto/bls:go_default_library",
|
"//crypto/bls:go_default_library",
|
||||||
"//encoding/bytesutil:go_default_library",
|
"//encoding/bytesutil:go_default_library",
|
||||||
|
"//monitoring/tracing:go_default_library",
|
||||||
"//network/forks:go_default_library",
|
"//network/forks:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//runtime/logging:go_default_library",
|
"//runtime/logging:go_default_library",
|
||||||
"//time/slots:go_default_library",
|
"//time/slots:go_default_library",
|
||||||
"@com_github_hashicorp_golang_lru//: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_pkg_errors//:go_default_library",
|
||||||
"@com_github_sirupsen_logrus//:go_default_library",
|
"@com_github_sirupsen_logrus//:go_default_library",
|
||||||
|
"@io_opencensus_go//trace:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
72
beacon-chain/verification/message.go
Normal file
72
beacon-chain/verification/message.go
Normal 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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user