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

     1  package peer
     2  
     3  import (
     4  	"errors"
     5  	"net"
     6  	"runtime"
     7  	"sync"
     8  	"sync/atomic"
     9  	"time"
    10  
    11  	comm "github.com/sixexorg/magnetic-ring/common"
    12  	"github.com/sixexorg/magnetic-ring/log"
    13  	"github.com/sixexorg/magnetic-ring/p2pserver/common"
    14  	"github.com/sixexorg/magnetic-ring/p2pserver/discover"
    15  	"github.com/sixexorg/magnetic-ring/p2pserver/sync/conn"
    16  )
    17  
    18  // PeerCom provides the basic information of a peer
    19  type PeerCom struct {
    20  	id           uint64
    21  	version      uint32
    22  	services     uint64
    23  	relay        bool
    24  	httpInfoPort uint16
    25  	syncPort     uint16
    26  	consPort     uint16
    27  	height       uint64
    28  	orgheight    map[comm.Address]uint64 // org info
    29  	syncorg      sync.RWMutex
    30  }
    31  
    32  // SetID sets a peer's id
    33  func (this *PeerCom) SetID(id uint64) {
    34  	this.id = id
    35  }
    36  
    37  // GetID returns a peer's id
    38  func (this *PeerCom) GetID() uint64 {
    39  	return this.id
    40  }
    41  
    42  // SetVersion sets a peer's version
    43  func (this *PeerCom) SetVersion(version uint32) {
    44  	this.version = version
    45  }
    46  
    47  // GetVersion returns a peer's version
    48  func (this *PeerCom) GetVersion() uint32 {
    49  	return this.version
    50  }
    51  
    52  // SetServices sets a peer's services
    53  func (this *PeerCom) SetServices(services uint64) {
    54  	this.services = services
    55  }
    56  
    57  // GetServices returns a peer's services
    58  func (this *PeerCom) GetServices() uint64 {
    59  	return this.services
    60  }
    61  
    62  // SerRelay sets a peer's relay
    63  func (this *PeerCom) SetRelay(relay bool) {
    64  	this.relay = relay
    65  }
    66  
    67  // GetRelay returns a peer's relay
    68  func (this *PeerCom) GetRelay() bool {
    69  	return this.relay
    70  }
    71  
    72  // SetSyncPort sets a peer's sync port
    73  func (this *PeerCom) SetSyncPort(port uint16) {
    74  	this.syncPort = port
    75  }
    76  
    77  // GetSyncPort returns a peer's sync port
    78  func (this *PeerCom) GetSyncPort() uint16 {
    79  	return this.syncPort
    80  }
    81  
    82  // SetConsPort sets a peer's consensus port
    83  func (this *PeerCom) SetConsPort(port uint16) {
    84  	this.consPort = port
    85  }
    86  
    87  // GetConsPort returns a peer's consensus port
    88  func (this *PeerCom) GetConsPort() uint16 {
    89  	return this.consPort
    90  }
    91  
    92  // SetHttpInfoPort sets a peer's http info port
    93  func (this *PeerCom) SetHttpInfoPort(port uint16) {
    94  	this.httpInfoPort = port
    95  }
    96  
    97  // GetHttpInfoPort returns a peer's http info port
    98  func (this *PeerCom) GetHttpInfoPort() uint16 {
    99  	return this.httpInfoPort
   100  }
   101  
   102  // SetHeight sets a peer's height
   103  func (this *PeerCom) SetHeight(height uint64) {
   104  	this.height = height
   105  }
   106  
   107  // GetHeight returns a peer's height
   108  func (this *PeerCom) GetHeight() uint64 {
   109  	return this.height
   110  }
   111  
   112  // p2pserver call the PeerAddOrg fuc ownnode
   113  func (this *PeerCom) PeerAddOrg(id comm.Address) {
   114  	this.syncorg.Lock()
   115  	defer this.syncorg.Unlock()
   116  	if this.orgheight == nil {
   117  		this.orgheight = make(map[comm.Address]uint64)
   118  	}
   119  
   120  	this.orgheight[id] = 0
   121  }
   122  
   123  // p2pserver call the PeerDelOrg fuc ownnode
   124  func (this *PeerCom) PeerDelOrg(id comm.Address) {
   125  	this.syncorg.Lock()
   126  	defer this.syncorg.Unlock()
   127  	if this.orgheight == nil {
   128  		this.orgheight = make(map[comm.Address]uint64)
   129  	}
   130  
   131  	delete(this.orgheight, id)
   132  	if len(this.orgheight) == 0 {
   133  		this.orgheight = make(map[comm.Address]uint64)
   134  	}
   135  }
   136  
   137  // p2pserver call the PeerGetOrg fuc ownnode
   138  func (this *PeerCom) PeerGetOrg() []comm.Address {
   139  	this.syncorg.Lock()
   140  	defer this.syncorg.Unlock()
   141  	if this.orgheight == nil {
   142  		this.orgheight = make(map[comm.Address]uint64)
   143  	}
   144  	result := make([]comm.Address, 0)
   145  	for id, _ := range this.orgheight {
   146  		result = append(result, id)
   147  	}
   148  
   149  	return result
   150  }
   151  
   152  func (this *PeerCom) PeerGetRealOrg() []comm.Address {
   153  	this.syncorg.Lock()
   154  	defer this.syncorg.Unlock()
   155  	if this.orgheight == nil {
   156  		this.orgheight = make(map[comm.Address]uint64)
   157  	}
   158  	result := make([]comm.Address, 0)
   159  	for id, _ := range this.orgheight {
   160  
   161  		if !id.Equals(common.StellarNodeID) {
   162  			result = append(result, id)
   163  		}
   164  	}
   165  
   166  	return result
   167  }
   168  
   169  // SetOrgHeight sets a org peer's height : ownnode
   170  func (this *PeerCom) SetOwnOrgHeight(height uint64, id comm.Address) {
   171  	this.syncorg.Lock()
   172  	defer this.syncorg.Unlock()
   173  	if this.orgheight == nil {
   174  		this.orgheight = make(map[comm.Address]uint64)
   175  	}
   176  
   177  	this.orgheight[id] = height
   178  }
   179  
   180  // GetOwnOrgHeight returns a own org peer's height : ownnode
   181  func (this *PeerCom) GetOwnOrgHeight(id comm.Address) uint64 {
   182  	this.syncorg.Lock()
   183  	defer this.syncorg.Unlock()
   184  	if this.orgheight == nil {
   185  		this.orgheight = make(map[comm.Address]uint64)
   186  	}
   187  
   188  	return this.orgheight[id]
   189  }
   190  
   191  // Remote peer handler
   192  
   193  // SetRemoteOrgHeight sets a org peer's height : remotenode
   194  func (this *PeerCom) SetRemoteOrgHeight(height uint64, id comm.Address) bool {
   195  	this.syncorg.Lock()
   196  	defer this.syncorg.Unlock()
   197  	if this.orgheight == nil {
   198  		this.orgheight = make(map[comm.Address]uint64)
   199  	}
   200  	bnew := true
   201  	if _, ok := this.orgheight[id]; ok {
   202  		bnew = false
   203  	}
   204  	this.orgheight[id] = height
   205  	return bnew
   206  }
   207  
   208  // GetRemoteOrgHeight returns a remote org peer's height : remotenode
   209  func (this *PeerCom) GetRemoteOrgHeight(id comm.Address) uint64 {
   210  	this.syncorg.Lock()
   211  	defer this.syncorg.Unlock()
   212  	if this.orgheight == nil {
   213  		this.orgheight = make(map[comm.Address]uint64)
   214  	}
   215  
   216  	return this.orgheight[id]
   217  }
   218  
   219  func (this *PeerCom) GetRemoteOrgs() []comm.Address {
   220  	this.syncorg.Lock()
   221  	defer this.syncorg.Unlock()
   222  
   223  	result := make([]comm.Address, 0)
   224  	for orgid, _ := range this.orgheight {
   225  		result = append(result, orgid)
   226  	}
   227  	return result
   228  }
   229  
   230  func (this *PeerCom) DelRemoteOrg(id comm.Address) bool {
   231  	this.syncorg.Lock()
   232  	defer this.syncorg.Unlock()
   233  
   234  	if this.orgheight == nil {
   235  		this.orgheight = make(map[comm.Address]uint64)
   236  	}
   237  
   238  	bhave := false
   239  	if _, ok := this.orgheight[id]; ok {
   240  		bhave = true
   241  	}
   242  	delete(this.orgheight, id)
   243  	if len(this.orgheight) == 0 {
   244  		this.orgheight = make(map[comm.Address]uint64)
   245  	}
   246  	return bhave
   247  }
   248  
   249  func (this *PeerCom) BHaveOrgs() bool {
   250  	this.syncorg.Lock()
   251  	defer this.syncorg.Unlock()
   252  
   253  	if this.orgheight == nil {
   254  		this.orgheight = make(map[comm.Address]uint64)
   255  	}
   256  
   257  	return len(this.orgheight) > 0
   258  }
   259  
   260  func (this *PeerCom) BHaveOrgID(id comm.Address) bool {
   261  	this.syncorg.Lock()
   262  	defer this.syncorg.Unlock()
   263  
   264  	if this.orgheight == nil {
   265  		this.orgheight = make(map[comm.Address]uint64)
   266  	}
   267  	bhave := false
   268  	if _, ok := this.orgheight[id]; ok {
   269  		bhave = true
   270  	}
   271  	return bhave
   272  }
   273  
   274  func (this *PeerCom) BHaveOrgsExceptId(id comm.Address) bool {
   275  	this.syncorg.Lock()
   276  	defer this.syncorg.Unlock()
   277  	if this.orgheight == nil {
   278  		this.orgheight = make(map[comm.Address]uint64)
   279  	}
   280  	bhave := false
   281  	if len(this.orgheight) > 1 {
   282  		bhave = true
   283  		return bhave
   284  	} else if len(this.orgheight) == 1 {
   285  		if _, ok := this.orgheight[id]; !ok {
   286  			bhave = true
   287  		}
   288  	}
   289  
   290  	return bhave
   291  }
   292  
   293  func (this *PeerCom) BHaveOrgsId(id comm.Address) bool {
   294  	this.syncorg.Lock()
   295  	defer this.syncorg.Unlock()
   296  	if this.orgheight == nil {
   297  		this.orgheight = make(map[comm.Address]uint64)
   298  	}
   299  	bhave := false
   300  	if _, ok := this.orgheight[id]; ok {
   301  		bhave = true
   302  	}
   303  
   304  	return bhave
   305  }
   306  
   307  //Peer represent the node in p2p
   308  type Peer struct {
   309  	base      PeerCom
   310  	cap       [32]byte
   311  	SyncLink  *conn.Link
   312  	ConsLink  *conn.Link
   313  	syncState uint32
   314  	consState uint32
   315  	txnCnt    uint64
   316  	rxTxnCnt  uint64
   317  	connLock  sync.RWMutex
   318  	node      *discover.Node
   319  }
   320  
   321  //NewPeer return new peer without publickey initial
   322  func NewPeer() *Peer {
   323  	p := &Peer{
   324  		syncState: common.INIT,
   325  		consState: common.INIT,
   326  	}
   327  	p.SyncLink = conn.NewLink()
   328  	p.ConsLink = conn.NewLink()
   329  	p.base.orgheight = make(map[comm.Address]uint64)
   330  	runtime.SetFinalizer(p, rmPeer)
   331  	return p
   332  }
   333  
   334  //rmPeer print a debug log when peer be finalized by system
   335  func rmPeer(p *Peer) {
   336  	log.Debug("[p2p]Remove unused", "peerid", p.GetID())
   337  }
   338  
   339  //DumpInfo print all information of peer
   340  func (this *Peer) DumpInfo() {
   341  	log.Debug("[p2p]Node info:")
   342  	log.Debug("[p2p]", "syncState", this.syncState)
   343  	log.Debug("[p2p]", "consState", this.consState)
   344  	log.Debug("[p2p]", "id", this.GetID())
   345  	log.Debug("[p2p]", "addr", this.SyncLink.GetAddr())
   346  	log.Debug("[p2p]", "cap", this.cap)
   347  	log.Debug("[p2p]", "version", this.GetVersion())
   348  	log.Debug("[p2p]", "services", this.GetServices())
   349  	log.Debug("[p2p]", "syncPort", this.GetSyncPort())
   350  	log.Debug("[p2p]", "consPort", this.GetConsPort())
   351  	log.Debug("[p2p]", "relay", this.GetRelay())
   352  	log.Debug("[p2p]", "height", this.GetHeight())
   353  }
   354  
   355  //GetVersion return peer`s version
   356  func (this *Peer) GetVersion() uint32 {
   357  	return this.base.GetVersion()
   358  }
   359  
   360  //GetHeight return peer`s block height
   361  func (this *Peer) GetHeight() uint64 {
   362  	return this.base.GetHeight()
   363  }
   364  
   365  //SetHeight set height to peer
   366  func (this *Peer) SetHeight(height uint64) {
   367  	this.base.SetHeight(height)
   368  }
   369  
   370  //GetOrgHeight return org peer`s block height
   371  func (this *Peer) GetRemoteOrgHeight(id comm.Address) uint64 {
   372  	return this.base.GetRemoteOrgHeight(id)
   373  }
   374  
   375  //SetOrgHeight set org height to peer
   376  func (this *Peer) SetRemoteOrgHeight(height uint64, id comm.Address) bool {
   377  	return this.base.SetRemoteOrgHeight(height, id)
   378  }
   379  
   380  // GetRemoteOrgs get Remote node orgs
   381  func (this *Peer) GetRemoteOrgs() []comm.Address {
   382  	return this.base.GetRemoteOrgs()
   383  }
   384  
   385  // DelRemoteOrg del remote org to peer
   386  func (this *Peer) DelRemoteOrg(id comm.Address) bool {
   387  	return this.base.DelRemoteOrg(id)
   388  }
   389  
   390  //BHaveOrgs the Remote node have org
   391  func (this *Peer) BHaveOrgs() bool {
   392  	return this.base.BHaveOrgs()
   393  }
   394  
   395  //BHaveOrgs the Remote node have org
   396  func (this *Peer) BHaveOrgsExceptId(id comm.Address) bool {
   397  	return this.base.BHaveOrgsExceptId(id)
   398  }
   399  
   400  //BHaveOrgID the Remote node have orgid
   401  func (this *Peer) BHaveOrgID(id comm.Address) bool {
   402  	return this.base.BHaveOrgID(id)
   403  }
   404  
   405  //GetConsConn return consensus link
   406  func (this *Peer) GetConsConn() *conn.Link {
   407  	return this.ConsLink
   408  }
   409  
   410  //SetConsConn set consensue link to peer
   411  func (this *Peer) SetConsConn(consLink *conn.Link) {
   412  	this.ConsLink = consLink
   413  }
   414  
   415  //GetSyncState return sync state
   416  func (this *Peer) GetSyncState() uint32 {
   417  	return this.syncState
   418  }
   419  
   420  //SetSyncState set sync state to peer
   421  func (this *Peer) SetSyncState(state uint32) {
   422  	atomic.StoreUint32(&(this.syncState), state)
   423  }
   424  
   425  //GetConsState return peer`s consensus state
   426  func (this *Peer) GetConsState() uint32 {
   427  	return this.consState
   428  }
   429  
   430  //SetConsState set consensus state to peer
   431  func (this *Peer) SetConsState(state uint32) {
   432  	atomic.StoreUint32(&(this.consState), state)
   433  }
   434  
   435  //GetSyncPort return peer`s sync port
   436  func (this *Peer) GetSyncPort() uint16 {
   437  	return this.SyncLink.GetPort()
   438  }
   439  
   440  //GetConsPort return peer`s consensus port
   441  func (this *Peer) GetConsPort() uint16 {
   442  	return this.ConsLink.GetPort()
   443  }
   444  
   445  //SetConsPort set peer`s consensus port
   446  func (this *Peer) SetConsPort(port uint16) {
   447  	this.ConsLink.SetPort(port)
   448  }
   449  
   450  //SendToSync call sync link to send buffer
   451  func (this *Peer) SendToSync(msg common.Message) error {
   452  	if this.SyncLink != nil && this.SyncLink.Valid() {
   453  		return this.SyncLink.Tx(msg)
   454  	}
   455  	return errors.New("[p2p]sync link invalid")
   456  }
   457  
   458  //SendToCons call consensus link to send buffer
   459  func (this *Peer) SendToCons(msg common.Message) error {
   460  	if this.ConsLink != nil && this.ConsLink.Valid() {
   461  		return this.ConsLink.Tx(msg)
   462  	}
   463  	return errors.New("[p2p]cons link invalid")
   464  }
   465  
   466  //CloseSync halt sync connection
   467  func (this *Peer) CloseSync() {
   468  	//fmt.Println(" ********* Peer CloseSync ... ")
   469  	this.SetSyncState(common.INACTIVITY)
   470  	conn := this.SyncLink.GetConn()
   471  	rlpconn := this.SyncLink.GetRLPConn()
   472  	this.connLock.Lock()
   473  	if rlpconn != nil {
   474  		rlpconn.Close()
   475  	}
   476  
   477  	if conn != nil {
   478  		conn.Close()
   479  	}
   480  	this.connLock.Unlock()
   481  }
   482  
   483  //CloseCons halt consensus connection
   484  func (this *Peer) CloseCons() {
   485  	this.SetConsState(common.INACTIVITY)
   486  	conn := this.ConsLink.GetConn()
   487  	this.connLock.Lock()
   488  	if conn != nil {
   489  		conn.Close()
   490  
   491  	}
   492  	this.connLock.Unlock()
   493  }
   494  
   495  //GetID return peer`s id
   496  func (this *Peer) GetID() uint64 {
   497  	return this.base.GetID()
   498  }
   499  
   500  //GetRelay return peer`s relay state
   501  func (this *Peer) GetRelay() bool {
   502  	return this.base.GetRelay()
   503  }
   504  
   505  //GetServices return peer`s service state
   506  func (this *Peer) GetServices() uint64 {
   507  	return this.base.GetServices()
   508  }
   509  
   510  //GetTimeStamp return peer`s latest contact time in ticks
   511  func (this *Peer) GetTimeStamp() int64 {
   512  	return this.SyncLink.GetRXTime().UnixNano()
   513  }
   514  
   515  //GetContactTime return peer`s latest contact time in Time struct
   516  func (this *Peer) GetContactTime() time.Time {
   517  	return this.SyncLink.GetRXTime()
   518  }
   519  
   520  //GetAddr return peer`s sync link address
   521  func (this *Peer) GetAddr() string {
   522  	return this.SyncLink.GetAddr()
   523  }
   524  
   525  //GetAddr16 return peer`s sync link address in []byte
   526  func (this *Peer) GetAddr16() ([16]byte, error) {
   527  	var result [16]byte
   528  	addrIp, err := common.ParseIPAddr(this.GetAddr())
   529  	if err != nil {
   530  		return result, err
   531  	}
   532  	ip := net.ParseIP(addrIp).To16()
   533  	if ip == nil {
   534  		log.Warn("[p2p]parse ip address error", "Addr", this.GetAddr())
   535  		return result, errors.New("[p2p]parse ip address error")
   536  	}
   537  
   538  	copy(result[:], ip[:16])
   539  	return result, nil
   540  }
   541  
   542  //AttachSyncChan set msg chan to sync link
   543  func (this *Peer) AttachSyncChan(msgchan chan *common.MsgPayload) {
   544  	this.SyncLink.SetChan(msgchan)
   545  }
   546  
   547  //AttachConsChan set msg chan to consensus link
   548  func (this *Peer) AttachConsChan(msgchan chan *common.MsgPayload) {
   549  	this.ConsLink.SetChan(msgchan)
   550  }
   551  
   552  //Send transfer buffer by sync or cons link
   553  func (this *Peer) Send(msg common.Message, isConsensus bool) error {
   554  
   555  	if isConsensus && this.ConsLink.Valid() {
   556  		return this.SendToCons(msg)
   557  	}
   558  	return this.SendToSync(msg)
   559  }
   560  
   561  //SetHttpInfoState set peer`s httpinfo state
   562  func (this *Peer) SetHttpInfoState(httpInfo bool) {
   563  	if httpInfo {
   564  		this.cap[common.HTTP_INFO_FLAG] = 0x01
   565  	} else {
   566  		this.cap[common.HTTP_INFO_FLAG] = 0x00
   567  	}
   568  }
   569  
   570  //GetHttpInfoState return peer`s httpinfo state
   571  func (this *Peer) GetHttpInfoState() bool {
   572  	return this.cap[common.HTTP_INFO_FLAG] == 1
   573  }
   574  
   575  //GetHttpInfoPort return peer`s httpinfo port
   576  func (this *Peer) GetHttpInfoPort() uint16 {
   577  	return this.base.GetHttpInfoPort()
   578  }
   579  
   580  //SetHttpInfoPort set peer`s httpinfo port
   581  func (this *Peer) SetHttpInfoPort(port uint16) {
   582  	this.base.SetHttpInfoPort(port)
   583  }
   584  
   585  //GetHttpInfoPort return peer`s httpinfo port
   586  func (this *Peer) GetNode() *discover.Node {
   587  	return this.node
   588  }
   589  
   590  //SetHttpInfoPort set peer`s httpinfo port
   591  func (this *Peer) SetNode(node *discover.Node) {
   592  	this.node = node
   593  }
   594  
   595  //UpdateInfo update peer`s information
   596  func (this *Peer) UpdateInfo(t time.Time, version uint32, services uint64,
   597  	syncPort uint16, consPort uint16, nonce uint64, relay uint8, height uint64) {
   598  
   599  	this.SyncLink.UpdateRXTime(t)
   600  	this.base.SetID(nonce)
   601  	this.base.SetVersion(version)
   602  	this.base.SetServices(services)
   603  	this.base.SetSyncPort(syncPort)
   604  	this.base.SetConsPort(consPort)
   605  	this.SyncLink.SetPort(syncPort)
   606  	this.ConsLink.SetPort(consPort)
   607  	if relay == 0 {
   608  		this.base.SetRelay(false)
   609  	} else {
   610  		this.base.SetRelay(true)
   611  	}
   612  	this.SetHeight(uint64(height))
   613  }