github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/consensus/pbft/core/body_request.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/consensus/pbft" 21 "github.com/bigzoro/my_simplechain/core/types" 22 ) 23 24 func (c *core) requestMissedTxs(missedTxs []types.MissedTx, val pbft.Validator) { 25 logger := c.logger.New("state", c.state, "to", val) 26 27 missedReq := &pbft.MissedReq{ 28 View: c.currentView(), 29 MissedTxs: missedTxs, 30 } 31 32 encMissedReq, err := Encode(missedReq) 33 if err != nil { 34 logger.Error("Failed to encode", "missedReq", missedReq, "err", err) 35 return 36 } 37 38 //logger.Trace("[report] requestMissedTxs", "view", missedReq.View, "missed", len(missedTxs)) 39 40 c.send(&message{ 41 Code: msgGetMissedTxs, 42 Msg: encMissedReq, 43 }, pbft.Validators{val}) 44 } 45 46 func (c *core) handleGetMissedTxs(msg *message, src pbft.Validator) error { 47 logger := c.logger.New("from", src, "state", c.state) 48 49 var missed *pbft.MissedReq 50 err := msg.Decode(&missed) 51 if err != nil { 52 logger.Error("Failed to decode", "err", err) 53 return errFailedDecodePrepare 54 } 55 56 //logger.Trace("[report] handleGetMissedTxs", "view", missed.View, "missed", len(missed.MissedTxs)) 57 58 if err := c.checkMessage(msgGetMissedTxs, missed.View); err != nil { 59 logFn := logger.Warn 60 switch err { 61 case errOldMessage: //TODO 62 logFn = logger.Trace 63 case errFutureMessage: //TODO 64 logFn = logger.Trace 65 } 66 logFn("GetMissedTxs checkMessage failed", "view", missed.View, "missed", len(missed.MissedTxs), "err", err) 67 return err 68 } 69 70 // proposer must have a filled proposal, return if the proposal is not exist 71 proposal := c.current.Proposal() 72 if proposal == nil { 73 logger.Warn("nonexistent completed proposal") 74 return errNonexistentProposal 75 } 76 77 txs, err := proposal.FetchMissedTxs(missed.MissedTxs) 78 if err != nil { 79 return err 80 } 81 82 c.responseMissedTxs(txs, src) 83 84 return nil 85 } 86 87 func (c *core) responseMissedTxs(txs types.Transactions, val pbft.Validator) { 88 logger := c.logger.New("state", c.state, "to", val) 89 90 missedResp := &pbft.MissedResp{ 91 View: c.currentView(), 92 ReqTxs: txs, 93 } 94 95 //logger.Trace("[report] responseMissedTxs", "view", missedResp.View, "missed", len(txs)) 96 97 //encMissedResp, err := Encode(missedResp) 98 encMissedResp, err := missedResp.EncodeOffset() 99 if err != nil { 100 logger.Error("Failed to encode", "missedResp", missedResp, "err", err) 101 return 102 } 103 104 // Mark txs known by val, and do not sync them again 105 c.backend.MarkTransactionKnownBy(val, txs) 106 107 c.send(&message{ 108 Code: msgMissedTxs, 109 Msg: encMissedResp, 110 }, pbft.Validators{val}) 111 } 112 113 func (c *core) handleMissedTxs(msg *message, src pbft.Validator) error { 114 logger := c.logger.New("from", src, "state", c.state) 115 116 var missed pbft.MissedResp 117 //err := msg.Decode(&missed) 118 err := missed.DecodeOffset(msg.Msg) 119 if err != nil { 120 return errFailedDecodePrepare 121 } 122 123 //logger.Trace("[report] handleMissedTxs", "view", missed.View) 124 125 if err := c.checkMessage(msgMissedTxs, missed.View); err != nil { 126 logFn := logger.Warn 127 switch err { 128 case errOldMessage: //TODO 129 logFn = logger.Trace 130 case errFutureMessage: //TODO 131 logFn = logger.Trace 132 } 133 logFn("MissedTxs checkMessage failed", "view", missed.View, "missed", len(missed.ReqTxs), "err", err) 134 return err 135 } 136 137 lp := c.current.LightProposal() 138 if lp == nil { 139 logger.Warn("local light proposal was lost", "view", missed.View, "Preprepare", c.current.Preprepare) 140 return nil 141 } 142 143 // do not accept completed proposal repeatedly 144 if lp.Completed() { 145 logger.Warn("local light was already completed", "view", missed.View) 146 return nil 147 } 148 149 if err := lp.FillMissedTxs(missed.ReqTxs); err != nil { 150 return err 151 } 152 153 return c.handleLightPrepare2(c.current.LightPrepare.FullPreprepare(), src) 154 }