Extract common types from sync (#7843)

* extract common types from sync

* fix tests

* simplify

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
Victor Farazdagi
2020-11-18 07:17:42 +03:00
committed by GitHub
parent fec469291e
commit 7735a083b2
17 changed files with 163 additions and 137 deletions

View File

@@ -3,7 +3,11 @@ load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["types.go"],
srcs = [
"rpc_errors.go",
"rpc_goodbye_codes.go",
"types.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types",
visibility = ["//beacon-chain:__subpackages__"],
deps = [

View File

@@ -0,0 +1,15 @@
package types
import "errors"
var (
ErrWrongForkDigestVersion = errors.New("wrong fork digest version")
ErrInvalidEpoch = errors.New("invalid epoch")
ErrInvalidFinalizedRoot = errors.New("invalid finalized root")
ErrInvalidSequenceNum = errors.New("invalid sequence number provided")
ErrGeneric = errors.New("internal service error")
ErrInvalidParent = errors.New("mismatched parent root")
ErrRateLimited = errors.New("rate limited")
ErrIODeadline = errors.New("i/o deadline exceeded")
ErrInvalidRequest = errors.New("invalid range, step or count")
)

View File

@@ -0,0 +1,40 @@
package types
// RPCGoodbyeCode represents goodbye code, used in sync package.
type RPCGoodbyeCode = SSZUint64
const (
// Spec defined codes.
GoodbyeCodeClientShutdown RPCGoodbyeCode = iota
GoodbyeCodeWrongNetwork
GoodbyeCodeGenericError
// Teku specific codes
GoodbyeCodeUnableToVerifyNetwork = RPCGoodbyeCode(128)
// Lighthouse specific codes
GoodbyeCodeTooManyPeers = RPCGoodbyeCode(129)
GoodbyeCodeBadScore = RPCGoodbyeCode(250)
GoodbyeCodeBanned = RPCGoodbyeCode(251)
)
// GoodbyeCodeMessages defines a mapping between goodbye codes and string messages.
var GoodbyeCodeMessages = map[RPCGoodbyeCode]string{
GoodbyeCodeClientShutdown: "client shutdown",
GoodbyeCodeWrongNetwork: "irrelevant network",
GoodbyeCodeGenericError: "fault/error",
GoodbyeCodeUnableToVerifyNetwork: "unable to verify network",
GoodbyeCodeTooManyPeers: "client has too many peers",
GoodbyeCodeBadScore: "peer score too low",
GoodbyeCodeBanned: "client banned this node",
}
// ErrToGoodbyeCode converts given error to RPC goodbye code.
func ErrToGoodbyeCode(err error) RPCGoodbyeCode {
switch err {
case ErrWrongForkDigestVersion:
return GoodbyeCodeWrongNetwork
default:
return GoodbyeCodeGenericError
}
}

View File

@@ -15,19 +15,6 @@ import (
"github.com/sirupsen/logrus"
)
const genericError = "internal service error"
const rateLimitedError = "rate limited"
const reqError = "invalid range, step or count"
const seqError = "invalid sequence number provided"
const deadlineError = "i/o deadline exceeded"
var errWrongForkDigestVersion = errors.New("wrong fork digest version")
var errInvalidEpoch = errors.New("invalid epoch")
var errInvalidFinalizedRoot = errors.New("invalid finalized root")
var errInvalidSequenceNum = errors.New(seqError)
var errGeneric = errors.New(genericError)
var errInvalidParent = errors.New("mismatched parent root")
var responseCodeSuccess = byte(0x00)
var responseCodeInvalidRequest = byte(0x01)
var responseCodeServerError = byte(0x02)

View File

@@ -15,7 +15,7 @@ import (
dbtest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers"
p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
p2pTypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/rand"
"github.com/prysmaticlabs/prysm/shared/testutil"
@@ -150,9 +150,9 @@ func TestRegularSyncBeaconBlockSubscriber_ProcessPendingBlocks_2Chains(t *testin
if code == 0 {
t.Error("Expected a non-zero code")
}
if errMsg != errWrongForkDigestVersion.Error() {
t.Logf("Received error string len %d, wanted error string len %d", len(errMsg), len(errWrongForkDigestVersion.Error()))
t.Errorf("Received unexpected message response in the stream: %s. Wanted %s.", errMsg, errWrongForkDigestVersion.Error())
if errMsg != p2ptypes.ErrWrongForkDigestVersion.Error() {
t.Logf("Received error string len %d, wanted error string len %d", len(errMsg), len(p2ptypes.ErrWrongForkDigestVersion.Error()))
t.Errorf("Received unexpected message response in the stream: %s. Wanted %s.", errMsg, p2ptypes.ErrWrongForkDigestVersion.Error())
}
})
@@ -374,15 +374,15 @@ func TestService_BatchRootRequest(t *testing.T) {
require.NoError(t, err)
// Send in duplicated roots to also test deduplicaton.
sentRoots := p2pTypes.BeaconBlockByRootsReq{b2Root, b2Root, b3Root, b3Root, b4Root, b5Root}
expectedRoots := p2pTypes.BeaconBlockByRootsReq{b2Root, b3Root, b4Root, b5Root}
sentRoots := p2ptypes.BeaconBlockByRootsReq{b2Root, b2Root, b3Root, b3Root, b4Root, b5Root}
expectedRoots := p2ptypes.BeaconBlockByRootsReq{b2Root, b3Root, b4Root, b5Root}
pcl := protocol.ID("/eth2/beacon_chain/req/beacon_blocks_by_root/1/ssz_snappy")
var wg sync.WaitGroup
wg.Add(1)
p2.BHost.SetStreamHandler(pcl, func(stream network.Stream) {
defer wg.Done()
var out p2pTypes.BeaconBlockByRootsReq
var out p2ptypes.BeaconBlockByRootsReq
assert.NoError(t, p2.Encoding().DecodeWithMaxLength(stream, &out))
assert.DeepEqual(t, expectedRoots, out, "Did not receive expected message")
response := []*ethpb.SignedBeaconBlock{b2, b3, b4, b5}

View File

@@ -9,6 +9,7 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
"github.com/sirupsen/logrus"
"github.com/trailofbits/go-mutexasserts"
)
@@ -81,8 +82,8 @@ func (l *limiter) validateRequest(stream network.Stream, amt uint64) error {
}
if amt > uint64(remaining) {
l.p2p.Peers().Scorers().BadResponsesScorer().Increment(stream.Conn().RemotePeer())
writeErrorResponseToStream(responseCodeInvalidRequest, rateLimitedError, stream, l.p2p)
return errors.New(rateLimitedError)
writeErrorResponseToStream(responseCodeInvalidRequest, p2ptypes.ErrRateLimited.Error(), stream, l.p2p)
return p2ptypes.ErrRateLimited
}
return nil
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
mockp2p "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -42,8 +43,7 @@ func TestRateLimiter_ExceedCapacity(t *testing.T) {
code, errMsg, err := readStatusCodeNoDeadline(stream, p2.Encoding())
require.NoError(t, err, "could not read incoming stream")
assert.Equal(t, responseCodeInvalidRequest, code, "not equal response codes")
assert.Equal(t, rateLimitedError, errMsg, "not equal errors")
assert.Equal(t, p2ptypes.ErrRateLimited.Error(), errMsg, "not equal errors")
})
wg.Add(1)
stream, err := p1.BHost.NewStream(context.Background(), p2.PeerID(), protocol.ID(topic))

View File

@@ -8,6 +8,7 @@ import (
libp2pcore "github.com/libp2p/go-libp2p-core"
"github.com/libp2p/go-libp2p-core/network"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/timeutils"
"github.com/prysmaticlabs/prysm/shared/traceutil"
@@ -73,7 +74,7 @@ func (s *Service) registerRPC(baseTopic string, handle rpcHandler) {
// Check before hand that peer is valid.
if s.p2p.Peers().IsBad(stream.Conn().RemotePeer()) {
closeStream(stream, log)
if err := s.sendGoodByeAndDisconnect(ctx, codeBanned, stream.Conn().RemotePeer()); err != nil {
if err := s.sendGoodByeAndDisconnect(ctx, p2ptypes.GoodbyeCodeBanned, stream.Conn().RemotePeer()); err != nil {
log.Debugf("Could not disconnect from peer: %v", err)
}
return
@@ -100,7 +101,7 @@ func (s *Service) registerRPC(baseTopic string, handle rpcHandler) {
if baseTopic == p2p.RPCMetaDataTopic {
if err := handle(ctx, base, stream); err != nil {
messageFailedProcessingCounter.WithLabelValues(topic).Inc()
if err != errWrongForkDigestVersion {
if err != p2ptypes.ErrWrongForkDigestVersion {
log.WithError(err).Debug("Failed to handle p2p RPC")
}
traceutil.AnnotateError(span, err)
@@ -126,7 +127,7 @@ func (s *Service) registerRPC(baseTopic string, handle rpcHandler) {
}
if err := handle(ctx, msg.Interface(), stream); err != nil {
messageFailedProcessingCounter.WithLabelValues(topic).Inc()
if err != errWrongForkDigestVersion {
if err != p2ptypes.ErrWrongForkDigestVersion {
log.WithError(err).Debug("Failed to handle p2p RPC")
}
traceutil.AnnotateError(span, err)
@@ -140,7 +141,7 @@ func (s *Service) registerRPC(baseTopic string, handle rpcHandler) {
}
if err := handle(ctx, msg.Elem().Interface(), stream); err != nil {
messageFailedProcessingCounter.WithLabelValues(topic).Inc()
if err != errWrongForkDigestVersion {
if err != p2ptypes.ErrWrongForkDigestVersion {
log.WithError(err).Debug("Failed to handle p2p RPC")
}
traceutil.AnnotateError(span, err)

View File

@@ -9,6 +9,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -80,14 +81,14 @@ func (s *Service) beaconBlocksByRangeRPCHandler(ctx context.Context, msg interfa
}
if endSlot-startSlot > rangeLimit {
s.writeErrorResponseToStream(responseCodeInvalidRequest, reqError, stream)
err := errors.New(reqError)
s.writeErrorResponseToStream(responseCodeInvalidRequest, p2ptypes.ErrInvalidRequest.Error(), stream)
err := p2ptypes.ErrInvalidRequest
traceutil.AnnotateError(span, err)
return err
}
err := s.writeBlockRangeToStream(ctx, startSlot, endSlot, m.Step, &prevRoot, stream)
if err != nil && !errors.Is(err, errInvalidParent) {
if err != nil && !errors.Is(err, p2ptypes.ErrInvalidParent) {
return err
}
// Reduce capacity of peer in the rate limiter first.
@@ -97,7 +98,7 @@ func (s *Service) beaconBlocksByRangeRPCHandler(ctx context.Context, msg interfa
}
// Exit in the event we have a disjoint chain to
// return.
if errors.Is(err, errInvalidParent) {
if errors.Is(err, p2ptypes.ErrInvalidParent) {
break
}
@@ -128,7 +129,7 @@ func (s *Service) writeBlockRangeToStream(ctx context.Context, startSlot, endSlo
blks, roots, err := s.db.Blocks(ctx, filter)
if err != nil {
log.WithError(err).Debug("Failed to retrieve blocks")
s.writeErrorResponseToStream(responseCodeServerError, genericError, stream)
s.writeErrorResponseToStream(responseCodeServerError, p2ptypes.ErrGeneric.Error(), stream)
traceutil.AnnotateError(span, err)
return err
}
@@ -137,7 +138,7 @@ func (s *Service) writeBlockRangeToStream(ctx context.Context, startSlot, endSlo
genBlock, genRoot, err := s.retrieveGenesisBlock(ctx)
if err != nil {
log.WithError(err).Debug("Failed to retrieve genesis block")
s.writeErrorResponseToStream(responseCodeServerError, genericError, stream)
s.writeErrorResponseToStream(responseCodeServerError, p2ptypes.ErrGeneric.Error(), stream)
traceutil.AnnotateError(span, err)
return err
}
@@ -148,15 +149,15 @@ func (s *Service) writeBlockRangeToStream(ctx context.Context, startSlot, endSlo
// we only return valid sets of blocks.
blks, roots, err = s.dedupBlocksAndRoots(blks, roots)
if err != nil {
s.writeErrorResponseToStream(responseCodeServerError, genericError, stream)
s.writeErrorResponseToStream(responseCodeServerError, p2ptypes.ErrGeneric.Error(), stream)
traceutil.AnnotateError(span, err)
return err
}
blks, roots = s.sortBlocksAndRoots(blks, roots)
blks, err = s.filterBlocks(ctx, blks, roots, prevRoot, step, startSlot)
if err != nil && err != errInvalidParent {
s.writeErrorResponseToStream(responseCodeServerError, genericError, stream)
if err != nil && err != p2ptypes.ErrInvalidParent {
s.writeErrorResponseToStream(responseCodeServerError, p2ptypes.ErrGeneric.Error(), stream)
traceutil.AnnotateError(span, err)
return err
}
@@ -166,7 +167,7 @@ func (s *Service) writeBlockRangeToStream(ctx context.Context, startSlot, endSlo
}
if chunkErr := s.chunkWriter(stream, b); chunkErr != nil {
log.WithError(chunkErr).Debug("Failed to send a chunked response")
s.writeErrorResponseToStream(responseCodeServerError, genericError, stream)
s.writeErrorResponseToStream(responseCodeServerError, p2ptypes.ErrGeneric.Error(), stream)
traceutil.AnnotateError(span, chunkErr)
return chunkErr
}
@@ -189,20 +190,20 @@ func (s *Service) validateRangeRequest(r *pb.BeaconBlocksByRangeRequest) error {
// Ensure all request params are within appropriate bounds
if count == 0 || count > maxRequestBlocks {
return errors.New(reqError)
return p2ptypes.ErrInvalidRequest
}
if step == 0 || step > rangeLimit {
return errors.New(reqError)
return p2ptypes.ErrInvalidRequest
}
if startSlot > highestExpectedSlot {
return errors.New(reqError)
return p2ptypes.ErrInvalidRequest
}
endSlot := startSlot + (step * (count - 1))
if endSlot-startSlot > rangeLimit {
return errors.New(reqError)
return p2ptypes.ErrInvalidRequest
}
return nil
}
@@ -228,7 +229,7 @@ func (s *Service) filterBlocks(ctx context.Context, blks []*ethpb.SignedBeaconBl
if isRequestedSlotStep && isCanonical {
// Exit early if our valid block is non linear.
if parentValid && isSingular && !isLinear {
return newBlks, errInvalidParent
return newBlks, p2ptypes.ErrInvalidParent
}
newBlks = append(newBlks, blks[i])
// Set the previous root as the

View File

@@ -18,6 +18,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/encoder"
p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -368,7 +369,7 @@ func TestRPCBeaconBlocksByRange_RPCHandlerRateLimitOverflow(t *testing.T) {
for i := 0; i < p2.Peers().Scorers().BadResponsesScorer().Params().Threshold; i++ {
err := sendRequest(p1, p2, r, req, false, true)
assert.ErrorContains(t, rateLimitedError, err)
assert.ErrorContains(t, p2ptypes.ErrRateLimited.Error(), err)
}
remainingCapacity := r.rateLimiter.limiterMap[topic].Remaining(p2.PeerID().String())
@@ -402,7 +403,7 @@ func TestRPCBeaconBlocksByRange_RPCHandlerRateLimitOverflow(t *testing.T) {
// One more request should result in overflow.
for i := 0; i < p2.Peers().Scorers().BadResponsesScorer().Params().Threshold; i++ {
err := sendRequest(p1, p2, r, req, false, false)
assert.ErrorContains(t, rateLimitedError, err)
assert.ErrorContains(t, p2ptypes.ErrRateLimited.Error(), err)
}
remainingCapacity := r.rateLimiter.limiterMap[topic].Remaining(p2.PeerID().String())
@@ -420,7 +421,7 @@ func TestRPCBeaconBlocksByRange_validateRangeRequest(t *testing.T) {
tests := []struct {
name string
req *pb.BeaconBlocksByRangeRequest
expectedError string
expectedError error
errorToLog string
}{
{
@@ -429,7 +430,7 @@ func TestRPCBeaconBlocksByRange_validateRangeRequest(t *testing.T) {
Count: 0,
Step: 1,
},
expectedError: reqError,
expectedError: p2ptypes.ErrInvalidRequest,
errorToLog: "validation did not fail with bad count",
},
{
@@ -438,7 +439,7 @@ func TestRPCBeaconBlocksByRange_validateRangeRequest(t *testing.T) {
Count: params.BeaconNetworkConfig().MaxRequestBlocks + 1,
Step: 1,
},
expectedError: reqError,
expectedError: p2ptypes.ErrInvalidRequest,
errorToLog: "validation did not fail with bad count",
},
{
@@ -455,7 +456,7 @@ func TestRPCBeaconBlocksByRange_validateRangeRequest(t *testing.T) {
Step: 0,
Count: 1,
},
expectedError: reqError,
expectedError: p2ptypes.ErrInvalidRequest,
errorToLog: "validation did not fail with bad step",
},
{
@@ -464,7 +465,7 @@ func TestRPCBeaconBlocksByRange_validateRangeRequest(t *testing.T) {
Step: rangeLimit + 1,
Count: 1,
},
expectedError: reqError,
expectedError: p2ptypes.ErrInvalidRequest,
errorToLog: "validation did not fail with bad step",
},
{
@@ -482,7 +483,7 @@ func TestRPCBeaconBlocksByRange_validateRangeRequest(t *testing.T) {
Step: 1,
Count: 1,
},
expectedError: reqError,
expectedError: p2ptypes.ErrInvalidRequest,
errorToLog: "validation did not fail with bad start slot",
},
{
@@ -491,7 +492,7 @@ func TestRPCBeaconBlocksByRange_validateRangeRequest(t *testing.T) {
Step: 1,
Count: params.BeaconNetworkConfig().MaxRequestBlocks + 1,
},
expectedError: reqError,
expectedError: p2ptypes.ErrInvalidRequest,
errorToLog: "validation did not fail with bad end slot",
},
{
@@ -500,7 +501,7 @@ func TestRPCBeaconBlocksByRange_validateRangeRequest(t *testing.T) {
Step: 3,
Count: uint64(slotsSinceGenesis / 2),
},
expectedError: reqError,
expectedError: p2ptypes.ErrInvalidRequest,
errorToLog: "validation did not fail with bad range",
},
{
@@ -516,8 +517,8 @@ func TestRPCBeaconBlocksByRange_validateRangeRequest(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.expectedError != "" {
assert.ErrorContains(t, tt.expectedError, r.validateRangeRequest(tt.req), tt.errorToLog)
if tt.expectedError != nil {
assert.ErrorContains(t, tt.expectedError.Error(), r.validateRangeRequest(tt.req), tt.errorToLog)
} else {
assert.NoError(t, r.validateRangeRequest(tt.req), tt.errorToLog)
}

View File

@@ -78,7 +78,7 @@ func (s *Service) beaconBlocksRootRPCHandler(ctx context.Context, msg interface{
blk, err := s.db.Block(ctx, root)
if err != nil {
log.WithError(err).Debug("Failed to fetch block")
resp, err := s.generateErrorResponse(responseCodeServerError, genericError)
resp, err := s.generateErrorResponse(responseCodeServerError, types.ErrGeneric.Error())
if err != nil {
log.WithError(err).Debug("Failed to generate a response error")
} else if _, err := stream.Write(resp); err != nil {

View File

@@ -14,46 +14,21 @@ import (
"github.com/sirupsen/logrus"
)
const (
// Spec defined codes
codeClientShutdown types.SSZUint64 = iota
codeWrongNetwork
codeGenericError
// Teku specific codes
codeUnableToVerifyNetwork = types.SSZUint64(128)
// Lighthouse specific codes
codeTooManyPeers = types.SSZUint64(129)
codeBadScore = types.SSZUint64(250)
codeBanned = types.SSZUint64(251)
)
var goodByes = map[types.SSZUint64]string{
codeClientShutdown: "client shutdown",
codeWrongNetwork: "irrelevant network",
codeGenericError: "fault/error",
codeUnableToVerifyNetwork: "unable to verify network",
codeTooManyPeers: "client has too many peers",
codeBadScore: "peer score too low",
codeBanned: "client banned this node",
}
var backOffTime = map[types.SSZUint64]time.Duration{
// Do not dial peers which are from a different/unverifiable
// network.
codeWrongNetwork: 24 * time.Hour,
codeUnableToVerifyNetwork: 24 * time.Hour,
types.GoodbyeCodeWrongNetwork: 24 * time.Hour,
types.GoodbyeCodeUnableToVerifyNetwork: 24 * time.Hour,
// If local peer is banned, we back off for
// 2 hours to let the remote peer score us
// back up again.
codeBadScore: 2 * time.Hour,
codeBanned: 2 * time.Hour,
codeClientShutdown: 1 * time.Hour,
types.GoodbyeCodeBadScore: 2 * time.Hour,
types.GoodbyeCodeBanned: 2 * time.Hour,
types.GoodbyeCodeClientShutdown: 1 * time.Hour,
// Wait 5 minutes before dialing a peer who is
// 'full'
codeTooManyPeers: 5 * time.Minute,
codeGenericError: 2 * time.Minute,
types.GoodbyeCodeTooManyPeers: 5 * time.Minute,
types.GoodbyeCodeGenericError: 2 * time.Minute,
}
// goodbyeRPCHandler reads the incoming goodbye rpc message from the peer.
@@ -83,10 +58,10 @@ func (s *Service) goodbyeRPCHandler(_ context.Context, msg interface{}, stream l
// A custom goodbye method that is used by our connection handler, in the
// event we receive bad peers.
func (s *Service) sendGoodbye(ctx context.Context, id peer.ID) error {
return s.sendGoodByeAndDisconnect(ctx, codeGenericError, id)
return s.sendGoodByeAndDisconnect(ctx, types.GoodbyeCodeGenericError, id)
}
func (s *Service) sendGoodByeAndDisconnect(ctx context.Context, code types.SSZUint64, id peer.ID) error {
func (s *Service) sendGoodByeAndDisconnect(ctx context.Context, code types.RPCGoodbyeCode, id peer.ID) error {
if err := s.sendGoodByeMessage(ctx, code, id); err != nil {
log.WithFields(logrus.Fields{
"error": err,
@@ -96,7 +71,7 @@ func (s *Service) sendGoodByeAndDisconnect(ctx context.Context, code types.SSZUi
return s.p2p.Disconnect(id)
}
func (s *Service) sendGoodByeMessage(ctx context.Context, code types.SSZUint64, id peer.ID) error {
func (s *Service) sendGoodByeMessage(ctx context.Context, code types.RPCGoodbyeCode, id peer.ID) error {
ctx, cancel := context.WithTimeout(ctx, respTimeout)
defer cancel()
@@ -114,17 +89,17 @@ func (s *Service) sendGoodByeMessage(ctx context.Context, code types.SSZUint64,
return nil
}
func goodbyeMessage(num types.SSZUint64) string {
reason, ok := goodByes[num]
func goodbyeMessage(num types.RPCGoodbyeCode) string {
reason, ok := types.GoodbyeCodeMessages[num]
if ok {
return reason
}
return fmt.Sprintf("unknown goodbye value of %d Received", num)
return fmt.Sprintf("unknown goodbye value of %d received", num)
}
// determines which backoff time to use depending on the
// goodbye code provided.
func goodByeBackoff(num types.SSZUint64) time.Time {
func goodByeBackoff(num types.RPCGoodbyeCode) time.Time {
duration, ok := backOffTime[num]
if !ok {
return time.Time{}

View File

@@ -11,7 +11,7 @@ import (
"github.com/libp2p/go-libp2p-core/protocol"
db "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
p2pTypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -43,7 +43,7 @@ func TestGoodByeRPCHandler_Disconnects_With_Peer(t *testing.T) {
})
stream1, err := p1.BHost.NewStream(context.Background(), p2.BHost.ID(), pcl)
require.NoError(t, err)
failureCode := codeClientShutdown
failureCode := p2ptypes.GoodbyeCodeClientShutdown
assert.NoError(t, r.goodbyeRPCHandler(context.Background(), &failureCode, stream1))
@@ -86,7 +86,7 @@ func TestGoodByeRPCHandler_BackOffPeer(t *testing.T) {
})
stream1, err := p1.BHost.NewStream(context.Background(), p2.BHost.ID(), pcl)
require.NoError(t, err)
failureCode := codeClientShutdown
failureCode := p2ptypes.GoodbyeCodeClientShutdown
assert.NoError(t, r.goodbyeRPCHandler(context.Background(), &failureCode, stream1))
@@ -113,7 +113,7 @@ func TestGoodByeRPCHandler_BackOffPeer(t *testing.T) {
stream2, err := p1.BHost.NewStream(context.Background(), p3.BHost.ID(), pcl)
require.NoError(t, err)
failureCode = codeBanned
failureCode = p2ptypes.GoodbyeCodeBanned
assert.NoError(t, r.goodbyeRPCHandler(context.Background(), &failureCode, stream2))
@@ -146,7 +146,7 @@ func TestSendGoodbye_SendsMessage(t *testing.T) {
p2p: p1,
rateLimiter: newRateLimiter(p1),
}
failureCode := codeClientShutdown
failureCode := p2ptypes.GoodbyeCodeClientShutdown
// Setup streams
pcl := protocol.ID("/eth2/beacon_chain/req/goodbye/1/ssz_snappy")
@@ -156,7 +156,7 @@ func TestSendGoodbye_SendsMessage(t *testing.T) {
wg.Add(1)
p2.BHost.SetStreamHandler(pcl, func(stream network.Stream) {
defer wg.Done()
out := new(p2pTypes.SSZUint64)
out := new(p2ptypes.SSZUint64)
assert.NoError(t, r.p2p.Encoding().DecodeWithMaxLength(stream, out))
assert.Equal(t, failureCode, *out)
assert.NoError(t, stream.Close())
@@ -188,7 +188,7 @@ func TestSendGoodbye_DisconnectWithPeer(t *testing.T) {
p2p: p1,
rateLimiter: newRateLimiter(p1),
}
failureCode := codeClientShutdown
failureCode := p2ptypes.GoodbyeCodeClientShutdown
// Setup streams
pcl := protocol.ID("/eth2/beacon_chain/req/goodbye/1/ssz_snappy")
@@ -198,7 +198,7 @@ func TestSendGoodbye_DisconnectWithPeer(t *testing.T) {
wg.Add(1)
p2.BHost.SetStreamHandler(pcl, func(stream network.Stream) {
defer wg.Done()
out := new(p2pTypes.SSZUint64)
out := new(p2ptypes.SSZUint64)
assert.NoError(t, r.p2p.Encoding().DecodeWithMaxLength(stream, out))
assert.Equal(t, failureCode, *out)
assert.NoError(t, stream.Close())

View File

@@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"strings"
libp2pcore "github.com/libp2p/go-libp2p-core"
"github.com/libp2p/go-libp2p-core/helpers"
@@ -33,9 +32,9 @@ func (s *Service) pingHandler(_ context.Context, msg interface{}, stream libp2pc
valid, err := s.validateSequenceNum(*m, stream.Conn().RemotePeer())
if err != nil {
// Descore peer for giving us a bad sequence number.
if errors.Is(err, errInvalidSequenceNum) {
if errors.Is(err, types.ErrInvalidSequenceNum) {
s.p2p.Peers().Scorers().BadResponsesScorer().Increment(stream.Conn().RemotePeer())
s.writeErrorResponseToStream(responseCodeInvalidRequest, seqError, stream)
s.writeErrorResponseToStream(responseCodeInvalidRequest, types.ErrInvalidSequenceNum.Error(), stream)
}
if err := stream.Close(); err != nil {
log.WithError(err).Debug("Failed to close stream")
@@ -76,7 +75,7 @@ func (s *Service) pingHandler(_ context.Context, msg interface{}, stream libp2pc
defer cancel()
md, err := s.sendMetaDataRequest(ctx, stream.Conn().RemotePeer())
if err != nil {
if !strings.Contains(err.Error(), deadlineError) {
if !errors.Is(err, types.ErrIODeadline) {
log.WithField("peer", stream.Conn().RemotePeer()).WithError(err).Debug("Failed to send metadata request")
}
return
@@ -122,7 +121,7 @@ func (s *Service) sendPingRequest(ctx context.Context, id peer.ID) error {
valid, err := s.validateSequenceNum(*msg, stream.Conn().RemotePeer())
if err != nil {
// Descore peer for giving us a bad sequence number.
if errors.Is(err, errInvalidSequenceNum) {
if errors.Is(err, types.ErrInvalidSequenceNum) {
s.p2p.Peers().Scorers().BadResponsesScorer().Increment(stream.Conn().RemotePeer())
}
return err
@@ -151,7 +150,7 @@ func (s *Service) validateSequenceNum(seq types.SSZUint64, id peer.ID) (bool, er
}
// Return error on invalid sequence number.
if md.SeqNumber > uint64(seq) {
return false, errInvalidSequenceNum
return false, types.ErrInvalidSequenceNum
}
return md.SeqNumber == uint64(seq), nil
}

View File

@@ -12,7 +12,7 @@ import (
"github.com/libp2p/go-libp2p-core/protocol"
db "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
p2pTypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -54,13 +54,13 @@ func TestPingRPCHandler_ReceivesPing(t *testing.T) {
p2.BHost.SetStreamHandler(pcl, func(stream network.Stream) {
defer wg.Done()
expectSuccess(t, stream)
out := new(p2pTypes.SSZUint64)
out := new(p2ptypes.SSZUint64)
assert.NoError(t, r.p2p.Encoding().DecodeWithMaxLength(stream, out))
assert.Equal(t, uint64(2), uint64(*out))
})
stream1, err := p1.BHost.NewStream(context.Background(), p2.BHost.ID(), pcl)
require.NoError(t, err)
seqNumber := p2pTypes.SSZUint64(2)
seqNumber := p2ptypes.SSZUint64(2)
assert.NoError(t, r.pingHandler(context.Background(), &seqNumber, stream1))
@@ -117,7 +117,7 @@ func TestPingRPCHandler_SendsPing(t *testing.T) {
wg.Add(1)
p2.BHost.SetStreamHandler(pcl, func(stream network.Stream) {
defer wg.Done()
out := new(p2pTypes.SSZUint64)
out := new(p2ptypes.SSZUint64)
assert.NoError(t, r2.p2p.Encoding().DecodeWithMaxLength(stream, out))
assert.Equal(t, uint64(2), uint64(*out))
assert.NoError(t, r2.pingHandler(context.Background(), out, stream))
@@ -174,14 +174,15 @@ func TestPingRPCHandler_BadSequenceNumber(t *testing.T) {
wg.Add(1)
p2.BHost.SetStreamHandler(pcl, func(stream network.Stream) {
defer wg.Done()
expectFailure(t, responseCodeInvalidRequest, seqError, stream)
expectFailure(t, responseCodeInvalidRequest, p2ptypes.ErrInvalidSequenceNum.Error(), stream)
})
stream1, err := p1.BHost.NewStream(context.Background(), p2.BHost.ID(), pcl)
require.NoError(t, err)
wantedSeq := p2pTypes.SSZUint64(p2.LocalMetadata.SeqNumber)
assert.ErrorContains(t, seqError, r.pingHandler(context.Background(), &wantedSeq, stream1))
wantedSeq := p2ptypes.SSZUint64(p2.LocalMetadata.SeqNumber)
err = r.pingHandler(context.Background(), &wantedSeq, stream1)
assert.ErrorContains(t, p2ptypes.ErrInvalidSequenceNum.Error(), err)
if testutil.WaitTimeout(&wg, 1*time.Second) {
t.Fatal("Did not receive stream within 1 sec")

View File

@@ -15,6 +15,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -42,7 +43,7 @@ func (s *Service) maintainPeerStatuses() {
return
}
if s.p2p.Peers().IsBad(id) {
if err := s.sendGoodByeAndDisconnect(s.ctx, codeGenericError, id); err != nil {
if err := s.sendGoodByeAndDisconnect(s.ctx, p2ptypes.GoodbyeCodeGenericError, id); err != nil {
log.Debugf("Error when disconnecting with bad peer: %v", err)
}
return
@@ -156,8 +157,8 @@ func (s *Service) sendRPCStatusRequest(ctx context.Context, id peer.ID) error {
if err != nil {
s.p2p.Peers().Scorers().BadResponsesScorer().Increment(stream.Conn().RemotePeer())
// Disconnect if on a wrong fork.
if errors.Is(err, errWrongForkDigestVersion) {
if err := s.sendGoodByeAndDisconnect(ctx, codeWrongNetwork, stream.Conn().RemotePeer()); err != nil {
if errors.Is(err, p2ptypes.ErrWrongForkDigestVersion) {
if err := s.sendGoodByeAndDisconnect(ctx, p2ptypes.GoodbyeCodeWrongNetwork, stream.Conn().RemotePeer()); err != nil {
return err
}
}
@@ -204,9 +205,9 @@ func (s *Service) statusRPCHandler(ctx context.Context, msg interface{}, stream
respCode := byte(0)
switch err {
case errGeneric:
case p2ptypes.ErrGeneric:
respCode = responseCodeServerError
case errWrongForkDigestVersion:
case p2ptypes.ErrWrongForkDigestVersion:
// Respond with our status and disconnect with the peer.
s.p2p.Peers().SetChainState(stream.Conn().RemotePeer(), m)
if err := s.respondWithStatus(ctx, stream); err != nil {
@@ -215,7 +216,7 @@ func (s *Service) statusRPCHandler(ctx context.Context, msg interface{}, stream
if err := stream.Close(); err != nil { // Close before disconnecting.
log.WithError(err).Debug("Failed to close stream")
}
if err := s.sendGoodByeAndDisconnect(ctx, codeWrongNetwork, stream.Conn().RemotePeer()); err != nil {
if err := s.sendGoodByeAndDisconnect(ctx, p2ptypes.GoodbyeCodeWrongNetwork, stream.Conn().RemotePeer()); err != nil {
return err
}
return nil
@@ -235,7 +236,7 @@ func (s *Service) statusRPCHandler(ctx context.Context, msg interface{}, stream
if err := stream.Close(); err != nil { // Close before disconnecting.
log.WithError(err).Debug("Failed to close stream")
}
if err := s.sendGoodByeAndDisconnect(ctx, codeGenericError, stream.Conn().RemotePeer()); err != nil {
if err := s.sendGoodByeAndDisconnect(ctx, p2ptypes.GoodbyeCodeGenericError, stream.Conn().RemotePeer()); err != nil {
return err
}
return originalErr
@@ -276,7 +277,7 @@ func (s *Service) validateStatusMessage(ctx context.Context, msg *pb.Status) err
return err
}
if !bytes.Equal(forkDigest[:], msg.ForkDigest) {
return errWrongForkDigestVersion
return p2ptypes.ErrWrongForkDigestVersion
}
genesis := s.chain.GenesisTime()
finalizedEpoch := s.chain.FinalizedCheckpt().Epoch
@@ -288,7 +289,7 @@ func (s *Service) validateStatusMessage(ctx context.Context, msg *pb.Status) err
maxFinalizedEpoch = maxEpoch - 2
}
if msg.FinalizedEpoch > maxFinalizedEpoch {
return errInvalidEpoch
return p2ptypes.ErrInvalidEpoch
}
// Exit early if the peer's finalized epoch
// is less than that of the remote peer's.
@@ -302,14 +303,14 @@ func (s *Service) validateStatusMessage(ctx context.Context, msg *pb.Status) err
return nil
}
if !s.db.IsFinalizedBlock(ctx, bytesutil.ToBytes32(msg.FinalizedRoot)) {
return errInvalidFinalizedRoot
return p2ptypes.ErrInvalidFinalizedRoot
}
blk, err := s.db.Block(ctx, bytesutil.ToBytes32(msg.FinalizedRoot))
if err != nil {
return errGeneric
return p2ptypes.ErrGeneric
}
if blk == nil {
return errGeneric
return p2ptypes.ErrGeneric
}
if helpers.SlotToEpoch(blk.Block.Slot) == msg.FinalizedEpoch {
return nil
@@ -317,12 +318,12 @@ func (s *Service) validateStatusMessage(ctx context.Context, msg *pb.Status) err
startSlot, err := helpers.StartSlot(msg.FinalizedEpoch)
if err != nil {
return errGeneric
return p2ptypes.ErrGeneric
}
if startSlot > blk.Block.Slot {
childBlock, err := s.db.FinalizedChildBlock(ctx, bytesutil.ToBytes32(msg.FinalizedRoot))
if err != nil {
return errGeneric
return p2ptypes.ErrGeneric
}
// Is a valid finalized block if no
// other child blocks exist yet.
@@ -332,9 +333,9 @@ func (s *Service) validateStatusMessage(ctx context.Context, msg *pb.Status) err
// If child finalized block also has a smaller or
// equal slot number we return an error.
if startSlot >= childBlock.Block.Slot {
return errInvalidEpoch
return p2ptypes.ErrInvalidEpoch
}
return nil
}
return errInvalidEpoch
return p2ptypes.ErrInvalidEpoch
}

View File

@@ -18,7 +18,7 @@ import (
testingDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers"
p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
p2pTypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
mockSync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync/testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
@@ -76,9 +76,9 @@ func TestStatusRPCHandler_Disconnects_OnForkVersionMismatch(t *testing.T) {
wg2.Add(1)
p2.BHost.SetStreamHandler(pcl2, func(stream network.Stream) {
defer wg2.Done()
msg := new(p2pTypes.SSZUint64)
msg := new(p2ptypes.SSZUint64)
assert.NoError(t, r.p2p.Encoding().DecodeWithMaxLength(stream, msg))
assert.Equal(t, codeWrongNetwork, *msg)
assert.Equal(t, p2ptypes.GoodbyeCodeWrongNetwork, *msg)
assert.NoError(t, stream.Close())
})
@@ -324,7 +324,7 @@ func TestHandshakeHandlers_Roundtrip(t *testing.T) {
wg2.Add(1)
p2.BHost.SetStreamHandler(pcl, func(stream network.Stream) {
defer wg2.Done()
out := new(p2pTypes.SSZUint64)
out := new(p2ptypes.SSZUint64)
assert.NoError(t, r.p2p.Encoding().DecodeWithMaxLength(stream, out))
assert.Equal(t, uint64(2), uint64(*out))
assert.NoError(t, r2.pingHandler(context.Background(), out, stream))