github.com/aergoio/aergo@v1.3.1/p2p/ancestorreceiver.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/message" 10 "github.com/aergoio/aergo/p2p/p2pcommon" 11 "github.com/aergoio/aergo/types" 12 "time" 13 ) 14 15 // BlocksChunkReceiver is send p2p getBlocksRequest to target peer and receive p2p responses till all requests blocks are received 16 // It will send response actor message if all blocks are received or failed to receive, but not send response if timeout expired. 17 type AncestorReceiver struct { 18 syncerSeq uint64 19 requestID p2pcommon.MsgID 20 21 peer p2pcommon.RemotePeer 22 actor p2pcommon.ActorService 23 24 hashes [][]byte 25 timeout time.Time 26 finished bool 27 } 28 29 func NewAncestorReceiver(actor p2pcommon.ActorService, peer p2pcommon.RemotePeer, seq uint64, hashes [][]byte, ttl time.Duration) *AncestorReceiver { 30 timeout := time.Now().Add(ttl) 31 return &AncestorReceiver{syncerSeq: seq, actor: actor, peer: peer, hashes: hashes, timeout: timeout} 32 } 33 34 func (br *AncestorReceiver) StartGet() { 35 // create message data 36 req := &types.GetAncestorRequest{Hashes: br.hashes} 37 mo := br.peer.MF().NewMsgBlockRequestOrder(br.ReceiveResp, p2pcommon.GetAncestorRequest, req) 38 br.requestID = mo.GetMsgID() 39 br.peer.SendMessage(mo) 40 } 41 42 // ReceiveResp must be called just in read go routine 43 func (br *AncestorReceiver) ReceiveResp(msg p2pcommon.Message, msgBody p2pcommon.MessageBody) (ret bool) { 44 ret = true 45 // timeout 46 if br.finished || br.timeout.Before(time.Now()) { 47 br.finished = true 48 br.peer.ConsumeRequest(br.requestID) 49 return 50 } 51 // remote peer response failure 52 data := msgBody.(*types.GetAncestorResponse) 53 if data.Status != types.ResultStatus_OK { 54 br.actor.TellRequest(message.SyncerSvc, &message.GetSyncAncestorRsp{Seq:br.syncerSeq, Ancestor: nil}) 55 br.finished = true 56 br.peer.ConsumeRequest(br.requestID) 57 return 58 } 59 ancestor := &types.BlockInfo{Hash: data.AncestorHash, No: data.AncestorNo} 60 61 br.actor.TellRequest(message.SyncerSvc, &message.GetSyncAncestorRsp{Seq:br.syncerSeq, Ancestor: ancestor}) 62 br.finished = true 63 br.peer.ConsumeRequest(br.requestID) 64 return 65 }