Example #1
0
        public ConsensusFeature(
            DBreezeCoinView dBreezeCoinView,
            Network network,
            LookaheadBlockPuller blockPuller,
            CoinView coinView,
            ChainState chainState,
            IConnectionManager connectionManager,
            Signals.Signals signals,
            ConsensusLoop consensusLoop,
            NodeDeployments nodeDeployments,
            ILoggerFactory loggerFactory,
            ConsensusStats consensusStats,
            ConsensusSettings consensusSettings,
            IRuleRegistration ruleRegistration,
            IConsensusRules consensusRules,
            StakeChainStore stakeChain = null)
        {
            this.dBreezeCoinView   = dBreezeCoinView;
            this.blockPuller       = blockPuller;
            this.coinView          = coinView;
            this.chainState        = chainState;
            this.connectionManager = connectionManager;
            this.signals           = signals;
            this.network           = network;
            this.consensusLoop     = consensusLoop;
            this.nodeDeployments   = nodeDeployments;
            this.stakeChain        = stakeChain;
            this.logger            = loggerFactory.CreateLogger(this.GetType().FullName);
            this.loggerFactory     = loggerFactory;
            this.consensusStats    = consensusStats;
            this.ruleRegistration  = ruleRegistration;
            this.consensusRules    = consensusRules;

            this.chainState.MaxReorgLength = this.network.Consensus.Option <PowConsensusOptions>().MaxReorgLength;
        }
 public ConsensusFeature(
     DBreezeCoinView dBreezeCoinView,
     Network network,
     PowConsensusValidator consensusValidator,
     ConcurrentChain chain,
     LookaheadBlockPuller blockPuller,
     CoinView coinView,
     ChainBehavior.ChainState chainState,
     ConnectionManager connectionManager,
     CancellationProvider globalCancellation,
     Signals signals,
     ConsensusLoop consensusLoop,
     NodeSettings nodeSettings,
     StakeChainStore stakeChain = null)
 {
     this.dBreezeCoinView    = dBreezeCoinView;
     this.consensusValidator = consensusValidator;
     this.chain              = chain;
     this.blockPuller        = blockPuller;
     this.coinView           = coinView;
     this.chainState         = chainState;
     this.connectionManager  = connectionManager;
     this.globalCancellation = globalCancellation;
     this.signals            = signals;
     this.network            = network;
     this.consensusLoop      = consensusLoop;
     this.nodeSettings       = nodeSettings;
     this.stakeChain         = stakeChain;
 }
Example #3
0
 public ConsensusFeature(
     DBreezeCoinView dBreezeCoinView,
     Network network,
     PowConsensusValidator consensusValidator,
     ConcurrentChain chain,
     LookaheadBlockPuller blockPuller,
     CoinView coinView,
     ChainBehavior.ChainState chainState,
     IConnectionManager connectionManager,
     INodeLifetime nodeLifetime,
     Signals signals,
     ConsensusLoop consensusLoop,
     NodeSettings nodeSettings,
     NodeDeployments nodeDeployments,
     StakeChainStore stakeChain = null)
 {
     this.dBreezeCoinView    = dBreezeCoinView;
     this.consensusValidator = consensusValidator;
     this.chain             = chain;
     this.blockPuller       = blockPuller;
     this.coinView          = coinView;
     this.chainState        = chainState;
     this.connectionManager = connectionManager;
     this.nodeLifetime      = nodeLifetime;
     this.signals           = signals;
     this.network           = network;
     this.consensusLoop     = consensusLoop;
     this.nodeSettings      = nodeSettings;
     this.nodeDeployments   = nodeDeployments;
     this.stakeChain        = stakeChain;
 }
        public ConsensusStats(
            CoinView coinView,
            IConsensusLoop consensusLoop,
            IInitialBlockDownloadState initialBlockDownloadState,
            ConcurrentChain chain,
            IConnectionManager connectionManager,
            IDateTimeProvider dateTimeProvider,
            ILoggerFactory loggerFactory)
        {
            CoinViewStack stack = new CoinViewStack(coinView);

            this.cache   = stack.Find <CachedCoinView>();
            this.dbreeze = stack.Find <DBreezeCoinView>();
            this.bottom  = stack.Bottom;

            this.consensusLoop   = consensusLoop;
            this.lookaheadPuller = this.consensusLoop.Puller as LookaheadBlockPuller;

            this.lastSnapshot              = consensusLoop.ConsensusRules.PerformanceCounter.Snapshot();
            this.lastSnapshot2             = this.dbreeze?.PerformanceCounter.Snapshot();
            this.lastSnapshot3             = this.cache?.PerformanceCounter.Snapshot();
            this.initialBlockDownloadState = initialBlockDownloadState;
            this.chain             = chain;
            this.connectionManager = connectionManager;
            this.dateTimeProvider  = dateTimeProvider;
            this.logger            = loggerFactory.CreateLogger(this.GetType().FullName);
        }
        public void Notify_WithSync_SetPullerLocationToPreviousBlockMatchingStartHash()
        {
            var blocks = this.CreateBlocks(3);

            var chain = new ConcurrentChain(blocks[0].Header);

            this.AppendBlocksToChain(chain, blocks.Skip(1).Take(2));

            var dataFolder        = CreateDataFolder(this);
            var connectionManager = new Mock <IConnectionManager>();

            connectionManager.Setup(c => c.ConnectedPeers).Returns(new NetworkPeerCollection());
            connectionManager.Setup(c => c.NodeSettings).Returns(new NodeSettings().LoadArguments(new string[] { $"-datadir={dataFolder.WalletPath}" }));
            connectionManager.Setup(c => c.Parameters).Returns(new NetworkPeerConnectionParameters());

            var lookAheadBlockPuller = new LookaheadBlockPuller(chain, connectionManager.Object, new Mock <ILoggerFactory>().Object);
            var lifetime             = new NodeLifetime();

            var notification = new BlockNotification(this.LoggerFactory.Object, chain, lookAheadBlockPuller, new Signals.Signals(), new AsyncLoopFactory(new LoggerFactory()), lifetime);

            notification.SyncFrom(blocks[0].GetHash());
            notification.SyncFrom(blocks[0].GetHash());

            notification.Notify(lifetime.ApplicationStopping);

            Assert.Equal(0, lookAheadBlockPuller.Location.Height);
            Assert.Equal(lookAheadBlockPuller.Location.Header.GetHash(), blocks[0].Header.GetHash());
        }
        public ConsensusStats(
            CoinViewStack stack,
            CoinView coinView,
            ConsensusLoop consensusLoop,
            ChainState chainState,
            ConcurrentChain chain,
            IConnectionManager connectionManager,
            ILoggerFactory loggerFactory)
        {
            stack        = new CoinViewStack(coinView);
            this.cache   = stack.Find <CachedCoinView>();
            this.dbreeze = stack.Find <DBreezeCoinView>();
            this.bottom  = stack.Bottom;

            this.consensusLoop   = consensusLoop;
            this.lookaheadPuller = this.consensusLoop.Puller as LookaheadBlockPuller;

            this.lastSnapshot      = consensusLoop.Validator.PerformanceCounter.Snapshot();
            this.lastSnapshot2     = this.dbreeze?.PerformanceCounter.Snapshot();
            this.lastSnapshot3     = this.cache?.PerformanceCounter.Snapshot();
            this.chainState        = chainState;
            this.chain             = chain;
            this.connectionManager = connectionManager;
            this.logger            = loggerFactory.CreateLogger(this.GetType().FullName);
        }
        /// <summary>
        /// Initialize a new instance of <see cref="ConsensusLoop"/>.
        /// </summary>
        /// <param name="asyncLoopFactory">The async loop we need to wait upon before we can shut down this feature.</param>
        /// <param name="validator">The validation logic for the consensus rules.</param>
        /// <param name="nodeLifetime">Contain information about the life time of the node, its used on startup and shutdown.</param>
        /// <param name="chain">A chain of headers all the way to genesis.</param>
        /// <param name="utxoSet">The consensus db, containing all unspent UTXO in the chain.</param>
        /// <param name="puller">A puller that can pull blocks from peers on demand.</param>
        /// <param name="nodeDeployments">Contain information about deployment and activation of features in the chain.</param>
        /// <param name="loggerFactory">A factory to provide logger instances.</param>
        /// <param name="chainState">Holds state related to the block chain.</param>
        /// <param name="connectionManager">Connection manager of all the currently connected peers.</param>
        /// <param name="dateTimeProvider">Provider of time functions.</param>
        /// <param name="signals">A signaler that used to signal messages between features.</param>
        /// <param name="checkpoints">Provider of block header hash checkpoints.</param>
        /// <param name="consensusSettings">Consensus settings for the full node.</param>
        /// <param name="nodeSettings">Settings for the full node.</param>
        /// <param name="peerBanning">Handles the banning of peers.</param>
        /// <param name="consensusRules">The consensus rules to validate.</param>
        /// <param name="stakeChain">Information holding POS data chained.</param>
        public ConsensusLoop(
            IAsyncLoopFactory asyncLoopFactory,
            PowConsensusValidator validator,
            INodeLifetime nodeLifetime,
            ConcurrentChain chain,
            CoinView utxoSet,
            LookaheadBlockPuller puller,
            NodeDeployments nodeDeployments,
            ILoggerFactory loggerFactory,
            ChainState chainState,
            IConnectionManager connectionManager,
            IDateTimeProvider dateTimeProvider,
            Signals.Signals signals,
            ICheckpoints checkpoints,
            ConsensusSettings consensusSettings,
            NodeSettings nodeSettings,
            IPeerBanning peerBanning,
            IConsensusRules consensusRules,
            StakeChain stakeChain = null)
        {
            Guard.NotNull(asyncLoopFactory, nameof(asyncLoopFactory));
            Guard.NotNull(validator, nameof(validator));
            Guard.NotNull(nodeLifetime, nameof(nodeLifetime));
            Guard.NotNull(chain, nameof(chain));
            Guard.NotNull(utxoSet, nameof(utxoSet));
            Guard.NotNull(puller, nameof(puller));
            Guard.NotNull(nodeDeployments, nameof(nodeDeployments));
            Guard.NotNull(connectionManager, nameof(connectionManager));
            Guard.NotNull(chainState, nameof(chainState));
            Guard.NotNull(signals, nameof(signals));
            Guard.NotNull(consensusSettings, nameof(consensusSettings));
            Guard.NotNull(nodeSettings, nameof(nodeSettings));
            Guard.NotNull(peerBanning, nameof(peerBanning));
            Guard.NotNull(consensusRules, nameof(consensusRules));

            this.consensusLock = new AsyncLock();

            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);

            this.asyncLoopFactory  = asyncLoopFactory;
            this.Validator         = validator;
            this.nodeLifetime      = nodeLifetime;
            this.chainState        = chainState;
            this.connectionManager = connectionManager;
            this.signals           = signals;
            this.Chain             = chain;
            this.UTXOSet           = utxoSet;
            this.Puller            = puller;
            this.NodeDeployments   = nodeDeployments;
            this.checkpoints       = checkpoints;
            this.dateTimeProvider  = dateTimeProvider;
            this.consensusSettings = consensusSettings;
            this.nodeSettings      = nodeSettings;
            this.peerBanning       = peerBanning;
            this.consensusRules    = consensusRules;

            // chain of stake info can be null if POS is not enabled
            this.StakeChain = stakeChain;
        }
Example #8
0
 public BlockNotificationFeature(BlockNotification blockNotification, IConnectionManager connectionManager,
                                 LookaheadBlockPuller blockPuller, ChainState chainState, ConcurrentChain chain)
 {
     this.blockNotification = blockNotification;
     this.connectionManager = connectionManager;
     this.blockPuller       = blockPuller;
     this.chainState        = chainState;
     this.chain             = chain;
 }
 public BlockNotificationFeature(BlockNotification blockNotification, FullNode.CancellationProvider cancellationProvider, ConnectionManager connectionManager, LookaheadBlockPuller blockPuller, ChainBehavior.ChainState chainState, ConcurrentChain chain)
 {
     this.blockNotification    = blockNotification;
     this.cancellationProvider = cancellationProvider;
     this.connectionManager    = connectionManager;
     this.blockPuller          = blockPuller;
     this.chainState           = chainState;
     this.chain = chain;
 }
 public BlockNotificationFeature(IBlockNotification blockNotification, IConnectionManager connectionManager,
                                 LookaheadBlockPuller blockPuller, ChainState chainState, ConcurrentChain chain, ILoggerFactory loggerFactory)
 {
     this.blockNotification = blockNotification;
     this.connectionManager = connectionManager;
     this.blockPuller       = blockPuller;
     this.chainState        = chainState;
     this.chain             = chain;
     this.loggerFactory     = loggerFactory;
 }
Example #11
0
        public ConsensusLoop(ConsensusValidator validator, ConcurrentChain chain, CoinView utxoSet, LookaheadBlockPuller puller)
        {
            Guard.NotNull(validator, nameof(validator));
            Guard.NotNull(chain, nameof(chain));
            Guard.NotNull(utxoSet, nameof(utxoSet));
            Guard.NotNull(puller, nameof(puller));

            _Validator = validator;
            _Chain     = chain;
            _utxoSet   = utxoSet;
            _Puller    = puller;
        }
Example #12
0
        /// <summary>
        /// Creates test chain with a consensus loop.
        /// </summary>
        public static async Task <TestChainContext> CreateAsync(Network network, string dataDir)
        {
            var testChainContext = new TestChainContext()
            {
                Network = network
            };

            testChainContext.NodeSettings = new NodeSettings(network, args: new string[] { $"-datadir={dataDir}" });

            if (dataDir != null)
            {
                testChainContext.NodeSettings.DataDir = dataDir;
            }

            testChainContext.ConnectionSettings = new ConnectionManagerSettings();
            testChainContext.ConnectionSettings.Load(testChainContext.NodeSettings);

            testChainContext.LoggerFactory    = testChainContext.NodeSettings.LoggerFactory;
            testChainContext.DateTimeProvider = DateTimeProvider.Default;
            network.Consensus.Options         = new PowConsensusOptions();

            ConsensusSettings consensusSettings = new ConsensusSettings().Load(testChainContext.NodeSettings);

            testChainContext.Checkpoints = new Checkpoints();

            PowConsensusValidator consensusValidator = new PowConsensusValidator(network, testChainContext.Checkpoints, testChainContext.DateTimeProvider, testChainContext.LoggerFactory);

            testChainContext.Chain = new ConcurrentChain(network);
            CachedCoinView cachedCoinView = new CachedCoinView(new InMemoryCoinView(testChainContext.Chain.Tip.HashBlock), DateTimeProvider.Default, testChainContext.LoggerFactory);

            DataFolder dataFolder = new DataFolder(TestBase.AssureEmptyDir(dataDir));

            testChainContext.PeerAddressManager = new PeerAddressManager(DateTimeProvider.Default, dataFolder, testChainContext.LoggerFactory, new SelfEndpointTracker());

            testChainContext.MockConnectionManager       = new Moq.Mock <IConnectionManager>();
            testChainContext.MockReadOnlyNodesCollection = new Moq.Mock <IReadOnlyNetworkPeerCollection>();
            testChainContext.MockConnectionManager.Setup(s => s.ConnectedPeers).Returns(testChainContext.MockReadOnlyNodesCollection.Object);
            testChainContext.MockConnectionManager.Setup(s => s.NodeSettings).Returns(testChainContext.NodeSettings);
            testChainContext.MockConnectionManager.Setup(s => s.ConnectionSettings).Returns(testChainContext.ConnectionSettings);

            testChainContext.ConnectionManager = testChainContext.MockConnectionManager.Object;

            LookaheadBlockPuller blockPuller = new LookaheadBlockPuller(testChainContext.Chain, testChainContext.ConnectionManager, testChainContext.LoggerFactory);

            testChainContext.PeerBanning = new PeerBanning(testChainContext.ConnectionManager, testChainContext.LoggerFactory, testChainContext.DateTimeProvider, testChainContext.PeerAddressManager);
            NodeDeployments deployments    = new NodeDeployments(testChainContext.Network, testChainContext.Chain);
            ConsensusRules  consensusRules = new PowConsensusRules(testChainContext.Network, testChainContext.LoggerFactory, testChainContext.DateTimeProvider, testChainContext.Chain, deployments, consensusSettings, testChainContext.Checkpoints).Register(new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration());

            testChainContext.Consensus = new ConsensusLoop(new AsyncLoopFactory(testChainContext.LoggerFactory), consensusValidator, new NodeLifetime(), testChainContext.Chain, cachedCoinView, blockPuller, new NodeDeployments(network, testChainContext.Chain), testChainContext.LoggerFactory, new ChainState(new InvalidBlockHashStore(testChainContext.DateTimeProvider)), testChainContext.ConnectionManager, testChainContext.DateTimeProvider, new Signals.Signals(), consensusSettings, testChainContext.NodeSettings, testChainContext.PeerBanning, consensusRules);
            await testChainContext.Consensus.StartAsync();

            return(testChainContext);
        }
            public ConsensusStats(FullNode fullNode, CoinViewStack stack)
            {
                this.fullNode = fullNode;

                stack   = new CoinViewStack(fullNode.CoinView);
                cache   = stack.Find <CachedCoinView>();
                dbreeze = stack.Find <DBreezeCoinView>();
                bottom  = stack.Bottom;

                lookaheadPuller = fullNode.ConsensusLoop.Puller as LookaheadBlockPuller;

                lastSnapshot  = fullNode.ConsensusLoop.Validator.PerformanceCounter.Snapshot();
                lastSnapshot2 = dbreeze?.PerformanceCounter.Snapshot();
                lastSnapshot3 = cache?.PerformanceCounter.Snapshot();
            }
Example #14
0
        public ConsensusStats(CoinViewStack stack, CoinView coinView, ConsensusLoop consensusLoop, ChainBehavior.ChainState chainState, ConcurrentChain chain, ConnectionManager connectionManager)
        {
            stack   = new CoinViewStack(coinView);
            cache   = stack.Find <CachedCoinView>();
            dbreeze = stack.Find <DBreezeCoinView>();
            bottom  = stack.Bottom;

            this.consensusLoop = consensusLoop;
            lookaheadPuller    = this.consensusLoop.Puller as LookaheadBlockPuller;

            lastSnapshot           = consensusLoop.Validator.PerformanceCounter.Snapshot();
            lastSnapshot2          = dbreeze?.PerformanceCounter.Snapshot();
            lastSnapshot3          = cache?.PerformanceCounter.Snapshot();
            this.chainState        = chainState;
            this.chain             = chain;
            this.connectionManager = connectionManager;
        }
        public ConsensusFeature(
            IAsyncLoopFactory asyncLoopFactory,
            DBreezeCoinView dBreezeCoinView,
            Network network,
            PowConsensusValidator consensusValidator,
            ConcurrentChain chain,
            LookaheadBlockPuller blockPuller,
            CoinView coinView,
            ChainState chainState,
            IConnectionManager connectionManager,
            INodeLifetime nodeLifetime,
            Signals.Signals signals,
            ConsensusLoop consensusLoop,
            NodeSettings nodeSettings,
            NodeDeployments nodeDeployments,
            ILoggerFactory loggerFactory,
            IDateTimeProvider dateTimeProvider,
            ConsensusManager consensusManager,
            ConsensusStats consensusStats,
            ConsensusSettings consensusSettings,
            StakeChainStore stakeChain = null)
        {
            this.dBreezeCoinView    = dBreezeCoinView;
            this.consensusValidator = consensusValidator;
            this.chain             = chain;
            this.blockPuller       = blockPuller;
            this.coinView          = coinView;
            this.chainState        = chainState;
            this.connectionManager = connectionManager;
            this.nodeLifetime      = nodeLifetime;
            this.signals           = signals;
            this.network           = network;
            this.consensusLoop     = consensusLoop;
            this.nodeSettings      = nodeSettings;
            this.nodeDeployments   = nodeDeployments;
            this.stakeChain        = stakeChain;
            this.logger            = loggerFactory.CreateLogger(this.GetType().FullName);
            this.loggerFactory     = loggerFactory;
            this.dateTimeProvider  = dateTimeProvider;
            this.consensusManager  = consensusManager;
            this.consensusStats    = consensusStats;
            this.consensusSettings = consensusSettings;

            this.chainState.MaxReorgLength = this.network.Consensus.Option <PowConsensusOptions>().MaxReorgLength;
        }
Example #16
0
        /// <summary>
        /// Creates test chain with a consensus loop.
        /// </summary>
        public static async Task <TestChainContext> CreateAsync(Network network, string dataDir)
        {
            var testChainContext = new TestChainContext()
            {
                Network = network
            };

            testChainContext.NodeSettings = new NodeSettings(network.Name, network).LoadArguments(new string[] { $"-datadir={dataDir}" });

            if (dataDir != null)
            {
                testChainContext.NodeSettings.DataDir = dataDir;
            }

            testChainContext.LoggerFactory = new ExtendedLoggerFactory();
            testChainContext.LoggerFactory.AddConsoleWithFilters();
            testChainContext.DateTimeProvider = DateTimeProvider.Default;

            network.Consensus.Options = new PowConsensusOptions();
            ConsensusSettings     consensusSettings  = new ConsensusSettings(testChainContext.NodeSettings, testChainContext.LoggerFactory);
            PowConsensusValidator consensusValidator = new PowConsensusValidator(network, new Checkpoints(network, consensusSettings), testChainContext.DateTimeProvider, testChainContext.LoggerFactory);

            testChainContext.Chain = new ConcurrentChain(network);
            CachedCoinView cachedCoinView = new CachedCoinView(new InMemoryCoinView(testChainContext.Chain.Tip.HashBlock), DateTimeProvider.Default, testChainContext.LoggerFactory);

            testChainContext.MockConnectionManager       = new Moq.Mock <IConnectionManager>();
            testChainContext.MockReadOnlyNodesCollection = new Moq.Mock <IReadOnlyNetworkPeerCollection>();
            testChainContext.MockConnectionManager.Setup(s => s.ConnectedNodes).Returns(testChainContext.MockReadOnlyNodesCollection.Object);
            testChainContext.MockConnectionManager.Setup(s => s.NodeSettings).Returns(testChainContext.NodeSettings);

            testChainContext.ConnectionManager = testChainContext.MockConnectionManager.Object;

            LookaheadBlockPuller blockPuller = new LookaheadBlockPuller(testChainContext.Chain, testChainContext.ConnectionManager, new LoggerFactory());

            testChainContext.PeerBanning = new PeerBanning(testChainContext.ConnectionManager, testChainContext.LoggerFactory, testChainContext.DateTimeProvider, testChainContext.NodeSettings);

            testChainContext.Consensus = new ConsensusLoop(new AsyncLoopFactory(testChainContext.LoggerFactory), consensusValidator, new NodeLifetime(), testChainContext.Chain, cachedCoinView, blockPuller, new NodeDeployments(network, testChainContext.Chain), testChainContext.LoggerFactory, new ChainState(new FullNode(), new InvalidBlockHashStore(testChainContext.DateTimeProvider)), testChainContext.ConnectionManager, testChainContext.DateTimeProvider, new Signals.Signals(), new Checkpoints(network, consensusSettings), consensusSettings, testChainContext.NodeSettings, testChainContext.PeerBanning);
            await testChainContext.Consensus.StartAsync();

            return(testChainContext);
        }
Example #17
0
            public async Task InitializeAsync()
            {
                this.blockinfo = new List <Blockinfo>();
                var lst = blockinfoarr.Cast <long>().ToList();

                for (int i = 0; i < lst.Count; i += 2)
                {
                    this.blockinfo.Add(new Blockinfo {
                        extranonce = (int)lst[i], nonce = (uint)lst[i + 1]
                    });
                }

                // Note that by default, these tests run with size accounting enabled.
                this.network = Network.Main;
                var hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");

                this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG });
                this.newBlock     = new BlockTemplate(this.network);

                this.entry = new TestMemPoolEntryHelper();
                this.chain = new ConcurrentChain(this.network);
                this.network.Consensus.Options = new PowConsensusOptions();
                IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

                this.cachedCoinView = new CachedCoinView(new InMemoryCoinView(this.chain.Tip.HashBlock), dateTimeProvider, new LoggerFactory());

                var loggerFactory = new ExtendedLoggerFactory();

                loggerFactory.AddConsoleWithFilters();

                NodeSettings nodeSettings      = new NodeSettings(args: new string[] { "-checkpoints" });
                var          consensusSettings = new ConsensusSettings().Load(nodeSettings);

                PowConsensusValidator consensusValidator = new PowConsensusValidator(this.network, new Checkpoints(), dateTimeProvider, loggerFactory);
                NetworkPeerFactory    networkPeerFactory = new NetworkPeerFactory(this.network, dateTimeProvider, loggerFactory, new PayloadProvider().DiscoverPayloads(), new SelfEndpointTracker());

                var peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory, new SelfEndpointTracker());
                var peerDiscovery      = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, Network.Main, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager);
                var connectionSettings = new ConnectionManagerSettings();

                connectionSettings.Load(nodeSettings);
                var connectionManager = new ConnectionManager(dateTimeProvider, loggerFactory, this.network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery, connectionSettings);

                LookaheadBlockPuller blockPuller    = new LookaheadBlockPuller(this.chain, connectionManager, new LoggerFactory());
                PeerBanning          peerBanning    = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, peerAddressManager);
                NodeDeployments      deployments    = new NodeDeployments(this.network, this.chain);
                ConsensusRules       consensusRules = new PowConsensusRules(this.network, loggerFactory, dateTimeProvider, this.chain, deployments, consensusSettings, new Checkpoints(), this.cachedCoinView, blockPuller).Register(new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration());

                this.consensus = new ConsensusLoop(new AsyncLoopFactory(loggerFactory), consensusValidator, new NodeLifetime(), this.chain, this.cachedCoinView, blockPuller, new NodeDeployments(this.network, this.chain), loggerFactory, new ChainState(new InvalidBlockHashStore(dateTimeProvider)), connectionManager, dateTimeProvider, new Signals.Signals(), consensusSettings, nodeSettings, peerBanning, consensusRules);
                await this.consensus.StartAsync();

                this.entry.Fee(11);
                this.entry.Height(11);
                var date1 = new MemoryPoolTests.DateTimeProviderSet();

                date1.time            = dateTimeProvider.GetTime();
                date1.timeutc         = dateTimeProvider.GetUtcNow();
                this.DateTimeProvider = date1;
                this.mempool          = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), new LoggerFactory(), nodeSettings), new LoggerFactory(), nodeSettings);
                this.mempoolLock      = new MempoolSchedulerLock();

                // Simple block creation, nothing special yet:
                this.newBlock = AssemblerForTest(this).Build(this.chain.Tip, this.scriptPubKey);
                this.chain.SetTip(this.newBlock.Block.Header);
                await this.consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext {
                    Block = this.newBlock.Block
                }, this.network.Consensus, this.consensus.Tip) { CheckPow = false, CheckMerkleRoot = false });

                // We can't make transactions until we have inputs
                // Therefore, load 100 blocks :)
                this.baseheight = 0;
                List <Block> blocks = new List <Block>();

                this.txFirst = new List <Transaction>();
                for (int i = 0; i < this.blockinfo.Count; ++i)
                {
                    var pblock = this.newBlock.Block.Clone(); // pointer for convenience
                    pblock.Header.HashPrevBlock = this.chain.Tip.HashBlock;
                    pblock.Header.Version       = 1;
                    pblock.Header.Time          = Utils.DateTimeToUnixTime(this.chain.Tip.GetMedianTimePast()) + 1;
                    Transaction txCoinbase = pblock.Transactions[0].Clone();
                    txCoinbase.Inputs.Clear();
                    txCoinbase.Version = 1;
                    txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(this.blockinfo[i].extranonce), Op.GetPushOp(this.chain.Height) })));
                    // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                    txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                    pblock.Transactions[0] = txCoinbase;

                    if (this.txFirst.Count == 0)
                    {
                        this.baseheight = this.chain.Height;
                    }
                    if (this.txFirst.Count < 4)
                    {
                        this.txFirst.Add(pblock.Transactions[0]);
                    }
                    pblock.UpdateMerkleRoot();

                    pblock.Header.Nonce = this.blockinfo[i].nonce;

                    this.chain.SetTip(pblock.Header);
                    await this.consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext {
                        Block = pblock
                    }, this.network.Consensus, this.consensus.Tip) { CheckPow = false, CheckMerkleRoot = false });

                    blocks.Add(pblock);
                }

                // Just to make sure we can still make simple blocks
                this.newBlock = AssemblerForTest(this).Build(this.chain.Tip, this.scriptPubKey);
                Assert.NotNull(this.newBlock);
            }
Example #18
0
        /// <summary>
        /// Creates the test chain with some default blocks and txs.
        /// </summary>
        /// <param name="network">Network to create the chain on.</param>
        /// <param name="scriptPubKey">Public key to create blocks/txs with.</param>
        /// <returns>Context object representing the test chain.</returns>
        public static async Task <ITestChainContext> CreateAsync(Network network, Script scriptPubKey, string dataDir)
        {
            var nodeSettings = new NodeSettings(network, args: new string[] { $"-datadir={dataDir}" });

            ILoggerFactory    loggerFactory    = nodeSettings.LoggerFactory;
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            network.Consensus.Options = new ConsensusOptions();
            network.Consensus.Rules   = new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration().GetRules();

            var consensusSettings             = new ConsensusSettings(nodeSettings);
            var chain                         = new ConcurrentChain(network);
            InMemoryCoinView inMemoryCoinView = new InMemoryCoinView(chain.Tip.HashBlock);

            var cachedCoinView     = new CachedCoinView(inMemoryCoinView, DateTimeProvider.Default, loggerFactory);
            var networkPeerFactory = new NetworkPeerFactory(network, dateTimeProvider, loggerFactory, new PayloadProvider().DiscoverPayloads(), new SelfEndpointTracker());

            var peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory, new SelfEndpointTracker());
            var peerDiscovery      = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, network, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager);
            var connectionSettings = new ConnectionManagerSettings(nodeSettings);
            var connectionManager  = new ConnectionManager(dateTimeProvider, loggerFactory, network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery, connectionSettings, new VersionProvider());

            var            blockPuller    = new LookaheadBlockPuller(chain, connectionManager, new LoggerFactory());
            var            peerBanning    = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, peerAddressManager);
            var            deployments    = new NodeDeployments(network, chain);
            ConsensusRules consensusRules = new PowConsensusRules(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(), inMemoryCoinView, new Mock <ILookaheadBlockPuller>().Object).Register();
            var            consensusLoop  = new ConsensusLoop(new AsyncLoopFactory(loggerFactory), new NodeLifetime(), chain, cachedCoinView, blockPuller, deployments, loggerFactory, new ChainState(new InvalidBlockHashStore(dateTimeProvider)), connectionManager, dateTimeProvider, new Signals.Signals(), consensusSettings, nodeSettings, peerBanning, consensusRules);
            await consensusLoop.StartAsync();

            var blockPolicyEstimator = new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings);
            var mempool     = new TxMempool(dateTimeProvider, blockPolicyEstimator, loggerFactory, nodeSettings);
            var mempoolLock = new MempoolSchedulerLock();

            var minerSettings = new MinerSettings(nodeSettings);

            // Simple block creation, nothing special yet:
            PowBlockDefinition blockDefinition = new PowBlockDefinition(consensusLoop, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules);
            BlockTemplate      newBlock        = blockDefinition.Build(chain.Tip, scriptPubKey);

            chain.SetTip(newBlock.Block.Header);

            RuleContext ruleContext = consensusRules.CreateRuleContext(new ValidationContext {
                Block = newBlock.Block
            }, consensusLoop.Tip);

            ruleContext.MinedBlock = true;
            await consensusLoop.ValidateAndExecuteBlockAsync(ruleContext);

            List <BlockInfo> blockinfo = CreateBlockInfoList();

            // We can't make transactions until we have inputs
            // Therefore, load 100 blocks :)
            int baseheight = 0;
            var blocks     = new List <Block>();
            var srcTxs     = new List <Transaction>();

            for (int i = 0; i < blockinfo.Count; ++i)
            {
                Block currentBlock = Block.Load(newBlock.Block.ToBytes(network.Consensus.ConsensusFactory), network);
                currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock;
                currentBlock.Header.Version       = 1;
                currentBlock.Header.Time          = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1;

                Transaction txCoinbase = network.CreateTransaction(currentBlock.Transactions[0].ToBytes());
                txCoinbase.Inputs.Clear();
                txCoinbase.Version = 1;
                txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) })));
                // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                currentBlock.Transactions[0] = txCoinbase;

                if (srcTxs.Count == 0)
                {
                    baseheight = chain.Height;
                }
                if (srcTxs.Count < 4)
                {
                    srcTxs.Add(currentBlock.Transactions[0]);
                }

                currentBlock.UpdateMerkleRoot();

                currentBlock.Header.Nonce = blockinfo[i].nonce;

                chain.SetTip(currentBlock.Header);
                RuleContext ruleContextForBlock = consensusRules.CreateRuleContext(new ValidationContext {
                    Block = currentBlock
                }, consensusLoop.Tip);
                ruleContextForBlock.MinedBlock = true;
                await consensusLoop.ValidateAndExecuteBlockAsync(ruleContextForBlock);

                blocks.Add(currentBlock);
            }

            // Just to make sure we can still make simple blocks
            blockDefinition = new PowBlockDefinition(consensusLoop, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules);
            newBlock        = blockDefinition.Build(chain.Tip, scriptPubKey);

            var mempoolValidator = new MempoolValidator(mempool, mempoolLock, dateTimeProvider, new MempoolSettings(nodeSettings), chain, cachedCoinView, loggerFactory, nodeSettings, consensusRules);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, SrcTxs = srcTxs
            });
        }
Example #19
0
        public static void Main(string[] args)
        {
            Directory.CreateDirectory(SpvFolderPath);

            // TestNet addresses, first time used
            //var a1 = BitcoinAddress.Create("2Mz3BiReit6sNrSh9EMuhwUnhtqf2B35HpN"); // testnet, 1088037
            //var a2 = BitcoinAddress.Create("mwiSUHLGngZd849Sz3TE6kRb7fHjJCuwKe"); // testnet, 1088031
            //var a3 = BitcoinAddress.Create("muE3Z5Lhdk3WerqVevH49htmV96HJu4RLJ"); // testnet, 1088031
            //LocalPartialChain.Track(a1.ScriptPubKey);
            //LocalPartialChain.Track(a2.ScriptPubKey);
            //LocalPartialChain.Track(a3.ScriptPubKey);
            //Console.WriteLine($"Tracking {a1}");
            //Console.WriteLine($"Tracking {a2}");
            //Console.WriteLine($"Tracking {a3}");

            _connectionParameters = new NodeConnectionParameters();

            //So we find nodes faster
            _connectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(AddressManager));
            //So we don't have to load the chain each time we start
            _connectionParameters.TemplateBehaviors.Add(new ChainBehavior(LocalSpvChain));

            _nodes = new NodesGroup(Network, _connectionParameters,
                                    new NodeRequirement
            {
                RequiredServices = NodeServices.Network,
                MinVersion       = ProtocolVersion.SENDHEADERS_VERSION
            });
            var bp = new NodesBlockPuller(LocalSpvChain, _nodes.ConnectedNodes);

            _connectionParameters.TemplateBehaviors.Add(new NodesBlockPuller.NodesBlockPullerBehavior(bp));
            _nodes.NodeConnectionParameters = _connectionParameters;
            BlockPuller = (LookaheadBlockPuller)bp;
            MemPoolJob memPool = new MemPoolJob(_nodes, LocalPartialChain);

            Console.WriteLine("Start connecting to nodes...");
            _nodes.Connect();

            CancellationTokenSource cts = new CancellationTokenSource();

            var t1 = ReportConnectedNodeCountAsync(cts.Token);
            var t2 = ReportHeightAsync(cts.Token);
            var t3 = PeriodicSaveAsync(TimeSpan.FromMinutes(3), cts.Token);
            var t4 = BlockPullerJobAsync(cts.Token);
            //var t5 = ReportTransactionsWhenAllBlocksDownAsync(cts.Token);
            var t6 = memPool.StartAsync(cts.Token);
            var t7 = ReportMemPoolStateAsync(memPool, cts.Token);

            //ReportTransactions();

            Console.WriteLine("Press a key to exit...");
            Console.ReadKey();
            Console.WriteLine("Exiting...");

            cts.Cancel();
            Task.WhenAll(t1, t2, t3, t4, t6, t7).Wait();            //, t5, t6).Wait();

            SaveAllAsync().Wait();

            _nodes.Dispose();
        }
Example #20
0
        /// <summary>
        /// Creates the test chain with some default blocks and txs.
        /// </summary>
        /// <param name="network">Network to create the chain on.</param>
        /// <param name="scriptPubKey">Public key to create blocks/txs with.</param>
        /// <returns>Context object representing the test chain.</returns>
        public static ITestChainContext Create(Network network, Script scriptPubKey)
        {
            NodeSettings      nodeSettings     = NodeSettings.Default();
            LoggerFactory     loggerFactory    = new LoggerFactory();
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            network.Consensus.Options = new PowConsensusOptions();
            PowConsensusValidator consensusValidator = new PowConsensusValidator(network);
            ConcurrentChain       chain          = new ConcurrentChain(network);
            CachedCoinView        cachedCoinView = new CachedCoinView(new InMemoryCoinView(chain.Tip.HashBlock), loggerFactory);

            ConnectionManager    connectionManager = new ConnectionManager(network, new NodeConnectionParameters(), nodeSettings, loggerFactory, new NodeLifetime());
            LookaheadBlockPuller blockPuller       = new LookaheadBlockPuller(chain, connectionManager, new LoggerFactory());

            ConsensusLoop consensus = new ConsensusLoop(consensusValidator, chain, cachedCoinView, blockPuller, new NodeDeployments(network));

            consensus.Initialize();

            BlockPolicyEstimator blockPolicyEstimator = new BlockPolicyEstimator(new FeeRate(1000), nodeSettings, loggerFactory);
            TxMempool            mempool     = new TxMempool(new FeeRate(1000), dateTimeProvider, blockPolicyEstimator, loggerFactory);
            MempoolAsyncLock     mempoolLock = new MempoolAsyncLock();

            // Simple block creation, nothing special yet:
            PowBlockAssembler blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider);
            BlockTemplate     newBlock       = blockAssembler.CreateNewBlock(scriptPubKey);

            chain.SetTip(newBlock.Block.Header);
            consensus.AcceptBlock(new ContextInformation(new BlockResult {
                Block = newBlock.Block
            }, network.Consensus)
            {
                CheckPow = false, CheckMerkleRoot = false
            });

            List <BlockInfo> blockinfo = CreateBlockInfoList();

            // We can't make transactions until we have inputs
            // Therefore, load 100 blocks :)
            int                baseheight = 0;
            List <Block>       blocks     = new List <Block>();
            List <Transaction> srcTxs     = new List <Transaction>();

            for (int i = 0; i < blockinfo.Count; ++i)
            {
                Block currentBlock = newBlock.Block.Clone(); // pointer for convenience
                currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock;
                currentBlock.Header.Version       = 1;
                currentBlock.Header.Time          = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1;
                Transaction txCoinbase = currentBlock.Transactions[0].Clone();
                txCoinbase.Inputs.Clear();
                txCoinbase.Version = 1;
                txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) })));
                // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                currentBlock.Transactions[0] = txCoinbase;

                if (srcTxs.Count == 0)
                {
                    baseheight = chain.Height;
                }
                if (srcTxs.Count < 4)
                {
                    srcTxs.Add(currentBlock.Transactions[0]);
                }
                currentBlock.UpdateMerkleRoot();

                currentBlock.Header.Nonce = blockinfo[i].nonce;

                chain.SetTip(currentBlock.Header);
                consensus.AcceptBlock(new ContextInformation(new BlockResult {
                    Block = currentBlock
                }, network.Consensus)
                {
                    CheckPow = false, CheckMerkleRoot = false
                });
                blocks.Add(currentBlock);
            }

            // Just to make sure we can still make simple blocks
            blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider);
            newBlock       = blockAssembler.CreateNewBlock(scriptPubKey);

            MempoolValidator mempoolValidator = new MempoolValidator(mempool, mempoolLock, consensusValidator, dateTimeProvider, nodeSettings, chain, cachedCoinView, loggerFactory);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, SrcTxs = srcTxs
            });
        }
Example #21
0
        public WalletJob(Safe safeToTrack, HttpClientHandler handler = null, bool trackDefaultSafe = true, params SafeAccount[] accountsToTrack)
        {
            _creationHeight = Height.Unknown;
            _tracker        = null;

            Safe               = safeToTrack;
            CurrentNetwork     = safeToTrack.Network;
            MemPoolJob.Enabled = false;

            _qBitClient = new QBitNinjaClient(safeToTrack.Network);
            _httpClient = new HttpClient();
            if (handler != null)
            {
                _qBitClient.SetHttpMessageHandler(handler);
                _httpClient = new HttpClient(handler);
            }

            if (accountsToTrack == null || !accountsToTrack.Any())
            {
                SafeAccounts = new ConcurrentHashSet <SafeAccount>();
            }
            else
            {
                SafeAccounts = new ConcurrentHashSet <SafeAccount>(accountsToTrack);
            }

            TracksDefaultSafe = trackDefaultSafe;

            State = WalletState.NotStarted;

            Directory.CreateDirectory(WorkFolderPath);

            Tracker.TrackedTransactions.CollectionChanged += delegate
            {
                UpdateSafeTracking();
            };

            _connectionParameters = new NodeConnectionParameters();
            //So we find nodes faster
            _connectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(AddressManager));
            //So we don't have to load the chain each time we start
            _connectionParameters.TemplateBehaviors.Add(new ChainBehavior(HeaderChain));

            UpdateSafeTracking();

            Nodes = new NodesGroup(Safe.Network, _connectionParameters,
                                   new NodeRequirement
            {
                RequiredServices = NodeServices.Network,
                MinVersion       = ProtocolVersion.SENDHEADERS_VERSION
            });
            var bp = new NodesBlockPuller(HeaderChain, Nodes.ConnectedNodes);

            _connectionParameters.TemplateBehaviors.Add(new NodesBlockPuller.NodesBlockPullerBehavior(bp));
            Nodes.NodeConnectionParameters = _connectionParameters;
            BlockPuller = (LookaheadBlockPuller)bp;

            MemPoolJob.Synced += delegate
            {
                State = WalletState.Synced;

                var trackedMemPoolTransactions = Tracker.TrackedTransactions.Where(x => x.Height == Height.MemPool);
                foreach (var tx in trackedMemPoolTransactions)
                {
                    // If we are tracking a tx that is malleated or fall out of mempool (too long to confirm) then stop tracking
                    if (!MemPoolJob.Transactions.Contains(tx.GetHash()))
                    {
                        Tracker.TrackedTransactions.TryRemove(tx);
                        Debug.WriteLine($"Transaction fall out of MemPool: {tx.GetHash()}");
                    }
                }

                Debug.WriteLine("MemPool updated");
            };

            MemPoolJob.NewTransaction += MemPoolJob_NewTransaction;

            Nodes.ConnectedNodes.Removed += delegate { OnConnectedNodeCountChanged(); };
            Nodes.ConnectedNodes.Added   += delegate { OnConnectedNodeCountChanged(); };

            Tracker.BestHeightChanged += delegate { OnBestHeightChanged(); };
        }
Example #22
0
        /// <summary>
        /// Creates the test chain with some default blocks and txs.
        /// </summary>
        /// <param name="network">Network to create the chain on.</param>
        /// <param name="scriptPubKey">Public key to create blocks/txs with.</param>
        /// <returns>Context object representing the test chain.</returns>
        public static async Task <ITestChainContext> CreateAsync(Network network, Script scriptPubKey, string dataDir)
        {
            NodeSettings nodeSettings = new NodeSettings(network.Name, network).LoadArguments(new string[] { $"-datadir={dataDir}" });

            if (dataDir != null)
            {
                nodeSettings.DataDir = dataDir;
            }

            var loggerFactory = new ExtendedLoggerFactory();
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            network.Consensus.Options = new PowConsensusOptions();
            ConsensusSettings     consensusSettings  = new ConsensusSettings(nodeSettings, loggerFactory);
            PowConsensusValidator consensusValidator = new PowConsensusValidator(network, new Checkpoints(), dateTimeProvider, loggerFactory);
            ConcurrentChain       chain              = new ConcurrentChain(network);
            CachedCoinView        cachedCoinView     = new CachedCoinView(new InMemoryCoinView(chain.Tip.HashBlock), DateTimeProvider.Default, loggerFactory);
            NetworkPeerFactory    networkPeerFactory = new NetworkPeerFactory(network, dateTimeProvider, loggerFactory);

            var peerAddressManager = new PeerAddressManager(nodeSettings.DataFolder, loggerFactory);
            var peerDiscovery      = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, Network.PurpleMain, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager);
            var connectionManager  = new ConnectionManager(dateTimeProvider, loggerFactory, network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery);

            LookaheadBlockPuller blockPuller    = new LookaheadBlockPuller(chain, connectionManager, new LoggerFactory());
            PeerBanning          peerBanning    = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, nodeSettings);
            NodeDeployments      deployments    = new NodeDeployments(network, chain);
            ConsensusRules       consensusRules = new ConsensusRules(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints()).Register(new FullNodeBuilderConsensusExtension.CoreConsensusRules());
            ConsensusLoop        consensus      = new ConsensusLoop(new AsyncLoopFactory(loggerFactory), consensusValidator, new NodeLifetime(), chain, cachedCoinView, blockPuller, deployments, loggerFactory, new ChainState(new InvalidBlockHashStore(dateTimeProvider)), connectionManager, dateTimeProvider, new Signals.Signals(), consensusSettings, nodeSettings, peerBanning, consensusRules);
            await consensus.StartAsync();

            BlockPolicyEstimator blockPolicyEstimator = new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings);
            TxMempool            mempool     = new TxMempool(dateTimeProvider, blockPolicyEstimator, loggerFactory, nodeSettings);
            MempoolSchedulerLock mempoolLock = new MempoolSchedulerLock();

            // Simple block creation, nothing special yet:
            PowBlockAssembler blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider, loggerFactory);
            BlockTemplate     newBlock       = blockAssembler.CreateNewBlock(scriptPubKey);

            chain.SetTip(newBlock.Block.Header);
            await consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext {
                Block = newBlock.Block
            }, network.Consensus, consensus.Tip) { CheckPow = false, CheckMerkleRoot = false });

            List <BlockInfo> blockinfo = CreateBlockInfoList();

            // We can't make transactions until we have inputs
            // Therefore, load 100 blocks :)
            int                baseheight = 0;
            List <Block>       blocks     = new List <Block>();
            List <Transaction> srcTxs     = new List <Transaction>();

            for (int i = 0; i < blockinfo.Count; ++i)
            {
                Block currentBlock = newBlock.Block.Clone(); // pointer for convenience
                currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock;
                currentBlock.Header.Version       = 1;
                currentBlock.Header.Time          = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1;
                Transaction txCoinbase = currentBlock.Transactions[0].Clone();
                txCoinbase.Inputs.Clear();
                txCoinbase.Version = 1;
                txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) })));
                // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                currentBlock.Transactions[0] = txCoinbase;

                if (srcTxs.Count == 0)
                {
                    baseheight = chain.Height;
                }
                if (srcTxs.Count < 4)
                {
                    srcTxs.Add(currentBlock.Transactions[0]);
                }
                currentBlock.UpdateMerkleRoot();

                currentBlock.Header.Nonce = blockinfo[i].nonce;

                chain.SetTip(currentBlock.Header);
                await consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext {
                    Block = currentBlock
                }, network.Consensus, consensus.Tip) { CheckPow = false, CheckMerkleRoot = false });

                blocks.Add(currentBlock);
            }

            // Just to make sure we can still make simple blocks
            blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider, loggerFactory);
            newBlock       = blockAssembler.CreateNewBlock(scriptPubKey);

            MempoolValidator mempoolValidator = new MempoolValidator(mempool, mempoolLock, consensusValidator, dateTimeProvider, new MempoolSettings(nodeSettings), chain, cachedCoinView, loggerFactory, nodeSettings);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, SrcTxs = srcTxs
            });
        }
        public void Start()
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException("FullNode");
            }
            _IsStarted.Reset();

            // start all the features defined
            this.StartFeatures();

            // == RPC ==  // todo: add an RPC feature
            if (_Settings.RPC != null)
            {
                RPCHost = new WebHostBuilder()
                          .UseKestrel()
                          .ForFullNode(this)
                          .UseUrls(_Settings.RPC.GetUrls())
                          .UseIISIntegration()
                          .UseStartup <RPC.Startup>()
                          .Build();
                RPCHost.Start();
                _Resources.Add(RPCHost);
                Logs.RPC.LogInformation("RPC Server listening on: " + Environment.NewLine + String.Join(Environment.NewLine, _Settings.RPC.GetUrls()));
            }

            // === Consensus ===
            var coinviewdb = this.Services.ServiceProvider.GetService <DBreezeCoinView>();            // DBreezeCoinView will be in the constructor of a feature

            coinviewdb.Initialize(this.Network.GetGenesis()).GetAwaiter().GetResult();

            var blockPuller = new LookaheadBlockPuller(Chain, ConnectionManager.ConnectedNodes);

            ConnectionManager.Parameters.TemplateBehaviors.Add(new BlockPuller.BlockPullerBehavior(blockPuller));
            var consensusValidator = this.Services.ServiceProvider.GetService <ConsensusValidator>();           // new ConsensusValidator(Network.Consensus);

            ConsensusLoop = new ConsensusLoop(consensusValidator, Chain, CoinView, blockPuller);
            this._ChainBehaviorState.HighestValidatedPoW = ConsensusLoop.Tip;

            // === Miner ===
            this.Miner = new Mining(this, this.DateTimeProvider);

            var flags = ConsensusLoop.GetFlags();

            if (flags.ScriptFlags.HasFlag(ScriptVerify.Witness))
            {
                ConnectionManager.AddDiscoveredNodesRequirement(NodeServices.NODE_WITNESS);
            }

            // add disposables (TODO: move this to the consensus feature)
            this.Resources.Add(coinviewdb);


            _ChainBehaviorState.HighestValidatedPoW = ConsensusLoop.Tip;
            ConnectionManager.Start();

            new Thread(RunLoop)
            {
                Name = "Consensus Loop"
            }.Start();
            _IsStarted.Set();

            this.StartPeriodicLog();
        }
        public ConsensusLoop(PowConsensusValidator validator, ConcurrentChain chain, CoinView utxoSet, LookaheadBlockPuller puller, NodeDeployments nodeDeployments, StakeChain stakeChain = null)
        {
            Guard.NotNull(validator, nameof(validator));
            Guard.NotNull(chain, nameof(chain));
            Guard.NotNull(utxoSet, nameof(utxoSet));
            Guard.NotNull(puller, nameof(puller));
            Guard.NotNull(nodeDeployments, nameof(nodeDeployments));

            this.Validator       = validator;
            this.Chain           = chain;
            this.UTXOSet         = utxoSet;
            this.Puller          = puller;
            this.NodeDeployments = nodeDeployments;

            // chain of stake info can be null if POS is not enabled
            this.StakeChain = stakeChain;
        }