github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/consensus/pbft/backend/handler_test.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package backend 18 19 import ( 20 "bytes" 21 "fmt" 22 "io/ioutil" 23 "math/big" 24 "testing" 25 "time" 26 27 "github.com/bigzoro/my_simplechain/common" 28 "github.com/bigzoro/my_simplechain/consensus/pbft" 29 "github.com/bigzoro/my_simplechain/core/types" 30 "github.com/bigzoro/my_simplechain/p2p" 31 "github.com/bigzoro/my_simplechain/rlp" 32 lru "github.com/hashicorp/golang-lru" 33 ) 34 35 func TestIstanbulMessage(t *testing.T) { 36 _, backend := newBlockChain(1) 37 38 // generate one msg 39 data := []byte("data1") 40 hash := pbft.RLPHash(data) 41 msg := makeMsg(PbftMsg, data) 42 addr := common.BytesToAddress([]byte("address")) 43 44 // 1. this message should not be in cache 45 // for peers 46 if _, ok := backend.recentMessages.Get(addr); ok { 47 t.Fatalf("the cache of messages for this peer should be nil") 48 } 49 50 // for self 51 if _, ok := backend.knownMessages.Get(hash); ok { 52 t.Fatalf("the cache of messages should be nil") 53 } 54 55 // 2. this message should be in cache after we handle it 56 _, err := backend.HandleMsg(addr, msg) 57 if err != nil { 58 t.Fatalf("handle message failed: %v", err) 59 } 60 // for peers 61 if ms, ok := backend.recentMessages.Get(addr); ms == nil || !ok { 62 t.Fatalf("the cache of messages for this peer cannot be nil") 63 } else if m, ok := ms.(*lru.ARCCache); !ok { 64 t.Fatalf("the cache of messages for this peer cannot be casted") 65 } else if _, ok := m.Get(hash); !ok { 66 t.Fatalf("the cache of messages for this peer cannot be found") 67 } 68 69 // for self 70 if _, ok := backend.knownMessages.Get(hash); !ok { 71 t.Fatalf("the cache of messages cannot be found") 72 } 73 } 74 75 func makeMsg(msgcode uint64, data interface{}) p2p.Msg { 76 size, r, _ := rlp.EncodeToReader(data) 77 return p2p.Msg{Code: msgcode, Size: uint32(size), Payload: r} 78 } 79 80 func TestHandleNewBlockMessage_whenTypical(t *testing.T) { 81 _, backend := newBlockChain(1) 82 arbitraryAddress := common.BytesToAddress([]byte("arbitrary")) 83 arbitraryBlock, arbitraryP2PMessage := buildArbitraryP2PNewBlockMessage(t, false) 84 postAndWait(backend, arbitraryBlock, t) 85 86 handled, err := backend.HandleMsg(arbitraryAddress, arbitraryP2PMessage) 87 88 if err != nil { 89 t.Errorf("expected message being handled successfully but got %s", err) 90 } 91 if !handled { 92 t.Errorf("expected message being handled but not") 93 } 94 if _, err := ioutil.ReadAll(arbitraryP2PMessage.Payload); err != nil { 95 t.Errorf("expected p2p message payload is restored") 96 } 97 } 98 99 func TestHandleNewBlockMessage_whenNotAProposedBlock(t *testing.T) { 100 _, backend := newBlockChain(1) 101 arbitraryAddress := common.BytesToAddress([]byte("arbitrary")) 102 arbitraryBlock, arbitraryP2PMessage := buildArbitraryP2PNewBlockMessage(t, false) 103 104 proposeBlock := types.NewBlock(&types.Header{ 105 Number: big.NewInt(1), 106 Root: common.BytesToHash([]byte("someroot")), 107 GasLimit: 10000, 108 MixDigest: types.PbftDigest, 109 }, nil, nil, nil) 110 111 postAndWait(backend, proposeBlock, t) 112 113 fmt.Println(arbitraryBlock.PendingHash().String()) 114 fmt.Println(proposeBlock.PendingHash().String()) 115 116 handled, err := backend.HandleMsg(arbitraryAddress, arbitraryP2PMessage) 117 118 if err != nil { 119 t.Errorf("expected message being handled successfully but got %s", err) 120 } 121 if handled { 122 t.Errorf("expected message not being handled") 123 } 124 if _, err := ioutil.ReadAll(arbitraryP2PMessage.Payload); err != nil { 125 t.Errorf("expected p2p message payload is restored") 126 } 127 } 128 129 func TestHandleNewBlockMessage_whenFailToDecode(t *testing.T) { 130 _, backend := newBlockChain(1) 131 arbitraryAddress := common.BytesToAddress([]byte("arbitrary")) 132 _, arbitraryP2PMessage := buildArbitraryP2PNewBlockMessage(t, true) 133 postAndWait(backend, types.NewBlock(&types.Header{ 134 Number: big.NewInt(1), 135 GasLimit: 1, 136 MixDigest: types.PbftDigest, 137 }, nil, nil, nil), t) 138 139 handled, err := backend.HandleMsg(arbitraryAddress, arbitraryP2PMessage) 140 141 if err != nil { 142 t.Errorf("expected message being handled successfully but got %s", err) 143 } 144 if handled { 145 t.Errorf("expected message not being handled") 146 } 147 if _, err := ioutil.ReadAll(arbitraryP2PMessage.Payload); err != nil { 148 t.Errorf("expected p2p message payload is restored") 149 } 150 } 151 152 func postAndWait(backend *backend, block *types.Block, t *testing.T) { 153 eventSub := backend.EventMux().Subscribe(pbft.RequestEvent{}) 154 defer eventSub.Unsubscribe() 155 stop := make(chan struct{}, 1) 156 eventLoop := func() { 157 <-eventSub.Chan() 158 // block until handleRequire finished 159 time.Sleep(time.Millisecond * 10) 160 stop <- struct{}{} 161 } 162 go eventLoop() 163 if err := backend.EventMux().Post(pbft.RequestEvent{ 164 Proposal: block, 165 }); err != nil { 166 t.Fatalf("%s", err) 167 } 168 <-stop 169 } 170 171 func buildArbitraryP2PNewBlockMessage(t *testing.T, invalidMsg bool) (*types.Block, p2p.Msg) { 172 arbitraryBlock := types.NewBlock(&types.Header{ 173 Number: big.NewInt(1), 174 GasLimit: 0, 175 MixDigest: types.PbftDigest, 176 }, nil, nil, nil) 177 request := []interface{}{&arbitraryBlock, big.NewInt(1)} 178 if invalidMsg { 179 request = []interface{}{"invalid msg"} 180 } 181 size, r, err := rlp.EncodeToReader(request) 182 if err != nil { 183 t.Fatalf("can't encode due to %s", err) 184 } 185 payload, err := ioutil.ReadAll(r) 186 if err != nil { 187 t.Fatalf("can't read payload due to %s", err) 188 } 189 arbitraryP2PMessage := p2p.Msg{Code: 0x07, Size: uint32(size), Payload: bytes.NewReader(payload)} 190 return arbitraryBlock, arbitraryP2PMessage 191 }