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);
        }
Exemplo n.º 2
0
        public void TestCacheCoinView()
        {
            using (NodeContext ctx = NodeContext.Create(this))
            {
                Block         genesis = ctx.Network.GetGenesis();
                var           genesisChainedHeader = new ChainedHeader(genesis.Header, ctx.Network.GenesisHash, 0);
                ChainedHeader chained          = this.MakeNext(genesisChainedHeader, ctx.Network);
                var           dateTimeProvider = new DateTimeProvider();

                var cacheCoinView = new CachedCoinView(ctx.PersistentCoinView, dateTimeProvider, this.loggerFactory, new NodeStats(dateTimeProvider));

                cacheCoinView.SaveChangesAsync(new UnspentOutputs[] { new UnspentOutputs(genesis.Transactions[0].GetHash(), new Coins(genesis.Transactions[0], 0)) }, null, genesisChainedHeader.HashBlock, chained.HashBlock).Wait();
                Assert.NotNull(cacheCoinView.FetchCoinsAsync(new[] { genesis.Transactions[0].GetHash() }).Result.UnspentOutputs[0]);
                Assert.Null(cacheCoinView.FetchCoinsAsync(new[] { new uint256() }).Result.UnspentOutputs[0]);
                Assert.Equal(chained.HashBlock, cacheCoinView.GetTipHashAsync().Result);

                Assert.Null(ctx.PersistentCoinView.FetchCoinsAsync(new[] { genesis.Transactions[0].GetHash() }).Result.UnspentOutputs[0]);
                Assert.Equal(chained.Previous.HashBlock, ctx.PersistentCoinView.GetTipHashAsync().Result);
                cacheCoinView.FlushAsync().GetAwaiter().GetResult();
                Assert.NotNull(ctx.PersistentCoinView.FetchCoinsAsync(new[] { genesis.Transactions[0].GetHash() }).Result.UnspentOutputs[0]);
                Assert.Equal(chained.HashBlock, ctx.PersistentCoinView.GetTipHashAsync().Result);
                //Assert.Null(ctx.PersistentCoinView.FetchCoinsAsync(new[] { new uint256() }).Result.UnspentOutputs[0]);

                //var previous = chained;
                //chained = MakeNext(MakeNext(genesisChainedBlock));
                //chained = MakeNext(MakeNext(genesisChainedBlock));
                //ctx.PersistentCoinView.SaveChangesAsync(new UnspentOutputs[0], previous.HashBlock, chained.HashBlock).Wait();
                //Assert.Equal(chained.HashBlock, ctx.PersistentCoinView.GetTipHashAsync().GetAwaiter().GetResult());
                //ctx.ReloadPersistentCoinView();
                //Assert.Equal(chained.HashBlock, ctx.PersistentCoinView.GetTipHashAsync().GetAwaiter().GetResult());
                //Assert.NotNull(ctx.PersistentCoinView.FetchCoinsAsync(new[] { genesis.Transactions[0].GetHash() }).Result.UnspentOutputs[0]);
                //Assert.Null(ctx.PersistentCoinView.FetchCoinsAsync(new[] { new uint256() }).Result.UnspentOutputs[0]);
            }
        }
Exemplo n.º 3
0
        public CoinviewTests()
        {
            this.network          = new StraxMain();
            this.dataFolder       = TestBase.CreateDataFolder(this);
            this.dateTimeProvider = new DateTimeProvider();
            this.loggerFactory    = new ExtendedLoggerFactory();
            this.nodeStats        = new NodeStats(this.dateTimeProvider, this.loggerFactory);

            this.coindb = new DBreezeCoindb(this.network, this.dataFolder, this.dateTimeProvider, this.loggerFactory, this.nodeStats, new DBreezeSerializer(this.network.Consensus.ConsensusFactory));
            this.coindb.Initialize();

            this.chainIndexer    = new ChainIndexer(this.network);
            this.stakeChainStore = new StakeChainStore(this.network, this.chainIndexer, (IStakedb)this.coindb, this.loggerFactory);
            this.stakeChainStore.Load();

            this.rewindDataIndexCache = new RewindDataIndexCache(this.dateTimeProvider, this.network, new FinalizedBlockInfoRepository(new HashHeightPair()), new Checkpoints());

            this.cachedCoinView = new CachedCoinView(this.network, new Checkpoints(), this.coindb, this.dateTimeProvider, this.loggerFactory, this.nodeStats, new ConsensusSettings(new NodeSettings(this.network)), this.stakeChainStore, this.rewindDataIndexCache);

            this.rewindDataIndexCache.Initialize(this.chainIndexer.Height, this.cachedCoinView);

            this.random = new Random();

            ChainedHeader newTip = ChainedHeadersHelper.CreateConsecutiveHeaders(1000, this.chainIndexer.Tip, true, null, this.network).Last();

            this.chainIndexer.SetTip(newTip);
        }
Exemplo n.º 4
0
        public void TestCacheCoinView()
        {
            using (NodeContext ctx = NodeContext.Create(this))
            {
                Block         genesis = ctx.Network.GetGenesis();
                var           genesisChainedHeader = new ChainedHeader(genesis.Header, ctx.Network.GenesisHash, 0);
                ChainedHeader chained          = this.MakeNext(genesisChainedHeader, ctx.Network);
                var           dateTimeProvider = new DateTimeProvider();

                var cacheCoinView = new CachedCoinView(this.network, new Checkpoints(), ctx.Coindb, dateTimeProvider, this.loggerFactory, new NodeStats(dateTimeProvider, NodeSettings.Default(this.network), new Mock <IVersionProvider>().Object), new ConsensusSettings(new NodeSettings(this.network)));

                cacheCoinView.SaveChanges(new UnspentOutput[] { new UnspentOutput(new OutPoint(genesis.Transactions[0], 0), new Coins(0, genesis.Transactions[0].Outputs.First(), true)) }, new HashHeightPair(genesisChainedHeader), new HashHeightPair(chained));
                Assert.NotNull(cacheCoinView.FetchCoins(new[] { new OutPoint(genesis.Transactions[0], 0) }).UnspentOutputs.Values.FirstOrDefault().Coins);
                Assert.Null(cacheCoinView.FetchCoins(new[] { new OutPoint() }).UnspentOutputs.Values.FirstOrDefault().Coins);
                Assert.Equal(new HashHeightPair(chained), cacheCoinView.GetTipHash());

                Assert.Null(ctx.Coindb.FetchCoins(new[] { new OutPoint(genesis.Transactions[0], 0) }).UnspentOutputs.Values.FirstOrDefault().Coins);
                Assert.Equal(chained.Previous.HashBlock, ctx.Coindb.GetTipHash().Hash);
                cacheCoinView.Flush();
                Assert.NotNull(ctx.Coindb.FetchCoins(new[] { new OutPoint(genesis.Transactions[0], 0) }).UnspentOutputs.Values.FirstOrDefault().Coins);
                Assert.Equal(chained.HashBlock, ctx.Coindb.GetTipHash().Hash);
                //Assert.Null(ctx.PersistentCoinView.FetchCoinsAsync(new[] { new uint256() }).Result.UnspentOutputs[0]);

                //var previous = chained;
                //chained = MakeNext(MakeNext(genesisChainedBlock));
                //chained = MakeNext(MakeNext(genesisChainedBlock));
                //ctx.PersistentCoinView.SaveChangesAsync(new UnspentOutputs[0], previous.HashBlock, chained.HashBlock).Wait();
                //Assert.Equal(chained.HashBlock, ctx.PersistentCoinView.GetTipHashAsync().GetAwaiter().GetResult());
                //ctx.ReloadPersistentCoinView();
                //Assert.Equal(chained.HashBlock, ctx.PersistentCoinView.GetTipHashAsync().GetAwaiter().GetResult());
                //Assert.NotNull(ctx.PersistentCoinView.FetchCoinsAsync(new[] { genesis.Transactions[0].GetHash() }).Result.UnspentOutputs[0]);
                //Assert.Null(ctx.PersistentCoinView.FetchCoinsAsync(new[] { new uint256() }).Result.UnspentOutputs[0]);
            }
        }
Exemplo n.º 5
0
        public ConsensusStats(
            ICoinView coinView,
            IConsensusManager consensusManager,
            IConsensusRuleEngine consensusRules,
            IInitialBlockDownloadState initialBlockDownloadState,
            ConcurrentChain chain,
            IConnectionManager connectionManager,
            IDateTimeProvider dateTimeProvider,
            IBlockPuller blockPuller,
            ILoggerFactory loggerFactory,
            INodeLifetime nodeLifetime)
        {
            var stack = new CoinViewStack(coinView);

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

            this.consensusManager = consensusManager;
            this.consensusRules   = consensusRules;

            this.lastSnapshot              = 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.blockPuller       = blockPuller;
            this.logger            = loggerFactory.CreateLogger(this.GetType().FullName);
            this.nodeLifetime      = nodeLifetime;
        }
Exemplo n.º 6
0
        public void TestCacheCoinView()
        {
            using (NodeContext ctx = NodeContext.Create())
            {
                var genesis             = ctx.Network.GetGenesis();
                var genesisChainedBlock = new ChainedBlock(genesis.Header, 0);
                var chained             = MakeNext(genesisChainedBlock);
                var cacheCoinView       = new CachedCoinView(ctx.PersistentCoinView);

                cacheCoinView.SaveChangesAsync(new UnspentOutputs[] { new UnspentOutputs(genesis.Transactions[0].GetHash(), new Coins(genesis.Transactions[0], 0)) }, null, genesisChainedBlock.HashBlock, chained.HashBlock).Wait();
                Assert.NotNull(cacheCoinView.FetchCoinsAsync(new[] { genesis.Transactions[0].GetHash() }).Result.UnspentOutputs[0]);
                Assert.Null(cacheCoinView.FetchCoinsAsync(new[] { new uint256() }).Result.UnspentOutputs[0]);
                Assert.Equal(chained.HashBlock, cacheCoinView.GetBlockHashAsync().Result);

                Assert.Null(ctx.PersistentCoinView.FetchCoinsAsync(new[] { genesis.Transactions[0].GetHash() }).Result.UnspentOutputs[0]);
                Assert.Equal(chained.Previous.HashBlock, ctx.PersistentCoinView.GetBlockHashAsync().Result);
                cacheCoinView.FlushAsync().GetAwaiter().GetResult();
                Assert.NotNull(ctx.PersistentCoinView.FetchCoinsAsync(new[] { genesis.Transactions[0].GetHash() }).Result.UnspentOutputs[0]);
                Assert.Equal(chained.HashBlock, ctx.PersistentCoinView.GetBlockHashAsync().Result);
                //Assert.Null(ctx.PersistentCoinView.FetchCoinsAsync(new[] { new uint256() }).Result.UnspentOutputs[0]);


                //var previous = chained;
                //chained = MakeNext(MakeNext(genesisChainedBlock));
                //chained = MakeNext(MakeNext(genesisChainedBlock));
                //ctx.PersistentCoinView.SaveChangesAsync(new UnspentOutputs[0], previous.HashBlock, chained.HashBlock).Wait();
                //Assert.Equal(chained.HashBlock, ctx.PersistentCoinView.GetBlockHashAsync().GetAwaiter().GetResult());
                //ctx.ReloadPersistentCoinView();
                //Assert.Equal(chained.HashBlock, ctx.PersistentCoinView.GetBlockHashAsync().GetAwaiter().GetResult());
                //Assert.NotNull(ctx.PersistentCoinView.FetchCoinsAsync(new[] { genesis.Transactions[0].GetHash() }).Result.UnspentOutputs[0]);
                //Assert.Null(ctx.PersistentCoinView.FetchCoinsAsync(new[] { new uint256() }).Result.UnspentOutputs[0]);
            }
        }
        public CoinviewTests()
        {
            this.network          = new StratisMain();
            this.dataFolder       = TestBase.CreateDataFolder(this);
            this.dateTimeProvider = new DateTimeProvider();
            this.loggerFactory    = new ExtendedLoggerFactory();
            this.nodeStats        = new NodeStats(this.dateTimeProvider);

            this.dbreezeCoinview = new DBreezeCoinView(this.network, this.dataFolder, this.dateTimeProvider, this.loggerFactory, this.nodeStats, new DBreezeSerializer(this.network));
            this.dbreezeCoinview.InitializeAsync().GetAwaiter().GetResult();

            this.concurrentChain = new ConcurrentChain(this.network);
            this.stakeChainStore = new StakeChainStore(this.network, this.concurrentChain, this.dbreezeCoinview, this.loggerFactory);
            this.stakeChainStore.LoadAsync().GetAwaiter().GetResult();

            this.rewindDataIndexCache = new RewindDataIndexCache(this.dateTimeProvider, this.network);

            this.cachedCoinView = new CachedCoinView(this.dbreezeCoinview, this.dateTimeProvider, this.loggerFactory, this.nodeStats, this.stakeChainStore, this.rewindDataIndexCache);

            this.rewindDataIndexCache.InitializeAsync(this.concurrentChain.Height, this.cachedCoinView);

            this.random = new Random();

            ChainedHeader newTip = ChainedHeadersHelper.CreateConsecutiveHeaders(1000, this.concurrentChain.Tip, true, null, this.network).Last();

            this.concurrentChain.SetTip(newTip);
        }
        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);
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
0
            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();
            }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
0
        public static IFullNodeBuilder AddRequired(this IFullNodeBuilder builder)
        {
            builder.UseBaseFeature();

            // TODO: move some of the required services will move to their own feature
            return(builder.ConfigureServices(service =>
            {
                var dataFolder = new DataFolder(builder.NodeSettings);

                // TODO: move to ConsensusFeature (required for mempool)
                var coinviewdb = new DBreezeCoinView(builder.Network, dataFolder.CoinViewPath);
                var coinView = new CachedCoinView(coinviewdb)
                {
                    MaxItems = builder.NodeSettings.Cache.MaxItems
                };
                var consensusValidator = new ConsensusValidator(builder.Network.Consensus);
                service.AddSingleton(consensusValidator);
                service.AddSingleton <DBreezeCoinView>(coinviewdb);
                service.AddSingleton <CoinView>(coinView);
            }));
        }
Exemplo n.º 13
0
        /// <summary>
        /// Before we continue to persist coindb we need to make sure the
        /// store is not behind our tip, if it is we will wait to let store
        /// catchup even if it means we need to block consensus form advancing
        /// </summary>
        /// <param name="cachedCoinView"></param>
        private void WaitForBlockstore(CachedCoinView cachedCoinView)
        {
            if (this.chainState.BlockStoreTip != null)
            {
                int            delaySec          = 3;
                int            rewindDataWindow  = cachedCoinView.CalculateRewindWindow();
                HashHeightPair cachedCoinViewTip = cachedCoinView.GetTipHash();

                while (cachedCoinViewTip.Height - rewindDataWindow + 1 > this.chainState.BlockStoreTip.Height)
                {
                    if (this.nodeLifetime.ApplicationStopping.IsCancellationRequested)
                    {
                        // node is closing do nothing.
                        return;
                    }

                    // wait 3 seconds to let blockstore catch up
                    this.Logger.LogWarning("Store tip `{0}` is behind coindb rewind data tip `{1}` waiting {2} seconds to let store catch up", this.chainState.BlockStoreTip.Height, cachedCoinViewTip.Height - rewindDataWindow + 1, delaySec);
                    Task.Delay(delaySec * 1000).Wait();
                }
            }
        }
Exemplo n.º 14
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
            });
        }
Exemplo n.º 15
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);
            }
Exemplo n.º 16
0
        public void CanRewind()
        {
            using (NodeContext nodeContext = NodeContext.Create(this))
            {
                var dateTimeProvider = new DateTimeProvider();
                var cacheCoinView    = new CachedCoinView(nodeContext.PersistentCoinView, dateTimeProvider, this.loggerFactory, new NodeStats(dateTimeProvider));
                var tester           = new CoinViewTester(cacheCoinView);

                Coin[] coinsA = tester.CreateCoins(5);
                Coin[] coinsB = tester.CreateCoins(1);
                tester.NewBlock();
                cacheCoinView.FlushAsync().Wait();
                Assert.True(tester.Exists(coinsA[2]));
                Assert.True(tester.Exists(coinsB[0]));

                // Spend some coins.
                tester.Spend(coinsA[2]);
                tester.Spend(coinsB[0]);

                tester.NewBlock();

                // This will save an empty RewindData instance
                tester.NewBlock();

                // Create a new coin set/
                Coin[] coinsC = tester.CreateCoins(1);
                tester.NewBlock();
                Assert.True(tester.Exists(coinsA[0]));
                Assert.True(tester.Exists(coinsC[0]));
                Assert.False(tester.Exists(coinsA[2]));
                Assert.False(tester.Exists(coinsB[0]));

                // We need to rewind 3 times as we are now rewinding one block at a time.
                tester.Rewind(); // coinsC[0] should not exist any more.
                tester.Rewind(); // coinsA[2] should be spendable again.
                tester.Rewind(); // coinsB[2] should be spendable again.
                Assert.False(tester.Exists(coinsC[0]));
                Assert.True(tester.Exists(coinsA[2]));
                Assert.True(tester.Exists(coinsB[0]));

                // Spend some coins and esnure they are not spendable.
                tester.Spend(coinsA[2]);
                tester.Spend(coinsB[0]);
                tester.NewBlock();
                cacheCoinView.FlushAsync().Wait();
                Assert.False(tester.Exists(coinsA[2]));
                Assert.False(tester.Exists(coinsB[0]));

                // Rewind so that coinsA[2] and coinsB[0] become spendable again.
                tester.Rewind();
                Assert.True(tester.Exists(coinsA[2]));
                Assert.True(tester.Exists(coinsB[0]));

                // Create 7 coins in a new coin set and spend the first coin.
                Coin[] coinsD = tester.CreateCoins(7);
                tester.Spend(coinsD[0]);
                // Create a coin in a new coin set and spend it.
                Coin[] coinsE = tester.CreateCoins(1);
                tester.Spend(coinsE[0]);
                tester.NewBlock();

                Assert.True(tester.Exists(coinsD[1]));
                Assert.False(tester.Exists(coinsD[0]));
                cacheCoinView.FlushAsync().Wait();

                // Creates another empty RewindData instance.
                tester.NewBlock();

                // Rewind one block.
                tester.Rewind();

                // coinsD[1] was never touched, so should remain unchanged.
                // coinsD[0] was spent but the block in which the changes happened was not yet rewound to, so it remains unchanged.
                // coinsE[0] was spent but the block in which the changes happened was not yet rewound to, so it remains unchanged.
                // coinsA[1] was not touched, so should remain unchanged.
                // coinsB[1] was not touched, so should remain unchanged.
                Assert.True(tester.Exists(coinsD[1]));
                Assert.False(tester.Exists(coinsD[0]));
                Assert.False(tester.Exists(coinsE[0]));
                Assert.True(tester.Exists(coinsA[2]));
                Assert.True(tester.Exists(coinsB[0]));

                // Rewind one block.
                tester.Rewind();

                // coinsD[0] should now not exist in CoinView anymore.
                // coinsE[0] should now not exist in CoinView anymore.
                Assert.False(tester.Exists(coinsD[0]));
                Assert.False(tester.Exists(coinsE[0]));
            }
        }
Exemplo n.º 17
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
            });
        }
Exemplo n.º 18
0
            public async Task InitializeAsync()
            {
                this.blockinfo = new List <Blockinfo>();
                List <long> 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 = KnownNetworks.RegTest;
                byte[] hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
                this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG });

                this.entry = new TestMemPoolEntryHelper();
                this.chain = new ConcurrentChain(this.network);
                this.network.Consensus.Options = new ConsensusOptions();

                new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration().RegisterRules(this.network.Consensus);

                IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

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

                var loggerFactory = new ExtendedLoggerFactory();

                loggerFactory.AddConsoleWithFilters();

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

                var networkPeerFactory = new NetworkPeerFactory(this.network, dateTimeProvider, loggerFactory, new PayloadProvider().DiscoverPayloads(), new SelfEndpointTracker(loggerFactory), new Mock <IInitialBlockDownloadState>().Object, new ConnectionManagerSettings());

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

                var peerBanning = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, peerAddressManager);
                var deployments = new NodeDeployments(this.network, this.chain);

                var genesis = this.network.GetGenesis();

                var chainState = new ChainState()
                {
                    BlockStoreTip = new ChainedHeader(genesis.Header, genesis.GetHash(), 0)
                };

                this.ConsensusRules = new PowConsensusRuleEngine(this.network, loggerFactory, dateTimeProvider, this.chain, deployments, consensusSettings,
                                                                 new Checkpoints(), this.cachedCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider)).Register();

                this.consensus = ConsensusManagerHelper.CreateConsensusManager(this.network);
                await this.consensus.InitializeAsync(chainState.BlockStoreTip);

                this.entry.Fee(11);
                this.entry.Height(11);

                var dateTimeProviderSet = new MemoryPoolTests.DateTimeProviderSet
                {
                    time    = dateTimeProvider.GetTime(),
                    timeutc = dateTimeProvider.GetUtcNow()
                };

                this.DateTimeProvider = dateTimeProviderSet;
                this.mempool          = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings), loggerFactory, nodeSettings);
                this.mempoolLock      = new MempoolSchedulerLock();

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

                this.txFirst = new List <Transaction>();

                this.nonce = 0;

                for (int i = 0; i < this.blockinfo.Count; ++i)
                {
                    Block block = this.network.CreateBlock();
                    block.Header.HashPrevBlock = this.chain.Tip.HashBlock;
                    block.Header.Version       = 1;
                    block.Header.Time          = Utils.DateTimeToUnixTime(this.chain.Tip.GetMedianTimePast()) + 1;

                    Transaction txCoinbase = this.network.CreateTransaction();
                    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()));
                    block.AddTransaction(txCoinbase);

                    if (this.txFirst.Count == 0)
                    {
                        this.baseheight = this.chain.Height;
                    }

                    if (this.txFirst.Count < 4)
                    {
                        this.txFirst.Add(block.Transactions[0]);
                    }

                    block.Header.Bits = block.Header.GetWorkRequired(this.network, this.chain.Tip);

                    block.UpdateMerkleRoot();

                    while (!block.CheckProofOfWork())
                    {
                        block.Header.Nonce = ++this.nonce;
                    }

                    // Serialization sets the BlockSize property.
                    block = Block.Load(block.ToBytes(), this.network);

                    await this.consensus.BlockMinedAsync(block);

                    blocks.Add(block);
                }

                // Just to make sure we can still make simple blocks
                this.newBlock = AssemblerForTest(this).Build(this.chain.Tip, this.scriptPubKey);
                Assert.NotNull(this.newBlock);
            }
Exemplo n.º 19
0
        public void CanRewind()
        {
            using (NodeContext ctx = NodeContext.Create())
            {
                var cacheCoinView = new CachedCoinView(ctx.PersistentCoinView);
                var tester        = new CoinViewTester(cacheCoinView);

                var coins = tester.CreateCoins(5);
                var coin  = tester.CreateCoins(1);

                // 1
                var h1 = tester.NewBlock();
                cacheCoinView.FlushAsync().Wait();
                Assert.True(tester.Exists(coins[2]));
                Assert.True(tester.Exists(coin[0]));

                tester.Spend(coins[2]);
                tester.Spend(coin[0]);
                //2
                tester.NewBlock();
                //3
                tester.NewBlock();
                //4
                var coin2 = tester.CreateCoins(1);
                tester.NewBlock();
                Assert.True(tester.Exists(coins[0]));
                Assert.True(tester.Exists(coin2[0]));
                Assert.False(tester.Exists(coins[2]));
                Assert.False(tester.Exists(coin[0]));
                //1
                tester.Rewind();
                Assert.False(tester.Exists(coin2[0]));
                Assert.True(tester.Exists(coins[2]));
                Assert.True(tester.Exists(coin[0]));


                tester.Spend(coins[2]);
                tester.Spend(coin[0]);
                //2
                var h2 = tester.NewBlock();
                cacheCoinView.FlushAsync().Wait();
                Assert.False(tester.Exists(coins[2]));
                Assert.False(tester.Exists(coin[0]));

                //1
                Assert.True(h1 == tester.Rewind());
                Assert.True(tester.Exists(coins[2]));
                Assert.True(tester.Exists(coin[0]));


                var coins2 = tester.CreateCoins(7);
                tester.Spend(coins2[0]);
                coin2 = tester.CreateCoins(1);
                tester.Spend(coin2[0]);
                //2
                tester.NewBlock();
                Assert.True(tester.Exists(coins2[1]));
                Assert.False(tester.Exists(coins2[0]));
                cacheCoinView.FlushAsync().Wait();
                //3
                tester.NewBlock();
                //2
                tester.Rewind();
                Assert.True(tester.Exists(coins2[1]));
                Assert.False(tester.Exists(coins2[0]));
                Assert.False(tester.Exists(coin2[0]));
                Assert.True(tester.Exists(coins[2]));
                Assert.True(tester.Exists(coin[0]));
            }
        }
Exemplo n.º 20
0
        /// <summary>
        /// Creates test chain with a consensus loop.
        /// </summary>
        public static async Task <TestChainContext> CreateAsync(Network network, string dataDir, Mock <IPeerAddressManager> mockPeerAddressManager = null)
        {
            var testChainContext = new TestChainContext()
            {
                Network = network
            };

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

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

            var consensusSettings = new ConsensusSettings(testChainContext.NodeSettings);

            testChainContext.Checkpoints = new Checkpoints();
            testChainContext.Chain       = new ConcurrentChain(network);
            testChainContext.ChainState  = new ChainState();
            testChainContext.InitialBlockDownloadState = new InitialBlockDownloadState(testChainContext.ChainState, testChainContext.Network, consensusSettings, new Checkpoints());

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

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

            testChainContext.PeerAddressManager =
                mockPeerAddressManager == null ?
                new PeerAddressManager(DateTimeProvider.Default, dataFolder, testChainContext.LoggerFactory, new SelfEndpointTracker(testChainContext.LoggerFactory))
                    : mockPeerAddressManager.Object;

            testChainContext.MockConnectionManager       = new Mock <IConnectionManager>();
            testChainContext.MockReadOnlyNodesCollection = new 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;

            testChainContext.PeerBanning = new PeerBanning(testChainContext.ConnectionManager, testChainContext.LoggerFactory, testChainContext.DateTimeProvider, testChainContext.PeerAddressManager);
            var deployments = new NodeDeployments(testChainContext.Network, testChainContext.Chain);

            testChainContext.ConsensusRules = new PowConsensusRuleEngine(testChainContext.Network, testChainContext.LoggerFactory, testChainContext.DateTimeProvider,
                                                                         testChainContext.Chain, deployments, consensusSettings, testChainContext.Checkpoints, cachedCoinView, testChainContext.ChainState, new InvalidBlockHashStore(new DateTimeProvider()))
                                              .Register();

            testChainContext.HeaderValidator    = new HeaderValidator(testChainContext.ConsensusRules, testChainContext.LoggerFactory);
            testChainContext.IntegrityValidator = new IntegrityValidator(testChainContext.ConsensusRules, testChainContext.LoggerFactory);
            testChainContext.PartialValidator   = new PartialValidator(testChainContext.ConsensusRules, testChainContext.LoggerFactory);
            testChainContext.FullValidator      = new FullValidator(testChainContext.ConsensusRules, testChainContext.LoggerFactory);

            var blockRepository = new BlockRepository(testChainContext.Network, dataFolder, testChainContext.DateTimeProvider, testChainContext.LoggerFactory);
            var blockStore      = new BlockStoreQueue(testChainContext.Chain, testChainContext.ChainState, new Mock <StoreSettings>().Object,
                                                      new Mock <INodeLifetime>().Object, blockRepository, testChainContext.LoggerFactory, new Mock <INodeStats>().Object);

            await blockStore.InitializeAsync();

            testChainContext.Consensus = ConsensusManagerHelper.CreateConsensusManager(network, dataDir);

            await testChainContext.Consensus.InitializeAsync(testChainContext.Chain.Tip);

            return(testChainContext);
        }
        public void CanRewind()
        {
            using (NodeContext ctx = NodeContext.Create(this))
            {
                var cacheCoinView = new CachedCoinView(ctx.PersistentCoinView, DateTimeProvider.Default, this.loggerFactory);
                var tester        = new CoinViewTester(cacheCoinView);

                Coin[] coins = tester.CreateCoins(5);
                Coin[] coin  = tester.CreateCoins(1);

                // 1
                uint256 h1 = tester.NewBlock();
                cacheCoinView.FlushAsync().Wait();
                Assert.True(tester.Exists(coins[2]));
                Assert.True(tester.Exists(coin[0]));

                tester.Spend(coins[2]);
                tester.Spend(coin[0]);
                //2
                tester.NewBlock();
                //3
                tester.NewBlock();
                //4
                Coin[] coin2 = tester.CreateCoins(1);
                tester.NewBlock();
                Assert.True(tester.Exists(coins[0]));
                Assert.True(tester.Exists(coin2[0]));
                Assert.False(tester.Exists(coins[2]));
                Assert.False(tester.Exists(coin[0]));
                //1
                tester.Rewind();
                Assert.False(tester.Exists(coin2[0]));
                Assert.True(tester.Exists(coins[2]));
                Assert.True(tester.Exists(coin[0]));

                tester.Spend(coins[2]);
                tester.Spend(coin[0]);
                //2
                uint256 h2 = tester.NewBlock();
                cacheCoinView.FlushAsync().Wait();
                Assert.False(tester.Exists(coins[2]));
                Assert.False(tester.Exists(coin[0]));

                //1
                Assert.True(h1 == tester.Rewind());
                Assert.True(tester.Exists(coins[2]));
                Assert.True(tester.Exists(coin[0]));

                Coin[] coins2 = tester.CreateCoins(7);
                tester.Spend(coins2[0]);
                coin2 = tester.CreateCoins(1);
                tester.Spend(coin2[0]);
                //2
                tester.NewBlock();
                Assert.True(tester.Exists(coins2[1]));
                Assert.False(tester.Exists(coins2[0]));
                cacheCoinView.FlushAsync().Wait();
                //3
                tester.NewBlock();
                //2
                tester.Rewind();
                Assert.True(tester.Exists(coins2[1]));
                Assert.False(tester.Exists(coins2[0]));
                Assert.False(tester.Exists(coin2[0]));
                Assert.True(tester.Exists(coins[2]));
                Assert.True(tester.Exists(coin[0]));
            }
        }
        private Task RunLoop(CancellationToken cancellationToken)
        {
            try
            {
                var            stack = new CoinViewStack(this.coinView);
                CachedCoinView cache = stack.Find <CachedCoinView>();
                var            stats = new ConsensusStats(stack, this.coinView, this.consensusLoop, this.chainState, this.chain, this.connectionManager, this.loggerFactory);

                ChainedBlock lastTip = this.consensusLoop.Tip;
                foreach (BlockResult block in this.consensusLoop.Execute(cancellationToken))
                {
                    if (this.consensusLoop.Tip.FindFork(lastTip) != lastTip)
                    {
                        this.logger.LogInformation("Reorg detected, rewinding from '{0}' to '{1}'.", lastTip.HashBlock, this.consensusLoop.Tip);
                    }

                    lastTip = this.consensusLoop.Tip;

                    cancellationToken.ThrowIfCancellationRequested();

                    if (block.Error != null)
                    {
                        this.logger.LogError("Block rejected: {0}", block.Error.Message);

                        // Pull again.
                        this.consensusLoop.Puller.SetLocation(this.consensusLoop.Tip);

                        if (block.Error == ConsensusErrors.BadWitnessNonceSize)
                        {
                            this.logger.LogInformation("You probably need witness information, activating witness requirement for peers.");
                            this.connectionManager.AddDiscoveredNodesRequirement(NodeServices.NODE_WITNESS);
                            this.consensusLoop.Puller.RequestOptions(TransactionOptions.Witness);
                            continue;
                        }

                        // Set the PoW chain back to ConsensusLoop.Tip.
                        this.chain.SetTip(this.consensusLoop.Tip);

                        // Since ChainHeadersBehavior check PoW, MarkBlockInvalid can't be spammed.
                        this.logger.LogError("Marking block as invalid.");
                        this.chainState.MarkBlockInvalid(block.Block.GetHash());
                    }

                    if (block.Error == null)
                    {
                        this.chainState.HighestValidatedPoW = this.consensusLoop.Tip;

                        // We really want to flush if we are at the top of the chain.
                        // Otherwise, we just allow the flush to happen if it is needed.
                        bool forceFlush = this.chain.Tip.HashBlock == block.ChainedBlock?.HashBlock;
                        this.consensusLoop.FlushAsync(forceFlush).GetAwaiter().GetResult();

                        this.signals.SignalBlock(block.Block);
                    }

                    // TODO: Replace this with a signalling object.
                    if (stats.CanLog)
                    {
                        stats.Log();
                    }
                }
            }
            catch (Exception ex)
            {
                if (ex is OperationCanceledException)
                {
                    if (this.nodeLifetime.ApplicationStopping.IsCancellationRequested)
                    {
                        return(Task.FromException(ex));
                    }
                }

                // TODO Need to revisit unhandled exceptions in a way that any process can signal an exception has been
                // thrown so that the node and all the disposables can stop gracefully.
                this.logger.LogDebug("Exception occurred in consensus loop: {0}", ex.ToString());
                this.logger.LogCritical(new EventId(0), ex, "Consensus loop at Tip:{0} unhandled exception {1}", this.consensusLoop.Tip?.Height, ex.ToString());
                NLog.LogManager.Flush();
                throw;
            }

            return(Task.CompletedTask);
        }
Exemplo n.º 23
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
            });
        }
Exemplo n.º 24
0
            public async Task InitializeAsync()
            {
                this.blockinfo = new List <Blockinfo>();
                List <long> 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 = KnownNetworks.RegTest;
                byte[] hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
                this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG });

                this.entry        = new TestMemPoolEntryHelper();
                this.ChainIndexer = new ChainIndexer(this.network);
                this.network.Consensus.Options = new ConsensusOptions();

                IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

                var loggerFactory = ExtendedLoggerFactory.Create();

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

                var inMemoryCoinView = new InMemoryCoinView(new HashHeightPair(this.ChainIndexer.Tip));
                var nodeStats        = new NodeStats(dateTimeProvider, loggerFactory);

                this.cachedCoinView = new CachedCoinView(this.network, new Checkpoints(), inMemoryCoinView, dateTimeProvider, new LoggerFactory(), nodeStats, consensusSettings);

                var signals       = new Signals.Signals(loggerFactory, null);
                var asyncProvider = new AsyncProvider(loggerFactory, signals, new NodeLifetime());

                var deployments = new NodeDeployments(this.network, this.ChainIndexer);

                var genesis = this.network.GetGenesis();

                var chainState = new ChainState()
                {
                    BlockStoreTip = new ChainedHeader(genesis.Header, genesis.GetHash(), 0)
                };

                var consensusRulesContainer = new ConsensusRulesContainer();

                foreach (var ruleType in this.network.Consensus.ConsensusRules.HeaderValidationRules)
                {
                    consensusRulesContainer.HeaderValidationRules.Add(Activator.CreateInstance(ruleType) as HeaderValidationConsensusRule);
                }
                foreach (var ruleType in this.network.Consensus.ConsensusRules.FullValidationRules)
                {
                    FullValidationConsensusRule rule = null;
                    if (ruleType == typeof(FlushUtxosetRule))
                    {
                        rule = new FlushUtxosetRule(new Mock <IInitialBlockDownloadState>().Object);
                    }
                    else
                    {
                        rule = Activator.CreateInstance(ruleType) as FullValidationConsensusRule;
                    }

                    consensusRulesContainer.FullValidationRules.Add(rule);
                }

                this.ConsensusRules = new PowConsensusRuleEngine(this.network, loggerFactory, dateTimeProvider, this.ChainIndexer, deployments, consensusSettings,
                                                                 new Checkpoints(), this.cachedCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider), nodeStats, asyncProvider, consensusRulesContainer).SetupRulesEngineParent();

                this.consensus = ConsensusManagerHelper.CreateConsensusManager(this.network, chainState: chainState, inMemoryCoinView: inMemoryCoinView, chainIndexer: this.ChainIndexer, consensusRules: this.ConsensusRules);

                await this.consensus.InitializeAsync(chainState.BlockStoreTip);

                this.entry.Fee(11);
                this.entry.Height(11);

                var dateTimeProviderSet = new DateTimeProviderSet
                {
                    time    = dateTimeProvider.GetTime(),
                    timeutc = dateTimeProvider.GetUtcNow()
                };

                this.DateTimeProvider = dateTimeProviderSet;
                this.mempool          = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings), loggerFactory, nodeSettings);
                this.mempoolLock      = new MempoolSchedulerLock();

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

                this.txFirst = new List <Transaction>();

                this.nonce = 0;

                for (int i = 0; i < this.blockinfo.Count; ++i)
                {
                    Block block = this.network.CreateBlock();
                    block.Header.HashPrevBlock = this.consensus.Tip.HashBlock;
                    block.Header.Version       = 1;
                    block.Header.Time          = Utils.DateTimeToUnixTime(this.ChainIndexer.Tip.GetMedianTimePast()) + 1;

                    Transaction txCoinbase = this.network.CreateTransaction();
                    txCoinbase.Version = 1;
                    txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(this.blockinfo[i].extranonce), Op.GetPushOp(this.ChainIndexer.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()));
                    block.AddTransaction(txCoinbase);

                    if (this.txFirst.Count == 0)
                    {
                        this.baseheight = this.ChainIndexer.Height;
                    }

                    if (this.txFirst.Count < 4)
                    {
                        this.txFirst.Add(block.Transactions[0]);
                    }

                    block.Header.Bits = block.Header.GetWorkRequired(this.network, this.ChainIndexer.Tip);

                    block.UpdateMerkleRoot();

                    while (!block.CheckProofOfWork())
                    {
                        block.Header.Nonce = ++this.nonce;
                    }

                    // Serialization sets the BlockSize property.
                    block = Block.Load(block.ToBytes(), this.network.Consensus.ConsensusFactory);

                    var res = await this.consensus.BlockMinedAsync(block);

                    if (res == null)
                    {
                        throw new InvalidOperationException();
                    }

                    blocks.Add(block);
                }

                // Just to make sure we can still make simple blocks
                this.newBlock = AssemblerForTest(this).Build(this.ChainIndexer.Tip, this.scriptPubKey);
                Assert.NotNull(this.newBlock);
            }
Exemplo n.º 25
0
            public TestContext()
            {
                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.entry = new TestMemPoolEntryHelper();
                this.chain = new ConcurrentChain(this.network);
                this.network.Consensus.Options = new PowConsensusOptions();
                this.cachedCoinView            = new CachedCoinView(new InMemoryCoinView(this.chain.Tip.HashBlock), new LoggerFactory());
                this.consensus = new ConsensusLoop(new PowConsensusValidator(this.network), this.chain, this.cachedCoinView, new LookaheadBlockPuller(this.chain, new ConnectionManager(this.network, new NodeConnectionParameters(), new NodeSettings(), new LoggerFactory(), new NodeLifetime()), new LoggerFactory()), new NodeDeployments(this.network));
                this.consensus.Initialize();

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

                date1.time       = DateTimeProvider.Default.GetTime();
                date1.timeutc    = DateTimeProvider.Default.GetUtcNow();
                this.date        = date1;
                this.mempool     = new TxMempool(new FeeRate(1000), DateTimeProvider.Default, new BlockPolicyEstimator(new FeeRate(1000), NodeSettings.Default(), new LoggerFactory()), new LoggerFactory());;
                this.mempoolLock = new MempoolAsyncLock();

                // Simple block creation, nothing special yet:
                this.newBlock = AssemblerForTest(this).CreateNewBlock(this.scriptPubKey);
                this.chain.SetTip(this.newBlock.Block.Header);
                this.consensus.AcceptBlock(new ContextInformation(new BlockResult {
                    Block = this.newBlock.Block
                }, this.network.Consensus)
                {
                    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);
                    this.consensus.AcceptBlock(new ContextInformation(new BlockResult {
                        Block = pblock
                    }, this.network.Consensus)
                    {
                        CheckPow = false, CheckMerkleRoot = false
                    });
                    blocks.Add(pblock);
                }

                // Just to make sure we can still make simple blocks
                this.newBlock = AssemblerForTest(this).CreateNewBlock(this.scriptPubKey);
                Assert.NotNull(this.newBlock);
            }