Skip to content

Commit

Permalink
add unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
bysomeone committed May 8, 2024
1 parent 945997c commit feabc26
Show file tree
Hide file tree
Showing 9 changed files with 352 additions and 36 deletions.
3 changes: 1 addition & 2 deletions system/consensus/snowman/blankvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,5 @@ func (*blankVM) Version(context.Context) (string, error) {

func recordUnimplementedError(funcName string) {

snowLog.Error("Call unimplemented function", "func", funcName)
panic("")
snowLog.Error("Call unimplemented function", "func", funcName, "stack", getStack())
}
2 changes: 1 addition & 1 deletion system/consensus/snowman/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (

func newSnowmanConfig(sm *snowman, params snowball.Parameters, snowCtx *snow.ConsensusContext) smeng.Config {

sender := newMsgSender(sm, snowCtx)
sender := newMsgSender(sm.vs, sm.ctx.Base.GetQueueClient(), snowCtx)
engineConfig := smeng.Config{
Ctx: snowCtx,
VM: sm.vm,
Expand Down
29 changes: 14 additions & 15 deletions system/consensus/snowman/sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ import (
// 向外部模块发送请求, blockchain/p2p等
type msgSender struct {
common.Sender
cli client.Client
sm *snowman
cli client.Client
vdrs *vdrSet
}

func newMsgSender(sm *snowman, snowCtx *snow.ConsensusContext) *msgSender {
func newMsgSender(vdrs *vdrSet, cli client.Client, snowCtx *snow.ConsensusContext) *msgSender {

s := &msgSender{sm: sm}
s.cli = sm.ctx.Base.GetQueueClient()
s := &msgSender{vdrs: vdrs, cli: cli}
sd, err := sender.New(snowCtx, nil, nil, nil, nil, p2p.EngineType_ENGINE_TYPE_SNOWMAN, nil)

if err != nil {
Expand All @@ -40,9 +39,9 @@ func newMsgSender(sm *snowman, snowCtx *snow.ConsensusContext) *msgSender {
}

// SendChits send chits to the specified node
func (s *msgSender) SendChits(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredID ids.ID, acceptedID ids.ID) {
func (s *msgSender) SendChits(_ context.Context, nodeID ids.NodeID, requestID uint32, preferredID ids.ID, acceptedID ids.ID) {

peerName := s.sm.vs.toLibp2pID(nodeID)
peerName := s.vdrs.toLibp2pID(nodeID)
snowLog.Debug("msgSender SendChits", "reqID", requestID, "peer", peerName,
"preferHash", hex.EncodeToString(preferredID[:]),
"acceptHash", hex.EncodeToString(acceptedID[:]))
Expand All @@ -64,9 +63,9 @@ func (s *msgSender) SendChits(ctx context.Context, nodeID ids.NodeID, requestID
}

// SendGet Request that the specified node send the specified container to this node.
func (s *msgSender) SendGet(ctx context.Context, nodeID ids.NodeID, requestID uint32, blockID ids.ID) {
func (s *msgSender) SendGet(_ context.Context, nodeID ids.NodeID, requestID uint32, blockID ids.ID) {

peerName := s.sm.vs.toLibp2pID(nodeID)
peerName := s.vdrs.toLibp2pID(nodeID)
snowLog.Debug("msgSender SendGet", "reqID", requestID, "peer", peerName, "blkHash", hex.EncodeToString(blockID[:]))
req := &types.SnowGetBlock{
RequestID: requestID,
Expand All @@ -83,9 +82,9 @@ func (s *msgSender) SendGet(ctx context.Context, nodeID ids.NodeID, requestID ui
}

// SendPut Tell the specified node about [container].
func (s *msgSender) SendPut(ctx context.Context, nodeID ids.NodeID, requestID uint32, blkData []byte) {
func (s *msgSender) SendPut(_ context.Context, nodeID ids.NodeID, requestID uint32, blkData []byte) {

peerName := s.sm.vs.toLibp2pID(nodeID)
peerName := s.vdrs.toLibp2pID(nodeID)
snowLog.Debug("msgSender SendPut", "reqID", requestID, "peer", peerName)
req := &types.SnowPutBlock{
RequestID: requestID,
Expand All @@ -101,7 +100,7 @@ func (s *msgSender) SendPut(ctx context.Context, nodeID ids.NodeID, requestID ui
}

// SendPullQuery Request from the specified nodes their preferred frontier, given the existence of the specified container.
func (s *msgSender) SendPullQuery(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, blockID ids.ID) {
func (s *msgSender) SendPullQuery(_ context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, blockID ids.ID) {

snowLog.Debug("msgSender SendPullQuery", "reqID", requestID, "peerLen", nodeIDs.Len(),
"blkHash", hex.EncodeToString(blockID[:]))
Expand All @@ -111,7 +110,7 @@ func (s *msgSender) SendPullQuery(ctx context.Context, nodeIDs set.Set[ids.NodeI
req := &types.SnowPullQuery{
RequestID: requestID,
BlockHash: blockID[:],
PeerName: s.sm.vs.toLibp2pID(nodeID),
PeerName: s.vdrs.toLibp2pID(nodeID),
}

msg := s.cli.NewMessage("p2p", types.EventSnowmanPullQuery, req)
Expand All @@ -128,7 +127,7 @@ func (s *msgSender) SendPullQuery(ctx context.Context, nodeIDs set.Set[ids.NodeI
// existence of the specified container.
// This is the same as PullQuery, except that this message includes the body
// of the container rather than its ID.
func (s *msgSender) SendPushQuery(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, blockData []byte) {
func (s *msgSender) SendPushQuery(_ context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, blockData []byte) {

snowLog.Debug("msgSender SendPushQuery", "reqID", requestID, "peerLen", nodeIDs.Len())

Expand All @@ -137,7 +136,7 @@ func (s *msgSender) SendPushQuery(ctx context.Context, nodeIDs set.Set[ids.NodeI
req := &types.SnowPushQuery{
RequestID: requestID,
BlockData: blockData,
PeerName: s.sm.vs.toLibp2pID(nodeID),
PeerName: s.vdrs.toLibp2pID(nodeID),
}

msg := s.cli.NewMessage("p2p", types.EventSnowmanPushQuery, req)
Expand Down
72 changes: 72 additions & 0 deletions system/consensus/snowman/sender_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package snowman

import (
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/types"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/bag"
"github.com/ava-labs/avalanchego/utils/set"
"github.com/stretchr/testify/require"
"testing"
)

func TestMsgSender(t *testing.T) {

q := queue.New("test")
cli := q.Client()
v := &vdrSet{}
v.init(nil, cli)
s := newMsgSender(v, cli, newSnowContext(types.NewChain33Config(types.GetDefaultCfgstring())))
defer cli.Close()
peer := "testpeer"
nodeID, err := v.toNodeID(peer)
require.Nil(t, err)

go func() {
cli.Sub("p2p")
var reqID, checkID uint32
var checkName string
for msg := range cli.Recv() {
reqID++
if msg.Ty == types.EventSnowmanChits {
req := msg.Data.(*types.SnowChits)
checkID = req.GetRequestID()
checkName = req.GetPeerName()
}else if msg.Ty == types.EventSnowmanPutBlock {
req := msg.Data.(*types.SnowPutBlock)
checkID = req.GetRequestID()
checkName = req.GetPeerName()
}else if msg.Ty == types.EventSnowmanGetBlock{
req := msg.Data.(*types.SnowGetBlock)
checkID = req.GetRequestID()
checkName = req.GetPeerName()
}else if msg.Ty == types.EventSnowmanPullQuery {
req := msg.Data.(*types.SnowPullQuery)
checkID = req.GetRequestID()
checkName = req.GetPeerName()

}else if msg.Ty == types.EventSnowmanPushQuery {
req := msg.Data.(*types.SnowPushQuery)
checkID = req.GetRequestID()
checkName = req.GetPeerName()
}

require.Equal(t, peer, checkName)
require.Equal(t, reqID, checkID)
}
}()

s.SendChits(nil, nodeID, 1, ids.Empty, ids.Empty)
s.SendGet(nil, nodeID, 2, ids.Empty)
s.SendPut(nil, nodeID, 3, nil)
vdrBag := bag.Bag[ids.NodeID]{}
vdrBag.Add(nodeID)
nodeIDs := set.Of(vdrBag.List()...)
s.SendPullQuery(nil, nodeIDs, 4, ids.Empty)
s.SendPushQuery(nil, nodeIDs, 5, nil)

// test unimplented method
s.SendGossip(nil, nil)
s.SendGetAncestors(nil, ids.EmptyNodeID, 0, ids.Empty)
s.SendAncestors(nil, ids.EmptyNodeID, 0, nil)
}
13 changes: 10 additions & 3 deletions system/consensus/snowman/snowman.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (s *snowman) Initialize(ctx *consensus.Context) {
s.vm.Init(ctx)

s.vs = &vdrSet{}
s.vs.init(ctx)
s.vs.init(ctx, ctx.Base.GetQueueClient())
s.initSnowEngine()

s.inMsg = make(chan *queue.Message, 1024)
Expand Down Expand Up @@ -119,9 +119,16 @@ func (s *snowman) startRoutine() {

func (s *snowman) AddBlock(blk *types.Block) {

if s.vm.addNewBlock(blk) {
s.engineNotify <- struct{}{}
if !s.vm.addNewBlock(blk) {
return
}

select {
case s.engineNotify <- struct{}{}:
default:

}

}

func (s *snowman) SubMsg(msg *queue.Message) {
Expand Down
26 changes: 17 additions & 9 deletions system/consensus/snowman/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package snowman

import (
"fmt"
"github.com/33cn/chain33/queue"
"math/rand"
"sync"
"time"
Expand All @@ -16,16 +17,18 @@ import (
type vdrSet struct {
validators.Set
ctx *consensus.Context
qclient queue.Client
self *types.Peer
peerIDs map[ids.NodeID]string
lock sync.RWMutex
rand *rand.Rand
}

func (s *vdrSet) init(ctx *consensus.Context) {
func (s *vdrSet) init(ctx *consensus.Context, cli queue.Client) {

s.Set = validators.NewSet()
s.ctx = ctx
s.qclient = cli
s.rand = rand.New(rand.NewSource(types.Now().Unix()))
s.peerIDs = make(map[ids.NodeID]string)
}
Expand All @@ -46,7 +49,7 @@ func (s *vdrSet) Sample(size int) ([]ids.NodeID, error) {

snowLog.Debug("vdrSet Sample", "require", size)
peers, err := s.getConnectedPeers()
if err != nil || len(peers) < size {
if err != nil || len(peers) < size || size <= 0 {
snowLog.Error("vdrSet Sample", "connected", len(peers), "require", size, "err", err)
return nil, utils.ErrValidatorSample
}
Expand Down Expand Up @@ -78,13 +81,13 @@ func (s *vdrSet) Sample(size int) ([]ids.NodeID, error) {

func (s *vdrSet) getConnectedPeers() ([]*types.Peer, error) {
snowLog.Debug("vdrSet getConnectedPeers")
msg := s.ctx.Base.GetQueueClient().NewMessage("p2p", types.EventPeerInfo, nil)
err := s.ctx.Base.GetQueueClient().Send(msg, true)
msg := s.qclient.NewMessage("p2p", types.EventPeerInfo, nil)
err := s.qclient.Send(msg, true)
if err != nil {
snowLog.Error("getConnectedPeers", "client.Send err:", err)
return nil, err
}
resp, err := s.ctx.Base.GetQueueClient().WaitTimeout(msg, 5*time.Second)
resp, err := s.qclient.WaitTimeout(msg, 5*time.Second)
if err != nil {
snowLog.Error("getConnectedPeers", "client.Wait err:", err)
return nil, err
Expand All @@ -101,8 +104,7 @@ func (s *vdrSet) getConnectedPeers() ([]*types.Peer, error) {
for _, p := range peerlist.GetPeers() {

if p.Self || p.Blocked ||
p.Header.GetHeight() < s.self.Finalized.GetHeight() ||
p.GetFinalized().GetHeight() < s.self.Finalized.GetHeight()-128 {
p.GetFinalized().GetHeight() < s.self.GetHeader().GetHeight()-128 {
continue
}
peers = append(peers, p)
Expand All @@ -123,8 +125,14 @@ func (s *vdrSet) toLibp2pID(id ids.NodeID) string {

func (s *vdrSet) toNodeID(id string) (ids.NodeID, error) {

shortID := id[:10] + id[len(id)-10:]
nid, err := ids.ToNodeID([]byte(shortID))
if id == "" {
return ids.EmptyNodeID, types.ErrInvalidParam
}
tempID := id
for len(tempID) < 20 {
tempID += tempID
}
nid, err := ids.ToNodeID([]byte(tempID[len(tempID)-20:]))
if err != nil {
return ids.EmptyNodeID, err
}
Expand Down
93 changes: 93 additions & 0 deletions system/consensus/snowman/validator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package snowman

import (
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/system/consensus/snowman/utils"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/require"
"strings"
"testing"
)

func TestNodeID(t *testing.T) {

v := &vdrSet{}
v.init(nil, nil)
peer := "16Uiu2HAmVXKApGkrdWMvJPKx8QQzcnLafETiHefzGxjBS163LD1k"

id, err := v.toNodeID(peer)
require.Nil(t, err)
ids := id.String()
require.True(t, strings.Contains(ids, peer[len(peer)-20:]))

ps := v.toLibp2pID(id)
require.Equal(t, peer, ps)
require.Equal(t, 1, v.Len())
_, err = v.toNodeID("")
require.Equal(t, types.ErrInvalidParam, err)
_, err = v.toNodeID("1")
require.Nil(t, err)
}

func Test_getConnectedPeers(t *testing.T) {

v := &vdrSet{}

q := queue.New("test")
cli := q.Client()
v.init(nil, cli)
defer cli.Close()
list := &types.PeerList{}
go func() {
cli.Sub("p2p")

for msg := range cli.Recv() {

if msg.Ty == types.EventPeerInfo {
msg.Reply(cli.NewMessage("", 0, list))
}
}
}()

self := &types.Peer{Self: true, Header: &types.Header{Height: 129}}


list.Peers = []*types.Peer{self}
peers, err := v.getConnectedPeers()
require.Nil(t, err)
require.Nil(t, peers)
peer := &types.Peer{Name: "peer", Header: &types.Header{}, Finalized: &types.SnowChoice{}, Blocked: true}

list.Peers = []*types.Peer{peer, self}
peers, err = v.getConnectedPeers()
require.Nil(t, err)
require.Equal(t, 0, len(peers))
peer.Blocked = false
peers, err = v.getConnectedPeers()
require.Nil(t, err)
require.Equal(t, 0, len(peers))
peer.Finalized.Height = 1

peers, err = v.getConnectedPeers()
require.Nil(t, err)
require.Equal(t, 1, len(peers))
require.Equal(t, peer, peers[0])

// test sample
_, err = v.Sample(2)
require.Equal(t, utils.ErrValidatorSample, err)
_, err = v.Sample(0)
require.Equal(t, utils.ErrValidatorSample, err)
peer1 := *peer
peer1.Name = "peer1"
list.Peers = []*types.Peer{peer,&peer1, self}
ids, err := v.Sample(2)
require.Nil(t, err)
require.Equal(t, 2, len(ids))
}

func TestVdrSetUnimplented(t *testing.T) {
v := &vdrSet{}
_ = v.String()
v.RegisterCallbackListener(nil)
}
Loading

0 comments on commit feabc26

Please sign in to comment.