github.com/klaytn/klaytn@v1.10.2/consensus/istanbul/backend/handler_test.go (about) 1 // Copyright 2020 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package backend 18 19 import ( 20 "testing" 21 "time" 22 23 "github.com/stretchr/testify/assert" 24 25 lru "github.com/hashicorp/golang-lru" 26 "github.com/klaytn/klaytn/common" 27 "github.com/klaytn/klaytn/consensus/istanbul" 28 "github.com/klaytn/klaytn/networks/p2p" 29 "github.com/klaytn/klaytn/rlp" 30 ) 31 32 func TestBackend_HandleMsg(t *testing.T) { 33 _, backend := newBlockChain(1) 34 defer backend.Stop() 35 eventSub := backend.istanbulEventMux.Subscribe(istanbul.MessageEvent{}) 36 37 addr := common.StringToAddress("test addr") 38 data := &istanbul.ConsensusMsg{ 39 PrevHash: common.HexToHash("0x1234"), 40 Payload: []byte("test data"), 41 } 42 hash := istanbul.RLPHash(data.Payload) 43 size, payload, _ := rlp.EncodeToReader(data) 44 45 // Success case 46 { 47 msg := p2p.Msg{ 48 Code: IstanbulMsg, 49 Size: uint32(size), 50 Payload: payload, 51 } 52 isHandled, err := backend.HandleMsg(addr, msg) 53 assert.Nil(t, err) 54 assert.True(t, isHandled) 55 56 if err != nil { 57 t.Fatalf("handle message failed: %v", err) 58 } 59 60 recentMsg, ok := backend.recentMessages.Get(addr) 61 assert.True(t, ok) 62 63 cachedMsg, ok := recentMsg.(*lru.ARCCache) 64 assert.True(t, ok) 65 66 value, ok := cachedMsg.Get(hash) 67 assert.True(t, ok) 68 assert.True(t, value.(bool)) 69 70 value, ok = backend.knownMessages.Get(hash) 71 assert.True(t, ok) 72 assert.True(t, value.(bool)) 73 74 evTimer := time.NewTimer(3 * time.Second) 75 defer evTimer.Stop() 76 77 select { 78 case event := <-eventSub.Chan(): 79 switch ev := event.Data.(type) { 80 case istanbul.MessageEvent: 81 assert.Equal(t, data.Payload, ev.Payload) 82 assert.Equal(t, data.PrevHash, ev.Hash) 83 default: 84 t.Fatal("unexpected message type") 85 } 86 case <-evTimer.C: 87 t.Fatal("failed to subscribe istanbul message event") 88 } 89 } 90 91 // Failure case - undefined message code 92 { 93 msg := p2p.Msg{ 94 Code: 0x99, 95 Size: uint32(size), 96 Payload: payload, 97 } 98 isHandled, err := backend.HandleMsg(addr, msg) 99 assert.Equal(t, nil, err) 100 assert.False(t, isHandled) 101 } 102 103 // Failure case - invalid message data 104 { 105 size, payload, _ := rlp.EncodeToReader([]byte{0x1, 0x2}) 106 msg := p2p.Msg{ 107 Code: IstanbulMsg, 108 Size: uint32(size), 109 Payload: payload, 110 } 111 isHandled, err := backend.HandleMsg(addr, msg) 112 assert.Equal(t, errDecodeFailed, err) 113 assert.True(t, isHandled) 114 } 115 116 // Failure case - stopped istanbul engine 117 { 118 msg := p2p.Msg{ 119 Code: IstanbulMsg, 120 Size: uint32(size), 121 Payload: payload, 122 } 123 _ = backend.Stop() 124 isHandled, err := backend.HandleMsg(addr, msg) 125 assert.Equal(t, istanbul.ErrStoppedEngine, err) 126 assert.True(t, isHandled) 127 } 128 } 129 130 func TestBackend_Protocol(t *testing.T) { 131 backend := newTestBackend() 132 assert.Equal(t, IstanbulProtocol, backend.Protocol()) 133 } 134 135 func TestBackend_ValidatePeerType(t *testing.T) { 136 _, backend := newBlockChain(1) 137 defer backend.Stop() 138 139 // Return nil if the input address is a validator 140 { 141 err := backend.ValidatePeerType(backend.address) 142 assert.Nil(t, err) 143 } 144 145 // Return an error if the input address is invalid 146 { 147 err := backend.ValidatePeerType(common.Address{}) 148 assert.Equal(t, errInvalidPeerAddress, err) 149 } 150 151 // Return an error if backend.chain is not set 152 { 153 backend.chain = nil 154 err := backend.ValidatePeerType(backend.address) 155 assert.Equal(t, errNoChainReader, err) 156 } 157 }