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); }
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)); }
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); }
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)); }
//#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)); }
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)); } } }
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); }