Skip to content

Commit

Permalink
Merge branch 'EN-4575-heartbeat-properties-long' into rc-BoN-v1033
Browse files Browse the repository at this point in the history
  • Loading branch information
iulianpascalau committed Oct 22, 2019
2 parents 167e8d3 + 94d38b9 commit ddc2942
Show file tree
Hide file tree
Showing 8 changed files with 334 additions and 16 deletions.
1 change: 1 addition & 0 deletions cmd/node/config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
StatusPollingIntervalSec = 2

# NodeDisplayName represents the friendly name a user can pick for his node in the status monitor
# Max Length should be less than 128 bytes
NodeDisplayName = ""

[Explorer]
Expand Down
77 changes: 61 additions & 16 deletions integrationTests/node/heartbeat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package node
import (
"context"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"testing"
Expand All @@ -14,6 +13,7 @@ import (
"github.com/ElrondNetwork/elrond-go/crypto/signing/kyber"
"github.com/ElrondNetwork/elrond-go/crypto/signing/kyber/singlesig"
"github.com/ElrondNetwork/elrond-go/integrationTests"
"github.com/ElrondNetwork/elrond-go/marshal"
"github.com/ElrondNetwork/elrond-go/node/heartbeat"
"github.com/ElrondNetwork/elrond-go/node/mock"
"github.com/ElrondNetwork/elrond-go/p2p"
Expand All @@ -33,10 +33,10 @@ func TestHeartbeatMonitorWillUpdateAnInactivePeer(t *testing.T) {
advertiser := integrationTests.CreateMessengerWithKadDht(context.Background(), "")
_ = advertiser.Bootstrap()
advertiserAddr := integrationTests.GetConnectableAddress(advertiser)
maxUnresposiveTime := time.Second * 2
maxUnresposiveTime := time.Second * 10

monitor := createMonitor(maxUnresposiveTime)
nodes, senders, pks := prepareNodes(advertiserAddr, monitor)
nodes, senders, pks := prepareNodes(advertiserAddr, monitor, 3, "nodeName")

defer func() {
_ = advertiser.Close()
Expand Down Expand Up @@ -69,13 +69,61 @@ func TestHeartbeatMonitorWillUpdateAnInactivePeer(t *testing.T) {
checkReceivedMessages(t, monitor, pks, []int{0})
}

func TestHeartbeatMonitorWillNotUpdateTooLongHeartbeatMessages(t *testing.T) {
if testing.Short() {
t.Skip("this is not a short test")
}

advertiser := integrationTests.CreateMessengerWithKadDht(context.Background(), "")
_ = advertiser.Bootstrap()
advertiserAddr := integrationTests.GetConnectableAddress(advertiser)
maxUnresposiveTime := time.Second * 10

length := 129
buff := make([]byte, length)

for i := 0; i < length; i++ {
buff[i] = byte(97)
}
bigNodeName := string(buff)

monitor := createMonitor(maxUnresposiveTime)
nodes, senders, pks := prepareNodes(advertiserAddr, monitor, 3, bigNodeName)

defer func() {
_ = advertiser.Close()
for _, n := range nodes {
_ = n.Close()
}
}()

fmt.Println("Delaying for node bootstrap and topic announcement...")
time.Sleep(time.Second * 5)

fmt.Println("Sending first messages from both public keys...")
_ = senders[1].SendHeartbeat()

time.Sleep(stepDelay)

secondPK := pks[1]

pkHeartBeats := monitor.GetHeartbeats()

assert.True(t, isPkActive(pkHeartBeats, secondPK))
expectedLen := 128
nodeName := pkHeartBeats[1].NodeDisplayName
actualLen := len(nodeName)
assert.Equal(t, expectedLen, actualLen)
}

func prepareNodes(
advertiserAddr string,
monitor *heartbeat.Monitor,
interactingNodes int,
defaultNodeName string,
) ([]p2p.Messenger, []*heartbeat.Sender, []crypto.PublicKey) {

senderIdxs := []int{0, 1}
interactingNodes := 3
nodes := make([]p2p.Messenger, interactingNodes)
topicHeartbeat := "topic"
senders := make([]*heartbeat.Sender, 0)
Expand All @@ -87,7 +135,7 @@ func prepareNodes(

isSender := integrationTests.IsIntInSlice(i, senderIdxs)
if isSender {
sender, pk := createSender(nodes[i], topicHeartbeat)
sender, pk := createSenderWithName(nodes[i], topicHeartbeat, defaultNodeName)
senders = append(senders, sender)
pks = append(pks, pk)
} else {
Expand Down Expand Up @@ -139,14 +187,12 @@ func isPkActive(heartbeats []heartbeat.PubKeyHeartbeat, pk crypto.PublicKey) boo
return false
}

func createSender(messenger p2p.Messenger, topic string) (*heartbeat.Sender, crypto.PublicKey) {
func createSenderWithName(messenger p2p.Messenger, topic string, nodeName string) (*heartbeat.Sender, crypto.PublicKey) {
suite := kyber.NewBlakeSHA256Ed25519()
signer := &singlesig.SchnorrSigner{}
keyGen := signing.NewKeyGenerator(suite)
sk, pk := keyGen.GeneratePair()

version := "v01"
nodeName := "nodeName"
sender, _ := heartbeat.NewSender(
messenger,
signer,
Expand All @@ -157,24 +203,23 @@ func createSender(messenger p2p.Messenger, topic string) (*heartbeat.Sender, cry
version,
nodeName,
)

return sender, pk
}

func createMonitor(maxDurationPeerUnresponsive time.Duration) *heartbeat.Monitor {
suite := kyber.NewBlakeSHA256Ed25519()
singlesigner := &singlesig.SchnorrSigner{}
keyGen := signing.NewKeyGenerator(suite)
marshalizer := &marshal.JsonMarshalizer{}

mp, _ := heartbeat.NewMessageProcessor(singlesigner, keyGen, marshalizer)

monitor, _ := heartbeat.NewMonitor(
integrationTests.TestMarshalizer,
maxDurationPeerUnresponsive,
map[uint32][]string{0: {""}},
time.Now(),
&mock.MessageHandlerStub{
CreateHeartbeatFromP2pMessageCalled: func(message p2p.MessageP2P) (*heartbeat.Heartbeat, error) {
var hb heartbeat.Heartbeat
_ = json.Unmarshal(message.Data(), &hb)
return &hb, nil
},
},
mp,
&mock.HeartbeatStorerStub{
UpdateGenesisTimeCalled: func(genesisTime time.Time) error {
return nil
Expand Down
3 changes: 3 additions & 0 deletions node/heartbeat/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,6 @@ var ErrUnmarshalGenesisTime = errors.New("monitor: can't unmarshal genesis time"

// ErrMarshalGenesisTime signals that the marshaling of the genesis time didn't work
var ErrMarshalGenesisTime = errors.New("monitor: can't marshal genesis time")

// ErrPropertyTooLong signals that one of the properties is too long
var ErrPropertyTooLong = errors.New("Property Too Long in Heartbeat")
8 changes: 8 additions & 0 deletions node/heartbeat/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,11 @@ func (hbmi *heartbeatMessageInfo) GetTotalDownTime() Duration {
func (hbmi *heartbeatMessageInfo) GetIsActive() bool {
return hbmi.isActive
}

func Verify(hbmi *Heartbeat) error {
return verifyLengths(hbmi)
}

func GetMaxSizeInBytes() int {
return maxSizeInBytes
}
28 changes: 28 additions & 0 deletions node/heartbeat/heartbeatMessageValidator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package heartbeat

const maxSizeInBytes = 128

func verifyLengths(heartbeat *Heartbeat) error {
if len(heartbeat.Pubkey) > maxSizeInBytes ||
len(heartbeat.Payload) > maxSizeInBytes ||
len(heartbeat.NodeDisplayName) > maxSizeInBytes ||
len(heartbeat.VersionNumber) > maxSizeInBytes ||
len(heartbeat.Signature) > maxSizeInBytes {
return ErrPropertyTooLong
}
return nil
}

func trimLengths(heartbeat *Heartbeat) {
if len(heartbeat.Payload) > maxSizeInBytes {
heartbeat.Payload = heartbeat.Payload[:maxSizeInBytes]
}

if len(heartbeat.NodeDisplayName) > maxSizeInBytes {
heartbeat.NodeDisplayName = heartbeat.NodeDisplayName[:maxSizeInBytes]
}

if len(heartbeat.VersionNumber) > maxSizeInBytes {
heartbeat.VersionNumber = heartbeat.VersionNumber[:maxSizeInBytes]
}
}
5 changes: 5 additions & 0 deletions node/heartbeat/messageProcessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ func (mp *MessageProcessor) CreateHeartbeatFromP2pMessage(message p2p.MessageP2P
return nil, err
}

err = verifyLengths(hbRecv)
if err != nil {
return nil, err
}

err = mp.verifySignature(hbRecv)
if err != nil {
return nil, err
Expand Down
Loading

0 comments on commit ddc2942

Please sign in to comment.