github.com/aergoio/aergo@v1.3.1/p2p/msgorder.go (about)

     1  /**
     2   *  @file
     3   *  @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package p2p
     7  
     8  import (
     9  	"github.com/aergoio/aergo/consensus"
    10  	"github.com/aergoio/aergo/p2p/raftsupport"
    11  	"github.com/aergoio/etcd/raft/raftpb"
    12  	"time"
    13  
    14  	"github.com/aergoio/aergo/internal/enc"
    15  	"github.com/aergoio/aergo/p2p/p2pcommon"
    16  	"github.com/aergoio/aergo/p2p/p2putil"
    17  
    18  	"github.com/aergoio/aergo/types"
    19  )
    20  
    21  // ClientVersion is the version of p2p protocol to which this codes are built
    22  
    23  type pbMessageOrder struct {
    24  	// reqID means that this message is response of the request of ID. Set empty if the message is request.
    25  	request    bool
    26  	needSign   bool
    27  	trace      bool
    28  	protocolID p2pcommon.SubProtocol // protocolName and msg struct type MUST be matched.
    29  
    30  	message p2pcommon.Message
    31  }
    32  
    33  var _ p2pcommon.MsgOrder = (*pbRequestOrder)(nil)
    34  var _ p2pcommon.MsgOrder = (*pbResponseOrder)(nil)
    35  var _ p2pcommon.MsgOrder = (*pbBlkNoticeOrder)(nil)
    36  var _ p2pcommon.MsgOrder = (*pbTxNoticeOrder)(nil)
    37  var _ p2pcommon.MsgOrder = (*pbRaftMsgOrder)(nil)
    38  
    39  func (pr *pbMessageOrder) GetMsgID() p2pcommon.MsgID {
    40  	return pr.message.ID()
    41  }
    42  
    43  func (pr *pbMessageOrder) Timestamp() int64 {
    44  	return pr.message.Timestamp()
    45  }
    46  
    47  func (pr *pbMessageOrder) IsRequest() bool {
    48  	return pr.request
    49  }
    50  
    51  func (pr *pbMessageOrder) IsNeedSign() bool {
    52  	return pr.needSign
    53  }
    54  
    55  func (pr *pbMessageOrder) GetProtocolID() p2pcommon.SubProtocol {
    56  	return pr.protocolID
    57  }
    58  
    59  func (pr *pbMessageOrder) CancelSend(pi p2pcommon.RemotePeer) {
    60  }
    61  
    62  type pbRequestOrder struct {
    63  	pbMessageOrder
    64  	respReceiver p2pcommon.ResponseReceiver
    65  }
    66  
    67  func (pr *pbRequestOrder) SendTo(pi p2pcommon.RemotePeer) error {
    68  	p := pi.(*remotePeerImpl)
    69  	p.reqMutex.Lock()
    70  	p.requests[pr.message.ID()] = &requestInfo{cTime: time.Now(), reqMO: pr, receiver: pr.respReceiver}
    71  	p.reqMutex.Unlock()
    72  	err := p.rw.WriteMsg(pr.message)
    73  	if err != nil {
    74  		p.logger.Warn().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Err(err).Msg("fail to SendTo")
    75  		p.reqMutex.Lock()
    76  		delete(p.requests, pr.message.ID())
    77  		p.reqMutex.Unlock()
    78  		return err
    79  	}
    80  
    81  	if pr.trace {
    82  		p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).
    83  			Str(p2putil.LogMsgID, pr.GetMsgID().String()).Msg("Send request message")
    84  	}
    85  	return nil
    86  }
    87  
    88  type pbResponseOrder struct {
    89  	pbMessageOrder
    90  }
    91  
    92  func (pr *pbResponseOrder) SendTo(pi p2pcommon.RemotePeer) error {
    93  	p := pi.(*remotePeerImpl)
    94  	err := p.rw.WriteMsg(pr.message)
    95  	if err != nil {
    96  		p.logger.Warn().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Err(err).Msg("fail to SendTo")
    97  		return err
    98  	}
    99  	if pr.trace {
   100  		p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).
   101  			Str(p2putil.LogMsgID, pr.GetMsgID().String()).Str(p2putil.LogOrgReqID, pr.message.OriginalID().String()).Msg("Send response message")
   102  	}
   103  
   104  	return nil
   105  }
   106  
   107  type pbBlkNoticeOrder struct {
   108  	pbMessageOrder
   109  	blkHash []byte
   110  	blkNo   uint64
   111  }
   112  
   113  func (pr *pbBlkNoticeOrder) SendTo(pi p2pcommon.RemotePeer) error {
   114  	p := pi.(*remotePeerImpl)
   115  	var blkHash = types.ToBlockID(pr.blkHash)
   116  	passedTime := time.Now().Sub(p.lastBlkNoticeTime)
   117  	skipNotice := false
   118  	if p.LastStatus().BlockNumber >= pr.blkNo {
   119  		heightDiff := p.LastStatus().BlockNumber - pr.blkNo
   120  		switch {
   121  		case heightDiff >= GapToSkipAll:
   122  			skipNotice = true
   123  		case heightDiff >= GapToSkipHourly:
   124  			skipNotice = p.skipCnt < GapToSkipHourly
   125  		default:
   126  			skipNotice = p.skipCnt < GapToSkip5Min
   127  		}
   128  	}
   129  	if skipNotice || passedTime < MinNewBlkNoticeInterval {
   130  		p.skipCnt++
   131  		if p.skipCnt&0x03ff == 0 && pr.trace {
   132  			p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Int32("skip_cnt", p.skipCnt).Msg("Skipped NewBlockNotice ")
   133  
   134  		}
   135  		return nil
   136  	}
   137  
   138  	if ok, _ := p.blkHashCache.ContainsOrAdd(blkHash, cachePlaceHolder); ok {
   139  		// the remote peer already know this block hash. skip too many not-interesting log,
   140  		// p.logger.Debug().Str(LogPeerName,p.Name()).Str(LogProtoID, pr.GetProtocolID().String()).
   141  		// 	Str(LogMsgID, pr.GetMsgID()).Msg("Cancel sending blk notice. peer knows this block")
   142  		return nil
   143  	}
   144  	err := p.rw.WriteMsg(pr.message)
   145  	if err != nil {
   146  		p.logger.Warn().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Err(err).Msg("fail to SendTo")
   147  		return err
   148  	}
   149  	p.lastBlkNoticeTime = time.Now()
   150  	if p.skipCnt > 100 && pr.trace {
   151  		p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Int32("skip_cnt", p.skipCnt).Msg("Send NewBlockNotice after long skip")
   152  	}
   153  	p.skipCnt = 0
   154  	return nil
   155  }
   156  
   157  type pbBpNoticeOrder struct {
   158  	pbMessageOrder
   159  	block *types.Block
   160  }
   161  
   162  func (pr *pbBpNoticeOrder) SendTo(pi p2pcommon.RemotePeer) error {
   163  	p := pi.(*remotePeerImpl)
   164  	var blkHash = types.ToBlockID(pr.block.Hash)
   165  	p.blkHashCache.ContainsOrAdd(blkHash, cachePlaceHolder)
   166  	err := p.rw.WriteMsg(pr.message)
   167  	if err != nil {
   168  		p.logger.Warn().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Err(err).Msg("fail to SendTo")
   169  		return err
   170  	}
   171  	if pr.trace {
   172  		p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).
   173  			Str(p2putil.LogMsgID, pr.GetMsgID().String()).Str(p2putil.LogBlkHash, enc.ToString(pr.block.Hash)).Msg("Notify block produced")
   174  	}
   175  	return nil
   176  }
   177  
   178  type pbTxNoticeOrder struct {
   179  	pbMessageOrder
   180  	txHashes []types.TxID
   181  	tnt p2pcommon.TxNoticeTracer
   182  }
   183  
   184  func (pr *pbTxNoticeOrder) SendTo(pi p2pcommon.RemotePeer) error {
   185  	p := pi.(*remotePeerImpl)
   186  
   187  	err := p.rw.WriteMsg(pr.message)
   188  	if err != nil {
   189  		p.logger.Warn().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Err(err).Msg("fail to SendTo")
   190  		pr.tnt.ReportNotSend(pr.txHashes, 1)
   191  		return err
   192  	}
   193  	if p.logger.IsDebugEnabled() && pr.trace {
   194  		p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).
   195  			Str(p2putil.LogMsgID, pr.GetMsgID().String()).Int("hash_cnt", len(pr.txHashes)).Array("hashes", types.NewLogTxIDsMarshaller(pr.txHashes, 10)).Msg("Sent tx notice")
   196  	}
   197  	pr.tnt.ReportSend(pr.txHashes, pi.ID())
   198  	return nil
   199  }
   200  
   201  func (pr *pbTxNoticeOrder) CancelSend(pi p2pcommon.RemotePeer) {
   202  	pr.tnt.ReportNotSend(pr.txHashes, 1)
   203  }
   204  
   205  type pbRaftMsgOrder struct {
   206  	pbMessageOrder
   207  	raftAcc consensus.AergoRaftAccessor
   208  	msg     *raftpb.Message
   209  }
   210  
   211  func (pr *pbRaftMsgOrder) SendTo(pi p2pcommon.RemotePeer) error {
   212  	p := pi.(*remotePeerImpl)
   213  
   214  	err := p.rw.WriteMsg(pr.message)
   215  	if err != nil {
   216  		p.logger.Warn().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Err(err).Object("raftMsg", raftsupport.RaftMsgMarshaller{pr.msg}).Msg("fail to Send raft message")
   217  		pr.raftAcc.ReportUnreachable(pi.ID())
   218  		return err
   219  	}
   220  	if pr.trace && p.logger.IsDebugEnabled() {
   221  		p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Object("raftMsg", raftsupport.RaftMsgMarshaller{pr.msg}).Msg("Sent raft message")
   222  	}
   223  	return nil
   224  }
   225  
   226  func (pr *pbRaftMsgOrder) CancelSend(pi p2pcommon.RemotePeer) {
   227  	// TODO test more whether to uncomment or to delete code below
   228  	//pr.raftAcc.ReportUnreachable(pi.ID())
   229  }