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  //}