github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/consensus/podc/core/request.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/consensus/podc" 23 "github.com/ethereum/go-ethereum/log" 24 ) 25 26 func (c *core) handleRequest(request *podc.Request) error { 27 log.Debug("handleRequest", "state", c.state, "seq", c.current.sequence) 28 logger := c.logger.New("state", c.state, "seq", c.current.sequence) 29 c.startTime = time.Now() 30 log.Info("1. Start") 31 if err := c.checkRequestMsg(request); err != nil { 32 logger.Warn("unexpected requests", "err", err, "request", request) 33 return err 34 } 35 36 log.Debug("handleRequest", "request", request.Proposal.Number()) 37 logger.Trace("handleRequest", "request", request.Proposal.Number()) 38 //if (reflect.DeepEqual(c.qmanager, c.Address())) { //if I'm Qmanager 39 // log.Info("I'm the Qman in handleRequest" ) 40 //} 41 42 if c.state == StateRequestQman { 43 // c.sendPre_prepare() //send to Qman to get Extradata 44 c.sendRequestExtraDataToQman(request) 45 } 46 47 //Qmanager response check is more prefer then StateAccepRequest state. 48 if c.state == StateAcceptRequest { 49 log.Info("StateAcceptRequest", "StateAcceptRequest", StateAcceptRequest) 50 c.sendPreprepare(request) 51 } 52 return nil 53 } 54 55 func (c *core) checkRequestMsg(request *podc.Request) error { 56 if request == nil || request.Proposal == nil { 57 return errInvalidMessage 58 } 59 60 if c := c.current.sequence.Cmp(request.Proposal.Number()); c > 0 { 61 return errOldMessage 62 } else if c < 0 { 63 return errFutureMessage 64 } else { 65 return nil 66 } 67 } 68 69 func (c *core) storeRequestMsg(request *podc.Request) { 70 logger := c.logger.New("state", c.state) 71 72 logger.Debug("Store future requests", "request", request) 73 74 c.pendingRequestsMu.Lock() 75 defer c.pendingRequestsMu.Unlock() 76 77 c.pendingRequests.Push(request, float32(-request.Proposal.Number().Int64())) 78 } 79 80 func (c *core) processPendingRequests() { 81 c.pendingRequestsMu.Lock() 82 defer c.pendingRequestsMu.Unlock() 83 84 log.Debug("processPendingRequests") 85 86 for !(c.pendingRequests.Empty()) { 87 m, prio := c.pendingRequests.Pop() 88 89 r, ok := m.(*podc.Request) 90 91 if !ok { 92 c.logger.Warn("Malformed request, skip", "msg", m) 93 continue 94 } 95 // Push back if it's a future message 96 err := c.checkRequestMsg(r) 97 if err != nil { 98 if err == errFutureMessage { 99 c.logger.Debug("Stop processing request", "request", r) 100 c.pendingRequests.Push(m, prio) 101 break 102 } 103 c.logger.Debug("Skip the pending request", "request", r, "err", err) 104 continue 105 } 106 c.logger.Debug("Post pending request", "request", r) 107 108 go c.sendEvent(podc.RequestEvent{ 109 110 Proposal: r.Proposal, 111 }) 112 } 113 } 114 115 //PendingRequest 는 지연 요청으로, 곧바로 보내지않고, 고루틴을 써서, 지연 처리.. ? 116 //func (c *core) processPendingRequestsQman() { 117 // c.pendingRequestsMu.Lock() 118 // defer c.pendingRequestsMu.Unlock() 119 // 120 // for !(c.pendingRequests.Empty()) { 121 // m, prio := c.pendingRequests.Pop() //stack에서 우선순위 가져온다. 122 // 123 // r, ok := m.(*podc.Request ) 124 // if !ok { 125 // c.logger.Warn("Malformed request, skip", "msg", m) 126 // continue 127 // } 128 // // Push back if it's a future message 129 // err := c.checkRequestMsg(r) 130 // if err != nil { 131 // if err == errFutureMessage { 132 // c.logger.Trace("Stop processing request", "request", r) 133 // c.pendingRequests.Push(m, prio) 134 // break 135 // } 136 // c.logger.Trace("Skip the pending request", "request", r, "err", err) 137 // continue 138 // } 139 // c.logger.Trace("Post pending request", "request", r) 140 // 141 // enode_slice := c.qmanager[:] 142 // go c.sendEvent(podc.QmanDataEvent{ 143 // Target : c.qmanager, 144 // Data : enode_slice , 145 // 146 // }) 147 // } 148 //}