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 }