github.com/aergoio/aergo@v1.3.1/p2p/hashbynoreceiver.go (about) 1 /* 2 * @file 3 * @copyright defined in aergo/LICENSE.txt 4 */ 5 6 package p2p 7 8 import ( 9 "time" 10 11 "github.com/aergoio/aergo/message" 12 "github.com/aergoio/aergo/p2p/p2pcommon" 13 "github.com/aergoio/aergo/types" 14 ) 15 16 // BlocksChunkReceiver is send p2p getBlocksRequest to target peer and receive p2p responses till all requests blocks are received 17 // It will send response actor message if all blocks are received or failed to receive, but not send response if timeout expired. 18 type BlockHashByNoReceiver struct { 19 syncerSeq uint64 20 requestID p2pcommon.MsgID 21 22 peer p2pcommon.RemotePeer 23 actor p2pcommon.ActorService 24 25 blockNo types.BlockNo 26 timeout time.Time 27 finished bool 28 29 got message.BlockHash 30 } 31 32 func NewBlockHashByNoReceiver(actor p2pcommon.ActorService, peer p2pcommon.RemotePeer, seq uint64, blockNo types.BlockNo, ttl time.Duration) *BlockHashByNoReceiver { 33 timeout := time.Now().Add(ttl) 34 return &BlockHashByNoReceiver{syncerSeq: seq, actor: actor, peer: peer, blockNo: blockNo, timeout: timeout} 35 } 36 37 func (br *BlockHashByNoReceiver) StartGet() { 38 // create message data 39 req := &types.GetHashByNo{BlockNo: br.blockNo} 40 mo := br.peer.MF().NewMsgBlockRequestOrder(br.ReceiveResp, p2pcommon.GetHashByNoRequest, req) 41 br.requestID = mo.GetMsgID() 42 br.peer.SendMessage(mo) 43 } 44 45 // ReceiveResp must be called just in read go routine 46 func (br *BlockHashByNoReceiver) ReceiveResp(msg p2pcommon.Message, msgBody p2pcommon.MessageBody) (ret bool) { 47 ret = true 48 // timeout 49 if br.finished || br.timeout.Before(time.Now()) { 50 // silently ignore already finished job 51 //br.actor.TellRequest(message.SyncerSvc,&message.GetBlockChunksRsp{ToWhom:br.peer.ID(), Err:message.RemotePeerFailError}) 52 br.finished = true 53 br.peer.ConsumeRequest(br.requestID) 54 return 55 } 56 // remote peer response failure 57 body := msgBody.(*types.GetHashByNoResponse) 58 if body.Status != types.ResultStatus_OK { 59 br.actor.TellRequest(message.SyncerSvc, &message.GetHashByNoRsp{Seq:br.syncerSeq, BlockHash: nil, Err: message.RemotePeerFailError}) 60 br.finished = true 61 br.peer.ConsumeRequest(br.requestID) 62 return 63 } 64 br.got = body.BlockHash 65 br.actor.TellRequest(message.SyncerSvc, &message.GetHashByNoRsp{Seq:br.syncerSeq, BlockHash: br.got}) 66 br.finished = true 67 br.peer.ConsumeRequest(br.requestID) 68 return 69 }