Пример #1
0
        public void KademliaTest()
        {
            var addr1 = new Address("0000000000000000000000000000000000000000");
            var addr2 = new Address("0000000000000000000000000000000000000001");
            var addr3 = new Address("000000000000000000000000000000000000000c");
            var addr4 = new Address("0000000001000001111110001000011001000001");
            var addr5 = new Address("ffffffffffffffffffffffffffffffffffffffff");

            Assert.Equal(
                new Address("000000000100000111111000100001100100000d"),
                Kademlia.CalculateDifference(addr3, addr4));
            Assert.Equal(
                Kademlia.CalculateDifference(addr2, addr4),
                Kademlia.CalculateDifference(addr4, addr2));

            Assert.Equal(159, Kademlia.CommonPrefixLength(addr1, addr2));
            Assert.Equal(156, Kademlia.CommonPrefixLength(addr1, addr3));
            Assert.Equal(39, Kademlia.CommonPrefixLength(addr1, addr4));

            Assert.Equal(0, Kademlia.CalculateDistance(addr4, addr4));
            Assert.Equal(Address.Size * 8, Kademlia.CalculateDistance(addr1, addr5));

            Assert.True(string.CompareOrdinal(addr1.ToHex(), addr2.ToHex()) < 1);
            Assert.True(string.CompareOrdinal(addr2.ToHex(), addr3.ToHex()) < 1);
            Assert.True(string.CompareOrdinal(addr3.ToHex(), addr4.ToHex()) < 1);
            Assert.True(string.CompareOrdinal(addr4.ToHex(), addr4.ToHex()) == 0);
        }
Пример #2
0
        public void PrefixLength()
        {
            var addr1 = new Address("0000000000000000000000000000000000000000");
            var addr2 = new Address("0000000000000000000000000000000000000001");
            var addr3 = new Address("000000000000000000000000000000000000000c");
            var addr4 = new Address("0000000001000001111110001000011001000001");

            Assert.Equal(159, Kademlia.CommonPrefixLength(addr1, addr2));
            Assert.Equal(156, Kademlia.CommonPrefixLength(addr1, addr3));
            Assert.Equal(39, Kademlia.CommonPrefixLength(addr1, addr4));
        }
Пример #3
0
        public async Task <int> Run()
        {
            if (_quitToken.IsCancellationRequested)
            {
                return(0);
            }

            await Kademlia.Start();

            TransactionManager.Start();
            await CouncilManager.Start();

            await NodeServer.Start();

            await ClientServer.Start();

            if (ServiceServer != null)
            {
                await ServiceServer.Start();
            }

            await _quitToken.WaitAsync();

            await PubSub.PublishAsync(new QuitEvent());

            await NodeServer.Stop();

            await ClientServer.Stop();

            await CouncilManager.Stop();

            TransactionManager.Stop();
            await Kademlia.Stop();

            await ChainManager.Stop();

            if (ServiceServer != null)
            {
                await ServiceServer.Stop();
            }

            await(Host as Host).Stop();

            return(0);
        }
Пример #4
0
        public void Test_Kademlia()
        {
            {
                var kademlia = new Kademlia<Node>(512, 20);

                {
                    Node node = null;

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                        node = new Node(id, uris);
                    }

                    kademlia.BaseNode = node;
                }

                for (int i = 0; i < 1024; i++)
                {
                    Node node = null;

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                        node = new Node(id, uris);
                    }

                    kademlia.Add(node);
                }

                for (int i = 0; i < 1024; i++)
                {
                    Node node = null;

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                        node = new Node(id, uris);
                    }

                    kademlia.Live(node);
                }

                foreach (var node in kademlia.ToArray().Take(kademlia.Count / 2))
                {
                    kademlia.Remove(node);
                }

                var v = kademlia.Verify();

                foreach (var node in kademlia.ToArray())
                {
                    var list = kademlia.Search(node.Id, kademlia.Count);
                    if (list.ElementAt(0) != node) throw new Exception();
                }

                for (int i = 0; i < 1024; i++)
                {
                    var id = new byte[32];
                    _random.NextBytes(id);

                    var slist = Kademlia<Node>.Search(kademlia.BaseNode.Id, id, kademlia.ToArray(), kademlia.Count).ToList();
                    var slist2 = Kademlia<Node>.Search(kademlia.BaseNode.Id, id, kademlia.ToArray(), 3).ToList();

                    if (slist.Count == 0 && slist2.Count == 0) continue;
                    var length = Math.Min(slist.Count, slist2.Count);

                    Assert.IsTrue(CollectionUtilities.Equals(slist, 0, slist2, 0, length));
                }

                for (int i = 0; i < 1024; i++)
                {
                    var id = new byte[32];
                    _random.NextBytes(id);

                    var slist = Kademlia<Node>.Search(id, kademlia.ToArray(), kademlia.Count).ToList();
                    var slist2 = Kademlia<Node>.Search(id, kademlia.ToArray(), 3).ToList();

                    if (slist.Count == 0 && slist2.Count == 0) continue;
                    var length = Math.Min(slist.Count, slist2.Count);

                    Assert.IsTrue(CollectionUtilities.Equals(slist, 0, slist2, 0, length));
                }
            }
        }
        //#endif
        public ConnectionsManager(ClientManager clientManager, ServerManager serverManager, CacheManager cacheManager, BufferManager bufferManager)
        {
            _clientManager = clientManager;
            _serverManager = serverManager;
            _cacheManager = cacheManager;
            _bufferManager = bufferManager;

            _settings = new Settings();

            _routeTable = new Kademlia<Node>(256, 20);

            _connectionManagers = new LockedList<ConnectionManager>();

            _packetControlManager = new PacketControlManager();
            _packetControlManager.GetLockNodesEvent = (object sender) =>
            {
                lock (_thisLock)
                {
                    return _connectionManagers.Select(n => n.Node).ToArray();
                }
            };

            _creatingNodes = new LockedList<Node>();

            _waitingNodes = new VolatileHashSet<Node>(new TimeSpan(0, 0, 30));
            _removeNodes = new VolatileHashSet<Node>(new TimeSpan(0, 30, 0));

            _succeededUris = new VolatileHashSet<string>(new TimeSpan(1, 0, 0));

            _downloadBlocks = new VolatileHashSet<Key>(new TimeSpan(0, 30, 0));

            _pushBroadcastMetadatasRequestList = new VolatileHashSet<string>(new TimeSpan(0, 3, 0));
            _pushUnicastMetadatasRequestList = new VolatileHashSet<string>(new TimeSpan(0, 3, 0));
            _pushMulticastMetadatasRequestList = new VolatileHashSet<Tag>(new TimeSpan(0, 3, 0));

            _relayBlocks = new VolatileHashSet<Key>(new TimeSpan(0, 30, 0));

            _refreshTimer = new WatchTimer(this.RefreshTimer, new TimeSpan(0, 0, 5));
            _mediateTimer = new WatchTimer(this.MediateTimer, new TimeSpan(0, 1, 0));
            _reduceTimer = new WatchTimer(this.ReduceTimer, new TimeSpan(0, 3, 0));
        }
Пример #6
0
        //#endif
        public ConnectionsManager(ClientManager clientManager, ServerManager serverManager, CacheManager cacheManager, BufferManager bufferManager)
        {
            _clientManager = clientManager;
            _serverManager = serverManager;
            _cacheManager = cacheManager;
            _bufferManager = bufferManager;

            _settings = new Settings(this.ThisLock);

            _routeTable = new Kademlia<Node>(512, 20);

            _connectionManagers = new LockedList<ConnectionManager>();

            _messagesManager = new MessagesManager();
            _messagesManager.GetLockNodesEvent = (object sender) =>
            {
                lock (this.ThisLock)
                {
                    return _connectionManagers.Select(n => n.Node).ToArray();
                }
            };

            _creatingNodes = new LockedList<Node>();

            _waitingNodes = new VolatileHashSet<Node>(new TimeSpan(0, 0, 30));
            _cuttingNodes = new VolatileHashSet<Node>(new TimeSpan(0, 10, 0));
            _removeNodes = new VolatileHashSet<Node>(new TimeSpan(0, 30, 0));

            _succeededUris = new VolatileHashSet<string>(new TimeSpan(1, 0, 0));

            _downloadBlocks = new VolatileHashSet<Key>(new TimeSpan(0, 30, 0));
            _pushBroadcastSignaturesRequestList = new VolatileHashSet<string>(new TimeSpan(0, 3, 0));
            _pushUnicastSignaturesRequestList = new VolatileHashSet<string>(new TimeSpan(0, 3, 0));
            _pushMulticastWikisRequestList = new VolatileHashSet<Wiki>(new TimeSpan(0, 3, 0));
            _pushMulticastChatsRequestList = new VolatileHashSet<Chat>(new TimeSpan(0, 3, 0));

            _relayBlocks = new VolatileHashSet<Key>(new TimeSpan(0, 30, 0));

            _refreshTimer = new WatchTimer(this.RefreshTimer, new TimeSpan(0, 0, 5));
        }
Пример #7
0
        public void Test_Kademlia()
        {
            {
                var kademlia = new Kademlia <Node>(512, 20);

                {
                    Node node = null;

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                        node = new Node(id, uris);
                    }

                    kademlia.BaseNode = node;
                }

                for (int i = 0; i < 1024; i++)
                {
                    Node node = null;

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                        node = new Node(id, uris);
                    }

                    kademlia.Add(node);
                }

                for (int i = 0; i < 1024; i++)
                {
                    Node node = null;

                    {
                        var id = new byte[32];
                        _random.NextBytes(id);
                        var uris = new string[] { "net.tcp://localhost:9000", "net.tcp://localhost:9001", "net.tcp://localhost:9002" };

                        node = new Node(id, uris);
                    }

                    kademlia.Live(node);
                }

                foreach (var node in kademlia.ToArray().Take(kademlia.Count / 2))
                {
                    kademlia.Remove(node);
                }

                var v = kademlia.Verify();

                foreach (var node in kademlia.ToArray())
                {
                    var list = kademlia.Search(node.Id, kademlia.Count);
                    if (list.ElementAt(0) != node)
                    {
                        throw new Exception();
                    }
                }

                for (int i = 0; i < 1024; i++)
                {
                    var id = new byte[32];
                    _random.NextBytes(id);

                    var slist = Kademlia <Node> .Search(kademlia.BaseNode.Id, id, kademlia.ToArray(), kademlia.Count).ToList();

                    var slist2 = Kademlia <Node> .Search(kademlia.BaseNode.Id, id, kademlia.ToArray(), 3).ToList();

                    if (slist.Count == 0 && slist2.Count == 0)
                    {
                        continue;
                    }
                    var length = Math.Min(slist.Count, slist2.Count);

                    Assert.IsTrue(CollectionUtilities.Equals(slist, 0, slist2, 0, length));
                }

                for (int i = 0; i < 1024; i++)
                {
                    var id = new byte[32];
                    _random.NextBytes(id);

                    var slist = Kademlia <Node> .Search(id, kademlia.ToArray(), kademlia.Count).ToList();

                    var slist2 = Kademlia <Node> .Search(id, kademlia.ToArray(), 3).ToList();

                    if (slist.Count == 0 && slist2.Count == 0)
                    {
                        continue;
                    }
                    var length = Math.Min(slist.Count, slist2.Count);

                    Assert.IsTrue(CollectionUtilities.Equals(slist, 0, slist2, 0, length));
                }
            }
        }
Пример #8
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);
        }