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 }