public BlockingCollectionWorker(string name, bool isConcurrent, Logger logger)
 {
     this.name         = name;
     this.isConcurrent = isConcurrent;
     this.logger       = logger;
     this.queueWorker  = new WorkerMethod(name, WorkAction, initialNotify: false, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue, logger: logger);
     this.queueWorker.Start();
 }
Beispiel #2
0
        public CoreDaemon(ICoreRules rules, IStorageManager storageManager)
        {
            this.rules = rules;
            this.storageManager = storageManager;
            coreStorage = new CoreStorage(storageManager);

            // create chain state builder
            chainStateBuilder = new ChainStateBuilder(this.rules, coreStorage, this.storageManager);

            // create unconfirmed txes builder
            unconfirmedTxesBuilder = new UnconfirmedTxesBuilder(this, coreStorage, this.storageManager);

            // create workers
            targetChainWorker = new TargetChainWorker(
                new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMilliseconds(0), maxIdleTime: TimeSpan.FromSeconds(30)),
                ChainParams, coreStorage);

            chainStateWorker = new ChainStateWorker(
                new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMilliseconds(0), maxIdleTime: TimeSpan.FromSeconds(5)),
                targetChainWorker, chainStateBuilder, this.rules, coreStorage);

            unconfirmedTxesWorker = new UnconfirmedTxesWorker(
                new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMilliseconds(0), maxIdleTime: TimeSpan.FromSeconds(5)),
                chainStateWorker, unconfirmedTxesBuilder, coreStorage);

            pruningWorker = new PruningWorker(
                new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromSeconds(0), maxIdleTime: TimeSpan.FromMinutes(5)),
                this, this.storageManager, chainStateWorker);

            defragWorker = new DefragWorker(
                new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMinutes(5), maxIdleTime: TimeSpan.FromMinutes(5)),
                this.storageManager);

            gcWorker = new WorkerMethod("GC Worker", GcWorker,
                initialNotify: true, minIdleTime: TimeSpan.FromMinutes(5), maxIdleTime: TimeSpan.FromMinutes(5));

            utxoScanWorker = new WorkerMethod("UTXO Scan Worker", UtxoScanWorker,
                initialNotify: true, minIdleTime: TimeSpan.FromSeconds(60), maxIdleTime: TimeSpan.FromSeconds(60));

            statsWorker = new StatsWorker(
                new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMinutes(0), maxIdleTime: TimeSpan.MaxValue),
                this);

            // wire events
            chainStateWorker.BlockMissed += HandleBlockMissed;
            targetChainWorker.OnTargetChainChanged += HandleTargetChainChanged;
            chainStateWorker.OnChainStateChanged += HandleChainStateChanged;
            pruningWorker.OnWorkFinished += defragWorker.NotifyWork;
            unconfirmedTxesBuilder.UnconfirmedTxAdded += RaiseUnconfirmedTxAdded;
            unconfirmedTxesBuilder.TxesConfirmed += RaiseTxesConfirmed;
            unconfirmedTxesBuilder.TxesUnconfirmed += RaiseTxesUnconfirmed;
        }
Beispiel #3
0
 private void ConsumeWorker(WorkerMethod instance)
 {
     try
     {
         foreach (var value in this.queue.GetConsumingEnumerable())
         {
             this.consumeAction(value);
         }
     }
     finally
     {
         CompleteWorker((int)instance.Data);
     }
 }
Beispiel #4
0
        private void WorkAction(WorkerMethod instance)
        {
            if (this.queue == null)
            {
                throw new InvalidOperationException();
            }

            foreach (var value in this.GetConsumingEnumerable())
            {
                ConsumeItem(value);
            }

            CompleteWorker((int)instance.Data);
        }
        public HeadersRequestWorker(WorkerConfig workerConfig, LocalClient localClient, CoreDaemon coreDaemon)
            : base("HeadersRequestWorker", workerConfig.initialNotify, workerConfig.minIdleTime, workerConfig.maxIdleTime)
        {
            this.localClient = localClient;
            this.coreDaemon = coreDaemon;
            this.coreStorage = coreDaemon.CoreStorage;

            this.headersRequestsByPeer = new ConcurrentDictionary<Peer, DateTimeOffset>();

            this.localClient.OnBlockHeaders += HandleBlockHeaders;
            this.coreDaemon.OnTargetChainChanged += HandleTargetChainChanged;

            this.flushWorker = new WorkerMethod("HeadersRequestWorker.FlushWorker", FlushWorkerMethod, initialNotify: true, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue);
            this.flushQueue = new ConcurrentQueue<FlushHeaders>();
        }
Beispiel #6
0
 private void ReadWorker(WorkerMethod instance)
 {
     try
     {
         foreach (var item in this.source)
         {
             this.queue.Add(item);
         }
     }
     finally
     {
         this.queue.CompleteAdding();
         this.completedReadingEvent.Set();
     }
 }
Beispiel #7
0
        public ParallelConsumer(string name, int consumerThreadCount, Logger logger)
        {
            this.name   = name;
            this.logger = logger;

            this.readWorker = new WorkerMethod(name + ".ReadWorker", ReadWorker, initialNotify: false, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue, logger: logger);
            this.readWorker.Start();

            this.consumeWorkers          = new WorkerMethod[consumerThreadCount];
            this.consumeWorkersCompleted = new bool[this.consumeWorkers.Length];
            this.consumeWorkersLock      = new object();

            for (var i = 0; i < this.consumeWorkers.Length; i++)
            {
                this.consumeWorkers[i]      = new WorkerMethod(name + ".ConsumeWorker." + i, ConsumeWorker, initialNotify: false, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue, logger: logger);
                this.consumeWorkers[i].Data = i;
                this.consumeWorkers[i].Start();
            }
        }
Beispiel #8
0
        public CoreDaemon(IBlockchainRules rules, IStorageManager storageManager)
        {
            this.rules = rules;
            this.storageManager = storageManager;
            this.coreStorage = new CoreStorage(storageManager);

            // create chain state builder
            this.chainStateBuilder = new ChainStateBuilder(this.rules, this.coreStorage, this.storageManager);

            // create workers
            this.targetChainWorker = new TargetChainWorker(
                new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMilliseconds(50), maxIdleTime: TimeSpan.FromSeconds(30)),
                this.rules, this.coreStorage);

            this.chainStateWorker = new ChainStateWorker(
                new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMilliseconds(0), maxIdleTime: TimeSpan.FromSeconds(5)),
                this.targetChainWorker, this.chainStateBuilder, this.rules, this.coreStorage);

            this.pruningWorker = new PruningWorker(
                new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromSeconds(0), maxIdleTime: TimeSpan.FromMinutes(5)),
                this, this.storageManager, this.chainStateWorker);

            this.defragWorker = new DefragWorker(
                new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMinutes(5), maxIdleTime: TimeSpan.FromMinutes(5)),
                this.storageManager);

            this.gcWorker = new WorkerMethod("GC Worker", GcWorker,
                initialNotify: true, minIdleTime: TimeSpan.FromMinutes(5), maxIdleTime: TimeSpan.FromMinutes(5));

            this.utxoScanWorker = new WorkerMethod("UTXO Scan Worker", UtxoScanWorker,
                initialNotify: true, minIdleTime: TimeSpan.FromSeconds(60), maxIdleTime: TimeSpan.FromSeconds(60));

            // wire events
            this.chainStateWorker.BlockMissed += HandleBlockMissed;
            this.targetChainWorker.OnTargetChainChanged += HandleTargetChainChanged;
            this.chainStateWorker.OnChainStateChanged += HandleChainStateChanged;
            this.pruningWorker.OnWorkFinished += this.defragWorker.NotifyWork;
        }
Beispiel #9
0
        private Task UtxoScanWorker(WorkerMethod instance)
        {
            // time taking chain state snapshots
            var stopwatch = Stopwatch.StartNew();
            int chainStateHeight;
            using (var chainState = this.GetChainState())
            {
                chainStateHeight = chainState.Chain.Height;
            }
            stopwatch.Stop();
            logger.Info($"GetChainState at {chainStateHeight:N0}: {stopwatch.Elapsed.TotalSeconds:N2}s");

            // time enumerating chain state snapshots
            stopwatch = Stopwatch.StartNew();
            using (var chainState = this.GetChainState())
            {
                chainStateHeight = chainState.Chain.Height;
                chainState.ReadUnspentTransactions().Count();
            }
            stopwatch.Stop();
            logger.Info($"Enumerate chain state at {chainStateHeight:N0}: {stopwatch.Elapsed.TotalSeconds:N2}s");

            //using (var chainStateLocal = this.GetChainState())
            //{
            //    new MethodTimer(logger).Time("UTXO Commitment: {0:N0}".Format2(chainStateLocal.UnspentTxCount), () =>
            //    {
            //        using (var utxoStream = new UtxoStream(logger, chainStateLocal.ReadUnspentTransactions()))
            //        {
            //            var utxoHash = SHA256Pool.ComputeHash(utxoStream);
            //            logger.Info("UXO Commitment Hash: {0}".Format2(utxoHash.ToHexNumberString()));
            //        }
            //    });

            //    //new MethodTimer().Time("Full UTXO Scan: {0:N0}".Format2(chainStateLocal.Utxo.TransactionCount), () =>
            //    //{
            //    //    foreach (var output in chainStateLocal.Utxo.GetUnspentTransactions())
            //    //    {
            //    //    }
            //    //});
            //}

            return Task.FromResult(false);
        }
Beispiel #10
0
        private Task GcWorker(WorkerMethod instance)
        {
            logger.Info(
                string.Join("\n",
                    new string('-', 80),
                    $"GC Memory:      {(float)GC.GetTotalMemory(false) / 1.MILLION(),10:N2} MB",
                    $"Process Memory: {(float)Process.GetCurrentProcess().PrivateMemorySize64 / 1.MILLION(),10:N2} MB",
                    new string('-', 80)
                ));

            return Task.FromResult(false);
        }
        private Task FlushWorkerMethod(WorkerMethod instance)
        {
            FlushHeaders flushHeaders;
            while (this.flushQueue.TryDequeue(out flushHeaders))
            {
                // cooperative loop
                this.ThrowIfCancelled();

                var peer = flushHeaders.Peer;
                var blockHeaders = flushHeaders.Headers;

                // chain the downloaded headers
                this.coreStorage.ChainHeaders(blockHeaders);

                DateTimeOffset ignore;
                this.headersRequestsByPeer.TryRemove(peer, out ignore);
            }

            return Task.CompletedTask;
        }