github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/consensus/podc/core/preprepare.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/common"
    23  	"github.com/ethereum/go-ethereum/consensus/podc"
    24  	"github.com/ethereum/go-ethereum/log"
    25  )
    26  
    27  func (c *core) sendRequestExtraDataToQman(request *podc.Request) {
    28  	logger := c.logger.New("state", c.state)
    29  	log.Info("2. Interval time between start new round and pre-prepare", "elapsed", common.PrettyDuration(time.Since(c.startTime)))
    30  	c.intervalTime = time.Now()
    31  
    32  	// If I'm the proposer and I have the same sequence with the proposal
    33  	if c.current.Sequence().Cmp(request.Proposal.Number()) == 0 && c.isProposer() { //?
    34  		log.Debug("sendRequestExtraDataToQman 1", "seq", c.current.Sequence())
    35  		curView := c.currentView()
    36  		preprepare, err := Encode(&podc.Preprepare{
    37  			View:     curView,
    38  			Proposal: request.Proposal,
    39  		})
    40  		if err != nil {
    41  			logger.Error("Failed to encode", "view", curView)
    42  			return
    43  		}
    44  		if c.valSet.IsProposer(c.Address()) {
    45  			//time.Sleep(100 * time.Millisecond) //Add delay for ensure receiving proposal in other nodes
    46  
    47  			log.Debug("sendRequestExtraDataToQman 2")
    48  
    49  			//c.handleQmanager(preprepare, c.valSet.GetProposer())
    50  			c.broadcast(&message{
    51  				Code: msgHandleQman,
    52  				Msg:  preprepare,
    53  			})
    54  		}
    55  	}
    56  }
    57  
    58  // 2. go to step 2 : pre-prepare step
    59  func (c *core) sendPreprepare(request *podc.Request) {
    60  	logger := c.logger.New("state", c.state)
    61  
    62  	// If I'm the proposer and I have the same sequence with the proposal
    63  	if c.current.Sequence().Cmp(request.Proposal.Number()) == 0 && c.isProposer() {
    64  		curView := c.currentView()
    65  		preprepare, err := Encode(&podc.Preprepare{
    66  			View:     curView,
    67  			Proposal: request.Proposal,
    68  		})
    69  		if err != nil {
    70  			logger.Error("Failed to encode", "view", curView)
    71  			return
    72  		}
    73  
    74  		c.broadcast(&message{
    75  			Code: msgPreprepare,
    76  			Msg:  preprepare,
    77  		})
    78  
    79  	}
    80  }
    81  
    82  func (c *core) handleQmanager(msg *message, src podc.Validator) error { //request to qman
    83  	log.Debug("handleQmanager", "from", src, "state", c.state)
    84  	logger := c.logger.New("from", src, "state", c.state)
    85  
    86  	var preprepare *podc.Preprepare
    87  	err := msg.Decode(&preprepare)
    88  	if err != nil {
    89  		return errFailedDecodePreprepare
    90  	}
    91  
    92  	// Ensure we have the same view with the preprepare message
    93  	if err := c.checkMessage(msgPreprepare, preprepare.View); err != nil {
    94  		return err
    95  	}
    96  
    97  	// Check if the message comes from current proposer
    98  	if !c.valSet.IsProposer(src.Address()) {
    99  		logger.Warn("Ignore preprepare messages from non-proposer")
   100  		return errNotFromProposer
   101  	}
   102  
   103  	if c.valSet.IsProposer(c.Address()) { // I'm Front node.
   104  		log.Info("I'm Proposer!!!!!!!")
   105  	}
   106  	// Verify the proposal we received
   107  	if err := c.backend.Verify(preprepare.Proposal); err != nil {
   108  		logger.Warn("handleQmanager: Failed to verify proposal", "err", err) //?
   109  		c.sendNextRoundChange()                                              //important : inconsistent mismatch ...
   110  		return err
   111  	}
   112  
   113  	elapsed := time.Since(c.intervalTime)
   114  	log.Info("3. Set pre-prepare state", "elapsed", common.PrettyDuration(elapsed))
   115  
   116  	c.intervalTime = time.Now()
   117  
   118  	if c.state == StateRequestQman {
   119  		c.acceptPreprepare(preprepare)
   120  		c.setState(StatePreprepared)
   121  		//c.sendPrepare()
   122  		if c.valSet.IsProposer(c.Address()) {
   123  			c.sendExtraDataRequest()
   124  		}
   125  	}
   126  	return nil
   127  }
   128  
   129  func (c *core) handlePreprepare(msg *message, src podc.Validator) error {
   130  	log.Debug("handlePreprepare")
   131  	logger := c.logger.New("from", src, "state", c.state)
   132  
   133  	// Decode preprepare
   134  	var preprepare *podc.Preprepare
   135  	err := msg.Decode(&preprepare)
   136  	if err != nil {
   137  		return errFailedDecodePreprepare
   138  	}
   139  
   140  	// Ensure we have the same view with the preprepare message
   141  	if err := c.checkMessage(msgPreprepare, preprepare.View); err != nil {
   142  		return err
   143  	}
   144  
   145  	// Check if the message comes from current proposer
   146  	if !c.valSet.IsProposer(src.Address()) {
   147  		logger.Warn("Ignore preprepare messages from non-proposer")
   148  		return errNotFromProposer
   149  	}
   150  
   151  	if c.valSet.IsProposer(c.Address()) {
   152  		log.Info("I'm Proposer!!!!!!!")
   153  	}
   154  	// Verify the proposal we received
   155  	if err := c.backend.Verify(preprepare.Proposal); err != nil {
   156  		logger.Warn("Failed to verify proposal", "err", err)
   157  		c.sendNextRoundChange()
   158  		return err
   159  	}
   160  
   161  	if c.state == StateAcceptRequest {
   162  		c.acceptPreprepare(preprepare)
   163  		c.setState(StatePreprepared)
   164  		if c.valSet.IsProposer(c.Address()) {
   165  			c.sendDSelect()
   166  		}
   167  
   168  	}
   169  	return nil
   170  }
   171  
   172  func (c *core) acceptPreprepare(preprepare *podc.Preprepare) {
   173  	c.consensusTimestamp = time.Now()
   174  	c.current.SetPreprepare(preprepare)
   175  }