public LocalClient(LocalClientType type, BlockchainDaemon blockchainDaemon, IBoundedStorage<NetworkAddressKey, NetworkAddressWithTime> knownAddressStorage) { this._type = type; this.blockchainDaemon = blockchainDaemon; this.shutdownToken = new CancellationTokenSource(); this.knownAddressCache = new BoundedCache<NetworkAddressKey, NetworkAddressWithTime> ( "KnownAddressCache", dataStorage: knownAddressStorage, maxFlushMemorySize: 5.THOUSAND(), maxCacheMemorySize: 500.THOUSAND(), sizeEstimator: knownAddress => 40 ); this.connectWorker = new Worker("LocalClient.ConnectWorker", ConnectWorker, true, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)); this.requestBlocksWorker = new Worker("LocalClient.RequestBlocksWorker", RequestBlocksWorker, true, TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(5000)); this.requestHeadersWorker = new Worker("LocalClient.RequestHeadersWorker", RequestHeadersWorker, true, TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(5000)); this.statsWorker = new Worker("LocalClient.StatsWorker", StatsWorker, true, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30)); this.blockchainDaemon.OnWinningBlockChanged += OnWinningBlockChanged; switch (this.Type) { case LocalClientType.MainNet: Messaging.Port = 8333; Messaging.Magic = Messaging.MAGIC_MAIN; break; case LocalClientType.TestNet3: Messaging.Port = 18333; Messaging.Magic = Messaging.MAGIC_TESTNET3; break; case LocalClientType.ComparisonToolTestNet: Messaging.Port = 18444; Messaging.Magic = Messaging.MAGIC_COMPARISON_TOOL; break; } }
public BlockchainDaemon(IBlockchainRules rules, CacheContext cacheContext) { this.shutdownToken = new CancellationTokenSource(); this._rules = rules; this._cacheContext = cacheContext; this._calculator = new BlockchainCalculator(this._rules, this._cacheContext, this.shutdownToken.Token); this._winningBlock = this._rules.GenesisChainedBlock; this._winningBlockchain = ImmutableArray.Create(this._rules.GenesisChainedBlock); this.winningBlockchainLock = new ReaderWriterLockSlim(); this._currentBlockchain = this._rules.GenesisBlockchain; this.currentBlockchainLock = new ReaderWriterLockSlim(); //TODO this.lastCurrentBlockchainWrite = Guid.NewGuid(); this.missingBlocks = new ConcurrentSetBuilder<UInt256>(); this.unchainedBlocks = new ConcurrentSetBuilder<UInt256>(); this.missingChainedBlocks = new ConcurrentSet<UInt256>(); this.missingTransactions = new ConcurrentSet<UInt256>(); // write genesis block out to storage this._cacheContext.BlockCache.UpdateValue(this._rules.GenesisBlock.Hash, this._rules.GenesisBlock); this._cacheContext.ChainedBlockCache.UpdateValue(this._rules.GenesisChainedBlock.BlockHash, this._rules.GenesisChainedBlock); // wait for genesis block to be flushed this._cacheContext.BlockCache.WaitForStorageFlush(); this._cacheContext.ChainedBlockCache.WaitForStorageFlush(); // pre-fill the chained block and header caches //this._cacheContext.BlockHeaderCache.FillCache(); this._cacheContext.ChainedBlockCache.FillCache(); // wire up cache events this._cacheContext.BlockHeaderCache.OnAddition += OnBlockHeaderAddition; this._cacheContext.BlockHeaderCache.OnModification += OnBlockHeaderModification; this._cacheContext.BlockCache.OnAddition += OnBlockAddition; this._cacheContext.BlockCache.OnModification += OnBlockModification; this._cacheContext.ChainedBlockCache.OnAddition += OnChainedBlockAddition; this._cacheContext.ChainedBlockCache.OnModification += OnChainedBlockModification; this.unchainedBlocks.UnionWith(this.CacheContext.BlockHeaderCache.GetAllKeys()); this.unchainedBlocks.ExceptWith(this.CacheContext.ChainedBlockCache.GetAllKeys()); // create workers this.chainingWorker = new Worker("BlockchainDaemon.ChainingWorker", ChainingWorker, runOnStart: true, waitTime: TimeSpan.FromSeconds(1), maxIdleTime: TimeSpan.FromSeconds(30)); this.winnerWorker = new Worker("BlockchainDaemon.WinnerWorker", WinnerWorker, runOnStart: true, waitTime: TimeSpan.FromSeconds(1), maxIdleTime: TimeSpan.FromSeconds(30)); this.validationWorker = new Worker("BlockchainDaemon.ValidationWorker", ValidationWorker, runOnStart: true, waitTime: TimeSpan.FromSeconds(10), maxIdleTime: TimeSpan.FromMinutes(5)); this.blockchainWorker = new Worker("BlockchainDaemon.BlockchainWorker", BlockchainWorker, runOnStart: true, waitTime: TimeSpan.FromSeconds(5), maxIdleTime: TimeSpan.FromMinutes(5)); this.validateCurrentChainWorker = new Worker("BlockchainDaemon.ValidateCurrentChainWorker", ValidateCurrentChainWorker, runOnStart: true, waitTime: TimeSpan.FromMinutes(30), maxIdleTime: TimeSpan.FromMinutes(30)); this.writeBlockchainWorker = new Worker("BlockchainDaemon.WriteBlockchainWorker", WriteBlockchainWorker, runOnStart: true, waitTime: TimeSpan.FromMinutes(5), maxIdleTime: TimeSpan.FromMinutes(30)); }