Skip to content

Commit

Permalink
feat: implementing pip-7 (#731)
Browse files Browse the repository at this point in the history
  • Loading branch information
amirvalhalla authored Oct 6, 2023
1 parent cbaa43a commit 76e7568
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 22 deletions.
39 changes: 23 additions & 16 deletions sync/bundle/message/hello.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package message

import (
"fmt"
"time"

"github.com/libp2p/go-libp2p/core/peer"
"github.com/pactus-project/pactus/crypto/bls"
Expand All @@ -12,28 +13,30 @@ import (
)

type HelloMessage struct {
PeerID peer.ID `cbor:"1,keyasint"`
Agent string `cbor:"2,keyasint"`
Moniker string `cbor:"3,keyasint"`
PublicKeys []*bls.PublicKey `cbor:"4,keyasint"`
Signature *bls.Signature `cbor:"5,keyasint"`
Height uint32 `cbor:"6,keyasint"`
Services services.Services `cbor:"7,keyasint"`
GenesisHash hash.Hash `cbor:"8,keyasint"`
BlockHash hash.Hash `cbor:"9,keyasint"`
PeerID peer.ID `cbor:"1,keyasint"`
Agent string `cbor:"2,keyasint"`
Moniker string `cbor:"3,keyasint"`
PublicKeys []*bls.PublicKey `cbor:"4,keyasint"`
Signature *bls.Signature `cbor:"5,keyasint"`
Height uint32 `cbor:"6,keyasint"`
Services services.Services `cbor:"7,keyasint"`
GenesisHash hash.Hash `cbor:"8,keyasint"`
BlockHash hash.Hash `cbor:"9,keyasint"`
MyTimeUnixMilli int64 `cbor:"10,keyasint"`
}

func NewHelloMessage(pid peer.ID, moniker string,
height uint32, services services.Services, blockHash, genesisHash hash.Hash,
) *HelloMessage {
return &HelloMessage{
PeerID: pid,
Agent: version.Agent(),
Moniker: moniker,
GenesisHash: genesisHash,
BlockHash: blockHash,
Height: height,
Services: services,
PeerID: pid,
Agent: version.Agent(),
Moniker: moniker,
GenesisHash: genesisHash,
BlockHash: blockHash,
Height: height,
Services: services,
MyTimeUnixMilli: time.Now().UnixMilli(),
}
}

Expand All @@ -48,6 +51,10 @@ func (m *HelloMessage) BasicCheck() error {
return aggPublicKey.Verify(m.SignBytes(), m.Signature)
}

func (m *HelloMessage) MyTime() time.Time {
return time.UnixMilli(m.MyTimeUnixMilli)
}

func (m *HelloMessage) SignBytes() []byte {
return []byte(fmt.Sprintf("%s:%s:%s:%s", m.Type(), m.Agent, m.PeerID, m.GenesisHash.String()))
}
Expand Down
11 changes: 11 additions & 0 deletions sync/bundle/message/hello_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package message

import (
"testing"
"time"

"github.com/pactus-project/pactus/crypto"
"github.com/pactus-project/pactus/crypto/bls"
Expand Down Expand Up @@ -45,6 +46,16 @@ func TestHelloMessage(t *testing.T) {
assert.Equal(t, errors.Code(m.BasicCheck()), errors.ErrInvalidPublicKey)
})

t.Run("MyTimeUnixMilli of time1 is less or equal than hello message time", func(t *testing.T) {
time1 := time.Now()
myTimeUnixMilli := time1.UnixMilli()

m := NewHelloMessage(ts.RandPeerID(), "Alice", 100, 0, ts.RandHash(), ts.RandHash())

assert.LessOrEqual(t, m.MyTimeUnixMilli, time.Now().UnixMilli())
assert.GreaterOrEqual(t, m.MyTimeUnixMilli, myTimeUnixMilli)
})

t.Run("Ok", func(t *testing.T) {
valKey := ts.RandValKey()
m := NewHelloMessage(ts.RandPeerID(), "Alice", 100, 0, ts.RandHash(), ts.RandHash())
Expand Down
9 changes: 9 additions & 0 deletions sync/handler_hello.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package sync

import (
"fmt"
"math"
"time"

"github.com/libp2p/go-libp2p/core/peer"
"github.com/pactus-project/pactus/sync/bundle"
Expand Down Expand Up @@ -38,6 +40,13 @@ func (handler *helloHandler) ParseMessage(m message.Message, initiator peer.ID)
return handler.acknowledge(response, initiator)
}

if math.Abs(time.Since(msg.MyTime()).Seconds()) > 10 {
response := message.NewHelloAckMessage(message.ResponseCodeRejected,
"time discrepancy exceeds 10 seconds")

return handler.acknowledge(response, initiator)
}

handler.logger.Debug("updating peer info",
"pid", initiator.ShortString(),
"moniker", msg.Moniker,
Expand Down
45 changes: 39 additions & 6 deletions sync/handler_hello_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sync

import (
"testing"
"time"

"github.com/pactus-project/pactus/crypto/bls"
"github.com/pactus-project/pactus/sync/bundle"
Expand Down Expand Up @@ -29,8 +30,8 @@ func TestParsingHelloMessages(t *testing.T) {

assert.NoError(t, td.receivingNewMessage(td.sync, msg, initiator))
assert.Equal(t, td.sync.peerSet.GetPeer(initiator).Status, peerset.StatusCodeBanned)
bundle := td.shouldPublishMessageWithThisType(t, td.network, message.TypeHelloAck)
assert.Equal(t, bundle.Message.(*message.HelloAckMessage).ResponseCode, message.ResponseCodeRejected)
bdl := td.shouldPublishMessageWithThisType(t, td.network, message.TypeHelloAck)
assert.Equal(t, bdl.Message.(*message.HelloAckMessage).ResponseCode, message.ResponseCodeRejected)
})

t.Run("Receiving Hello message from a peer. Genesis hash is wrong.",
Expand All @@ -44,8 +45,40 @@ func TestParsingHelloMessages(t *testing.T) {

assert.NoError(t, td.receivingNewMessage(td.sync, msg, pid))
td.checkPeerStatus(t, pid, peerset.StatusCodeBanned)
bundle := td.shouldPublishMessageWithThisType(t, td.network, message.TypeHelloAck)
assert.Equal(t, bundle.Message.(*message.HelloAckMessage).ResponseCode, message.ResponseCodeRejected)
bdl := td.shouldPublishMessageWithThisType(t, td.network, message.TypeHelloAck)
assert.Equal(t, bdl.Message.(*message.HelloAckMessage).ResponseCode, message.ResponseCodeRejected)
})

t.Run("Receiving Hello message from a peer. Difference is greater or equal than -10 seconds.",
func(t *testing.T) {
valKey := td.RandValKey()
height := td.RandUint32NonZero(td.state.LastBlockHeight())
pid := td.RandPeerID()
msg := message.NewHelloMessage(pid, "kitty", height, services.New(services.Network),
td.state.LastBlockHash(), td.state.Genesis().Hash())
msg.Sign([]*bls.ValidatorKey{valKey})

msg.MyTimeUnixMilli = msg.MyTime().Add(-10 * time.Second).UnixMilli()
assert.NoError(t, td.receivingNewMessage(td.sync, msg, pid))
td.checkPeerStatus(t, pid, peerset.StatusCodeBanned)
bdl := td.shouldPublishMessageWithThisType(t, td.network, message.TypeHelloAck)
assert.Equal(t, bdl.Message.(*message.HelloAckMessage).ResponseCode, message.ResponseCodeRejected)
})

t.Run("Receiving Hello message from a peer. Difference is less or equal than 20 seconds.",
func(t *testing.T) {
valKey := td.RandValKey()
height := td.RandUint32NonZero(td.state.LastBlockHeight())
pid := td.RandPeerID()
msg := message.NewHelloMessage(pid, "kitty", height, services.New(services.Network),
td.state.LastBlockHash(), td.state.Genesis().Hash())
msg.Sign([]*bls.ValidatorKey{valKey})

msg.MyTimeUnixMilli = msg.MyTime().Add(20 * time.Second).UnixMilli()
assert.NoError(t, td.receivingNewMessage(td.sync, msg, pid))
td.checkPeerStatus(t, pid, peerset.StatusCodeBanned)
bdl := td.shouldPublishMessageWithThisType(t, td.network, message.TypeHelloAck)
assert.Equal(t, bdl.Message.(*message.HelloAckMessage).ResponseCode, message.ResponseCodeRejected)
})

t.Run("Receiving Hello message from a peer. It should be acknowledged and updates the peer info",
Expand All @@ -59,8 +92,8 @@ func TestParsingHelloMessages(t *testing.T) {

assert.NoError(t, td.receivingNewMessage(td.sync, msg, pid))

bundle := td.shouldPublishMessageWithThisType(t, td.network, message.TypeHelloAck)
assert.Equal(t, bundle.Message.(*message.HelloAckMessage).ResponseCode, message.ResponseCodeOK)
bdl := td.shouldPublishMessageWithThisType(t, td.network, message.TypeHelloAck)
assert.Equal(t, bdl.Message.(*message.HelloAckMessage).ResponseCode, message.ResponseCodeOK)

// Check if the peer info is updated
p := td.sync.peerSet.GetPeer(pid)
Expand Down

0 comments on commit 76e7568

Please sign in to comment.