cmd/polaris/server/litentcontainer.go
/*
* @file
* @copyright defined in aergo/LICENSE.txt
*/
package server
import (
"net"
"strconv"
"sync"
"time"
"github.com/aergoio/aergo-actor/actor"
"github.com/aergoio/aergo-lib/log"
"github.com/aergoio/aergo/v2/config"
"github.com/aergoio/aergo/v2/consensus"
"github.com/aergoio/aergo/v2/internal/network"
"github.com/aergoio/aergo/v2/p2p/p2pcommon"
"github.com/aergoio/aergo/v2/p2p/p2pkey"
"github.com/aergoio/aergo/v2/p2p/p2putil"
"github.com/aergoio/aergo/v2/p2p/transport"
"github.com/aergoio/aergo/v2/pkg/component"
"github.com/aergoio/aergo/v2/types"
"github.com/aergoio/aergo/v2/types/message"
)
// P2P is actor component for p2p
type LiteContainerService struct {
*component.BaseComponent
dummySetting p2pcommon.LocalSettings
chainID *types.ChainID
meta p2pcommon.PeerMeta
nt p2pcommon.NetworkTransport
mutex sync.Mutex
}
func (lntc *LiteContainerService) ConsensusAccessor() consensus.ConsensusAccessor {
panic("implement me")
}
func (lntc *LiteContainerService) PeerManager() p2pcommon.PeerManager {
panic("implement me")
}
func (lntc *LiteContainerService) LocalSettings() p2pcommon.LocalSettings {
return lntc.dummySetting
}
func (lntc *LiteContainerService) RoleManager() p2pcommon.PeerRoleManager {
panic("implement me")
}
var (
// _ ActorService = (*LiteContainerService)(nil)
)
// NewP2P create a new ActorService for p2p
func NewNTContainer(cfg *config.Config) *LiteContainerService {
lntc := &LiteContainerService{}
lntc.BaseComponent = component.NewBaseComponent(message.P2PSvc, lntc, log.NewLogger("p2p"))
lntc.init(cfg)
return lntc
}
func (lntc *LiteContainerService) SetHub(hub *component.ComponentHub) {
lntc.BaseComponent.SetHub(hub)
}
// BeforeStart starts p2p service.
func (lntc *LiteContainerService) BeforeStart() {}
func (lntc *LiteContainerService) AfterStart() {
lntc.mutex.Lock()
nt := lntc.nt
nt.Start()
lntc.mutex.Unlock()
}
// BeforeStop is called before actor hub stops. it finishes underlying peer manager
func (lntc *LiteContainerService) BeforeStop() {
lntc.mutex.Lock()
nt := lntc.nt
lntc.mutex.Unlock()
nt.Stop()
}
// Statistics show statistic information of p2p module. NOTE: It it not implemented yet
func (lntc *LiteContainerService) Statistics() *map[string]interface{} {
return nil
}
func (lntc *LiteContainerService) GetNetworkTransport() p2pcommon.NetworkTransport {
lntc.mutex.Lock()
defer lntc.mutex.Unlock()
return lntc.nt
}
func (lntc *LiteContainerService) GenesisChainID() *types.ChainID {
return lntc.chainID
}
func (lntc *LiteContainerService) init(cfg *config.Config) {
// load genesis file
// init from genesis file
genesis, err := readGenesis(cfg.Polaris.GenesisFile)
if err != nil {
panic(err.Error())
}
chainIdBytes, err := genesis.ChainID()
if err != nil {
panic("genesis block is not set properly: " + err.Error())
}
chainID := types.NewChainID()
err = chainID.Read(chainIdBytes)
if err != nil {
panic("invalid chainid: " + err.Error())
}
lntc.chainID = chainID
lntc.meta = initMeta(p2pkey.NodeID(), cfg.P2P)
lntc.Logger.Info().Str("genesis", chainID.ToJSON()).Msg("genesis block loaded")
netTransport := transport.NewNetworkTransport(cfg.P2P, lntc.Logger, lntc)
lntc.mutex.Lock()
lntc.nt = netTransport
lntc.mutex.Unlock()
}
// Receive got actor message and then handle it.
func (lntc *LiteContainerService) Receive(context actor.Context) {
rawMsg := context.Message()
switch msg := rawMsg.(type) {
case time.Time:
lntc.Logger.Debug().Interface("time", msg.String()).Msg("why time is came?")
default:
lntc.Logger.Debug().Interface("type", msg).Msg("unexpected msg was sent")
// do nothing
}
}
// TODO need refactoring. this code is copied from subprotcoladdrs.go
func (lntc *LiteContainerService) checkAndAddPeerAddresses(peers []*types.PeerAddress) {
selfPeerID := p2pkey.NodeID()
peerMetas := make([]p2pcommon.PeerMeta, 0, len(peers))
for _, rPeerAddr := range peers {
rPeerID := types.PeerID(rPeerAddr.PeerID)
if selfPeerID == rPeerID {
continue
}
meta := p2pcommon.FromPeerAddress(rPeerAddr)
peerMetas = append(peerMetas, meta)
}
}
func (lntc *LiteContainerService) SelfMeta() p2pcommon.PeerMeta {
return lntc.meta
}
// TellRequest implement interface method of ActorService
func (lntc *LiteContainerService) TellRequest(actor string, msg interface{}) {
lntc.TellTo(actor, msg)
}
// SendRequest implement interface method of ActorService
func (lntc *LiteContainerService) SendRequest(actor string, msg interface{}) {
lntc.RequestTo(actor, msg)
}
// FutureRequest implement interface method of ActorService
func (lntc *LiteContainerService) FutureRequest(actor string, msg interface{}, timeout time.Duration) *actor.Future {
return lntc.RequestToFuture(actor, msg, timeout)
}
// FutureRequestDefaultTimeout implement interface method of ActorService
func (lntc *LiteContainerService) FutureRequestDefaultTimeout(actor string, msg interface{}) *actor.Future {
return lntc.RequestToFuture(actor, msg, p2pcommon.DefaultActorMsgTTL)
}
// CallRequest implement interface method of ActorService
func (lntc *LiteContainerService) CallRequest(actor string, msg interface{}, timeout time.Duration) (interface{}, error) {
future := lntc.RequestToFuture(actor, msg, timeout)
return future.Result()
}
// CallRequest implement interface method of ActorService
func (lntc *LiteContainerService) CallRequestDefaultTimeout(actor string, msg interface{}) (interface{}, error) {
future := lntc.RequestToFuture(actor, msg, p2pcommon.DefaultActorMsgTTL)
return future.Result()
}
func (lntc *LiteContainerService) SelfNodeID() types.PeerID {
return lntc.meta.ID
}
func (lntc *LiteContainerService) SelfRole() types.PeerRole {
// return dummy value
return types.PeerRole_Watcher
}
func (lntc *LiteContainerService) GetChainAccessor() types.ChainAccessor {
// return dummy value
return nil
}
func (lntc *LiteContainerService) CertificateManager() p2pcommon.CertificateManager {
// return dummy value
return nil
}
// it is copy of initMeta() in p2p package
func initMeta(peerID types.PeerID, conf *config.P2PConfig) p2pcommon.PeerMeta {
protocolAddr := conf.NetProtocolAddr
var ipAddress net.IP
var err error
var protocolPort int
if len(conf.NetProtocolAddr) != 0 {
ipAddress, err = network.GetSingleIPAddress(protocolAddr)
if err != nil {
panic("Invalid protocol address " + protocolAddr + " : " + err.Error())
}
if ipAddress.IsUnspecified() {
panic("NetProtocolAddr should be a specified IP address, not 0.0.0.0")
}
} else {
extIP, err := p2putil.ExternalIP()
if err != nil {
panic("error while finding IP address: " + err.Error())
}
ipAddress = extIP
protocolAddr = ipAddress.String()
}
protocolPort = conf.NetProtocolPort
if protocolPort <= 0 {
panic("invalid NetProtocolPort " + strconv.Itoa(conf.NetProtocolPort))
}
ma, err := types.ToMultiAddr(ipAddress.String(), uint32(protocolPort))
var meta p2pcommon.PeerMeta
meta.ID = peerID
meta.Addresses = []types.Multiaddr{ma}
meta.Hidden = !conf.NPExposeSelf
meta.Version = p2pkey.NodeVersion()
return meta
}