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