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  }