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  }