github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/consensus/pbft/core/lightprepare_test.go (about) 1 // Copyright 2020 The go-simplechain Authors 2 // This file is part of the go-simplechain library. 3 // 4 // The go-simplechain 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-simplechain 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-simplechain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "github.com/bigzoro/my_simplechain/core/types" 21 "github.com/bigzoro/my_simplechain/crypto" 22 "math/big" 23 "reflect" 24 "testing" 25 26 "github.com/bigzoro/my_simplechain/consensus/pbft" 27 ) 28 29 func TestHandleLightPreprepare(t *testing.T) { 30 N := uint64(4) // replica 0 is the proposer, it will send messages to others 31 F := uint64(1) // F does not affect tests 32 33 signer := types.NewEIP155Signer(big.NewInt(110)) 34 key, _ := crypto.GenerateKey() 35 36 testCases := []struct { 37 system *testSystem 38 expectedRequest pbft.Proposal 39 expectedErr error 40 existingBlock bool 41 }{ 42 { 43 // empty proposal case 44 func() *testSystem { 45 sys := NewTestSystemWithBackend(N, F) 46 for i, backend := range sys.backends { 47 c := backend.engine.(*core) 48 c.valSet = backend.peers 49 c.config.LightMode = true 50 if i != 0 { 51 c.state = StateAcceptRequest 52 } 53 } 54 return sys 55 }(), 56 newTestLightProposal(), 57 nil, 58 false, 59 }, 60 { 61 // light proposal case 62 func() *testSystem { 63 sys := NewTestSystemWithBackend(N, F) 64 for i, backend := range sys.backends { 65 c := backend.engine.(*core) 66 c.valSet = backend.peers 67 c.config.LightMode = true 68 if i != 0 { 69 c.state = StateAcceptRequest 70 // set empty txpool for follow node 71 backend.txpool = newTestSystemTxPool() 72 } else { 73 backend.txpool = newTestSystemTxPool(newTransactions(1, signer, key)...) 74 } 75 } 76 return sys 77 }(), 78 newTestLightProposal(newTransactions(1, signer, key)...), 79 nil, 80 false, 81 }, 82 } 83 84 OUTER: 85 for _, test := range testCases { 86 test.system.Run(false) 87 88 v0 := test.system.backends[0] 89 r0 := v0.engine.(*core) 90 91 curView := r0.currentView() 92 93 lightPrepare := &pbft.LightPreprepare{ 94 View: curView, 95 Proposal: test.expectedRequest, 96 } 97 98 for i, v := range test.system.backends { 99 if i == 0 { 100 continue 101 } 102 103 c := v.engine.(*core) 104 105 m, _ := Encode(lightPrepare) 106 107 _, val := r0.valSet.GetByAddress(v0.Address()) 108 // run each backends and verify handleLightPrepare function. 109 if err := c.handleLightPrepare(&message{ 110 Code: msgLightPreprepare, 111 Msg: m, 112 Address: v0.Address(), 113 }, val); err != nil { 114 if err != test.expectedErr { 115 t.Errorf("error mismatch: have %v, want %v", err, test.expectedErr) 116 } 117 continue OUTER 118 } 119 120 if c.state != StatePreprepared { 121 missedResp := &pbft.MissedResp{ 122 View: c.currentView(), 123 ReqTxs: test.expectedRequest.(*types.LightBlock).Block.Transactions(), 124 } 125 encMissedResp, _ := missedResp.EncodeOffset() 126 msg := &message{ 127 Code: msgMissedTxs, 128 Msg: encMissedResp, 129 } 130 if err := c.handleMissedTxs(msg, val); err != nil { 131 t.Errorf("failed to handleMissedTxs:%v", err) 132 } 133 } 134 135 if c.state != StatePreprepared { 136 t.Errorf("state mismatch: have %v, want %v", c.state, StatePreprepared) 137 } 138 139 if !test.existingBlock && !reflect.DeepEqual(c.current.Subject().View, curView) { 140 t.Errorf("view mismatch: have %v, want %v", c.current.Subject().View, curView) 141 } 142 143 // verify prepare messages 144 decodedMsg := new(message) 145 err := decodedMsg.FromPayload(v.sentMsgs[0], nil) 146 if err != nil { 147 t.Errorf("error mismatch: have %v, want nil", err) 148 } 149 150 expectedCode := msgPrepare 151 if test.existingBlock { 152 expectedCode = msgCommit 153 } 154 if decodedMsg.Code != expectedCode { 155 t.Errorf("message code mismatch: have %v, want %v", decodedMsg.Code, expectedCode) 156 } 157 158 var subject *pbft.Subject 159 err = decodedMsg.Decode(&subject) 160 if err != nil { 161 t.Errorf("error mismatch: have %v, want nil", err) 162 } 163 if !test.existingBlock && !reflect.DeepEqual(subject, c.current.Subject()) { 164 t.Errorf("subject mismatch: have %v, want %v", subject, c.current.Subject()) 165 } 166 } 167 } 168 }