示例#1
0
        public void MakeReady(CommandDispatcher dispatcher)
        {
            var nodeMode = Settings.Node.Mode;

            Logger.Success($"Node is now running in {nodeMode.ToString().ToLower()} mode!");
            _nodeReady = true;
        }
示例#2
0
        private void Mempool_OnTransactionFailed(Hash hash)
        {
            if (!Running || _mempool == null)
            {
                return;
            }

            var status = _mempool.GetTransactionStatus(hash, out string reason);

            Logger.Warning($"Rejected transaction {hash} => " + reason);
        }
示例#3
0
        public void ExecuteAPI(string name, string[] args)
        {
            var result = _nexusApi.Execute(name, args);

            if (result == null)
            {
                Logger.Warning("API returned null value...");
                return;
            }

            Logger.Message(result);
        }
示例#4
0
        private PeerCaps SetupPeerCaps()
        {
            PeerCaps caps = PeerCaps.None;

            if (Settings.Node.HasSync)
            {
                caps |= PeerCaps.Sync;
            }
            if (Settings.Node.HasEvents)
            {
                caps |= PeerCaps.Events;
            }
            if (Settings.Node.HasRelay)
            {
                caps |= PeerCaps.Relay;
            }
            if (Settings.Node.HasArchive)
            {
                caps |= PeerCaps.Archive;
            }
            if (Settings.Node.HasRpc)
            {
                caps |= PeerCaps.RPC;
            }
            if (Settings.Node.HasRest)
            {
                caps |= PeerCaps.REST;
            }

            if (Settings.Node.HasMempool)
            {
                if (Settings.Node.Readonly)
                {
                    Logger.Warning("Mempool will be disabled due to read-only mode");
                }
                else
                {
                    caps |= PeerCaps.Mempool;
                }
            }

            var possibleCaps = Enum.GetValues(typeof(PeerCaps)).Cast <PeerCaps>().ToArray();

            foreach (var cap in possibleCaps)
            {
                if (cap != PeerCaps.None && caps.HasFlag(cap))
                {
                    Logger.Message("Feature enabled: " + cap);
                }
            }

            return(caps);
        }
示例#5
0
        private NexusAPI SetupNexusApi()
        {
            var apiCache     = Settings.Node.ApiCache;
            var apiLog       = Settings.Node.ApiLog;
            var apiProxyURL  = Settings.Node.ApiProxyUrl;
            var readOnlyMode = Settings.Node.Readonly;
            var hasRPC       = Settings.Node.HasRpc;
            var hasREST      = Settings.Node.HasRest;

            NexusAPI nexusApi = new NexusAPI(_nexus, apiCache, apiLog ? Logger : null);

            if (apiProxyURL != null)
            {
                nexusApi.ProxyURL = apiProxyURL;
                // TEMP Normal node needs a proxy url set to relay transactions to the BPs
                nexusApi.Node = _node;
                Logger.Message($"API will be acting as proxy for {apiProxyURL}");
            }
            else
            {
                nexusApi.Node = _node;
            }

            if (readOnlyMode)
            {
                Logger.Warning($"Node will be running in read-only mode.");
            }
            else
            {
                nexusApi.Mempool = _mempool;
            }

            // RPC setup
            if (hasRPC)
            {
                var rpcPort = Settings.Node.RpcPort;
                Logger.Message($"RPC server listening on port {rpcPort}...");
                var rpcServer = new RPCServer(nexusApi, "/rpc", rpcPort, (level, text) => WebLogMapper("rpc", level, text));
                rpcServer.StartInThread(ThreadPriority.AboveNormal);
            }

            // REST setup
            if (hasREST)
            {
                var restPort = Settings.Node.RestPort;
                Logger.Message($"REST server listening on port {restPort}...");
                var restServer = new RESTServer(nexusApi, "/api", restPort, (level, text) => WebLogMapper("rest", level, text));
                restServer.StartInThread(ThreadPriority.AboveNormal);
            }

            return(nexusApi);
        }
示例#6
0
        protected override void OnStop()
        {
            Logger.Message("Termination started...");

            if (_mempool != null && _mempool.IsRunning)
            {
                Logger.Message("Stopping mempool...");
                _mempool.Stop();
            }

            if (_node != null && _node.IsRunning)
            {
                Logger.Message("Stopping node...");
                _node.Stop();
            }
        }
示例#7
0
        private void SetupOracleApis()
        {
            var neoPlatform = Settings.Oracle.SwapPlatforms.FirstOrDefault(x => x.Chain == SwapPlatformChain.Neo);

            if (neoPlatform != null && neoPlatform.Enabled)
            {
                var neoScanURL = Settings.Oracle.NeoscanUrl;

                this._neoAPI = new Neo.Core.RemoteRPCNode(neoScanURL, neoPlatform.RpcNodes);
                this._neoAPI.SetLogger((s) => Logger.Message(s));

                this._neoScanAPI = new NeoScanAPI(neoScanURL, Logger, _nexus, _nodeKeys);
            }

            var bscPlatform = Settings.Oracle.SwapPlatforms.FirstOrDefault(x => x.Chain == SwapPlatformChain.BSC);

            if (bscPlatform != null && bscPlatform.Enabled)
            {
                var bscWIF  = Settings.GetInteropWif(Nexus, _nodeKeys, BSCWallet.BSCPlatform);
                var bscKeys = PhantasmaKeys.FromWIF(bscWIF);

                this._bscAPI = new EthAPI(SwapPlatformChain.BSC, this.Nexus, this.Settings, new EthAccount(bscKeys.PrivateKey.ToHex()), Logger);
            }

            var ethPlatform = Settings.Oracle.SwapPlatforms.FirstOrDefault(x => x.Chain == SwapPlatformChain.Ethereum);

            if (ethPlatform != null && ethPlatform.Enabled)
            {
                var ethWIF  = Settings.GetInteropWif(Nexus, _nodeKeys, EthereumWallet.EthereumPlatform);
                var ethKeys = PhantasmaKeys.FromWIF(ethWIF);

                this._ethAPI = new EthAPI(SwapPlatformChain.Ethereum, this.Nexus, this.Settings, new EthAccount(ethKeys.PrivateKey.ToHex()), Logger);
            }

            this._cryptoCompareAPIKey = Settings.Oracle.CryptoCompareAPIKey;
            if (!string.IsNullOrEmpty(this._cryptoCompareAPIKey))
            {
                Logger.Message($"CryptoCompare API enabled.");
            }
            else
            {
                throw new Exception($"CryptoCompare API key missing, oracles won't work properly and oracles are no longer optional...");
            }
        }
示例#8
0
        public void Terminate()
        {
            if (!Running)
            {
                Logger.Message("Termination already in progress...");
            }

            if (Prompt.running)
            {
                Prompt.running = false;
            }

            this.OnStop();

            //Thread.Sleep(3000);
            if (Prompt.running)
            {
                Prompt.running = false;
            }

            Logger.Message("Termination complete...");
            Environment.Exit(0);
        }
示例#9
0
        private Mempool SetupMempool()
        {
            var mempool = new Mempool(_nexus
                                      , Settings.Node.BlockTime
                                      , Settings.Node.MinimumFee
                                      , System.Text.Encoding.UTF8.GetBytes(TxIdentifier)
                                      , 0
                                      , Logger
                                      , Settings.Node.ProfilerPath
                                      );

            if (Settings.Node.MempoolLog)
            {
                mempool.OnTransactionFailed    += Mempool_OnTransactionFailed;
                mempool.OnTransactionAdded     += (hash) => Logger.Message($"Received transaction {hash}");
                mempool.OnTransactionCommitted += (hash) => Logger.Message($"Commited transaction {hash}");
                mempool.OnTransactionDiscarded += (hash) => Logger.Message($"Discarded transaction {hash}");
            }
            if (Settings.App.NodeStart)
            {
                mempool.StartInThread(ThreadPriority.AboveNormal);
            }
            return(mempool);
        }
示例#10
0
        private void SetupOracleApis()
        {
            var neoScanURL = Settings.Oracle.NeoscanUrl;

            var neoRpcList = Settings.Oracle.NeoRpcNodes;

            this._neoAPI = new Neo.Core.RemoteRPCNode(neoScanURL, neoRpcList.ToArray());
            this._neoAPI.SetLogger((s) => Logger.Message(s));

            var ethRpcList = Settings.Oracle.EthRpcNodes;

            var ethWIF  = Settings.GetInteropWif(Nexus, _nodeKeys, EthereumWallet.EthereumPlatform);
            var ethKeys = PhantasmaKeys.FromWIF(ethWIF);

            this._ethAPI = new EthAPI(this.Nexus, this.Settings, new EthAccount(ethKeys.PrivateKey.ToHex()), Logger);

            this._neoScanAPI = new NeoScanAPI(neoScanURL, Logger, _nexus, _nodeKeys);

            this._cryptoCompareAPIKey = Settings.Oracle.CryptoCompareAPIKey;
            if (!string.IsNullOrEmpty(this._cryptoCompareAPIKey))
            {
                Logger.Message($"CryptoCompare API enabled...");
            }
        }
示例#11
0
        private Node SetupNode()
        {
            if (Settings.Node.Mode == NodeMode.Proxy)
            {
                Logger.Warning("No nexus will be setup locally due to proxy mode being enabled");
                return(null);
            }

            Node node = null;

            if (this._mempool != null)
            {
                this._mempool.SetKeys(_nodeKeys);
            }

            if (!Settings.Node.IsValidator && Settings.Node.Seeds.Count == 0 && _peerCaps.HasFlag(PeerCaps.Sync))
            {
                throw new Exception("A non-validator node with sync enabled must specificy a non-empty list of seed endpoints");
            }

            node = new Node("Spook v" + Version
                            , _nexus
                            , _mempool
                            , _nodeKeys
                            , Settings.Node.NodeHost
                            , _availablePorts
                            , _peerCaps
                            , Settings.Node.Seeds
                            , Logger);

            var missingNexus = !_nexus.HasGenesis;

            if (missingNexus)
            {
                if (Settings.Node.IsValidator)
                {
                    var nexusName = Settings.Node.NexusName;
                    if (Settings.Node.NexusBootstrap)
                    {
                        if (!ValidationUtils.IsValidIdentifier(nexusName))
                        {
                            Logger.Error("Invalid nexus name: " + nexusName);
                            this.Terminate();
                        }

                        Logger.Message($"Boostraping {nexusName} nexus using {_nodeKeys.Address}...");

                        var genesisTimestamp = Settings.Node.GenesisTimestamp;

                        if (!_nexus.CreateGenesisBlock(_nodeKeys, genesisTimestamp, DomainSettings.LatestKnownProtocol))
                        {
                            throw new ChainException("Genesis block failure");
                        }

                        Logger.Success("Genesis block created: " + _nexus.GetGenesisHash(_nexus.RootStorage));

                        missingNexus = false;
                    }
                }
                else
                {
                    if (_mempool != null)
                    {
                        _mempool.SubmissionCallback = (tx, chain) =>
                        {
                            Logger.Message($"Relaying tx {tx.Hash} to other node");
                        };
                    }
                }

                if (missingNexus && !_peerCaps.HasFlag(PeerCaps.Sync))
                {
                    Logger.Error("No Nexus found.");
                    this.Terminate();
                }
            }
            else
            {
                var genesisAddress = _nexus.GetGenesisAddress(_nexus.RootStorage);
                if (Settings.Node.IsValidator && !Settings.Node.Readonly)
                {
                    if (!_nexus.IsKnownValidator(_nodeKeys.Address))
                    {
                        throw new Exception("Specified node key does not match a known validator address");
                    }
                    else
                    if (_nodeKeys.Address != genesisAddress)
                    {
                        Logger.Warning("Specified node key does not match genesis address " + genesisAddress.Text);
                    }
                }

                var chainHeight = _nexus.RootChain.Height;
                var genesisHash = _nexus.GetGenesisHash(_nexus.RootStorage);
                Logger.Success($"Loaded {Nexus.Name} Nexus with genesis {genesisHash } with {chainHeight} blocks");
            }

            return(node);
        }