github.com/turingchain2020/turingchain@v1.1.21/system/p2p/dht/protocol/broadcast/tx.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package broadcast
     6  
     7  import (
     8  	"encoding/hex"
     9  
    10  	"github.com/turingchain2020/turingchain/types"
    11  )
    12  
    13  func (p *broadcastProtocol) sendTx(tx *types.P2PTx, p2pData *types.BroadCastData, pid string) (doSend bool) {
    14  
    15  	txHash := hex.EncodeToString(tx.Tx.Hash())
    16  	ttl := tx.GetRoute().GetTTL()
    17  	isLightSend := ttl >= p.p2pCfg.LightTxTTL
    18  
    19  	//检测冗余发送, 已经发送或者接收过此Tx
    20  	if addIgnoreSendPeerAtomic(p.txSendFilter, txHash, pid) {
    21  		return false
    22  	}
    23  
    24  	//log.Debug("P2PSendTx", "txHash", txHash, "ttl", ttl, "peerAddr", peerAddr)
    25  	//超过最大的ttl, 不再发送
    26  	if ttl > p.p2pCfg.MaxTTL { //超过最大发送次数
    27  		return false
    28  	}
    29  
    30  	//新版本且ttl达到设定值
    31  	if isLightSend {
    32  		p2pData.Value = &types.BroadCastData_LtTx{ //超过最大的ttl, 不再发送
    33  			LtTx: &types.LightTx{
    34  				TxHash: tx.Tx.Hash(),
    35  				Route:  tx.GetRoute(),
    36  			},
    37  		}
    38  	} else {
    39  		p2pData.Value = &types.BroadCastData_Tx{Tx: tx} //完整Tx发送
    40  	}
    41  	return true
    42  }
    43  
    44  func (p *broadcastProtocol) recvTx(tx *types.P2PTx, pid string) (err error) {
    45  	if tx.GetTx() == nil {
    46  		return
    47  	}
    48  	txHash := hex.EncodeToString(tx.GetTx().Hash())
    49  	//将节点id添加到发送过滤, 避免冗余发送
    50  	addIgnoreSendPeerAtomic(p.txSendFilter, txHash, pid)
    51  	//避免重复接收
    52  	if p.txFilter.AddWithCheckAtomic(txHash, true) {
    53  		return
    54  	}
    55  	//log.Debug("recvTx", "tx", txHash, "ttl", tx.GetRoute().GetTTL(), "peerAddr", peerAddr)
    56  	//有可能收到老版本的交易路由,此时route是空指针
    57  	if tx.GetRoute() == nil {
    58  		tx.Route = &types.P2PRoute{TTL: 1}
    59  	}
    60  	p.txFilter.Add(txHash, tx.GetRoute())
    61  	return p.postMempool(txHash, tx.GetTx())
    62  
    63  }
    64  
    65  func (p *broadcastProtocol) recvLtTx(tx *types.LightTx, pid, peerAddr, version string) (err error) {
    66  
    67  	txHash := hex.EncodeToString(tx.TxHash)
    68  	//将节点id添加到发送过滤, 避免冗余发送
    69  	addIgnoreSendPeerAtomic(p.txSendFilter, txHash, pid)
    70  	//存在则表示本地已经接收过此交易, 不做任何操作
    71  	if p.txFilter.Contains(txHash) {
    72  		return nil
    73  	}
    74  
    75  	//log.Debug("recvLtTx", "txHash", txHash, "ttl", tx.GetRoute().GetTTL(), "peerAddr", peerAddr)
    76  	//本地不存在, 需要向对端节点发起完整交易请求
    77  	query := &types.P2PQueryData{}
    78  	query.Value = &types.P2PQueryData_TxReq{
    79  		TxReq: &types.P2PTxReq{
    80  			TxHash: tx.TxHash,
    81  		},
    82  	}
    83  	//发布到指定的节点
    84  	if p.sendPeer(query, pid, version) != nil {
    85  		log.Error("recvLtTx", "pid", pid, "addr", peerAddr, "err", err)
    86  		return errSendPeer
    87  	}
    88  
    89  	return nil
    90  }