github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/consensus/podc/core/preprepare.go (about) 1 // Copyright 2017 AMIS Technologies 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 core 18 19 import ( 20 "time" 21 22 "github.com/ethereum/go-ethereum/common" 23 "github.com/ethereum/go-ethereum/consensus/podc" 24 "github.com/ethereum/go-ethereum/log" 25 ) 26 27 func (c *core) sendRequestExtraDataToQman(request *podc.Request) { 28 logger := c.logger.New("state", c.state) 29 log.Info("2. Interval time between start new round and pre-prepare", "elapsed", common.PrettyDuration(time.Since(c.startTime))) 30 c.intervalTime = time.Now() 31 32 // If I'm the proposer and I have the same sequence with the proposal 33 if c.current.Sequence().Cmp(request.Proposal.Number()) == 0 && c.isProposer() { //? 34 log.Debug("sendRequestExtraDataToQman 1", "seq", c.current.Sequence()) 35 curView := c.currentView() 36 preprepare, err := Encode(&podc.Preprepare{ 37 View: curView, 38 Proposal: request.Proposal, 39 }) 40 if err != nil { 41 logger.Error("Failed to encode", "view", curView) 42 return 43 } 44 if c.valSet.IsProposer(c.Address()) { 45 //time.Sleep(100 * time.Millisecond) //Add delay for ensure receiving proposal in other nodes 46 47 log.Debug("sendRequestExtraDataToQman 2") 48 49 //c.handleQmanager(preprepare, c.valSet.GetProposer()) 50 c.broadcast(&message{ 51 Code: msgHandleQman, 52 Msg: preprepare, 53 }) 54 } 55 } 56 } 57 58 // 2. go to step 2 : pre-prepare step 59 func (c *core) sendPreprepare(request *podc.Request) { 60 logger := c.logger.New("state", c.state) 61 62 // If I'm the proposer and I have the same sequence with the proposal 63 if c.current.Sequence().Cmp(request.Proposal.Number()) == 0 && c.isProposer() { 64 curView := c.currentView() 65 preprepare, err := Encode(&podc.Preprepare{ 66 View: curView, 67 Proposal: request.Proposal, 68 }) 69 if err != nil { 70 logger.Error("Failed to encode", "view", curView) 71 return 72 } 73 74 c.broadcast(&message{ 75 Code: msgPreprepare, 76 Msg: preprepare, 77 }) 78 79 } 80 } 81 82 func (c *core) handleQmanager(msg *message, src podc.Validator) error { //request to qman 83 log.Debug("handleQmanager", "from", src, "state", c.state) 84 logger := c.logger.New("from", src, "state", c.state) 85 86 var preprepare *podc.Preprepare 87 err := msg.Decode(&preprepare) 88 if err != nil { 89 return errFailedDecodePreprepare 90 } 91 92 // Ensure we have the same view with the preprepare message 93 if err := c.checkMessage(msgPreprepare, preprepare.View); err != nil { 94 return err 95 } 96 97 // Check if the message comes from current proposer 98 if !c.valSet.IsProposer(src.Address()) { 99 logger.Warn("Ignore preprepare messages from non-proposer") 100 return errNotFromProposer 101 } 102 103 if c.valSet.IsProposer(c.Address()) { // I'm Front node. 104 log.Info("I'm Proposer!!!!!!!") 105 } 106 // Verify the proposal we received 107 if err := c.backend.Verify(preprepare.Proposal); err != nil { 108 logger.Warn("handleQmanager: Failed to verify proposal", "err", err) //? 109 c.sendNextRoundChange() //important : inconsistent mismatch ... 110 return err 111 } 112 113 elapsed := time.Since(c.intervalTime) 114 log.Info("3. Set pre-prepare state", "elapsed", common.PrettyDuration(elapsed)) 115 116 c.intervalTime = time.Now() 117 118 if c.state == StateRequestQman { 119 c.acceptPreprepare(preprepare) 120 c.setState(StatePreprepared) 121 //c.sendPrepare() 122 if c.valSet.IsProposer(c.Address()) { 123 c.sendExtraDataRequest() 124 } 125 } 126 return nil 127 } 128 129 func (c *core) handlePreprepare(msg *message, src podc.Validator) error { 130 log.Debug("handlePreprepare") 131 logger := c.logger.New("from", src, "state", c.state) 132 133 // Decode preprepare 134 var preprepare *podc.Preprepare 135 err := msg.Decode(&preprepare) 136 if err != nil { 137 return errFailedDecodePreprepare 138 } 139 140 // Ensure we have the same view with the preprepare message 141 if err := c.checkMessage(msgPreprepare, preprepare.View); err != nil { 142 return err 143 } 144 145 // Check if the message comes from current proposer 146 if !c.valSet.IsProposer(src.Address()) { 147 logger.Warn("Ignore preprepare messages from non-proposer") 148 return errNotFromProposer 149 } 150 151 if c.valSet.IsProposer(c.Address()) { 152 log.Info("I'm Proposer!!!!!!!") 153 } 154 // Verify the proposal we received 155 if err := c.backend.Verify(preprepare.Proposal); err != nil { 156 logger.Warn("Failed to verify proposal", "err", err) 157 c.sendNextRoundChange() 158 return err 159 } 160 161 if c.state == StateAcceptRequest { 162 c.acceptPreprepare(preprepare) 163 c.setState(StatePreprepared) 164 if c.valSet.IsProposer(c.Address()) { 165 c.sendDSelect() 166 } 167 168 } 169 return nil 170 } 171 172 func (c *core) acceptPreprepare(preprepare *podc.Preprepare) { 173 c.consensusTimestamp = time.Now() 174 c.current.SetPreprepare(preprepare) 175 }