github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/consensus/pbft/core/body_request.go (about)

     1  // Copyright 2020 The go-simplechain Authors
     2  // This file is part of the go-simplechain library.
     3  //
     4  // The go-simplechain 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-simplechain 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-simplechain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  import (
    20  	"github.com/bigzoro/my_simplechain/consensus/pbft"
    21  	"github.com/bigzoro/my_simplechain/core/types"
    22  )
    23  
    24  func (c *core) requestMissedTxs(missedTxs []types.MissedTx, val pbft.Validator) {
    25  	logger := c.logger.New("state", c.state, "to", val)
    26  
    27  	missedReq := &pbft.MissedReq{
    28  		View:      c.currentView(),
    29  		MissedTxs: missedTxs,
    30  	}
    31  
    32  	encMissedReq, err := Encode(missedReq)
    33  	if err != nil {
    34  		logger.Error("Failed to encode", "missedReq", missedReq, "err", err)
    35  		return
    36  	}
    37  
    38  	//logger.Trace("[report] requestMissedTxs", "view", missedReq.View, "missed", len(missedTxs))
    39  
    40  	c.send(&message{
    41  		Code: msgGetMissedTxs,
    42  		Msg:  encMissedReq,
    43  	}, pbft.Validators{val})
    44  }
    45  
    46  func (c *core) handleGetMissedTxs(msg *message, src pbft.Validator) error {
    47  	logger := c.logger.New("from", src, "state", c.state)
    48  
    49  	var missed *pbft.MissedReq
    50  	err := msg.Decode(&missed)
    51  	if err != nil {
    52  		logger.Error("Failed to decode", "err", err)
    53  		return errFailedDecodePrepare
    54  	}
    55  
    56  	//logger.Trace("[report] handleGetMissedTxs", "view", missed.View, "missed", len(missed.MissedTxs))
    57  
    58  	if err := c.checkMessage(msgGetMissedTxs, missed.View); err != nil {
    59  		logFn := logger.Warn
    60  		switch err {
    61  		case errOldMessage: //TODO
    62  			logFn = logger.Trace
    63  		case errFutureMessage: //TODO
    64  			logFn = logger.Trace
    65  		}
    66  		logFn("GetMissedTxs checkMessage failed", "view", missed.View, "missed", len(missed.MissedTxs), "err", err)
    67  		return err
    68  	}
    69  
    70  	// proposer must have a filled proposal, return if the proposal is not exist
    71  	proposal := c.current.Proposal()
    72  	if proposal == nil {
    73  		logger.Warn("nonexistent completed proposal")
    74  		return errNonexistentProposal
    75  	}
    76  
    77  	txs, err := proposal.FetchMissedTxs(missed.MissedTxs)
    78  	if err != nil {
    79  		return err
    80  	}
    81  
    82  	c.responseMissedTxs(txs, src)
    83  
    84  	return nil
    85  }
    86  
    87  func (c *core) responseMissedTxs(txs types.Transactions, val pbft.Validator) {
    88  	logger := c.logger.New("state", c.state, "to", val)
    89  
    90  	missedResp := &pbft.MissedResp{
    91  		View:   c.currentView(),
    92  		ReqTxs: txs,
    93  	}
    94  
    95  	//logger.Trace("[report] responseMissedTxs", "view", missedResp.View, "missed", len(txs))
    96  
    97  	//encMissedResp, err := Encode(missedResp)
    98  	encMissedResp, err := missedResp.EncodeOffset()
    99  	if err != nil {
   100  		logger.Error("Failed to encode", "missedResp", missedResp, "err", err)
   101  		return
   102  	}
   103  
   104  	// Mark txs known by val, and do not sync them again
   105  	c.backend.MarkTransactionKnownBy(val, txs)
   106  
   107  	c.send(&message{
   108  		Code: msgMissedTxs,
   109  		Msg:  encMissedResp,
   110  	}, pbft.Validators{val})
   111  }
   112  
   113  func (c *core) handleMissedTxs(msg *message, src pbft.Validator) error {
   114  	logger := c.logger.New("from", src, "state", c.state)
   115  
   116  	var missed pbft.MissedResp
   117  	//err := msg.Decode(&missed)
   118  	err := missed.DecodeOffset(msg.Msg)
   119  	if err != nil {
   120  		return errFailedDecodePrepare
   121  	}
   122  
   123  	//logger.Trace("[report] handleMissedTxs", "view", missed.View)
   124  
   125  	if err := c.checkMessage(msgMissedTxs, missed.View); err != nil {
   126  		logFn := logger.Warn
   127  		switch err {
   128  		case errOldMessage: //TODO
   129  			logFn = logger.Trace
   130  		case errFutureMessage: //TODO
   131  			logFn = logger.Trace
   132  		}
   133  		logFn("MissedTxs checkMessage failed", "view", missed.View, "missed", len(missed.ReqTxs), "err", err)
   134  		return err
   135  	}
   136  
   137  	lp := c.current.LightProposal()
   138  	if lp == nil {
   139  		logger.Warn("local light proposal was lost", "view", missed.View, "Preprepare", c.current.Preprepare)
   140  		return nil
   141  	}
   142  
   143  	// do not accept completed proposal repeatedly
   144  	if lp.Completed() {
   145  		logger.Warn("local light was already completed", "view", missed.View)
   146  		return nil
   147  	}
   148  
   149  	if err := lp.FillMissedTxs(missed.ReqTxs); err != nil {
   150  		return err
   151  	}
   152  
   153  	return c.handleLightPrepare2(c.current.LightPrepare.FullPreprepare(), src)
   154  }