Example #1
0
        public async Task MinerCreateBlockAbsoluteHeightLockedAsync()
        {
            var context = new TestContext();
            await context.InitializeAsync();

            var tx = new Transaction();

            tx.AddInput(new TxIn());
            tx.AddOutput(new TxOut());
            var flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast;

            int        MedianTimeSpan = 11;
            List <int> prevheights    = new List <int>();

            prevheights.Add(1);
            tx.Version = 2;
            tx.Inputs[0].PrevOut.Hash  = context.txFirst[1].GetHash();
            tx.Inputs[0].ScriptSig     = new Script(OpcodeType.OP_1);
            tx.Inputs[0].PrevOut.N     = 0;
            tx.Inputs[0].Sequence      = new Sequence(TimeSpan.FromMinutes(10)); // txFirst[1] is the 3rd block
            tx.Outputs[0].Value        = context.BLOCKSUBSIDY - context.HIGHFEE;
            tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1);
            tx.LockTime    = 0;
            prevheights[0] = context.baseheight + 2;

            for (int i = 0; i < MedianTimeSpan; i++)
            {
                context.chain.SetTip(new BlockHeader {
                    HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 512
                });
            }
            var locks = (tx.CalculateSequenceLocks(prevheights.ToArray(), context.chain.Tip, flags));

            Assert.True(locks.Evaluate(context.chain.Tip));

            context = new TestContext();
            await context.InitializeAsync();

            // absolute height locked
            tx.Inputs[0].PrevOut.Hash = context.txFirst[2].GetHash();
            tx.Inputs[0].Sequence     = Sequence.Final - 1;
            prevheights[0]            = context.baseheight + 3;
            tx.LockTime  = context.chain.Tip.Height + 1;
            context.hash = tx.GetHash();
            context.mempool.AddUnchecked(context.hash, context.entry.Time(context.DateTimeProvider.GetTime()).FromTx(tx));
            Assert.True(!MempoolValidator.CheckFinalTransaction(context.chain, context.DateTimeProvider, tx, flags)); // Locktime fails
            Assert.True(this.TestSequenceLocks(context, context.chain.Tip, tx, flags));                               // Sequence locks pass
            context.chain.SetTip(new BlockHeader {
                HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 512
            });
            context.chain.SetTip(new BlockHeader {
                HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 512
            });
            Assert.True(tx.IsFinal(context.chain.Tip.GetMedianTimePast(), context.chain.Tip.Height + 2)); // Locktime passes on 2nd block
        }
Example #2
0
        public async Task MinerCreateBlockNonFinalTxsInMempoolAsync()
        {
            var context = new TestContext();
            await context.InitializeAsync();

            var tx = context.network.CreateTransaction();

            tx.AddInput(new TxIn());
            tx.AddOutput(new TxOut());

            // non - final txs in mempool
            (context.DateTimeProvider as DateTimeProviderSet).time = context.ChainIndexer.Tip.Header.Time + 1;
            //SetMockTime(chainActive.Tip().GetMedianTimePast() + 1);
            Transaction.LockTimeFlags flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast;
            // height map
            var prevheights = new List <int>();

            // relative height locked
            tx.Version = 2;
            prevheights.Add(1);
            tx.Inputs[0].PrevOut.Hash  = context.txFirst[0].GetHash(); // only 1 transaction
            tx.Inputs[0].PrevOut.N     = 0;
            tx.Inputs[0].ScriptSig     = new Script(OpcodeType.OP_1);
            tx.Inputs[0].Sequence      = new Sequence(context.ChainIndexer.Tip.Height + 1); // txFirst[0] is the 2nd block
            prevheights[0]             = context.baseheight + 1;
            tx.Outputs[0].Value        = context.BLOCKSUBSIDY - context.HIGHFEE;
            tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1);
            tx.LockTime  = 0;
            context.hash = tx.GetHash();
            context.mempool.AddUnchecked(context.hash, context.entry.Fee(context.HIGHFEE).Time(context.DateTimeProvider.GetTime()).SpendsCoinbase(true).FromTx(tx));
            Assert.True(MempoolValidator.CheckFinalTransaction(context.ChainIndexer, context.DateTimeProvider, tx, flags)); // Locktime passes
            Assert.True(!this.TestSequenceLocks(context, context.ChainIndexer.Tip, tx, flags));                             // Sequence locks fail

            BlockHeader blockHeader = context.network.Consensus.ConsensusFactory.CreateBlockHeader();

            blockHeader.HashPrevBlock = context.ChainIndexer.Tip.HashBlock;
            blockHeader.Time          = Utils.DateTimeToUnixTime(context.ChainIndexer.Tip.GetMedianTimePast()) + 1;
            context.ChainIndexer.SetTip(blockHeader);

            blockHeader = context.network.Consensus.ConsensusFactory.CreateBlockHeader();
            blockHeader.HashPrevBlock = context.ChainIndexer.Tip.HashBlock;
            blockHeader.Time          = Utils.DateTimeToUnixTime(context.ChainIndexer.Tip.GetMedianTimePast()) + 1;
            context.ChainIndexer.SetTip(blockHeader);

            blockHeader = context.network.Consensus.ConsensusFactory.CreateBlockHeader();
            blockHeader.HashPrevBlock = context.ChainIndexer.Tip.HashBlock;
            blockHeader.Time          = Utils.DateTimeToUnixTime(context.ChainIndexer.Tip.GetMedianTimePast()) + 1;
            context.ChainIndexer.SetTip(blockHeader);

            SequenceLock locks = tx.CalculateSequenceLocks(prevheights.ToArray(), context.ChainIndexer.Tip, flags);

            Assert.True(locks.Evaluate(context.ChainIndexer.Tip)); // Sequence locks pass on 2nd block
        }
Example #3
0
        /// <summary>
        /// Add an orphan transaction to the orphan pool.
        /// </summary>
        /// <param name="nodeId">Node id of the source node.</param>
        /// <param name="tx">The transaction to add.</param>
        /// <returns>Whether the orphan transaction was added.</returns>
        public Task <bool> AddOrphanTx(ulong nodeId, Transaction tx)
        {
            return(this.MempoolLock.WriteAsync(() =>
            {
                uint256 hash = tx.GetHash();
                if (this.mapOrphanTransactions.ContainsKey(hash))
                {
                    return false;
                }

                // Ignore big transactions, to avoid a
                // send-big-orphans memory exhaustion attack. If a peer has a legitimate
                // large transaction with a missing parent then we assume
                // it will rebroadcast it later, after the parent transaction(s)
                // have been mined or received.
                // 100 orphans, each of which is at most 99,999 bytes big is
                // at most 10 megabytes of orphans and somewhat more byprev index (in the worst case):
                int sz = MempoolValidator.GetTransactionWeight(tx, this.Validator.ConsensusOptions);
                if (sz >= this.consensusValidator.ConsensusOptions.MaxStandardTxWeight)
                {
                    this.mempoolLogger.LogInformation($"ignoring large orphan tx (size: {sz}, hash: {hash})");
                    return false;
                }

                var orphan = new OrphanTx
                {
                    Tx = tx,
                    NodeId = nodeId,
                    TimeExpire = this.dateTimeProvider.GetTime() + OrphanTxExpireTime
                };
                if (this.mapOrphanTransactions.TryAdd(hash, orphan))
                {
                    foreach (var txin in tx.Inputs)
                    {
                        List <OrphanTx> prv = this.mapOrphanTransactionsByPrev.TryGet(txin.PrevOut);
                        if (prv == null)
                        {
                            prv = new List <OrphanTx>();
                            this.mapOrphanTransactionsByPrev.Add(txin.PrevOut, prv);
                        }
                        prv.Add(orphan);
                    }
                }

                int orphanSize = this.mapOrphanTransactions.Count;
                this.mempoolLogger.LogInformation($"stored orphan tx {hash} (mapsz {orphanSize} outsz {this.mapOrphanTransactionsByPrev.Count})");
                this.Validator.PerformanceCounter.SetMempoolOrphanSize(orphanSize);

                return true;
            }));
        }
        private static MempoolManager CreateTestMempool(NodeSettings settings, out TxMempool txMemPool)
        {
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            txMemPool = new TxMempool(new FeeRate(1000), dateTimeProvider, new BlockPolicyEstimator(new FeeRate(1000), NodeSettings.Default(), new LoggerFactory()), new LoggerFactory());
            var mempoolLock        = new MempoolAsyncLock();
            var coins              = new InMemoryCoinView(settings.Network.GenesisHash);
            var chain              = new ConcurrentChain(Network.Main.GetGenesis().Header);
            var mempoolPersistence = new MempoolPersistence(settings, new LoggerFactory());

            NBitcoin.Network.Main.Consensus.Options = new PosConsensusOptions();
            var consensusValidator = new PowConsensusValidator(NBitcoin.Network.Main);
            var mempoolValidator   = new MempoolValidator(txMemPool, mempoolLock, consensusValidator, dateTimeProvider, settings, chain, coins, new LoggerFactory());
            var mempoolOrphans     = new MempoolOrphans(mempoolLock, txMemPool, chain, new Bitcoin.Signals.Signals(), mempoolValidator, consensusValidator, coins, dateTimeProvider, settings, new LoggerFactory());

            return(new MempoolManager(mempoolLock, txMemPool, mempoolValidator, mempoolOrphans, dateTimeProvider, settings, mempoolPersistence, coins, new LoggerFactory()));
        }
        private static MempoolManager CreateTestMempool(NodeSettings settings, out TxMempool txMemPool)
        {
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            txMemPool = new TxMempool(new FeeRate(1000), settings);
            var mempoolScheduler   = new MempoolScheduler();
            var coins              = new InMemoryCoinView(settings.Network.GenesisHash);
            var chain              = new ConcurrentChain(Network.Main.GetGenesis().Header);
            var mempoolPersistence = new MempoolPersistence(settings);

            NBitcoin.Network.Main.Consensus.Options = new PosConsensusOptions();
            var consensusValidator = new PowConsensusValidator(NBitcoin.Network.Main);
            var mempoolValidator   = new MempoolValidator(txMemPool, mempoolScheduler, consensusValidator, dateTimeProvider, settings, chain, coins);
            var mempoolOrphans     = new MempoolOrphans(mempoolScheduler, txMemPool, chain, mempoolValidator, consensusValidator, coins, dateTimeProvider, settings);

            return(new MempoolManager(mempoolScheduler, txMemPool, mempoolValidator, mempoolOrphans, dateTimeProvider, settings, mempoolPersistence));
        }
Example #6
0
        public void MinerCreateBlockNonFinalTxsInMempool()
        {
            var context = new TestContext();
            var tx      = new Transaction();

            tx.AddInput(new TxIn());
            tx.AddOutput(new TxOut());

            // non - final txs in mempool
            (context.date as MemoryPoolTests.DateTimeProviderSet).time = context.chain.Tip.Header.Time + 1;
            //SetMockTime(chainActive.Tip().GetMedianTimePast() + 1);
            var flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast;
            // height map
            List <int> prevheights = new List <int>();

            // relative height locked
            tx.Version = 2;
            prevheights.Add(1);
            tx.Inputs[0].PrevOut.Hash  = context.txFirst[0].GetHash();            // only 1 transaction
            tx.Inputs[0].PrevOut.N     = 0;
            tx.Inputs[0].ScriptSig     = new Script(OpcodeType.OP_1);
            tx.Inputs[0].Sequence      = new Sequence(context.chain.Tip.Height + 1);        // txFirst[0] is the 2nd block
            prevheights[0]             = context.baseheight + 1;
            tx.Outputs[0].Value        = context.BLOCKSUBSIDY - context.HIGHFEE;
            tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1);
            tx.LockTime  = 0;
            context.hash = tx.GetHash();
            context.mempool.AddUnchecked(context.hash, context.entry.Fee(context.HIGHFEE).Time(context.date.GetTime()).SpendsCoinbase(true).FromTx(tx));
            Assert.True(MempoolValidator.CheckFinalTransaction(context.chain, context.date, tx, flags)); // Locktime passes
            Assert.True(!TestSequenceLocks(context, context.chain.Tip, tx, flags));                      // Sequence locks fail
            context.chain.SetTip(new BlockHeader()
            {
                HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 1
            });
            context.chain.SetTip(new BlockHeader()
            {
                HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 1
            });
            context.chain.SetTip(new BlockHeader()
            {
                HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 1
            });
            var locks = tx.CalculateSequenceLocks(prevheights.ToArray(), context.chain.Tip, flags);

            Assert.True(locks.Evaluate(context.chain.Tip));             // Sequence locks pass on 2nd block
        }
Example #7
0
        /// <summary>
        /// Create the MempoolManager used for testing whether transactions are accepted to the memory pool.
        /// </summary>
        private void CreateMempoolManager()
        {
            this.mempoolSettings   = new MempoolSettings(this.nodeSettings);
            this.consensusSettings = new ConsensusSettings(this.nodeSettings);
            this.txMemPool         = new TxMempool(this.dateTimeProvider, new BlockPolicyEstimator(
                                                       new MempoolSettings(this.nodeSettings), this.loggerFactory, this.nodeSettings), this.loggerFactory, this.nodeSettings);
            this.chainIndexer    = new ChainIndexer(this.Network);
            this.nodeDeployments = new NodeDeployments(this.Network, this.chainIndexer);

            this.MockCoinView();
            this.MockStakeChain();
            this.MockStakeValidator();

            // Create POS consensus rules engine.
            var checkpoints = new Mock <ICheckpoints>();
            var chainState  = new ChainState();

            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)
            {
                consensusRulesContainer.FullValidationRules.Add(Activator.CreateInstance(ruleType) as FullValidationConsensusRule);
            }

            ConsensusRuleEngine consensusRuleEngine = new PosConsensusRuleEngine(this.Network, this.loggerFactory, this.dateTimeProvider,
                                                                                 this.chainIndexer, this.nodeDeployments, this.consensusSettings, checkpoints.Object, this.coinView.Object, this.stakeChain.Object,
                                                                                 this.stakeValidator.Object, chainState, new InvalidBlockHashStore(this.dateTimeProvider), new Mock <INodeStats>().Object, new Mock <IRewindDataIndexCache>().Object, this.asyncProvider, consensusRulesContainer)
                                                      .SetupRulesEngineParent();

            // Create mempool validator.
            var mempoolLock      = new MempoolSchedulerLock();
            var mempoolValidator = new MempoolValidator(this.txMemPool, mempoolLock, this.dateTimeProvider, this.mempoolSettings, this.chainIndexer,
                                                        this.coinView.Object, this.loggerFactory, this.nodeSettings, consensusRuleEngine);

            // Create mempool manager.
            var mempoolPersistence = new Mock <IMempoolPersistence>();

            this.mempoolManager = new MempoolManager(mempoolLock, this.txMemPool, mempoolValidator, this.dateTimeProvider, this.mempoolSettings,
                                                     mempoolPersistence.Object, this.coinView.Object, this.loggerFactory, this.Network);
        }
Example #8
0
        public async Task MinerCreateBlockAbsoluteTimeLockedAsync()
        {
            var context = new TestContext();
            await context.InitializeAsync();

            var tx = context.network.CreateTransaction();

            tx.AddInput(new TxIn());
            tx.AddOutput(new TxOut());
            Transaction.LockTimeFlags flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast;

            var prevheights = new List <int>();

            prevheights.Add(1);
            tx.Version = 2;
            tx.Inputs[0].PrevOut.Hash  = context.txFirst[3].GetHash();
            tx.Inputs[0].ScriptSig     = new Script(OpcodeType.OP_1);
            tx.Inputs[0].PrevOut.N     = 0;
            tx.Outputs[0].Value        = context.BLOCKSUBSIDY - context.HIGHFEE;
            tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1);

            // absolute time locked
            tx.LockTime           = context.ChainIndexer.Tip.GetMedianTimePast().AddMinutes(1);
            tx.Inputs[0].Sequence = Sequence.Final - 1;
            prevheights[0]        = context.baseheight + 4;
            context.hash          = tx.GetHash();
            context.mempool.AddUnchecked(context.hash, context.entry.Time(context.DateTimeProvider.GetTime()).FromTx(tx));
            Assert.True(!MempoolValidator.CheckFinalTransaction(context.ChainIndexer, context.DateTimeProvider, tx, flags)); // Locktime fails
            Assert.True(this.TestSequenceLocks(context, context.ChainIndexer.Tip, tx, flags));                               // Sequence locks pass

            BlockHeader blockHeader = context.network.Consensus.ConsensusFactory.CreateBlockHeader();

            blockHeader.HashPrevBlock = context.ChainIndexer.Tip.HashBlock;
            blockHeader.Time          = Utils.DateTimeToUnixTime(context.ChainIndexer.Tip.GetMedianTimePast()) + 512;
            context.ChainIndexer.SetTip(blockHeader);

            blockHeader = context.network.Consensus.ConsensusFactory.CreateBlockHeader();
            blockHeader.HashPrevBlock = context.ChainIndexer.Tip.HashBlock;
            blockHeader.Time          = Utils.DateTimeToUnixTime(context.ChainIndexer.Tip.GetMedianTimePast()) + 512;
            context.ChainIndexer.SetTip(blockHeader);

            Assert.True(tx.IsFinal(context.ChainIndexer.Tip.GetMedianTimePast().AddMinutes(2), context.ChainIndexer.Tip.Height + 2)); // Locktime passes 2 min later
        }
        private static MempoolManager CreateTestMempool(NodeSettings settings, out TxMempool txMemPool)
        {
            var mempoolSettings = new MempoolSettings(settings);
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;
            NodeSettings      nodeSettings     = NodeSettings.Default();
            ILoggerFactory    loggerFactory    = nodeSettings.LoggerFactory;
            var consensusSettings = new ConsensusSettings(nodeSettings);

            txMemPool = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings), loggerFactory, nodeSettings);
            var mempoolLock        = new MempoolSchedulerLock();
            var coins              = new InMemoryCoinView(settings.Network.GenesisHash);
            var chain              = new ConcurrentChain(Network.Main.GetGenesis().Header);
            var mempoolPersistence = new MempoolPersistence(settings, loggerFactory);

            Network.Main.Consensus.Options = new PosConsensusOptions();
            ConsensusRules consensusRules   = new PowConsensusRules(Network.Main, loggerFactory, dateTimeProvider, chain, new NodeDeployments(Network.Main, chain), consensusSettings, new Checkpoints(), new InMemoryCoinView(new uint256()), new Mock <ILookaheadBlockPuller>().Object).Register(new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration());
            var            mempoolValidator = new MempoolValidator(txMemPool, mempoolLock, dateTimeProvider, mempoolSettings, chain, coins, loggerFactory, settings, consensusRules);

            return(new MempoolManager(mempoolLock, txMemPool, mempoolValidator, dateTimeProvider, mempoolSettings, mempoolPersistence, coins, loggerFactory, settings.Network));
        }
        private static MempoolManager CreateTestMempool(NodeSettings settings, out TxMempool txMemPool)
        {
            var mempoolSettings = new MempoolSettings(settings);
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;
            NodeSettings      nodeSettings     = NodeSettings.Default();
            var loggerFactory = nodeSettings.LoggerFactory;
            ConsensusSettings consensusSettings = new ConsensusSettings().Load(nodeSettings);

            txMemPool = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings), loggerFactory, nodeSettings);
            var mempoolLock        = new MempoolSchedulerLock();
            var coins              = new InMemoryCoinView(settings.Network.GenesisHash);
            var chain              = new ConcurrentChain(Network.Main.GetGenesis().Header);
            var mempoolPersistence = new MempoolPersistence(settings, loggerFactory);

            Network.Main.Consensus.Options = new PosConsensusOptions();
            var consensusValidator = new PowConsensusValidator(Network.Main, new Checkpoints(Network.Main, consensusSettings), dateTimeProvider, loggerFactory);
            var mempoolValidator   = new MempoolValidator(txMemPool, mempoolLock, consensusValidator, dateTimeProvider, mempoolSettings, chain, coins, loggerFactory, settings);
            var mempoolOrphans     = new MempoolOrphans(mempoolLock, txMemPool, chain, new Signals.Signals(), mempoolValidator, consensusValidator, coins, dateTimeProvider, mempoolSettings, loggerFactory);

            return(new MempoolManager(mempoolLock, txMemPool, mempoolValidator, mempoolOrphans, dateTimeProvider, mempoolSettings, mempoolPersistence, coins, loggerFactory, settings.Network));
        }
        public WalletManager(ILoggerFactory loggerFactory, IConnectionManager connectionManager, Network network, ConcurrentChain chain,
                             NodeSettings settings, DataFolder dataFolder, IWalletFeePolicy walletFeePolicy, IAsyncLoopFactory asyncLoopFactory,
                             INodeLifetime nodeLifetime, MempoolValidator mempoolValidator = null) // mempool does not exist in a light wallet
        {
            this.logger  = loggerFactory.CreateLogger(this.GetType().FullName);
            this.Wallets = new ConcurrentBag <Wallet>();

            this.connectionManager = connectionManager;
            this.network           = network;
            this.coinType          = (CoinType)network.Consensus.CoinType;
            this.chain             = chain;
            this.settings          = settings;
            this.dataFolder        = dataFolder;
            this.walletFeePolicy   = walletFeePolicy;
            this.mempoolValidator  = mempoolValidator;
            this.asyncLoopFactory  = asyncLoopFactory;
            this.nodeLifetime      = nodeLifetime;

            // register events
            this.TransactionFound += this.OnTransactionFound;
        }
Example #12
0
        private MempoolManager CreateTestMempool(NodeSettings settings, out TxMempool txMemPool)
        {
            var mempoolSettings = new MempoolSettings(settings);
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;
            NodeSettings      nodeSettings     = NodeSettings.Default(settings.Network);
            ILoggerFactory    loggerFactory    = nodeSettings.LoggerFactory;
            var consensusSettings = new ConsensusSettings(nodeSettings);

            txMemPool = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings), loggerFactory, nodeSettings);
            var mempoolLock        = new MempoolSchedulerLock();
            var coins              = new InMemoryCoinView(settings.Network.GenesisHash);
            var chain              = new ChainIndexer(settings.Network);
            var chainState         = new ChainState();
            var mempoolPersistence = new MempoolPersistence(settings, loggerFactory);

            this.network.Consensus.Options = new PosConsensusOptions();
            new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration().RegisterRules(this.network.Consensus);
            ConsensusRuleEngine consensusRules = new PowConsensusRuleEngine(this.network, loggerFactory, dateTimeProvider, chain, new NodeDeployments(this.network, chain),
                                                                            consensusSettings, new Checkpoints(), coins, chainState, new InvalidBlockHashStore(dateTimeProvider), new NodeStats(dateTimeProvider)).Register();
            var mempoolValidator = new MempoolValidator(txMemPool, mempoolLock, dateTimeProvider, mempoolSettings, chain, coins, loggerFactory, settings, consensusRules);

            return(new MempoolManager(mempoolLock, txMemPool, mempoolValidator, dateTimeProvider, mempoolSettings, mempoolPersistence, coins, loggerFactory, settings.Network));
        }
Example #13
0
        public void MinerCreateBlockAbsoluteTimeLocked()
        {
            var context = new TestContext();
            var tx      = new Transaction();

            tx.AddInput(new TxIn());
            tx.AddOutput(new TxOut());
            var flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast;

            List <int> prevheights = new List <int>();

            prevheights.Add(1);
            tx.Version = 2;
            tx.Inputs[0].PrevOut.Hash  = context.txFirst[3].GetHash();
            tx.Inputs[0].ScriptSig     = new Script(OpcodeType.OP_1);
            tx.Inputs[0].PrevOut.N     = 0;
            tx.Outputs[0].Value        = context.BLOCKSUBSIDY - context.HIGHFEE;
            tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1);

            // absolute time locked
            tx.LockTime           = context.chain.Tip.GetMedianTimePast().AddMinutes(1);
            tx.Inputs[0].Sequence = Sequence.Final - 1;
            prevheights[0]        = context.baseheight + 4;
            context.hash          = tx.GetHash();
            context.mempool.AddUnchecked(context.hash, context.entry.Time(context.date.GetTime()).FromTx(tx));
            Assert.True(!MempoolValidator.CheckFinalTransaction(context.chain, context.date, tx, flags)); // Locktime fails
            Assert.True(TestSequenceLocks(context, context.chain.Tip, tx, flags));                        // Sequence locks pass
            context.chain.SetTip(new BlockHeader()
            {
                HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 512
            });
            context.chain.SetTip(new BlockHeader()
            {
                HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 512
            });
            Assert.True(tx.IsFinal(context.chain.Tip.GetMedianTimePast().AddMinutes(2), context.chain.Tip.Height + 2));             // Locktime passes 2 min later
        }
        public WalletFeePolicy(BlockPolicyEstimator blockPolicyEstimator, MempoolValidator mempoolValidator, TxMempool mempool, Network network)
        {
            this.blockPolicyEstimator = blockPolicyEstimator;
            this.mempoolValidator     = mempoolValidator;
            this.mempool = mempool;

            this.minTxFee      = new FeeRate(1000);
            this.fallbackFee   = new FeeRate(20000);
            this.payTxFee      = new FeeRate(0);
            this.maxTxFee      = new Money(0.1M, MoneyUnit.BTC);
            this.minRelayTxFee = MempoolValidator.MinRelayTxFee;

            // this is a very very ugly hack
            // the fee constants should be set at the
            // network level or the consensus options
            if (network.Name.ToLower().Contains("stratis"))
            {
                this.minTxFee      = new FeeRate(10000);
                this.fallbackFee   = new FeeRate(40000);
                this.payTxFee      = new FeeRate(0);
                this.maxTxFee      = new Money(0.1M, MoneyUnit.BTC);
                this.minRelayTxFee = new FeeRate(10000);
            }
        }
        private MempoolManager CreateTestMempool(NodeSettings settings, out TxMempool txMemPool)
        {
            var mempoolSettings = new MempoolSettings(settings);
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;
            NodeSettings      nodeSettings     = NodeSettings.Default(settings.Network);
            ILoggerFactory    loggerFactory    = nodeSettings.LoggerFactory;
            var consensusSettings = new ConsensusSettings(nodeSettings);

            txMemPool = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings), loggerFactory, nodeSettings);
            var mempoolLock        = new MempoolSchedulerLock();
            var coins              = new InMemoryCoinView(settings.Network.GenesisHash);
            var chain              = new ChainIndexer(settings.Network);
            var chainState         = new ChainState();
            var mempoolPersistence = new MempoolPersistence(settings, loggerFactory);

            this.network.Consensus.Options = new PosConsensusOptions();

            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)
            {
                consensusRulesContainer.FullValidationRules.Add(Activator.CreateInstance(ruleType) as FullValidationConsensusRule);
            }

            var asyncProvider = new AsyncProvider(nodeSettings.LoggerFactory, new Mock <ISignals>().Object, new NodeLifetime());

            ConsensusRuleEngine consensusRules = new PowConsensusRuleEngine(this.network, loggerFactory, dateTimeProvider, chain, new NodeDeployments(this.network, chain),
                                                                            consensusSettings, new Checkpoints(), coins, chainState, new InvalidBlockHashStore(dateTimeProvider), new NodeStats(dateTimeProvider, loggerFactory), asyncProvider, consensusRulesContainer).SetupRulesEngineParent();
            var mempoolValidator = new MempoolValidator(txMemPool, mempoolLock, dateTimeProvider, mempoolSettings, chain, coins, loggerFactory, settings, consensusRules);

            return(new MempoolManager(mempoolLock, txMemPool, mempoolValidator, dateTimeProvider, mempoolSettings, mempoolPersistence, coins, loggerFactory, settings.Network));
        }
        public static async Task <ITestChainContext> CreatePosAsync(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();

            var consensusRulesContainer = new ConsensusRulesContainer();

            foreach (var ruleType in network.Consensus.ConsensusRules.HeaderValidationRules)
            {
                // Dont check PoW of a header in this test.
                if (ruleType == typeof(CheckDifficultyPowRule))
                {
                    continue;
                }

                consensusRulesContainer.HeaderValidationRules.Add(Activator.CreateInstance(ruleType) as HeaderValidationConsensusRule);
            }
            foreach (var ruleType in network.Consensus.ConsensusRules.FullValidationRules)
            {
                consensusRulesContainer.FullValidationRules.Add(Activator.CreateInstance(ruleType) as FullValidationConsensusRule);
            }
            foreach (var ruleType in network.Consensus.ConsensusRules.PartialValidationRules)
            {
                consensusRulesContainer.PartialValidationRules.Add(Activator.CreateInstance(ruleType) as PartialValidationConsensusRule);
            }

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

            var chainState  = new ChainState();
            var deployments = new NodeDeployments(network, chain);
            ConsensusRuleEngine consensusRules;

            var asyncProvider = new AsyncProvider(loggerFactory, new Mock <ISignals>().Object, new NodeLifetime());

            var stakeChain = new StakeChainStore(network, chain, null, loggerFactory);

            consensusRules = new PosConsensusRuleEngine(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(),
                                                        inMemoryCoinView, stakeChain, new StakeValidator(network, stakeChain, chain, inMemoryCoinView, loggerFactory), chainState, new InvalidBlockHashStore(dateTimeProvider),
                                                        new NodeStats(dateTimeProvider, loggerFactory), new RewindDataIndexCache(dateTimeProvider, network), asyncProvider, consensusRulesContainer).SetupRulesEngineParent();

            ConsensusManager consensus = ConsensusManagerHelper.CreateConsensusManager(network, dataDir, chainState, chainIndexer: chain, consensusRules: consensusRules, inMemoryCoinView: inMemoryCoinView);

            var genesis = new ChainedHeader(network.GetGenesis().Header, network.GenesisHash, 0);

            chainState.BlockStoreTip = genesis;
            await consensus.InitializeAsync(genesis).ConfigureAwait(false);

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

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

            return(new TestChainContext {
                MempoolValidator = mempoolValidator
            });
        }
Example #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
            });
        }
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)
        {
            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
            });
        }
        /// <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();
            new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration().RegisterRules(network.Consensus);

            // Dont check PoW of a header in this test.
            network.Consensus.HeaderValidationRules.RemoveAll(x => x.GetType() == typeof(CheckDifficultyPowRule));

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

            var chainState  = new ChainState();
            var deployments = new NodeDeployments(network, chain);
            ConsensusRuleEngine consensusRules = new PowConsensusRuleEngine(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(),
                                                                            inMemoryCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider), new NodeStats(dateTimeProvider)).Register();

            ConsensusManager consensus = ConsensusManagerHelper.CreateConsensusManager(network, dataDir, chainState);

            var genesis = new ChainedHeader(network.GetGenesis().Header, network.GenesisHash, 0);

            chainState.BlockStoreTip = genesis;
            await consensus.InitializeAsync(genesis).ConfigureAwait(false);

            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:
            var           blockDefinition = new PowBlockDefinition(consensus, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules);
            BlockTemplate newBlock        = blockDefinition.Build(chain.Tip, scriptPubKey);

            await consensus.BlockMinedAsync(newBlock.Block);

            List <BlockInfo> blockinfo = CreateBlockInfoList();

            // We can't make transactions until we have inputs therefore, load 100 blocks.
            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 < 4)
                {
                    srcTxs.Add(currentBlock.Transactions[0]);
                }

                currentBlock.UpdateMerkleRoot();

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

                chain.SetTip(currentBlock.Header);
            }

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

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

            var outputs = new List <UnspentOutputs>();

            foreach (Transaction tx in srcTxs)
            {
                var output = new UnspentOutputs(0, tx);

                outputs.Add(output);
            }

            await inMemoryCoinView.SaveChangesAsync(outputs, new List <TxOut[]>(), chain.GetBlock(0).HashBlock, chain.GetBlock(1).HashBlock, chain.GetBlock(0).Height);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, SrcTxs = srcTxs
            });
        }
Example #20
0
        /// <summary>
        /// Create the MempoolManager used for testing whether transactions are accepted to the memory pool.
        /// </summary>
        private void CreateMempoolManager()
        {
            this.mempoolSettings   = new MempoolSettings(this.nodeSettings);
            this.consensusSettings = new ConsensusSettings(this.nodeSettings);
            this.txMemPool         = new TxMempool(this.dateTimeProvider, new BlockPolicyEstimator(
                                                       new MempoolSettings(this.nodeSettings), this.loggerFactory, this.nodeSettings), this.loggerFactory, this.nodeSettings);
            this.chainIndexer    = new ChainIndexer(this.Network);
            this.nodeDeployments = new NodeDeployments(this.Network, this.chainIndexer);

            this.MockCoinView();
            this.MockStakeChain();
            this.MockStakeValidator();

            // Create POS consensus rules engine.
            var checkpoints = new Mock <ICheckpoints>();
            var chainState  = new ChainState();

            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)
            {
                consensusRulesContainer.FullValidationRules.Add(Activator.CreateInstance(ruleType) as FullValidationConsensusRule);
            }

            ConsensusRuleEngine consensusRuleEngine = new PosConsensusRuleEngine(this.Network, this.loggerFactory, this.dateTimeProvider,
                                                                                 this.chainIndexer, this.nodeDeployments, this.consensusSettings, checkpoints.Object, this.coinView.Object, this.stakeChain.Object,
                                                                                 this.stakeValidator.Object, chainState, new InvalidBlockHashStore(this.dateTimeProvider), new Mock <INodeStats>().Object, new Mock <IRewindDataIndexCache>().Object, this.asyncProvider, consensusRulesContainer)
                                                      .SetupRulesEngineParent();

            // Create mempool validator.
            var mempoolLock = new MempoolSchedulerLock();

            // The mempool rule constructors aren't parameterless, so we have to manually inject the dependencies for every rule
            var mempoolRules = new List <MempoolRule>
            {
                new CheckConflictsMempoolRule(this.Network, this.txMemPool, this.mempoolSettings, this.chainIndexer, this.loggerFactory),
                new CheckCoinViewMempoolRule(this.Network, this.txMemPool, this.mempoolSettings, this.chainIndexer, this.loggerFactory),
                new CreateMempoolEntryMempoolRule(this.Network, this.txMemPool, this.mempoolSettings, this.chainIndexer, consensusRuleEngine, this.loggerFactory),
                new CheckSigOpsMempoolRule(this.Network, this.txMemPool, this.mempoolSettings, this.chainIndexer, this.loggerFactory),
                new CheckFeeMempoolRule(this.Network, this.txMemPool, this.mempoolSettings, this.chainIndexer, this.loggerFactory),
                new CheckRateLimitMempoolRule(this.Network, this.txMemPool, this.mempoolSettings, this.chainIndexer, this.loggerFactory),
                new CheckAncestorsMempoolRule(this.Network, this.txMemPool, this.mempoolSettings, this.chainIndexer, this.loggerFactory),
                new CheckReplacementMempoolRule(this.Network, this.txMemPool, this.mempoolSettings, this.chainIndexer, this.loggerFactory),
                new CheckAllInputsMempoolRule(this.Network, this.txMemPool, this.mempoolSettings, this.chainIndexer, consensusRuleEngine, this.loggerFactory),
                new CheckTxOutDustRule(this.Network, this.txMemPool, this.mempoolSettings, this.chainIndexer, this.loggerFactory)
            };

            // We also have to check that the manually instantiated rules match the ones in the network, or the test isn't valid
            for (int i = 0; i < this.Network.Consensus.MempoolRules.Count; i++)
            {
                if (this.Network.Consensus.MempoolRules[i] != mempoolRules[i].GetType())
                {
                    throw new Exception("Mempool rule type mismatch");
                }
            }

            Assert.Equal(this.Network.Consensus.MempoolRules.Count, mempoolRules.Count);

            var mempoolValidator = new MempoolValidator(this.txMemPool, mempoolLock, this.dateTimeProvider, this.mempoolSettings, this.chainIndexer,
                                                        this.coinView.Object, this.loggerFactory, this.nodeSettings, consensusRuleEngine, mempoolRules, new NodeDeployments(this.Network, this.chainIndexer));

            // Create mempool manager.
            var mempoolPersistence = new Mock <IMempoolPersistence>();

            this.mempoolManager = new MempoolManager(mempoolLock, this.txMemPool, mempoolValidator, this.dateTimeProvider, this.mempoolSettings,
                                                     mempoolPersistence.Object, this.coinView.Object, this.loggerFactory, this.Network);
        }
Example #21
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>
        /// <param name="requireStandard">By default testnet and regtest networks do not require transactions to be standard. This changes that default.</param>
        /// <returns>Context object representing the test chain.</returns>
        public static async Task <ITestChainContext> CreateAsync(Network network, Script scriptPubKey, string dataDir, bool requireStandard = true)
        {
            var nodeSettings = new NodeSettings(network, args: new string[] { $"-datadir={dataDir}" });

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

            network.Consensus.Options = new ConsensusOptions();

            var consensusRulesContainer = new ConsensusRulesContainer();

            foreach (Type ruleType in network.Consensus.ConsensusRules.HeaderValidationRules)
            {
                // Don't check PoW of a header in this test.
                if (ruleType == typeof(CheckDifficultyPowRule))
                {
                    continue;
                }

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

                consensusRulesContainer.FullValidationRules.Add(rule);
            }

            var consensusSettings = new ConsensusSettings(nodeSettings);
            var chain             = new ChainIndexer(network);
            var inMemoryCoinView  = new InMemoryCoinView(new HashHeightPair(chain.Tip));

            var asyncProvider = new AsyncProvider(loggerFactory, new Mock <ISignals>().Object, new NodeLifetime());

            var chainState  = new ChainState();
            var deployments = new NodeDeployments(network, chain);

            ConsensusRuleEngine consensusRules = new PowConsensusRuleEngine(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(),
                                                                            inMemoryCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider), new NodeStats(dateTimeProvider, loggerFactory), asyncProvider, consensusRulesContainer).SetupRulesEngineParent();

            ConsensusManager consensus = ConsensusManagerHelper.CreateConsensusManager(network, dataDir, chainState, chainIndexer: chain, consensusRules: consensusRules, inMemoryCoinView: inMemoryCoinView);

            var genesis = new ChainedHeader(network.GetGenesis().Header, network.GenesisHash, 0);

            chainState.BlockStoreTip = genesis;
            await consensus.InitializeAsync(genesis).ConfigureAwait(false);

            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:
            var           blockDefinition = new PowBlockDefinition(consensus, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules, deployments);
            BlockTemplate newBlock        = blockDefinition.Build(chain.Tip, scriptPubKey);

            await consensus.BlockMinedAsync(newBlock.Block);

            List <BlockInfo> blockinfo = CreateBlockInfoList();

            // We can't make transactions until we have inputs therefore, load 100 blocks.

            var srcTxs = new List <Transaction>();

            for (int i = 0; i < blockinfo.Count; ++i)
            {
                Block currentBlock = Block.Load(newBlock.Block.ToBytes(network.Consensus.ConsensusFactory), network.Consensus.ConsensusFactory);
                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;

                currentBlock.UpdateMerkleRoot();
                currentBlock.Header.Nonce = blockinfo[i].nonce;

                chain.SetTip(currentBlock.Header);
                srcTxs.Add(currentBlock.Transactions[0]);

                inMemoryCoinView.SaveChanges(new List <UnspentOutput>()
                {
                    new UnspentOutput(new OutPoint(currentBlock.Transactions[0], 0), new Coins((uint)(i + 1), currentBlock.Transactions[0].Outputs.First(), currentBlock.Transactions[0].IsCoinBase))
                }, new HashHeightPair(chain.Tip.Previous), new HashHeightPair(chain.Tip));
            }

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

            var mempoolSettings = new MempoolSettings(nodeSettings)
            {
                RequireStandard = requireStandard
            };

            // The mempool rule constructors aren't parameterless, so we have to manually inject the dependencies for every rule
            var mempoolRules = new List <MempoolRule>
            {
                new CheckConflictsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckCoinViewMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CreateMempoolEntryMempoolRule(network, mempool, mempoolSettings, chain, consensusRules, loggerFactory),
                new CheckSigOpsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckFeeMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckRateLimitMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckAncestorsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckReplacementMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckAllInputsMempoolRule(network, mempool, mempoolSettings, chain, consensusRules, deployments, loggerFactory),
                new CheckTxOutDustRule(network, mempool, mempoolSettings, chain, loggerFactory),
            };

            // We also have to check that the manually instantiated rules match the ones in the network, or the test isn't valid
            for (int i = 0; i < network.Consensus.MempoolRules.Count; i++)
            {
                if (network.Consensus.MempoolRules[i] != mempoolRules[i].GetType())
                {
                    throw new Exception("Mempool rule type mismatch");
                }
            }

            Assert.Equal(network.Consensus.MempoolRules.Count, mempoolRules.Count);

            var mempoolValidator = new MempoolValidator(mempool, mempoolLock, dateTimeProvider, mempoolSettings, chain, inMemoryCoinView, loggerFactory, nodeSettings, consensusRules, mempoolRules, deployments);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, MempoolSettings = mempoolSettings, ChainIndexer = chain, SrcTxs = srcTxs
            });
        }
        private MempoolManager CreateTestMempool(NodeSettings settings, out TxMempool txMemPool)
        {
            var mempoolSettings = new MempoolSettings(settings);
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;
            NodeSettings      nodeSettings     = NodeSettings.Default(settings.Network);
            ILoggerFactory    loggerFactory    = nodeSettings.LoggerFactory;
            var consensusSettings = new ConsensusSettings(nodeSettings);

            txMemPool = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(mempoolSettings, loggerFactory, nodeSettings), loggerFactory, nodeSettings);
            var mempoolLock        = new MempoolSchedulerLock();
            var coins              = new InMemoryCoinView(new HashHeightPair(settings.Network.GenesisHash, 0));
            var chain              = new ChainIndexer(settings.Network);
            var deployments        = new NodeDeployments(this.network, chain);
            var chainState         = new ChainState();
            var mempoolPersistence = new MempoolPersistence(settings, loggerFactory);

            this.network.Consensus.Options = new PosConsensusOptions();

            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 network.Consensus.ConsensusRules.FullValidationRules)
            {
                FullValidationConsensusRule rule = null;
                if (ruleType == typeof(FlushCoinviewRule))
                {
                    rule = new FlushCoinviewRule(new Mock <IInitialBlockDownloadState>().Object);
                }
                else
                {
                    rule = Activator.CreateInstance(ruleType) as FullValidationConsensusRule;
                }

                consensusRulesContainer.FullValidationRules.Add(rule);
            }

            var asyncProvider = new AsyncProvider(nodeSettings.LoggerFactory, new Mock <ISignals>().Object, new NodeLifetime());

            ConsensusRuleEngine consensusRules = new PowConsensusRuleEngine(this.network, loggerFactory, dateTimeProvider, chain, deployments,
                                                                            consensusSettings, new Checkpoints(), coins, chainState, new InvalidBlockHashStore(dateTimeProvider), new NodeStats(dateTimeProvider, loggerFactory), asyncProvider, consensusRulesContainer).SetupRulesEngineParent();

            // The mempool rule constructors aren't parameterless, so we have to manually inject the dependencies for every rule
            var mempoolRules = new List <MempoolRule>
            {
                new CheckConflictsMempoolRule(this.network, txMemPool, mempoolSettings, chain, loggerFactory),
                new CheckCoinViewMempoolRule(this.network, txMemPool, mempoolSettings, chain, loggerFactory),
                new CreateMempoolEntryMempoolRule(this.network, txMemPool, mempoolSettings, chain, consensusRules, loggerFactory),
                new CheckSigOpsMempoolRule(this.network, txMemPool, mempoolSettings, chain, loggerFactory),
                new CheckFeeMempoolRule(this.network, txMemPool, mempoolSettings, chain, loggerFactory),
                new CheckRateLimitMempoolRule(this.network, txMemPool, mempoolSettings, chain, loggerFactory),
                new CheckAncestorsMempoolRule(this.network, txMemPool, mempoolSettings, chain, loggerFactory),
                new CheckReplacementMempoolRule(this.network, txMemPool, mempoolSettings, chain, loggerFactory),
                new CheckAllInputsMempoolRule(this.network, txMemPool, mempoolSettings, chain, consensusRules, deployments, loggerFactory),
                new CheckTxOutDustRule(this.network, txMemPool, mempoolSettings, chain, loggerFactory),
            };

            // We also have to check that the manually instantiated rules match the ones in the network, or the test isn't valid
            for (int i = 0; i < this.network.Consensus.MempoolRules.Count; i++)
            {
                if (this.network.Consensus.MempoolRules[i] != mempoolRules[i].GetType())
                {
                    throw new Exception("Mempool rule type mismatch");
                }
            }

            var mempoolValidator = new MempoolValidator(txMemPool, mempoolLock, dateTimeProvider, mempoolSettings, chain, coins, loggerFactory, settings, consensusRules, mempoolRules, deployments);

            return(new MempoolManager(mempoolLock, txMemPool, mempoolValidator, dateTimeProvider, mempoolSettings, mempoolPersistence, coins, loggerFactory, settings.Network));
        }
        public static async Task <ITestChainContext> CreatePosAsync(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();

            var consensusRulesContainer = new ConsensusRulesContainer();

            foreach (var ruleType in network.Consensus.ConsensusRules.HeaderValidationRules)
            {
                // Dont check PoW of a header in this test.
                if (ruleType == typeof(CheckDifficultyPowRule))
                {
                    continue;
                }

                consensusRulesContainer.HeaderValidationRules.Add(Activator.CreateInstance(ruleType) as HeaderValidationConsensusRule);
            }
            foreach (var ruleType in network.Consensus.ConsensusRules.FullValidationRules)
            {
                consensusRulesContainer.FullValidationRules.Add(Activator.CreateInstance(ruleType) as FullValidationConsensusRule);
            }
            foreach (var ruleType in network.Consensus.ConsensusRules.PartialValidationRules)
            {
                consensusRulesContainer.PartialValidationRules.Add(Activator.CreateInstance(ruleType) as PartialValidationConsensusRule);
            }

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

            var chainState  = new ChainState();
            var deployments = new NodeDeployments(network, chain);
            ConsensusRuleEngine consensusRules;

            var asyncProvider = new AsyncProvider(loggerFactory, new Mock <ISignals>().Object, new NodeLifetime());

            var stakeChain = new StakeChainStore(network, chain, null, loggerFactory);

            consensusRules = new PosConsensusRuleEngine(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(),
                                                        inMemoryCoinView, stakeChain, new StakeValidator(network, stakeChain, chain, inMemoryCoinView, loggerFactory), chainState, new InvalidBlockHashStore(dateTimeProvider),
                                                        new NodeStats(dateTimeProvider, loggerFactory), new RewindDataIndexCache(dateTimeProvider, network), asyncProvider, consensusRulesContainer).SetupRulesEngineParent();

            ConsensusManager consensus = ConsensusManagerHelper.CreateConsensusManager(network, dataDir, chainState, chainIndexer: chain, consensusRules: consensusRules, inMemoryCoinView: inMemoryCoinView);

            var genesis = new ChainedHeader(network.GetGenesis().Header, network.GenesisHash, 0);

            chainState.BlockStoreTip = genesis;
            await consensus.InitializeAsync(genesis).ConfigureAwait(false);

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

            // The mempool rule constructors aren't parameterless, so we have to manually inject the dependencies for every rule
            var mempoolRules = new List <MempoolRule>
            {
                new CheckConflictsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckCoinViewMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CreateMempoolEntryMempoolRule(network, mempool, mempoolSettings, chain, consensusRules, loggerFactory),
                new CheckSigOpsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckFeeMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckRateLimitMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckAncestorsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckReplacementMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckAllInputsMempoolRule(network, mempool, mempoolSettings, chain, consensusRules, loggerFactory),
                new CheckTxOutDustRule(network, mempool, mempoolSettings, chain, loggerFactory),
            };

            // We also have to check that the manually instantiated rules match the ones in the network, or the test isn't valid
            for (int i = 0; i < network.Consensus.MempoolRules.Count; i++)
            {
                if (network.Consensus.MempoolRules[i] != mempoolRules[i].GetType())
                {
                    throw new Exception("Mempool rule type mismatch");
                }
            }

            var nodeDeployments  = new NodeDeployments(network, chain);
            var mempoolValidator = new MempoolValidator(mempool, mempoolLock, dateTimeProvider, new MempoolSettings(nodeSettings), chain, inMemoryCoinView, loggerFactory, nodeSettings, consensusRules, mempoolRules, nodeDeployments);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator
            });
        }
Example #24
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 #25
0
        public static async Task <ITestChainContext> CreatePosAsync(Network network, Script scriptPubKey, string dataDir, bool requireStandard = true)
        {
            var nodeSettings = new NodeSettings(network, args: new string[] { $"-datadir={dataDir}" });

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

            network.Consensus.Options = new ConsensusOptions();

            var consensusRulesContainer = new ConsensusRulesContainer();

            foreach (var ruleType in network.Consensus.ConsensusRules.HeaderValidationRules)
            {
                // Don't check PoW of a header in this test.
                if (ruleType == typeof(CheckDifficultyPowRule))
                {
                    continue;
                }

                consensusRulesContainer.HeaderValidationRules.Add(Activator.CreateInstance(ruleType) as HeaderValidationConsensusRule);
            }
            foreach (Type ruleType in network.Consensus.ConsensusRules.FullValidationRules)
            {
                consensusRulesContainer.FullValidationRules.Add(Activator.CreateInstance(ruleType) as FullValidationConsensusRule);
            }
            foreach (Type ruleType in network.Consensus.ConsensusRules.PartialValidationRules)
            {
                consensusRulesContainer.PartialValidationRules.Add(Activator.CreateInstance(ruleType) as PartialValidationConsensusRule);
            }

            var consensusSettings = new ConsensusSettings(nodeSettings);
            var chain             = new ChainIndexer(network);
            var inMemoryCoinView  = new InMemoryCoinView(new HashHeightPair(chain.Tip));

            var chainState  = new ChainState();
            var deployments = new NodeDeployments(network, chain);

            var asyncProvider = new AsyncProvider(loggerFactory, new Mock <ISignals>().Object, new NodeLifetime());

            var stakeChain = new StakeChainStore(network, chain, null, loggerFactory);
            ConsensusRuleEngine consensusRules = new PosConsensusRuleEngine(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(),
                                                                            inMemoryCoinView, stakeChain, new StakeValidator(network, stakeChain, chain, inMemoryCoinView, loggerFactory), chainState, new InvalidBlockHashStore(dateTimeProvider),
                                                                            new NodeStats(dateTimeProvider, loggerFactory), new RewindDataIndexCache(dateTimeProvider, network, new FinalizedBlockInfoRepository(new HashHeightPair()), new Checkpoints()), asyncProvider, consensusRulesContainer).SetupRulesEngineParent();

            ConsensusManager consensus = ConsensusManagerHelper.CreateConsensusManager(network, dataDir, chainState, chainIndexer: chain, consensusRules: consensusRules, inMemoryCoinView: inMemoryCoinView);

            var genesis = new ChainedHeader(network.GetGenesis().Header, network.GenesisHash, 0);

            chainState.BlockStoreTip = genesis;
            await consensus.InitializeAsync(genesis).ConfigureAwait(false);

            var mempoolSettings = new MempoolSettings(nodeSettings)
            {
                RequireStandard = requireStandard
            };
            var blockPolicyEstimator = new BlockPolicyEstimator(mempoolSettings, loggerFactory, nodeSettings);
            var mempool     = new TxMempool(dateTimeProvider, blockPolicyEstimator, loggerFactory, nodeSettings);
            var mempoolLock = new MempoolSchedulerLock();

            // The mempool rule constructors aren't parameterless, so we have to manually inject the dependencies for every rule
            var mempoolRules = new List <MempoolRule>
            {
                new CheckConflictsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckCoinViewMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CreateMempoolEntryMempoolRule(network, mempool, mempoolSettings, chain, consensusRules, loggerFactory),
                new CheckSigOpsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckFeeMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckRateLimitMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckAncestorsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckReplacementMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckAllInputsMempoolRule(network, mempool, mempoolSettings, chain, consensusRules, deployments, loggerFactory),
                new CheckTxOutDustRule(network, mempool, mempoolSettings, chain, loggerFactory),
            };

            // We also have to check that the manually instantiated rules match the ones in the network, or the test isn't valid
            for (int i = 0; i < network.Consensus.MempoolRules.Count; i++)
            {
                if (network.Consensus.MempoolRules[i] != mempoolRules[i].GetType())
                {
                    throw new Exception("Mempool rule type mismatch");
                }
            }

            var mempoolValidator = new MempoolValidator(mempool, mempoolLock, dateTimeProvider, mempoolSettings, chain, inMemoryCoinView, loggerFactory, nodeSettings, consensusRules, mempoolRules, deployments);

            var            blocks = new List <Block>();
            var            srcTxs = new List <Transaction>();
            DateTimeOffset now    = DateTimeOffset.UtcNow;

            for (int i = 0; i < 50; i++)
            {
                uint  nonce = 0;
                Block block = network.CreateBlock();
                block.Header.HashPrevBlock = chain.Tip.HashBlock;
                block.Header.Bits          = block.Header.GetWorkRequired(network, chain.Tip);
                block.Header.UpdateTime(now, network, chain.Tip);

                Transaction coinbase = network.CreateTransaction();
                coinbase.AddInput(TxIn.CreateCoinbase(chain.Height + 1));
                coinbase.AddOutput(new TxOut(network.Consensus.ProofOfWorkReward, scriptPubKey));
                block.AddTransaction(coinbase);
                block.UpdateMerkleRoot();
                while (!block.CheckProofOfWork())
                {
                    block.Header.Nonce = ++nonce;
                }
                block.Header.PrecomputeHash();
                blocks.Add(block);
                chain.SetTip(block.Header);
                srcTxs.Add(block.Transactions[0]);

                inMemoryCoinView.SaveChanges(new List <UnspentOutput>()
                {
                    new UnspentOutput(new OutPoint(block.Transactions[0], 0), new Coins((uint)(i + 1), block.Transactions[0].Outputs.First(), block.Transactions[0].IsCoinBase))
                }, new HashHeightPair(chain.Tip.Previous), new HashHeightPair(chain.Tip));
            }

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, MempoolSettings = mempoolSettings, ChainIndexer = chain, SrcTxs = srcTxs
            });
        }