github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/consensus/dpos/msg_pool_test.go (about)

     1  // Copyright 2019 The go-vnt Authors
     2  // This file is part of the go-vnt library.
     3  //
     4  // The go-vnt library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-vnt library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-vnt library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package dpos
    18  
    19  import (
    20  	"math/big"
    21  	"testing"
    22  
    23  	"github.com/vntchain/go-vnt/common"
    24  	"github.com/vntchain/go-vnt/core/types"
    25  )
    26  
    27  func TestMsgPool_GetOrNewRoundMsgPool(t *testing.T) {
    28  	// n = 4, f = 1
    29  	quo := 3
    30  	mp := newMsgPool(quo, "test")
    31  	h := big.NewInt(1)
    32  	r := uint32(0)
    33  
    34  	if _, ok := mp.pool[h.Uint64()]; ok {
    35  		t.Errorf("mp should empty")
    36  	}
    37  	if rmp := mp.getOrNewRoundMsgPool(h, r); rmp == nil {
    38  		t.Errorf("rmp should be valid")
    39  	}
    40  
    41  	// should have
    42  	if _, ok := mp.pool[h.Uint64()]; !ok {
    43  		t.Errorf("mp should have h manger")
    44  	}
    45  
    46  	if _, ok := mp.pool[h.Uint64()].pool[r]; !ok {
    47  		t.Errorf("mp should have r manager")
    48  	}
    49  
    50  	// make Pre-prepareMsg as a tag
    51  	mp.pool[h.Uint64()].pool[r].prePreMsg = &types.PreprepareMsg{Round: r, Block: nil}
    52  
    53  	if rmp, err := mp.getRoundMsgPool(h, r); err != nil || rmp == nil {
    54  		t.Errorf("get roundMsgPool failed, %s", err)
    55  	} else {
    56  		if rmp.prePreMsg == nil {
    57  			t.Errorf("pre prepare msg should not be nil")
    58  		} else {
    59  			t.Logf("tag round: %d", rmp.prePreMsg.Round)
    60  		}
    61  	}
    62  }
    63  
    64  func TestMsgPool_AddMsgAndMajoritySuccess(t *testing.T) {
    65  	// n = 4, f = 1
    66  	quo := 3
    67  	mp := newMsgPool(quo, "test")
    68  	h := big.NewInt(1)
    69  	r := uint32(0)
    70  
    71  	header := &types.Header{
    72  		Number:   big.NewInt(0).Set(h),
    73  		Coinbase: common.BytesToAddress([]byte{1}),
    74  	}
    75  	b := types.NewBlock(header, nil, nil)
    76  
    77  	// add 1 pre-prepare msg
    78  	prePre := &types.PreprepareMsg{
    79  		Round: r,
    80  		Block: b,
    81  	}
    82  	if err := mp.addMsg(prePre); err != nil {
    83  		t.Errorf("add pre prepare message error: %s", err)
    84  	}
    85  
    86  	if msg, err := mp.getPrePrepareMsg(h, r); msg == nil || err != nil {
    87  		t.Errorf("should success, but got: %s", err)
    88  	} else {
    89  		t.Logf("msg: %d", msg.Round)
    90  	}
    91  
    92  	header1 := &types.Header{
    93  		Number:   big.NewInt(0).Set(h),
    94  		Coinbase: common.BytesToAddress([]byte{2}),
    95  	}
    96  	b1 := types.NewBlock(header1, nil, nil)
    97  
    98  	prePre1 := &types.PreprepareMsg{
    99  		Round: r,
   100  		Block: b1,
   101  	}
   102  
   103  	// can not add pre-prepare msg again
   104  	if err := mp.addMsg(prePre1); err == nil {
   105  		t.Errorf("Adding pre-premessage the second time should failed")
   106  	}
   107  
   108  	// add 2 prepare message for same block hash
   109  	preMsg := &types.PrepareMsg{
   110  		BlockNumber: h,
   111  		Round:       0,
   112  		BlockHash:   common.HexToHash("503290d0c4dd2d72202521e4701e89daecf048d400b2fbb8cbad1f15a4ec2e8d"),
   113  		PrepareAddr: common.BytesToAddress([]byte{1}),
   114  	}
   115  	if err := mp.addMsg(preMsg); err != nil {
   116  		t.Errorf("should success, but get: %s", err)
   117  	}
   118  	// 相同消息,添加会失败
   119  	if err := mp.addMsg(preMsg); err == nil {
   120  		t.Errorf("Adding same message the second time should failed")
   121  	}
   122  
   123  	preMsg1 := &types.PrepareMsg{
   124  		BlockNumber: h,
   125  		Round:       0,
   126  		BlockHash:   common.HexToHash("503290d0c4dd2d72202521e4701e89daecf048d400b2fbb8cbad1f15a4ec2e8d"),
   127  		PrepareAddr: common.BytesToAddress([]byte{2}),
   128  	}
   129  	if err := mp.addMsg(preMsg1); err != nil {
   130  		t.Errorf("should success, but get: %s", err)
   131  	}
   132  
   133  	// can not get majority prepare message
   134  	if _, err := mp.getTwoThirdMajorityPrepareMsg(h, r); err == nil {
   135  		t.Errorf("should failed, but success")
   136  	}
   137  
   138  	preMsg2 := &types.PrepareMsg{
   139  		BlockNumber: h,
   140  		Round:       0,
   141  		BlockHash:   common.HexToHash("503290d0c4dd2d72202521e4701e89daecf048d400b2fbb8cbad1f15a4ec2e8d"),
   142  		PrepareAddr: common.BytesToAddress([]byte{3}),
   143  	}
   144  	// add 1 prepare message for the same block hash
   145  	if err := mp.addMsg(preMsg2); err != nil {
   146  		t.Errorf("should success, but get: %s", err)
   147  	}
   148  
   149  	// success get majority prepare message
   150  	if msgs, err := mp.getTwoThirdMajorityPrepareMsg(h, r); err != nil {
   151  		t.Errorf("should success, but get: %s", err)
   152  	} else {
   153  		for i, m := range msgs {
   154  			t.Logf("prepare msg: %d, for block: %s", i, m.BlockHash.String())
   155  		}
   156  	}
   157  
   158  	// clean messages of previous height
   159  	_ = mp.cleanMsgOfHeight(h)
   160  
   161  	// below should failed
   162  	if rmp, err := mp.getRoundMsgPool(h, r); rmp != nil || err == nil {
   163  		t.Errorf("should failed, but success")
   164  	}
   165  	if pp, err := mp.getPrePrepareMsg(h, r); pp != nil || err == nil {
   166  		t.Errorf("should failed, but success")
   167  	}
   168  }
   169  
   170  func TestMsgPool_MajorityFail(t *testing.T) {
   171  	// n = 4, f = 1
   172  	quo := 3
   173  	mp := newMsgPool(quo, "test")
   174  	h := big.NewInt(1)
   175  	r := uint32(0)
   176  
   177  	// add 2 prepare message for same block hash
   178  	preMsg := &types.PrepareMsg{
   179  		BlockNumber: h,
   180  		Round:       0,
   181  		BlockHash:   common.HexToHash("503290d0c4dd2d72202521e4701e89daecf048d400b2fbb8cbad1f15a4ec2e8d"),
   182  	}
   183  	if err := mp.addMsg(preMsg); err != nil {
   184  		t.Errorf("should success, but get: %s", err)
   185  	}
   186  	if err := mp.addMsg(preMsg); err == nil {
   187  		t.Errorf("Adding same message the second time should failed")
   188  	}
   189  
   190  	// can not get majority prepare message
   191  	if _, err := mp.getTwoThirdMajorityPrepareMsg(h, r); err == nil {
   192  		t.Errorf("should failed, but success")
   193  	}
   194  
   195  	preMsg1 := &types.PrepareMsg{
   196  		BlockNumber: h,
   197  		Round:       0,
   198  		BlockHash:   common.HexToHash("503290d0c4dd2d72202521e4701e89daecf048d400b2fbb8cbad1f15a4ec2e8d"),
   199  		PrepareAddr: common.BytesToAddress([]byte{2}),
   200  	}
   201  	if err := mp.addMsg(preMsg1); err != nil {
   202  		t.Errorf("should success, but get: %s", err)
   203  	}
   204  
   205  	// get 1 prepare message for the same block hash
   206  	preMsg2 := &types.PrepareMsg{
   207  		BlockNumber: h,
   208  		Round:       0,
   209  		BlockHash:   common.HexToHash("233290d0c4dd2d72202521e4701e89daecf048d400b2fbb8cbad1f15a4ec2e8d"),
   210  		PrepareAddr: common.BytesToAddress([]byte{3}),
   211  	}
   212  	if err := mp.addMsg(preMsg2); err != nil {
   213  		t.Errorf("should success, but get: %s", err)
   214  	}
   215  
   216  	// fail get majority prepare message
   217  	if pms, err := mp.getTwoThirdMajorityPrepareMsg(h, r); pms != nil || err == nil {
   218  		t.Errorf("should fail, but success. err: %v", err)
   219  		for i, m := range pms {
   220  			t.Logf("prepare msg: %d, block: %s\n", i, m.BlockHash.Hex())
   221  		}
   222  	}
   223  }
   224  
   225  func TestMsgPool_cleanOldMessage(t *testing.T) {
   226  	// n = 4, f = 1
   227  	quo := 3
   228  	mp := newMsgPool(quo, "test")
   229  	h1 := big.NewInt(100)
   230  	h2 := big.NewInt(101)
   231  	r := uint32(0)
   232  
   233  	hd1 := &types.Header{
   234  		Number: h1,
   235  	}
   236  	hd2 := &types.Header{
   237  		Number: h2,
   238  	}
   239  	b1 := types.NewBlockWithHeader(hd1)
   240  	b2 := types.NewBlockWithHeader(hd2)
   241  	// add msg of height 100 and 101 to msg pool
   242  	preMsg := &types.PreprepareMsg{
   243  		Block: b1,
   244  		Round: 0,
   245  	}
   246  	if err := mp.addMsg(preMsg); err != nil {
   247  		t.Errorf("should success, but get: %s", err)
   248  	}
   249  	preMsg2 := &types.PreprepareMsg{
   250  		Block: b2,
   251  		Round: 0,
   252  	}
   253  	if err := mp.addMsg(preMsg2); err != nil {
   254  		t.Errorf("should success, but get: %s", err)
   255  	}
   256  
   257  	// 	get preMsg && preMsg2 should success
   258  	if msg, err := mp.getPrePrepareMsg(h1, r); err != nil || msg == nil {
   259  		t.Errorf("Should get preMsg, but failed, err: %s", err)
   260  	} else if msg.Hash() != preMsg.Hash() {
   261  		t.Errorf("want header: %x, got: %x", preMsg.Hash(), msg.Hash())
   262  	}
   263  	if msg, err := mp.getPrePrepareMsg(h2, r); err != nil || msg == nil {
   264  		t.Errorf("Should get preMsg2, but failed, err: %s", err)
   265  	}
   266  
   267  	// clean message
   268  	mp.cleanOldMessage(h1)
   269  
   270  	// get preMsg should failed
   271  	if msg, err := mp.getPrePrepareMsg(h1, r); err == nil || msg != nil {
   272  		t.Errorf("Still get preMsg, cleanOldMessage failed, err: %s, number: %s", err, msg.GetBlockNum().String())
   273  	}
   274  	// 	get preMsg2 should success
   275  	if msg, err := mp.getPrePrepareMsg(h2, r); err != nil || msg == nil {
   276  		t.Errorf("Should still get preMsg2, but failed, err: %s", err)
   277  	}
   278  }
   279  
   280  func TestCleanOldMsg(t *testing.T) {
   281  	// n = 4, f = 1
   282  	quo := 3
   283  	mp := newMsgPool(quo, "test")
   284  
   285  	// less
   286  	preMsg1 := &types.PrepareMsg{
   287  		BlockNumber: big.NewInt(msgCleanInterval - 10),
   288  		Round:       0,
   289  		BlockHash:   common.HexToHash("503290d0c4dd2d72202521e4701e89daecf048d400b2fbb8cbad1f15a4ec2e8d"),
   290  		PrepareAddr: common.BytesToAddress([]byte{2}),
   291  	}
   292  	if err := mp.addMsg(preMsg1); err != nil {
   293  		t.Errorf("should success, but get: %s", err)
   294  	}
   295  
   296  	// equal
   297  	preMsg2 := &types.PrepareMsg{
   298  		BlockNumber: big.NewInt(msgCleanInterval),
   299  		Round:       0,
   300  		BlockHash:   common.HexToHash("503290d0c4dd2d72202521e4701e89daecf048d400b2fbb8cbad1f15a4ec2e8d"),
   301  		PrepareAddr: common.BytesToAddress([]byte{2}),
   302  	}
   303  	if err := mp.addMsg(preMsg2); err != nil {
   304  		t.Errorf("should success, but get: %s", err)
   305  	}
   306  
   307  	// bigger
   308  	preMsg3 := &types.PrepareMsg{
   309  		BlockNumber: big.NewInt(msgCleanInterval + 10),
   310  		Round:       0,
   311  		BlockHash:   common.HexToHash("503290d0c4dd2d72202521e4701e89daecf048d400b2fbb8cbad1f15a4ec2e8d"),
   312  		PrepareAddr: common.BytesToAddress([]byte{2}),
   313  	}
   314  	if err := mp.addMsg(preMsg3); err != nil {
   315  		t.Errorf("should success, but get: %s", err)
   316  	}
   317  
   318  	// clean
   319  	mp.cleanOldMessage(big.NewInt(msgCleanInterval))
   320  
   321  	// check result
   322  	if _, ok := mp.msgHashSet[preMsg1.Hash()]; ok {
   323  		t.Errorf("premsg1 should not exist")
   324  	}
   325  	if rmp, _ := mp.getRoundMsgPool(preMsg1.BlockNumber, 0); rmp != nil {
   326  		t.Errorf("rmp of (%d,%d) should be nil", preMsg1.BlockNumber.Uint64(), preMsg1.Round)
   327  	}
   328  
   329  	if _, ok := mp.msgHashSet[preMsg2.Hash()]; ok {
   330  		t.Errorf("premsg2 should not exist")
   331  	}
   332  	if rmp, _ := mp.getRoundMsgPool(preMsg2.BlockNumber, 0); rmp != nil {
   333  		t.Errorf("rmp of (%d,%d) should be nil", preMsg2.BlockNumber.Uint64(), preMsg2.Round)
   334  	}
   335  
   336  	if _, ok := mp.msgHashSet[preMsg3.Hash()]; !ok {
   337  		t.Errorf("premsg3 should exist, but not, before clean")
   338  	}
   339  	if rmp, _ := mp.getRoundMsgPool(preMsg3.BlockNumber, 0); rmp == nil {
   340  		t.Errorf("rmp of (%d,%d) should be valid, but nil", preMsg3.BlockNumber.Uint64(), preMsg3.Round)
   341  	} else {
   342  		find := false
   343  		if len(rmp.preMsgs) == 0 {
   344  			t.Errorf("round msg pool is empty")
   345  		}
   346  		for _, msg := range rmp.preMsgs {
   347  			if msg.Hash() == preMsg3.Hash() {
   348  				find = true
   349  				break
   350  			}
   351  		}
   352  		if find == false {
   353  			t.Errorf("premsg3 should exist, but not in list")
   354  		}
   355  	}
   356  }