Broadcast slashing (#5073)

* add flag
* broadcast slashings
* Merge branch 'master' of github.com:prysmaticlabs/prysm into broadcast_slashing

# Conflicts:
#	beacon-chain/rpc/beacon/slashings_test.go
* fix tests
* goimports
* goimports
* Merge branch 'master' into broadcast_slashing
* Merge branch 'master' into broadcast_slashing
* Merge branch 'master' into broadcast_slashing
This commit is contained in:
shayzluf 2020-03-13 01:59:23 +05:30 committed by GitHub
parent 359e0abe1d
commit f937713fe9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 130 additions and 0 deletions

View File

@ -31,12 +31,14 @@ go_library(
"//beacon-chain/flags:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/slashings:go_default_library",
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/powchain:go_default_library",
"//beacon-chain/state:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/event:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/pagination:go_default_library",
"//shared/params:go_default_library",
@ -81,10 +83,12 @@ go_test(
"//beacon-chain/flags:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/slashings:go_default_library",
"//beacon-chain/p2p/testing:go_default_library",
"//beacon-chain/rpc/testing:go_default_library",
"//beacon-chain/state:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",

View File

@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
)
@ -33,6 +34,7 @@ type Server struct {
StateNotifier statefeed.Notifier
BlockNotifier blockfeed.Notifier
AttestationNotifier operation.Notifier
Broadcaster p2p.Broadcaster
AttestationsPool attestations.Pool
SlashingsPool *slashings.Pool
CanonicalStateChan chan *pbp2p.BeaconState

View File

@ -4,6 +4,7 @@ import (
"context"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@ -23,6 +24,9 @@ func (bs *Server) SubmitProposerSlashing(
if err := bs.SlashingsPool.InsertProposerSlashing(ctx, beaconState, req); err != nil {
return nil, status.Errorf(codes.Internal, "Could not insert proposer slashing into pool: %v", err)
}
if featureconfig.Get().BroadcastSlashings {
bs.Broadcaster.Broadcast(ctx, req)
}
return &ethpb.SubmitSlashingResponse{
SlashedIndices: []uint64{req.ProposerIndex},
}, nil
@ -42,6 +46,9 @@ func (bs *Server) SubmitAttesterSlashing(
if err := bs.SlashingsPool.InsertAttesterSlashing(ctx, beaconState, req); err != nil {
return nil, status.Errorf(codes.Internal, "Could not insert attester slashing into pool: %v", err)
}
if featureconfig.Get().BroadcastSlashings {
bs.Broadcaster.Broadcast(ctx, req)
}
slashedIndices := sliceutil.IntersectionUint64(req.Attestation_1.AttestingIndices, req.Attestation_2.AttestingIndices)
return &ethpb.SubmitSlashingResponse{
SlashedIndices: slashedIndices,

View File

@ -8,6 +8,8 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
mockp2p "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/testutil"
)
@ -24,11 +26,13 @@ func TestServer_SubmitProposerSlashing(t *testing.T) {
t.Fatal(err)
}
mb := &mockp2p.MockBroadcaster{}
bs := &Server{
HeadFetcher: &mock.ChainService{
State: st,
},
SlashingsPool: slashings.NewPool(),
Broadcaster: mb,
}
// We want a proposer slashing for validator with index 2 to
@ -49,6 +53,10 @@ func TestServer_SubmitProposerSlashing(t *testing.T) {
t.Errorf("Wanted %v, received %v", wanted, res)
}
if mb.BroadcastCalled {
t.Errorf("Expected broadcast not to be called by default")
}
slashing, err = testutil.GenerateProposerSlashingForValidator(st, privs[5], uint64(5))
if err != nil {
t.Fatal(err)
@ -61,6 +69,53 @@ func TestServer_SubmitProposerSlashing(t *testing.T) {
}
}
func TestServer_SubmitProposerSlashingBroadcast(t *testing.T) {
ctx := context.Background()
cfg := featureconfig.Get()
cfg.BroadcastSlashings = true
featureconfig.Init(cfg)
defer func() {
cfg.BroadcastSlashings = false
featureconfig.Init(cfg)
}()
st, privs := testutil.DeterministicGenesisState(t, 64)
slashedVal, err := st.ValidatorAtIndex(5)
if err != nil {
t.Fatal(err)
}
// We mark the validator at index 5 as already slashed.
slashedVal.Slashed = true
if err := st.UpdateValidatorAtIndex(5, slashedVal); err != nil {
t.Fatal(err)
}
mb := &mockp2p.MockBroadcaster{}
bs := &Server{
HeadFetcher: &mock.ChainService{
State: st,
},
SlashingsPool: slashings.NewPool(),
Broadcaster: mb,
}
// We want a proposer slashing for validator with index 2 to
// be included in the pool.
slashing, err := testutil.GenerateProposerSlashingForValidator(st, privs[2], uint64(2))
if err != nil {
t.Fatal(err)
}
_, err = bs.SubmitProposerSlashing(ctx, slashing)
if err != nil {
t.Fatal(err)
}
if !mb.BroadcastCalled {
t.Errorf("Expected broadcast to be called")
}
}
func TestServer_SubmitAttesterSlashing(t *testing.T) {
ctx := context.Background()
// We mark the validators at index 5, 6 as already slashed.
@ -76,11 +131,13 @@ func TestServer_SubmitAttesterSlashing(t *testing.T) {
t.Fatal(err)
}
mb := &mockp2p.MockBroadcaster{}
bs := &Server{
HeadFetcher: &mock.ChainService{
State: st,
},
SlashingsPool: slashings.NewPool(),
Broadcaster: mb,
}
slashing, err := testutil.GenerateAttesterSlashingForValidator(st, privs[2], uint64(2))
@ -101,6 +158,9 @@ func TestServer_SubmitAttesterSlashing(t *testing.T) {
if !proto.Equal(wanted, res) {
t.Errorf("Wanted %v, received %v", wanted, res)
}
if mb.BroadcastCalled {
t.Errorf("Expected broadcast not to be called by default")
}
slashing, err = testutil.GenerateAttesterSlashingForValidator(st, privs[5], uint64(5))
if err != nil {
@ -112,3 +172,51 @@ func TestServer_SubmitAttesterSlashing(t *testing.T) {
t.Error("Expected including a attester slashing for an already slashed validator to fail")
}
}
func TestServer_SubmitAttesterSlashingBroadcast(t *testing.T) {
ctx := context.Background()
cfg := featureconfig.Get()
cfg.BroadcastSlashings = true
featureconfig.Init(cfg)
defer func() {
cfg.BroadcastSlashings = false
featureconfig.Init(cfg)
}()
// We mark the validators at index 5, 6 as already slashed.
st, privs := testutil.DeterministicGenesisState(t, 64)
slashedVal, err := st.ValidatorAtIndex(5)
if err != nil {
t.Fatal(err)
}
// We mark the validator at index 5 as already slashed.
slashedVal.Slashed = true
if err := st.UpdateValidatorAtIndex(5, slashedVal); err != nil {
t.Fatal(err)
}
mb := &mockp2p.MockBroadcaster{}
bs := &Server{
HeadFetcher: &mock.ChainService{
State: st,
},
SlashingsPool: slashings.NewPool(),
Broadcaster: mb,
}
slashing, err := testutil.GenerateAttesterSlashingForValidator(st, privs[2], uint64(2))
if err != nil {
t.Fatal(err)
}
// We want the intersection of the slashing attesting indices
// to be slashed, so we expect validators 2 and 3 to be in the response
// slashed indices.
_, err = bs.SubmitAttesterSlashing(ctx, slashing)
if err != nil {
t.Fatal(err)
}
if !mb.BroadcastCalled {
t.Errorf("Expected broadcast to be called when flag is set")
}
}

View File

@ -257,6 +257,7 @@ func (s *Service) Start() {
StateNotifier: s.stateNotifier,
BlockNotifier: s.blockNotifier,
AttestationNotifier: s.operationNotifier,
Broadcaster: s.p2p,
ReceivedAttestationsBuffer: make(chan *ethpb.Attestation, 100),
CollectedAttestationsBuffer: make(chan []*ethpb.Attestation, 100),
}

View File

@ -53,6 +53,9 @@ type Flags struct {
// as the chain head. UNSAFE, use with caution.
DisableForkChoice bool
// BroadcastSlashings enables p2p broadcasting of proposer or attester slashing.
BroadcastSlashings bool
// Cache toggles.
EnableSSZCache bool // EnableSSZCache see https://github.com/prysmaticlabs/prysm/pull/4558.
EnableEth1DataVoteCache bool // EnableEth1DataVoteCache; see https://github.com/prysmaticlabs/prysm/issues/3106.

View File

@ -5,6 +5,10 @@ import (
)
var (
broadcastSlashingFlag = cli.BoolFlag{
Name: "broadcast-slashing",
Usage: "Broadcast slashings from slashing pool.",
}
noCustomConfigFlag = cli.BoolFlag{
Name: "no-custom-config",
Usage: "Run the beacon chain with the real parameters from phase 0.",
@ -293,6 +297,7 @@ var BeaconChainFlags = append(deprecatedFlags, []cli.Flag{
checkHeadState,
enableNoiseHandshake,
dontPruneStateStartUp,
broadcastSlashingFlag,
}...)
// E2EBeaconChainFlags contains a list of the beacon chain feature flags to be tested in E2E.