github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/consensus/podc/core/d_select.go (about) 1 package core 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "math" 7 "math/rand" 8 "os" 9 "time" 10 11 "github.com/ethereum/go-ethereum/common" 12 "github.com/ethereum/go-ethereum/consensus/podc" 13 "github.com/ethereum/go-ethereum/log" 14 "github.com/ethereum/go-ethereum/qmanager/global" 15 "github.com/ethereum/go-ethereum/qmanager/utils" 16 ) 17 18 //var ExtraDataLength int = 0 //int value is zero, 19 20 func (c *core) sendDSelect() { 21 log.Debug("sendDSelect") 22 logger := c.logger.New("state", c.state) 23 var extra [7]common.ValidatorInfo // 최소 7개 노드에서 추가? 기동시 최소 7개 이상 띄워야함. 24 //var extra [50]ValidatorInfo //debugging... 7 -> 50 ,, logical bug. 임시로 50개,, 나중에 수정할 것. 25 flag := false 26 27 for i, v := range c.valSet.List() { 28 validatorInfo := common.ValidatorInfo{} 29 validatorInfo.Address = v.Address() 30 validatorInfo.Qrnd = rand.Uint64() 31 32 if i == 0 { 33 if !c.valSet.IsProposer(v.Address()) { 34 validatorInfo.Tag = common.Coordinator 35 } else { 36 flag = true 37 } 38 } else if i == 1 { 39 if flag { 40 validatorInfo.Tag = common.Coordinator 41 } 42 } else { 43 validatorInfo.Tag = common.Candidate 44 } 45 46 extra[i] = validatorInfo 47 } 48 49 extraDataJson, err := json.Marshal(extra) 50 if err != nil { 51 logger.Error("Failed to encode JSON", err) 52 } 53 54 c.broadcast(&message{ 55 Code: msgDSelect, 56 Msg: extraDataJson, 57 }) 58 } 59 60 func (c *core) sendExtraDataRequest() { 61 //c.send(&message{ 62 // Code: msgExtraDataRequest, 63 // Msg: []byte("extra data request testing."), 64 //}, c.qmanager) 65 66 log.Info("Extra Data Request", "Status", "Requesting to Standalone Qmanager") 67 68 extra, err := utils.RequestExtraData(c.valSet.GetProposer().Address().String()) 69 70 if err != nil { 71 log.Error("Extra Data Request Failure", "Error", err.Error()) 72 73 } else { 74 //log.Info("Qmanager", "Recieved ExtraData", extra) 75 76 extraDataJson, err := json.Marshal(extra) 77 //log.Info("Qmanager", "Recieved extraDataJson", extraDataJson) 78 log.Info("Extra Data Request", "Status", "Recieved ExtraData") 79 80 if err != nil { 81 log.Error("Failed to encode", "extra data", extra) 82 } 83 c.ExtraDataLength = len(extra) 84 85 c.broadcast(&message{ 86 Code: msgDSelect, 87 Msg: extraDataJson, 88 }) 89 } 90 } 91 92 func (c *core) sendCoordinatorDecide() { 93 log.Debug("sendCoordinatorDecide") 94 coordinatorData := c.valSet.GetProposer() 95 encodedCoordinatorData, err := Encode(&coordinatorData) 96 97 if err != nil { 98 log.Error("Failed to encode", "extra data", coordinatorData) 99 return 100 } 101 102 c.multicast(&message{ 103 Code: msgCoordinatorDecide, 104 Msg: encodedCoordinatorData, 105 }, c.GetValidatorListExceptQman()) 106 } 107 108 func (c *core) sendRacing(addr common.Address) { 109 log.Debug("sendRacing") 110 c.send(&message{ 111 Code: msgRacing, 112 Msg: []byte("racing testing"), 113 }, addr) 114 } 115 116 func (c *core) sendCandidateDecide() { 117 log.Debug("sendCandidateDecide") 118 119 // var addrs []common.Address 120 // for _, val := range c.voteSet.List() { 121 // addrs = append(addrs, val.Address()) 122 // } 123 124 // enc, err := rlp.EncodeToBytes(addrs) 125 // if err != nil { 126 // log.Error("Rlp encode error", "err", err) 127 // return 128 // } 129 130 c.multicast(&message{ 131 Code: msgCandidateDecide, 132 Msg: []byte("Candidate decide testing"), 133 //Msg: enc, 134 }, c.GetValidatorListExceptQman()) 135 // c.multicast(&message{ 136 // Code: msgCandidateDecide, 137 // //Msg: []byte("Candidate decide testing"), 138 // Msg: enc, 139 // }, addrs) 140 } 141 142 //D-Select msg 143 func (c *core) handleSentExtraData(msg *message, src podc.Validator) error { 144 // Decode d-select message 145 var extraData common.ValidatorInfos 146 if err := json.Unmarshal(msg.Msg, &extraData); err != nil { 147 log.Error("JSON Decode Error", "Err", err) 148 log.Info("Decode Error") 149 return errFailedDecodePrepare 150 } 151 c.ExtraDataLength = len(extraData) 152 153 c.broadcast(&message{ 154 Code: msgDSelect, 155 Msg: msg.Msg, 156 }) 157 158 return nil 159 } 160 161 func (c *core) handleDSelect(msg *message, src podc.Validator) error { 162 log.Info("4. Get extra data and start d-select", "elapsed", common.PrettyDuration(time.Since(c.intervalTime))) 163 c.racingFlag = false 164 c.count = 0 165 c.intervalTime = time.Now() 166 167 // Decode d-select message 168 var extraData []common.ValidatorInfo 169 170 if err := json.Unmarshal(msg.Msg, &extraData); err != nil { 171 log.Error("JSON Decode Error", "Err", err) 172 return errFailedDecodePrepare 173 } 174 175 log.Debug("handleDSelect 1", "len(extraData)", len(extraData), "extraData", extraData) 176 177 nodename, err := os.Getwd() 178 if err != nil { 179 log.Debug("handleDSelect", "current nodename", nodename, "err", err) 180 } 181 182 var QRND uint64 183 //var vaddrs []common.Address 184 // var saddrs []common.Address 185 // scount := 0 186 for _, v := range extraData { 187 if v.Address == c.address { 188 c.tag = v.Tag 189 QRND = v.Qrnd 190 } 191 // if v.Tag == common.Senator || v.Tag == common.Coordinator { 192 // saddrs = append(saddrs, v.Address) 193 // scount++ 194 // } 195 //vaddrs = append(vaddrs, v.Address) 196 } 197 198 //c.valSet = validator.NewSet(vaddrs, c.config.ProposerPolicy) 199 // c.voteSet = validator.NewSet(saddrs, c.config.ProposerPolicy) 200 // c.agreeCriteria = int((float64(scount)+math.Ceil(float64(scount)*float64(1.08)))*2/3) + 1 201 202 log.Debug("handleDSelect 2", "c.address", c.address, "c.tag", c.tag, "QRND", QRND) 203 204 if c.tag == common.Coordinator { 205 //QRNDArray := make([]byte, 8) 206 //binary.LittleEndian.PutUint64(QRNDArray, QRND) 207 208 c.ExtraDataLength = len(extraData) 209 c.criteria = 29 210 211 isCoordinator, err := utils.CoordinatorConfirmation(global.RequestCoordiStruct{QRND: QRND}) 212 if err != nil { 213 log.Error("Coordinator Confirm Failure", "Error", err.Error()) 214 } 215 if isCoordinator { 216 var err error 217 log.Info(fmt.Sprintf("I am Coordinator! ExtraDataLength %d", c.ExtraDataLength)) //grep -r 'I am Coordinator!' *.log 218 if c.ExtraDataLength != 0 { 219 c.criteria = math.Ceil(((float64(c.ExtraDataLength) - 1.00) * float64(0.51))) //Ceil.. >= 수 리턴. 220 // c.criteria = math.Ceil(float64(scount) * float64(1.08)) // Parliamentarian 52% = Senator*52/48, racing criteria 221 } else { 222 log.Error("ExtraDataLength has problem") 223 //utils.Fatalf("ExtraDataLength has problem) 224 return err 225 } 226 227 c.sendCoordinatorDecide() 228 } 229 230 } else { 231 c.ExtraDataLength = 0 232 c.criteria = 0 233 } 234 log.Debug("handleDSelect 3", "c.criteria", c.criteria, "c.ExtraDataLength", c.ExtraDataLength) 235 236 return nil 237 } 238 239 func (c *core) handleCoordinatorConfirm(msg *message, src podc.Validator) error { 240 var err error 241 log.Info(fmt.Sprintf("I am Coordinator! ExtraDataLength %d", c.ExtraDataLength)) //grep -r 'I am Coordinator!' *.log 242 if c.ExtraDataLength != 0 { 243 c.criteria = math.Ceil(((float64(c.ExtraDataLength) - 1.00) * float64(0.51))) //Ceil.. >= 수 리턴. 244 } 245 if c.ExtraDataLength == 0 { 246 log.Info("ExtraDataLength has problem") 247 //utils.Fatalf("ExtraDataLength has problem) 248 return err 249 } 250 251 log.Info("c.criteria=", "c.criteria", c.criteria) 252 c.sendCoordinatorDecide() 253 254 return nil 255 } 256 257 func (c *core) handleCoordinatorDecide(msg *message, src podc.Validator) error { 258 log.Debug("handleCoordinatorDecide", "extra", c.ExtraDataLength, "criteria", c.criteria) 259 // if c.tag != common.Coordinator { 260 if c.tag != common.Coordinator || c.ExtraDataLength == 0 { //TODO-REAP: workaround for disappeared racing msg 261 // if c.tag == common.Candidate { //TODO-REAP: workaround for disappeared racing msg 262 log.Debug("handleCoordinatorDecide - send racing", "extra", c.ExtraDataLength, "criteria", c.criteria) 263 c.sendRacing(src.Address()) //레이싱 시작 메시지 전송 264 } 265 266 return nil 267 } 268 269 func (c *core) handleRacing(msg *message, src podc.Validator) error { 270 c.racingMu.Lock() 271 defer c.racingMu.Unlock() 272 if c.tag == common.Coordinator { 273 c.count = c.count + 1 274 log.Debug("handleRacing 1", "c.count", c.count) 275 // if c.count <= uint(c.criteria) && !c.racingFlag { 276 // c.voteSet.AddValidator(src.Address()) 277 // } 278 if c.count >= uint(c.criteria) && !c.racingFlag { 279 log.Debug("handleRacing 2", "c.count", c.count, "c.criteria", c.criteria, "c.racingFlag", c.racingFlag) 280 c.racingFlag = true 281 // send msg with voteSet list 282 c.sendCandidateDecide() 283 } 284 } 285 286 return nil 287 } 288 289 func (c *core) handleCandidateDecide(msg *message, src podc.Validator) error { //커밋단계로 진입 290 log.Debug("handleCandidateDecide", "c.state", c.state) 291 if c.state == StatePreprepared { 292 log.Info("5. Racing complete and d-select finished.", "elapsed", common.PrettyDuration(time.Since(c.intervalTime))) 293 //decode msg 294 // var addrs []common.Address 295 // err := rlp.DecodeBytes(msg.Msg, &addrs) 296 // if err != nil { 297 // log.Error("Rlp decode error", "err", err) 298 // return err 299 // } 300 // for _, addr := range addrs { 301 // if c.address == addr { 302 // c.intervalTime = time.Now() 303 // c.setState(StateDSelected) //D-selected 상태로 설정하고, 커밋 상태로 진입. 304 // c.sendDCommit() // msgCommit 를 통하여, 메시지핸들러에서, handleDCommit를 실행, 여기서 c.verifyDCommit에서 inconsistent 발생, 305 // break 306 // } 307 // } 308 c.intervalTime = time.Now() 309 c.setState(StateDSelected) //D-selected 상태로 설정하고, 커밋 상태로 진입. 310 c.sendDCommit() // msgCommit 를 통하여, 메시지핸들러에서, handleDCommit를 실행, 여기서 c.verifyDCommit에서 inconsistent 발생, 311 } 312 313 return nil 314 }