github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/consensus/podc/core/handler.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  	"math/big"
    21  	"time"
    22  
    23  	"github.com/ethereum/go-ethereum/log"
    24  
    25  	//"github.com/ethereum/go-ethereum/cmd/utils"
    26  	"github.com/ethereum/go-ethereum/common"
    27  	"github.com/ethereum/go-ethereum/consensus/podc"
    28  )
    29  
    30  // Start implements core.Engine.Start
    31  func (c *core) Start(lastSequence *big.Int, lastProposer common.Address, lastProposal podc.Proposal) error {
    32  	// Initialize last proposer
    33  	//log.Info("lastSequence", "lastSequence", lastSequence)
    34  
    35  	c.lastProposer = lastProposer
    36  	//var err error
    37  	//if qmanager == nil  {
    38  	//	return err
    39  	//}
    40  	//if len(qmanager) <= 0 {
    41  	//	log.Debug("Qmanager node is not exist")
    42  	//    return nil // err ?
    43  	//}
    44  	//
    45  	//QmanEnode := qmanager[0].ID[:]  //여기까지 정상
    46  
    47  	//c.qmanager = crypto.PublicKeyBytesToAddress(QmanEnode) //common.Address output from this [account addr]              //slice ->
    48  	//Qmanager account address(20byte): 926ea01d982c8aeafab7f440084f90fe078cba92
    49  	c.lastProposal = lastProposal
    50  	c.lastSequence = lastSequence
    51  	c.valSet = c.backend.Validators(c.lastProposal) // Validator array 관리
    52  
    53  	// Start a new round from last sequence + 1
    54  	start := time.Now()
    55  	log.Info("start time of consensus of core engine start()", "start time", start)
    56  	c.startNewRound(&podc.View{
    57  		Sequence: new(big.Int).Add(lastSequence, common.Big1), //lastSequence +1
    58  		Round:    common.Big0,                                 //round 0
    59  	}, false)
    60  
    61  	// Tests will handle events itself, so we have to make subscribeEvents()
    62  	// be able to call in test.
    63  	c.subscribeEvents()
    64  	go c.handleEvents()
    65  
    66  	return nil
    67  }
    68  
    69  // Stop implements core.Engine.Stop
    70  func (c *core) Stop() error {
    71  	c.unsubscribeEvents()
    72  	return nil
    73  }
    74  
    75  // ----------------------------------------------------------------------------
    76  
    77  // Subscribe both internal and external events
    78  func (c *core) subscribeEvents() {
    79  	c.events = c.backend.EventMux().Subscribe(
    80  		// external events
    81  		podc.RequestEvent{},
    82  		podc.MessageEvent{},
    83  		podc.FinalCommittedEvent{},
    84  		// internal events
    85  		backlogEvent{},
    86  	)
    87  }
    88  
    89  // Unsubscribe all events
    90  func (c *core) unsubscribeEvents() {
    91  	c.events.Unsubscribe()
    92  }
    93  
    94  func (c *core) handleEvents() {
    95  	for event := range c.events.Chan() {
    96  		// A real event arrived, process interesting content
    97  		switch ev := event.Data.(type) {
    98  		case podc.RequestEvent:
    99  			//c.startTime = time.Now()
   100  			//log.Info("1. Start")
   101  			r := &podc.Request{
   102  				Proposal: ev.Proposal,
   103  			}
   104  			err := c.handleRequest(r) //send qman here
   105  			if err == errFutureMessage {
   106  				c.storeRequestMsg(r)
   107  			}
   108  		case podc.MessageEvent:
   109  			c.handleMsg(ev.Payload)
   110  		case podc.FinalCommittedEvent:
   111  			c.handleFinalCommitted(ev.Proposal, ev.Proposer)
   112  		case backlogEvent: //내부에서만 받는 이벤트, 서명 불필요.
   113  			// No need to check signature for internal messages
   114  			c.handleCheckedMsg(ev.msg, ev.src)
   115  		}
   116  	}
   117  }
   118  
   119  // sendEvent sends events to mux
   120  func (c *core) sendEvent(ev interface{}) {
   121  	c.backend.EventMux().Post(ev)
   122  }
   123  
   124  func (c *core) handleMsg(payload []byte) error {
   125  	logger := c.logger.New("address", c.address)
   126  
   127  	// Decode message and check its signature
   128  	msg := new(message)
   129  	if err := msg.FromPayload(payload, c.validateFn); err != nil {
   130  		logger.Error("Failed to decode message from payload", "err", err) //getbyaddress에서, validator에 있는지 체크 안하고 넘어오면, 여기서 또 에러..
   131  		// return err  //unauthorixed address
   132  	}
   133  	//log.Debug("handleMsg", "code", msg.Code)
   134  
   135  	// Only accept message if the address is valid
   136  	_, src := c.valSet.GetByAddress(msg.Address)
   137  	if src == nil {
   138  		logger.Error("Invalid address in message", "msg", msg)
   139  		return podc.ErrUnauthorizedAddress
   140  	}
   141  
   142  	return c.handleCheckedMsg(msg, src)
   143  }
   144  
   145  func (c *core) handleCheckedMsg(msg *message, src podc.Validator) error {
   146  	logger := c.logger.New("address", c.address, "from", src)
   147  
   148  	// Store the message if it's a future message
   149  	testBacklog := func(err error) error {
   150  		if err == errFutureMessage {
   151  			c.storeBacklog(msg, src)
   152  			return nil
   153  		}
   154  
   155  		return err
   156  	}
   157  
   158  	switch msg.Code {
   159  
   160  	case msgHandleQman:
   161  		/* Qmanager handler for receiving from geth : sending qmanager event */
   162  		//case msgRequest:
   163  		return testBacklog(c.handleQmanager(msg, src)) //Sending to Qmanager  event hadler  // this geth only proposer.
   164  
   165  	case msgPreprepare:
   166  		return testBacklog(c.handlePreprepare(msg, src))
   167  	case msgDSelect:
   168  		return testBacklog(c.handleDSelect(msg, src))
   169  	case msgCoordinatorDecide:
   170  		return testBacklog(c.handleCoordinatorDecide(msg, src)) //레이싱 시작 메시지 전송
   171  	case msgRacing:
   172  		return testBacklog(c.handleRacing(msg, src))
   173  	case msgCandidateDecide:
   174  		return testBacklog(c.handleCandidateDecide(msg, src))
   175  	//case msgDSelect:
   176  	//	return testBacklog(c.handlePrepare(msg, src))
   177  	case msgCommit:
   178  		return testBacklog(c.handleDCommit(msg, src))
   179  	case msgRoundChange:
   180  		return testBacklog(c.handleRoundChange(msg, src))
   181  
   182  	//case msgExtraDataRequest:
   183  	//	return testBacklog(c.handleExtraData(msg, src))
   184  	//case msgExtraDataSend:
   185  	//	return testBacklog(c.handleSentExtraData(msg, src))
   186  	//case msgCoordinatorConfirmRequest:
   187  	//	return testBacklog(c.CoordinatorConfirmation(msg, src))
   188  	//case msgCoordinatorConfirmSend:
   189  	//	return testBacklog(c.handleCoordinatorConfirm(msg, src))  //c.criteria 결정,
   190  
   191  	default:
   192  		logger.Error("Invalid message", "msg", msg)
   193  	}
   194  
   195  	return errInvalidMessage
   196  }