public override ServiceBlock GetBlockProposal(VoteProcess <ServiceBlock> voteProcess, ServiceBlock lastBlock, int revision)
        {
            var remove    = new HashSet <long>();
            var generator = new ServiceBlockGenerator(_coreChain, _serviceChain, _maintainChain, lastBlock);

            lock (_lock)
            {
                foreach (var item in _transactions)
                {
                    var transaction = item.Value;
                    if (_blockStorage.HistoryContainsTransactionOrRegistration(transaction) != TransactionResultTypes.Ok)
                    {
                        remove.Add(transaction.UniqueIdentifier);
                        continue;
                    }

                    if (generator.ConsumeTransaction(transaction as ServiceTransaction) != TransactionResultTypes.Ok)
                    {
                        remove.Add(transaction.UniqueIdentifier);
                    }
                }

                foreach (var item in remove)
                {
                    _transactions.Remove(item);
                }
            }

            return(generator.GenerateBlock(voteProcess.LocalIssuer, revision));
        }
Exemple #2
0
        public async Task <bool> Start(string[] args, CancellationTokenSource quiteToken)
        {
            _quitToken = quiteToken;

            if (_quitToken.IsCancellationRequested)
            {
                return(false);
            }

            var dataPath = "heleusdata";

            var genesis        = false;
            var sync           = false;
            var run            = false;
            var init           = false;
            var newChainConfig = false;

            if (args.Length == 1)
            {
                dataPath = args[0];
                run      = true;
            }
            else if (args.Length == 2)
            {
                dataPath = args[0];
                var cmd = args[1];

                if (cmd == "init")
                {
                    init = true;
                }
                else if (cmd == "run")
                {
                    run = true;
                }
                else if (cmd == "sync")
                {
                    sync = true;
                }
                else if (cmd == "chainconfig")
                {
                    newChainConfig = true;
                }
                else if (cmd == "genesis")
                {
                    genesis = true;
                }
                else
                {
                    Usage();
                    return(false);
                }
            }
            else
            {
                Usage();
                return(false);
            }

            if ((run || sync) && !File.Exists(Path.Combine(dataPath, $"{nameof(NodeConfig).ToLower()}.txt")))
            {
                Usage();
                var dp = new DirectoryInfo(dataPath);
                Log.Error($"Data path {dp.FullName} not initalized.", this);
                return(false);
            }

            Storage = new Storage(dataPath);
            if (!Storage.IsWriteable)
            {
                Log.Fatal($"Data path {Storage.Root} is not writeable!", this);
                return(false);
            }

            if (genesis)
            {
                Storage.DeleteDirectory("cache");
                Storage.DeleteDirectory("chains");
            }

            PubSub = Log.PubSub = new PubSub();

            Log.Write($"Starting Heleus Node (Version {Program.Version}).");
            Log.Trace($"PID {System.Diagnostics.Process.GetCurrentProcess().Id}");

            Log.Write($"Data path is '{Storage.Root.FullName}'.");

            var config = Config.Load <NodeConfig>(Storage);

            Log.AddIgnoreList(config.LogIgnore);
            Log.LogLevel = config.LogLevel;

            if (Program.IsDebugging)
            {
                Log.LogLevel = LogLevels.Trace;
            }

            if (newChainConfig)
            {
                var chainConfig = Config.Load <ChainConfig>(Storage, true);
                //if (chainConfig.Chains.Count == 0)
                {
                    Log.Write("Chain config generated.");

                    chainConfig.Chains.Add(new ChainConfig.ChainInfo {
                        ChainKeys = new List <ChainConfig.ChainKeyInfo> {
                            new ChainConfig.ChainKeyInfo {
                                ChainKey = string.Empty, ChainKeyPassword = string.Empty, AttachementKey = -1
                            }
                        }
                    });
                    Config.Save(chainConfig);
                }

                return(false);
            }

            if (init)
            {
                Log.Write("Config file generated.");
                return(false);
            }

            if (!genesis)
            {
                if (config.NetworkPublicKey.IsNullOrEmpty())
                {
                    Log.Write("Network key not set. Querying beacon nodes.");
                    var beacons = config.BeaconNodes;
                    foreach (var beacon in beacons)
                    {
                        Log.Write($"Querying beacon node {beacon}.");
                        var client   = new NodeClient(new Uri(beacon));
                        var nodeInfo = (await client.DownloadNodeInfo()).Data;
                        if (nodeInfo != null)
                        {
                            config.NetworkPublicKey = nodeInfo.NetworkKey.HexString;
                            Config.Save(config);
                            Log.Write($"Network key set to {config.NetworkPublicKey}.");
                            break;
                        }
                    }
                }

                if (config.NetworkPublicKey.IsNullOrEmpty())
                {
                    Log.Write("No valid network key found or set.", this);
                    return(false);
                }
            }

            NodeConfiguration = new NodeConfiguration(config, Config.Load <CoreKeyConfig>(Storage, false), Config.Load <ChainConfig>(Storage, false));
            Host = new Host(config);
            AttachementManager = new AttachementManager(this);
            ChainManager       = new ChainManager(this);
            if (!await ChainManager.Initalize())
            {
                return(false);
            }

            if (genesis)
            {
                var result = GenesisBlock.Generate(Storage);

                var blockData = new BlockData <CoreBlock>(result.Block, result.Signature);
                await ChainManager.Start(false);

                await ChainManager.CoreChain.BlockStorage.StoreBlock(blockData);

                ChainManager.ConsumeBlockData(blockData);

                Log.Write($"Genesis block and keys generated. Network public key: {result.NetworkPublicKey.HexString}.");

                var coreKeyConfig = Config.Load <CoreKeyConfig>(Storage);
                coreKeyConfig.Key      = result.NetworkVoteKey.HexString;
                coreKeyConfig.Password = result.NetworkVotePassword;

                config.NetworkPublicKey = result.NetworkPublicKey.HexString;

                Config.Save(config);
                Config.Save(coreKeyConfig);

                await ChainManager.Stop();

                await ChainManager.Start(true);

                if (result.ServiceTransactions.Count > 0)
                {
                    foreach (var serviceTransactions in result.ServiceTransactions)
                    {
                        var chainId      = serviceTransactions.Key;
                        var transactions = serviceTransactions.Value;

                        var serviceChain  = ChainManager.GetServiceChain(chainId);
                        var maintainChain = ChainManager.GetMaintainChain(chainId);
                        if (serviceChain != null)
                        {
                            var generator = new ServiceBlockGenerator(ChainManager.CoreChain, serviceChain, maintainChain, null);
                            foreach (var transaction in transactions)
                            {
                                generator.ConsumeTransaction(transaction);
                            }

                            var serviceBlock     = generator.GenerateBlock(0, 0);
                            var serviceBlockData = new BlockData <ServiceBlock>(serviceBlock, new BlockSignatures(serviceBlock));
                            await serviceChain.BlockStorage.StoreBlock(serviceBlockData);

                            serviceChain.ConsumeBlockData(serviceBlockData);
                        }
                    }
                }

                await ChainManager.Stop();

                return(false);
            }

            SyncManager = new SyncManager(this);
            await SyncManager.Start();

            //if (!await SyncManager.Start())
            //    return false;

            if (sync)
            {
                Log.Write("Sync done.");
                return(false);
            }

            AttachementManager.Start();

            Kademlia           = new Kademlia(Storage, this);
            TransactionManager = new TransactionManager(this);
            CouncilManager     = new CouncilManager(this);

            NodeServer   = new NodeServer(this, config.MaxIncomingConnections, config.MaxOutgoingConnectoins);
            ClientServer = new ClientServer(this);

            if (Host.EnableRemoteServices)
            {
                ServiceServer = new ServiceServer();
            }

            await(Host as Host).Start(this);
            return(true);
        }