github.com/aergoio/aergo@v1.3.1/polaris/server/litentcontainer.go (about)

     1  /*
     2   * @file
     3   * @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package server
     7  
     8  import (
     9  	"github.com/aergoio/aergo/internal/network"
    10  	"github.com/aergoio/aergo/p2p/p2putil"
    11  	"github.com/aergoio/aergo/p2p/transport"
    12  	"net"
    13  	"strconv"
    14  	"sync"
    15  	"time"
    16  
    17  	"github.com/aergoio/aergo-actor/actor"
    18  	"github.com/aergoio/aergo-lib/log"
    19  	"github.com/aergoio/aergo/config"
    20  	"github.com/aergoio/aergo/message"
    21  	"github.com/aergoio/aergo/p2p/p2pcommon"
    22  	"github.com/aergoio/aergo/p2p/p2pkey"
    23  	"github.com/aergoio/aergo/pkg/component"
    24  	"github.com/aergoio/aergo/types"
    25  )
    26  
    27  // P2P is actor component for p2p
    28  type LiteContainerService struct {
    29  	*component.BaseComponent
    30  
    31  	chainID *types.ChainID
    32  	meta    p2pcommon.PeerMeta
    33  	nt      p2pcommon.NetworkTransport
    34  
    35  	mutex sync.Mutex
    36  }
    37  
    38  var (
    39  //_ ActorService     = (*LiteContainerService)(nil)
    40  )
    41  
    42  // NewP2P create a new ActorService for p2p
    43  func NewNTContainer(cfg *config.Config) *LiteContainerService {
    44  	lntc := &LiteContainerService{}
    45  	lntc.BaseComponent = component.NewBaseComponent(message.P2PSvc, lntc, log.NewLogger("p2p"))
    46  	lntc.init(cfg)
    47  	return lntc
    48  }
    49  
    50  func (lntc *LiteContainerService) SetHub(hub *component.ComponentHub) {
    51  	lntc.BaseComponent.SetHub(hub)
    52  }
    53  
    54  // BeforeStart starts p2p service.
    55  func (lntc *LiteContainerService) BeforeStart() {}
    56  
    57  func (lntc *LiteContainerService) AfterStart() {
    58  	lntc.mutex.Lock()
    59  	nt := lntc.nt
    60  	nt.Start()
    61  	lntc.mutex.Unlock()
    62  }
    63  
    64  // BeforeStop is called before actor hub stops. it finishes underlying peer manager
    65  func (lntc *LiteContainerService) BeforeStop() {
    66  	lntc.mutex.Lock()
    67  	nt := lntc.nt
    68  	lntc.mutex.Unlock()
    69  	nt.Stop()
    70  }
    71  
    72  // Statistics show statistic information of p2p module. NOTE: It it not implemented yet
    73  func (lntc *LiteContainerService) Statistics() *map[string]interface{} {
    74  	return nil
    75  }
    76  
    77  func (lntc *LiteContainerService) GetNetworkTransport() p2pcommon.NetworkTransport {
    78  	lntc.mutex.Lock()
    79  	defer lntc.mutex.Unlock()
    80  	return lntc.nt
    81  }
    82  
    83  func (lntc *LiteContainerService) ChainID() *types.ChainID {
    84  	return lntc.chainID
    85  }
    86  
    87  func (lntc *LiteContainerService) init(cfg *config.Config) {
    88  	// load genesis file
    89  	// init from genesis file
    90  	// TODO code duplication. refactor to delete dupplicate with p2p.go
    91  	genesis, err := readGenesis(cfg.Polaris.GenesisFile)
    92  	if err != nil {
    93  		panic(err.Error())
    94  	}
    95  	chainIdBytes, err := genesis.ChainID()
    96  	if err != nil {
    97  		panic("genesis block is not set properly: " + err.Error())
    98  	}
    99  	chainID := types.NewChainID()
   100  	err = chainID.Read(chainIdBytes)
   101  	if err != nil {
   102  		panic("invalid chainid: " + err.Error())
   103  	}
   104  	lntc.chainID = chainID
   105  
   106  	lntc.meta = initMeta(p2pkey.NodeID(), cfg.P2P)
   107  	lntc.Logger.Info().Str("genesis", chainID.ToJSON()).Msg("genesis block loaded")
   108  
   109  	netTransport := transport.NewNetworkTransport(cfg.P2P, lntc.Logger, lntc)
   110  
   111  	lntc.mutex.Lock()
   112  	lntc.nt = netTransport
   113  	lntc.mutex.Unlock()
   114  }
   115  
   116  // Receive got actor message and then handle it.
   117  func (lntc *LiteContainerService) Receive(context actor.Context) {
   118  	rawMsg := context.Message()
   119  	switch msg := rawMsg.(type) {
   120  	case time.Time:
   121  		lntc.Logger.Debug().Interface("time", msg.String()).Msg("why time is came?")
   122  	default:
   123  		lntc.Logger.Debug().Interface("type", msg).Msg("unexpected msg was sent")
   124  		// do nothing
   125  	}
   126  }
   127  
   128  // TODO need refactoring. this code is copied from subprotcoladdrs.go
   129  func (lntc *LiteContainerService) checkAndAddPeerAddresses(peers []*types.PeerAddress) {
   130  	selfPeerID := p2pkey.NodeID()
   131  	peerMetas := make([]p2pcommon.PeerMeta, 0, len(peers))
   132  	for _, rPeerAddr := range peers {
   133  		rPeerID := types.PeerID(rPeerAddr.PeerID)
   134  		if selfPeerID == rPeerID {
   135  			continue
   136  		}
   137  		meta := p2pcommon.FromPeerAddress(rPeerAddr)
   138  		peerMetas = append(peerMetas, meta)
   139  	}
   140  }
   141  
   142  func (lntc *LiteContainerService) SelfMeta() p2pcommon.PeerMeta {
   143  	return lntc.meta
   144  }
   145  
   146  // TellRequest implement interface method of ActorService
   147  func (lntc *LiteContainerService) TellRequest(actor string, msg interface{}) {
   148  	lntc.TellTo(actor, msg)
   149  }
   150  
   151  // SendRequest implement interface method of ActorService
   152  func (lntc *LiteContainerService) SendRequest(actor string, msg interface{}) {
   153  	lntc.RequestTo(actor, msg)
   154  }
   155  
   156  // FutureRequest implement interface method of ActorService
   157  func (lntc *LiteContainerService) FutureRequest(actor string, msg interface{}, timeout time.Duration) *actor.Future {
   158  	return lntc.RequestToFuture(actor, msg, timeout)
   159  }
   160  
   161  // FutureRequestDefaultTimeout implement interface method of ActorService
   162  func (lntc *LiteContainerService) FutureRequestDefaultTimeout(actor string, msg interface{}) *actor.Future {
   163  	return lntc.RequestToFuture(actor, msg, p2pcommon.DefaultActorMsgTTL)
   164  }
   165  
   166  // CallRequest implement interface method of ActorService
   167  func (lntc *LiteContainerService) CallRequest(actor string, msg interface{}, timeout time.Duration) (interface{}, error) {
   168  	future := lntc.RequestToFuture(actor, msg, timeout)
   169  	return future.Result()
   170  }
   171  
   172  // CallRequest implement interface method of ActorService
   173  func (lntc *LiteContainerService) CallRequestDefaultTimeout(actor string, msg interface{}) (interface{}, error) {
   174  	future := lntc.RequestToFuture(actor, msg, p2pcommon.DefaultActorMsgTTL)
   175  	return future.Result()
   176  }
   177  
   178  func (lntc *LiteContainerService) SelfNodeID() types.PeerID {
   179  	return lntc.meta.ID
   180  }
   181  
   182  func (lntc *LiteContainerService) SelfRole() p2pcommon.PeerRole {
   183  	// return dummy value
   184  	return p2pcommon.Watcher
   185  }
   186  
   187  func (lntc *LiteContainerService) GetChainAccessor() types.ChainAccessor {
   188  	// return dummy value
   189  	return nil
   190  }
   191  
   192  // it is copy of initMeta() in p2p package
   193  func initMeta(peerID types.PeerID, conf *config.P2PConfig) p2pcommon.PeerMeta {
   194  	protocolAddr := conf.NetProtocolAddr
   195  	var ipAddress net.IP
   196  	var err error
   197  	var protocolPort int
   198  	if len(conf.NetProtocolAddr) != 0 {
   199  		ipAddress, err = network.GetSingleIPAddress(protocolAddr)
   200  		if err != nil {
   201  			panic("Invalid protocol address " + protocolAddr + " : " + err.Error())
   202  		}
   203  		if ipAddress.IsUnspecified() {
   204  			panic("NetProtocolAddr should be a specified IP address, not 0.0.0.0")
   205  		}
   206  	} else {
   207  		extIP, err := p2putil.ExternalIP()
   208  		if err != nil {
   209  			panic("error while finding IP address: " + err.Error())
   210  		}
   211  		ipAddress = extIP
   212  		protocolAddr = ipAddress.String()
   213  	}
   214  	protocolPort = conf.NetProtocolPort
   215  	if protocolPort <= 0 {
   216  		panic("invalid NetProtocolPort " + strconv.Itoa(conf.NetProtocolPort))
   217  	}
   218  	var meta p2pcommon.PeerMeta
   219  	meta.IPAddress = protocolAddr
   220  	meta.Port = uint32(protocolPort)
   221  	meta.ID = peerID
   222  	meta.Hidden = !conf.NPExposeSelf
   223  	meta.Version = p2pkey.NodeVersion()
   224  
   225  	return meta
   226  }