github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/p2pserver/sync/sync_handler_org.go (about)

     1  package sync
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/sixexorg/magnetic-ring/p2pserver/temp"
     8  
     9  	// "net"
    10  	// "strconv"
    11  	// "strings"
    12  	// "time"
    13  
    14  	lru "github.com/hashicorp/golang-lru"
    15  	evtActor "github.com/ontio/ontology-eventbus/actor"
    16  	"github.com/sixexorg/magnetic-ring/common"
    17  	"github.com/sixexorg/magnetic-ring/log"
    18  
    19  	"github.com/sixexorg/magnetic-ring/bactor"
    20  	"github.com/sixexorg/magnetic-ring/core/orgchain/types"
    21  	msgCommon "github.com/sixexorg/magnetic-ring/p2pserver/common"
    22  	msgpack "github.com/sixexorg/magnetic-ring/p2pserver/message"
    23  	"github.com/sixexorg/magnetic-ring/p2pserver/net/protocol"
    24  )
    25  
    26  //respCache cache for some response data
    27  var respOrgCache *lru.ARCCache
    28  
    29  // HeaderReqHandle handles the header sync req from peer
    30  func OrgHeadersReqHandle(data *msgCommon.MsgPayload, p2p p2p.P2P, pid *evtActor.PID, args ...interface{}) {
    31  	log.Trace("[p2p]receive headers request message", "Addr", data.Addr, "Id", data.Id)
    32  
    33  	headersReq := data.Payload.(*msgCommon.HeadersReq)
    34  
    35  	startHash := headersReq.HashStart
    36  	stopHash := headersReq.HashEnd
    37  
    38  	// headers, err := OrgGetHeadersFromHash(startHash, stopHash,headersReq.OrgID,headersReq.SyncType,headersReq.OrgID)
    39  
    40  	// for test start
    41  	headers, err := OrgGetHeadersFromHeight(headersReq.Height, headersReq.OrgID)
    42  	// OrgGetHeadersFromHeight(srcHeight uint32) ([]*types.Header, error) {
    43  	// for test end
    44  
    45  	if err != nil {
    46  		log.Warn("get headers in HeadersReqHandle ", "error", err.Error(), "startHash", startHash.String(), "stopHash", stopHash.String())
    47  		return
    48  	}
    49  	remotePeer := p2p.GetPeer(data.Id)
    50  	if remotePeer == nil {
    51  		log.Debug("[p2p]remotePeer invalid in HeadersReqHandle, peer", "id", data.Id)
    52  		return
    53  	}
    54  	msg := msgpack.NewHeaders(nil, headers, headersReq.OrgID, headersReq.SyncType)
    55  	err = p2p.Send(remotePeer, msg, false)
    56  	if err != nil {
    57  		log.Warn("err", "err", err)
    58  		return
    59  	}
    60  }
    61  
    62  
    63  func ANodeSendToStellarPeingData(data *msgCommon.MsgPayload, p2p p2p.P2P, pid *evtActor.PID, args ...interface{}) {
    64  	log.Trace("[p2p]receive data req message", "Addr", data.Addr, "Id", data.Id)
    65  	var dataReq = data.Payload.(*msgCommon.Block)
    66  	notifyp2pactor, err := bactor.GetActorPid(bactor.MAINRADARACTOR)
    67  	if err != nil {
    68  		log.Error("ANodeSendToStellarPeingData GetActorPid err", "org", dataReq.OrgID, "err", err)
    69  		return
    70  	}
    71  	fmt.Println("🌐 ANodeSendToStellarPeingData ", dataReq.BlkOrg)
    72  	notifyp2pactor.Tell(dataReq.BlkOrg)
    73  }
    74  
    75  
    76  func StellaNodeSendToStellarPeingData(data *msgCommon.MsgPayload, p2p p2p.P2P, pid *evtActor.PID, args ...interface{}) {
    77  	log.Trace("[p2p]receive data req message", "Addr", data.Addr, "Id", data.Id)
    78  	var dataReq = data.Payload.(*msgCommon.Block)
    79  	notifyp2pactor, err := bactor.GetActorPid(bactor.MAINRADARACTOR)
    80  	if err != nil {
    81  		log.Error("StellaNodeSendToStellarPeingData GetActorPid err", "org", dataReq.OrgID, "err", err)
    82  		return
    83  	}
    84  	notifyp2pactor.Tell(dataReq.BlkOrg)
    85  }
    86  
    87  // OrgDataReqHandle handles the data req(block/Transaction) from peer
    88  func OrgDataReqHandle(data *msgCommon.MsgPayload, p2p p2p.P2P, pid *evtActor.PID, args ...interface{}) {
    89  	log.Trace("[p2p]receive data req message", "Addr", data.Addr, "Id", data.Id)
    90  
    91  	var dataReq = data.Payload.(*msgCommon.DataReq)
    92  
    93  	remotePeer := p2p.GetPeer(data.Id)
    94  	if remotePeer == nil {
    95  		log.Debug("[p2p]remotePeer invalid in DataReqHandle")
    96  		return
    97  	}
    98  	reqType := common.InventoryType(dataReq.DataType)
    99  	hash := dataReq.Hash
   100  	orgID := dataReq.OrgID
   101  	synctype := dataReq.SyncType
   102  	switch reqType {
   103  	case common.BLOCK:
   104  		reqID := fmt.Sprintf("%x%s", reqType, hash.String())
   105  		data := getRespOrgCacheValue(reqID)
   106  		var block *types.Block
   107  		var err error
   108  		if data != nil {
   109  			switch data.(type) {
   110  			case *types.Block:
   111  				block = data.(*types.Block)
   112  			}
   113  		}
   114  		if block == nil {
   115  			if synctype == msgCommon.SYNC_DATA_ORG {
   116  				block, err = temp.GetLedger(orgID).GetBlockByHash(hash /*,orgID*/)
   117  			}
   118  			if err != nil || block == nil || block.Header == nil {
   119  				log.Debug("[p2p]can't get block send not found message by", "hash", hash)
   120  				msg := msgpack.NewNotFound(hash)
   121  				err := p2p.Send(remotePeer, msg, false)
   122  				if err != nil {
   123  					log.Warn("err", "err", err)
   124  					return
   125  				}
   126  				return
   127  			}
   128  			saveRespOrgCache(reqID, block)
   129  		}
   130  		log.Debug("[p2p]block ", "height", block.Header.Height, "hash", hash)
   131  		msg := msgpack.NewBlock(nil, block, orgID, synctype)
   132  		err = p2p.Send(remotePeer, msg, false)
   133  		if err != nil {
   134  			log.Warn("err", "err", err)
   135  			return
   136  		}
   137  	}
   138  }
   139  
   140  func OrgGetHeadersFromHeight(srcHeight uint64, orgID common.Address) ([]*types.Header, error) {
   141  	var count uint64 = 0
   142  	headers := []*types.Header{}
   143  	// var startHeight uint32
   144  	var stopHeight uint64
   145  
   146  	curHeight := temp.GetLedger(orgID).GetCurrentHeaderHeight()
   147  	if srcHeight == 0 {
   148  		if curHeight > msgCommon.MAX_BLK_HDR_CNT {
   149  			count = msgCommon.MAX_BLK_HDR_CNT
   150  		} else {
   151  			count = curHeight
   152  		}
   153  	} else {
   154  		// bkStop, err := ledger.DefLedger.GetHeaderByHash(stopHash)
   155  		// if err != nil || bkStop == nil {
   156  		// 	return nil, err
   157  		// }
   158  		stopHeight = srcHeight
   159  		count = curHeight - stopHeight
   160  		if count > msgCommon.MAX_BLK_HDR_CNT {
   161  			count = msgCommon.MAX_BLK_HDR_CNT
   162  		}
   163  	}
   164  
   165  	var i uint64
   166  	for i = 1; i <= count; i++ {
   167  		hash, _ := temp.GetLedger(orgID).GetBlockHashByHeight(stopHeight + i)
   168  		hd, err := temp.GetLedger(orgID).GetHeaderByHash(hash)
   169  		if err != nil {
   170  			log.Debug("[p2p]net_server GetBlockWithHeight failed with", "err", err.Error(), "hash", hash, "height", stopHeight+i)
   171  			return nil, err
   172  		}
   173  		headers = append(headers, hd)
   174  	}
   175  
   176  	return headers, nil
   177  }
   178  
   179  //get blk hdrs from starthash to stophash
   180  func OrgGetHeadersFromHash(startHash common.Hash, stopHash common.Hash,
   181  	orgid common.Address, orgtype string, orgID common.Address) ([]*types.Header, error) {
   182  	var count uint32 = 0
   183  	headers := []*types.Header{}
   184  	var startHeight uint32
   185  	var stopHeight uint32
   186  	curHeight := uint32(0)
   187  	if orgtype == msgCommon.SYNC_DATA_MAIN {
   188  		curHeight = uint32(temp.GetLedger(orgID).GetCurrentHeaderHeight())
   189  	} else if orgtype == msgCommon.SYNC_DATA_ORG {
   190  		curHeight = uint32(temp.GetLedger(orgID).GetCurrentHeaderHeight( /*orgid*/ ))
   191  	}
   192  
   193  	empty := common.Hash{}
   194  	if startHash == empty {
   195  		if stopHash == empty {
   196  			if curHeight > msgCommon.MAX_BLK_HDR_CNT {
   197  				count = msgCommon.MAX_BLK_HDR_CNT
   198  			} else {
   199  				count = curHeight
   200  			}
   201  		} else {
   202  			var bkStop *types.Header
   203  			var err error
   204  			if orgtype == msgCommon.SYNC_DATA_MAIN {
   205  				bkStop, err = temp.GetLedger(orgID).GetHeaderByHash(stopHash)
   206  			} else if orgtype == msgCommon.SYNC_DATA_ORG {
   207  				bkStop, err = temp.GetLedger(orgID).GetHeaderByHash(stopHash /*,orgid*/)
   208  			}
   209  
   210  			if err != nil || bkStop == nil {
   211  				return nil, err
   212  			}
   213  			stopHeight = uint32(bkStop.Height)
   214  			count = curHeight - stopHeight
   215  			if count > msgCommon.MAX_BLK_HDR_CNT {
   216  				count = msgCommon.MAX_BLK_HDR_CNT
   217  			}
   218  		}
   219  	} else {
   220  		var bkStart *types.Header
   221  		var err error
   222  		if orgtype == msgCommon.SYNC_DATA_MAIN {
   223  			bkStart, err = temp.GetLedger(orgID).GetHeaderByHash(startHash)
   224  		} else if orgtype == msgCommon.SYNC_DATA_ORG {
   225  			bkStart, err = temp.GetLedger(orgID).GetHeaderByHash(startHash /*,orgid*/)
   226  		}
   227  
   228  		if err != nil || bkStart == nil {
   229  			return nil, err
   230  		}
   231  		startHeight = uint32(bkStart.Height)
   232  		empty := common.Hash{}
   233  		if stopHash != empty {
   234  			var bkStop *types.Header
   235  			var err error
   236  			if orgtype == msgCommon.SYNC_DATA_MAIN {
   237  				bkStop, err = temp.GetLedger(orgID).GetHeaderByHash(stopHash)
   238  			} else if orgtype == msgCommon.SYNC_DATA_ORG {
   239  				bkStop, err = temp.GetLedger(orgID).GetHeaderByHash(stopHash /*,orgid*/)
   240  			}
   241  
   242  			if err != nil || bkStop == nil {
   243  				return nil, err
   244  			}
   245  			stopHeight = uint32(bkStop.Height)
   246  
   247  			// avoid unsigned integer underflow
   248  			if startHeight < stopHeight {
   249  				return nil, errors.New("[p2p]do not have header to send")
   250  			}
   251  			count = startHeight - stopHeight
   252  
   253  			if count >= msgCommon.MAX_BLK_HDR_CNT {
   254  				count = msgCommon.MAX_BLK_HDR_CNT
   255  				stopHeight = startHeight - msgCommon.MAX_BLK_HDR_CNT
   256  			}
   257  		} else {
   258  
   259  			if startHeight > msgCommon.MAX_BLK_HDR_CNT {
   260  				count = msgCommon.MAX_BLK_HDR_CNT
   261  			} else {
   262  				count = startHeight
   263  			}
   264  		}
   265  	}
   266  	var i uint32
   267  	for i = 1; i <= count; i++ {
   268  		var (
   269  			hash common.Hash
   270  			hd   *types.Header
   271  			err  error
   272  		)
   273  		if orgtype == msgCommon.SYNC_DATA_MAIN {
   274  			hash, _ = temp.GetLedger(orgID).GetBlockHashByHeight(uint64(stopHeight + i))
   275  			hd, err = temp.GetLedger(orgID).GetHeaderByHash(hash)
   276  		} else if orgtype == msgCommon.SYNC_DATA_ORG {
   277  			hash, _ = temp.GetLedger(orgID).GetBlockHashByHeight(uint64(stopHeight + i) /*,orgid*/)
   278  			hd, err = temp.GetLedger(orgID).GetHeaderByHash(hash /*,orgid*/)
   279  		}
   280  
   281  		if err != nil {
   282  			log.Debug("[p2p]net_server GetBlockWithHeight failed with", "err", err.Error(), "hash", hash, "height", stopHeight+i)
   283  			return nil, err
   284  		}
   285  		headers = append(headers, hd)
   286  	}
   287  
   288  	return headers, nil
   289  }
   290  
   291  //getRespOrgCacheValue get response data from cache
   292  func getRespOrgCacheValue(key string) interface{} {
   293  	if respOrgCache == nil {
   294  		return nil
   295  	}
   296  	data, ok := respOrgCache.Get(key)
   297  	if ok {
   298  		return data
   299  	}
   300  	return nil
   301  }
   302  
   303  //saveRespOrgCache save response msg to cache
   304  func saveRespOrgCache(key string, value interface{}) bool {
   305  	if respOrgCache == nil {
   306  		var err error
   307  		respOrgCache, err = lru.NewARC(msgCommon.MAX_RESP_CACHE_SIZE)
   308  		if err != nil {
   309  			return false
   310  		}
   311  	}
   312  	respOrgCache.Add(key, value)
   313  	return true
   314  }