github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/consensus/bft/core/request.go (about) 1 package core 2 3 import "github.com/quickchainproject/quickchain/consensus/bft" 4 5 func (c *core) handleRequest(request *bft.Request) error { 6 logger := c.logger.New("state", c.state, "seq", c.current.sequence) 7 8 if err := c.checkRequestMsg(request); err != nil { 9 if err == errInvalidMessage { 10 logger.Warn("invalid request") 11 return err 12 } 13 logger.Warn("unexpected request", "err", err, "number", request.Proposal.Number(), "hash", request.Proposal.Hash()) 14 return err 15 } 16 17 logger.Trace("handleRequest", "number", request.Proposal.Number(), "hash", request.Proposal.Hash()) 18 19 c.current.pendingRequest = request 20 if c.state == StateAcceptRequest { 21 c.sendPreprepare(request) 22 } 23 return nil 24 } 25 26 // check request state 27 // return errInvalidMessage if the message is invalid 28 // return errFutureMessage if the sequence of proposal is larger than current sequence 29 // return errOldMessage if the sequence of proposal is smaller than current sequence 30 func (c *core) checkRequestMsg(request *bft.Request) error { 31 if request == nil || request.Proposal == nil { 32 return errInvalidMessage 33 } 34 35 if c := c.current.sequence.Cmp(request.Proposal.Number()); c > 0 { 36 return errOldMessage 37 } else if c < 0 { 38 return errFutureMessage 39 } else { 40 return nil 41 } 42 } 43 44 func (c *core) storeRequestMsg(request *bft.Request) { 45 logger := c.logger.New("state", c.state) 46 47 logger.Trace("Store future request", "number", request.Proposal.Number(), "hash", request.Proposal.Hash()) 48 49 c.pendingRequestsMu.Lock() 50 defer c.pendingRequestsMu.Unlock() 51 52 c.pendingRequests.Push(request, float32(-request.Proposal.Number().Int64())) 53 } 54 55 func (c *core) processPendingRequests() { 56 c.pendingRequestsMu.Lock() 57 defer c.pendingRequestsMu.Unlock() 58 59 for !(c.pendingRequests.Empty()) { 60 m, prio := c.pendingRequests.Pop() 61 r, ok := m.(*bft.Request) 62 if !ok { 63 c.logger.Warn("Malformed request, skip", "msg", m) 64 continue 65 } 66 // Push back if it's a future message 67 err := c.checkRequestMsg(r) 68 if err != nil { 69 if err == errFutureMessage { 70 c.logger.Trace("Stop processing request", "number", r.Proposal.Number(), "hash", r.Proposal.Hash()) 71 c.pendingRequests.Push(m, prio) 72 break 73 } 74 c.logger.Trace("Skip the pending request", "number", r.Proposal.Number(), "hash", r.Proposal.Hash(), "err", err) 75 continue 76 } 77 c.logger.Trace("Post pending request", "number", r.Proposal.Number(), "hash", r.Proposal.Hash()) 78 79 go c.sendEvent(bft.RequestEvent{ 80 Proposal: r.Proposal, 81 }) 82 } 83 }