aergoio/aergo

View on GitHub
cmd/polaris/server/litentcontainer.go

Summary

Maintainability
B
4 hrs
Test Coverage
F
0%
/*
 * @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
}