github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/consensus/podc/core/d_commit.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  	"reflect"
    21  	"time"
    22  
    23  	"github.com/ethereum/go-ethereum/common"
    24  	"github.com/ethereum/go-ethereum/consensus/podc"
    25  	"github.com/ethereum/go-ethereum/log"
    26  )
    27  
    28  func (c *core) sendDCommit() { //전송
    29  	log.Debug("sendDCommit")
    30  	//logger := c.logger.New("state", c.state)
    31  	//logger.Warn("sendDCommit:")
    32  
    33  	if c.state == StateDSelected {
    34  
    35  		logger := c.logger.New("state", c.state)
    36  		//logger.Warn("sendDCommit(StateDSelected)")
    37  
    38  		sub := c.current.Subject()
    39  		//log.Info("I'm  not the Qmanager : sendDCommit ", "sub.View.Sequence", sub.View.Sequence, "sub.View.Round", sub.View.Round)
    40  
    41  		if sub == nil {
    42  			logger.Error("Failed to get Subject")
    43  			return
    44  		}
    45  		encodedSubject, err := Encode(sub)
    46  		if err != nil {
    47  			logger.Error("Failed to encode", "subject", sub)
    48  			return
    49  		}
    50  		c.broadcast(&message{
    51  			Code: msgCommit,
    52  			Msg:  encodedSubject,
    53  		})
    54  	}
    55  }
    56  
    57  //==============================
    58  func (c *core) handleDCommit(msg *message, src podc.Validator) error { //2. 수신 핸들러가 같은 프로그램에 있음. 상태 천이로,, 해야함.
    59  	//logger := c.logger.New("from", src, "state", c.state)
    60  	//logger.Warn("handleDCommit:")
    61  	// Decode commit message
    62  	var commit *podc.Subject
    63  	err := msg.Decode(&commit) //commit 으로 메모리번지를 통해서, round와 sequence를 가져옴.
    64  	if c.state != StateRequestQman {
    65  		//log.Info("I'm  not the Qmanager : handleDCommit ", "commit.View.Sequence", commit.View.Sequence, "commit.View.Round", commit.View.Round)
    66  		if err != nil {
    67  			return errFailedDecodeCommit
    68  		}
    69  
    70  		if err := c.checkMessage(msgCommit, commit.View); err != nil {
    71  			return err
    72  		}
    73  
    74  		if err := c.verifyDCommit(commit, src); err != nil { //inconsistent.. 3.
    75  			return err
    76  		}
    77  
    78  		c.acceptDCommit(msg, src)
    79  
    80  		log.Debug("handleDCommit 1", "commit count", c.current.Commits.Size())
    81  		// Commit the proposal once we have enough commit messages and we are not in StateCommitted.
    82  		//
    83  		// If we already have a proposal, we may have chance to speed up the consensus process
    84  		// by committing the proposal without prepare messages.
    85  		if c.current.Commits.Size() > 2*c.valSet.F() && c.state.Cmp(StateCommitted) < 0 {
    86  			//if c.current.Commits.Size() > 2*c.voteSet.F() && c.state.Cmp(StateCommitted) < 0 {
    87  			log.Debug("handleDCommit 2 - accepted dcommit 2/3")
    88  			c.commit()
    89  			log.Info("6. D-commit end", "elapsed", common.PrettyDuration(time.Since(c.intervalTime)))
    90  			c.intervalTime = time.Now()
    91  			log.Info("Total Time", "elapsed", common.PrettyDuration(time.Since(c.startTime)))
    92  		}
    93  	}
    94  	return nil
    95  }
    96  
    97  // verifyCommit verifies if the received commit message is equivalent to our subject
    98  func (c *core) verifyDCommit(commit *podc.Subject, src podc.Validator) error {
    99  	logger := c.logger.New("from", src, "state", c.state) //state="Request ExtraData"
   100  
   101  	sub := c.current.Subject()
   102  	//if( !qManager.QManConnected ) { // if I'm not Qman and general geth.
   103  
   104  	//if (!reflect.DeepEqual(c.qmanager, c.Address())) { //if I'm not Qmanager
   105  	//log.Info("I'm not Qmanager : verifyDCommit ", "sub.View.Sequence", sub.View.Sequence, "sub.View.Round", sub.View.Round)
   106  	//if !reflect.DeepEqual(commit, sub) {
   107  	//	logger.Warn("Inconsistent subjects between commit and proposal(verifyDCommit)", "expected", sub, "got", commit)
   108  	//	return errInconsistentSubject
   109  	//}
   110  	//}
   111  	//}else{
   112  	//	log.Info("verifyDCommit ", "Sequence", sub.View.Sequence, "Round", sub.View.Round)
   113  	if !reflect.DeepEqual(commit, sub) {
   114  		logger.Warn("Inconsistent subjects between commit and proposal(verifyDCommit)", "expected", sub, "got", commit)
   115  		return errInconsistentSubject
   116  	}
   117  
   118  	//}
   119  	return nil
   120  }
   121  
   122  func (c *core) acceptDCommit(msg *message, src podc.Validator) error {
   123  	logger := c.logger.New("from", src, "state", c.state)
   124  
   125  	// Add the commit message to current round state
   126  	if err := c.current.Commits.Add(msg); err != nil {
   127  		logger.Error("Failed to record commit message", "msg", msg, "err", err)
   128  		return err
   129  	}
   130  
   131  	return nil
   132  }