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  }