Esempio n. 1
0
        public void CreateCoinbase_CreatesCoinbaseTemplateTransaction_AddsToBlockTemplate()
        {
            this.ExecuteWithConsensusOptions(new ConsensusOptions(), () =>
            {
                ConcurrentChain chain = GenerateChainWithHeight(5, this.testNet, this.key);
                this.dateTimeProvider.Setup(d => d.GetAdjustedTimeAsUnixTimestamp())
                .Returns(new DateTime(2017, 1, 7, 0, 0, 1, DateTimeKind.Utc).ToUnixTimestamp());

                var blockDefinition = new PowTestBlockDefinition(this.consensusManager.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object, new MempoolSchedulerLock(), this.minerSettings, this.testNet, this.consensusRules.Object);

                BlockTemplate result = blockDefinition.CreateCoinBase(chain.Tip, this.key.ScriptPubKey);

                Assert.NotEmpty(result.Block.Transactions);

                Transaction resultingTransaction = result.Block.Transactions[0];
                Assert.Equal((uint)new DateTime(2017, 1, 7, 0, 0, 1, DateTimeKind.Utc).ToUnixTimestamp(), resultingTransaction.Time);
                Assert.True(resultingTransaction.IsCoinBase);
                Assert.False(resultingTransaction.IsCoinStake);
                Assert.Equal(Money.Zero, resultingTransaction.TotalOut);

                Assert.NotEmpty(resultingTransaction.Inputs);
                Assert.Equal(TxIn.CreateCoinbase(6).ScriptSig, resultingTransaction.Inputs[0].ScriptSig);

                Assert.NotEmpty(resultingTransaction.Outputs);
                Assert.Equal(this.key.ScriptPubKey, resultingTransaction.Outputs[0].ScriptPubKey);
                Assert.Equal(Money.Zero, resultingTransaction.Outputs[0].Value);
            });
        }
        public void AddTransactions_TransactionAlreadyInInblock_DoesNotAddTransactionToBlock()
        {
            var newOptions = new ConsensusOptions()
            {
                MaxBlockWeight = 1500
            };

            this.ExecuteWithConsensusOptions(newOptions, () =>
            {
                ConcurrentChain chain = GenerateChainWithHeight(5, this.network, this.key);
                this.consensusLoop.Setup(c => c.Tip)
                .Returns(chain.GetBlock(5));
                Transaction transaction = CreateTransaction(this.network, this.key, 5, new Money(400 * 1000 * 1000), new Key(), new uint256(124124));
                var txFee = new Money(1000);
                TxMempoolEntry[] entries = SetupTxMempool(chain, newOptions, txFee, transaction);

                var blockDefinition = new PowTestBlockDefinition(this.consensusLoop.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object, new MempoolSchedulerLock(), this.network, this.consensusRules.Object);
                blockDefinition.AddInBlockTxEntries(entries);

                (Block Block, int Selected, int Updated)result = blockDefinition.AddTransactions();

                Assert.Empty(result.Block.Transactions);
                Assert.Equal(0, result.Selected);
                Assert.Equal(0, result.Updated);
            });
        }
        public void TestBlockValidity_UsesRuleContextToValidateBlock()
        {
            var newOptions = new ConsensusOptions()
            {
                MaxBlockWeight = 1500
            };

            this.ExecuteWithConsensusOptions(newOptions, () =>
            {
                ConcurrentChain chain = GenerateChainWithHeight(5, this.network, new Key());
                this.consensusLoop.Setup(c => c.Tip).Returns(chain.GetBlock(5));

                ValidationContext validationContext = null;
                var powRuleContext = new PowRuleContext(new ValidationContext(), this.network.Consensus, chain.Tip, this.dateTimeProvider.Object.GetTimeOffset());
                this.consensusRules
                .Setup(s => s.CreateRuleContext(It.IsAny <ValidationContext>(), It.IsAny <ChainedHeader>())).Callback <ValidationContext, ChainedHeader>((r, s) => validationContext = r)
                .Returns(powRuleContext);

                var powBlockAssembler = new PowTestBlockDefinition(this.consensusLoop.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object, new MempoolSchedulerLock(), this.network, this.consensusRules.Object);
                Block block           = powBlockAssembler.TestBlockValidity();

                Assert.NotNull(this.callbackRuleContext);

                Assert.True(this.callbackRuleContext.MinedBlock);
                Assert.Equal(block.GetHash(), validationContext.Block.GetHash());
                Assert.Equal(chain.GetBlock(5).HashBlock, powRuleContext.ConsensusTip.HashBlock);
                Assert.Equal(1500, this.callbackRuleContext.Consensus.Options.MaxBlockWeight);
                this.consensusLoop.Verify();
            });
        }
        public void AddTransactions_WithoutTransactionsInMempool_DoesNotAddEntriesToBlock()
        {
            var newOptions = new ConsensusOptions()
            {
                MaxBlockWeight = 1500
            };

            this.ExecuteWithConsensusOptions(newOptions, () =>
            {
                ConcurrentChain chain = GenerateChainWithHeight(5, this.network, new Key());
                this.consensusLoop.Setup(c => c.Tip)
                .Returns(chain.GetBlock(5));
                var indexedTransactionSet = new TxMempool.IndexedTransactionSet();
                this.txMempool.Setup(t => t.MapTx)
                .Returns(indexedTransactionSet);

                var blockDefinition = new PowTestBlockDefinition(this.consensusLoop.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object,
                                                                 new MempoolSchedulerLock(), this.network, this.consensusRules.Object);

                (Block Block, int Selected, int Updated)result = blockDefinition.AddTransactions();

                Assert.Empty(result.Block.Transactions);
                Assert.Equal(0, result.Selected);
                Assert.Equal(0, result.Updated);
            });
        }
Esempio n. 5
0
        public void AddTransactions_TransactionNotInblock_AddsTransactionToBlock()
        {
            var newOptions = new PowConsensusOptions()
            {
                MaxBlockWeight = 1500
            };

            this.ExecuteWithConsensusOptions(newOptions, () =>
            {
                var chain = GenerateChainWithHeight(5, this.network, this.key);
                this.consensusLoop.Setup(c => c.Tip).Returns(chain.GetBlock(5));
                var transaction = CreateTransaction(this.network, this.key, 5, new Money(400 * 1000 * 1000), new Key(), new uint256(124124));
                var txFee       = new Money(1000);
                SetupTxMempool(chain, newOptions, txFee, transaction);

                var blockDefinition = new PowTestBlockDefinition(this.consensusLoop.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object,
                                                                 new MempoolSchedulerLock(), this.network, this.consensusRules.Object);

                var result = blockDefinition.AddTransactions();

                Assert.NotEmpty(result.Block.Transactions);

                Assert.Equal(transaction.ToHex(), result.Block.Transactions[0].ToHex());
                Assert.Equal(1, result.Selected);
                Assert.Equal(0, result.Updated);
            });
        }
Esempio n. 6
0
        public void ComputeBlockVersion_UsingChainTipAndConsensus_NoBip9DeploymentActive_UpdatesHeightAndVersion()
        {
            this.ExecuteWithConsensusOptions(new PowConsensusOptions(), () =>
            {
                ConcurrentChain chain = GenerateChainWithHeight(5, this.network, new Key());

                var blockDefinition = new PowTestBlockDefinition(this.consensusLoop.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object, new MempoolSchedulerLock(), this.network, this.consensusRules.Object);

                (int Height, int Version)result = blockDefinition.ComputeBlockVersion(chain.GetBlock(4));

                Assert.Equal(5, result.Height);
                uint version = ThresholdConditionCache.VersionbitsTopBits;
                Assert.Equal((int)version, result.Version);
            });
        }
Esempio n. 7
0
        public void ComputeBlockVersion_UsingChainTipAndConsensus_NoBip9DeploymentActive_UpdatesHeightAndVersion()
        {
            this.ExecuteWithConsensusOptions(new ConsensusOptions(), () =>
            {
                ChainIndexer chainIndexer = GenerateChainWithHeight(5, this.testNet, new Key());
                this.SetupRulesEngine(chainIndexer);

                var blockDefinition = new PowTestBlockDefinition(this.consensusManager.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object, new MempoolSchedulerLock(), this.minerSettings, this.testNet, this.consensusRules.Object, new NodeDeployments(this.testNet, chainIndexer));

                (int Height, int Version)result = blockDefinition.ComputeBlockVersion(chainIndexer.GetHeader(4));

                Assert.Equal(5, result.Height);
                Assert.Equal((int)ThresholdConditionCache.VersionbitsTopBits, result.Version);
            });
        }
Esempio n. 8
0
        public void UpdateHeaders_UsingChainAndNetwork_PreparesBlockHeaders()
        {
            this.ExecuteWithConsensusOptions(new PowConsensusOptions(), () =>
            {
                this.dateTimeProvider.Setup(d => d.GetTimeOffset()).Returns(new DateTimeOffset(new DateTime(2017, 1, 7, 0, 0, 0, DateTimeKind.Utc)));

                ConcurrentChain chain = GenerateChainWithHeight(5, this.network, new Key(), new Target(235325239));

                var blockDefinition = new PowTestBlockDefinition(this.consensusLoop.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object, new MempoolSchedulerLock(), this.network, this.consensusRules.Object);
                Block block         = blockDefinition.UpdateHeaders(chain.Tip);

                Assert.Equal(chain.Tip.HashBlock, block.Header.HashPrevBlock);
                Assert.Equal((uint)1483747200, block.Header.Time);
                Assert.Equal(1, block.Header.Bits.Difficulty);
                Assert.Equal((uint)0, block.Header.Nonce);
            });
        }
Esempio n. 9
0
        public void ComputeBlockVersion_UsingChainTipAndConsensus_Bip9DeploymentActive_UpdatesHeightAndVersion()
        {
            ConsensusOptions options          = this.testNet.Consensus.Options;
            int minerConfirmationWindow       = this.testNet.Consensus.MinerConfirmationWindow;
            int ruleChangeActivationThreshold = this.testNet.Consensus.RuleChangeActivationThreshold;

            try
            {
                var newOptions = new ConsensusOptions();
                this.testNet.Consensus.Options            = newOptions;
                this.testNet.Consensus.BIP9Deployments[0] = new BIP9DeploymentsParameters(19,
                                                                                          new DateTimeOffset(new DateTime(2016, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
                                                                                          new DateTimeOffset(new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc)));

                // As we are effectively using TestNet the other deployments need to be disabled
                this.testNet.Consensus.BIP9Deployments[BitcoinBIP9Deployments.CSV]    = null;
                this.testNet.Consensus.BIP9Deployments[BitcoinBIP9Deployments.Segwit] = null;

                this.testNet.Consensus.MinerConfirmationWindow       = 2;
                this.testNet.Consensus.RuleChangeActivationThreshold = 2;

                ConcurrentChain chain = GenerateChainWithHeightAndActivatedBip9(5, this.testNet, new Key(), this.testNet.Consensus.BIP9Deployments[0]);
                this.SetupRulesEngine(chain);

                var blockDefinition = new PowTestBlockDefinition(this.consensusManager.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object, new MempoolSchedulerLock(), this.minerSettings, this.testNet, this.consensusRules.Object);

                (int Height, int Version)result = blockDefinition.ComputeBlockVersion(chain.GetBlock(4));

                Assert.Equal(5, result.Height);
                int expectedVersion = (int)(ThresholdConditionCache.VersionbitsTopBits | (((uint)1) << 19));
                Assert.Equal(expectedVersion, result.Version);
                Assert.NotEqual((int)ThresholdConditionCache.VersionbitsTopBits, result.Version);
            }
            finally
            {
                // This is a static in the global context so be careful updating it. I'm resetting it after being done testing so I don't influence other tests.
                this.testNet.Consensus.Options                       = options;
                this.testNet.Consensus.BIP9Deployments[0]            = null;
                this.testNet.Consensus.MinerConfirmationWindow       = minerConfirmationWindow;
                this.testNet.Consensus.RuleChangeActivationThreshold = ruleChangeActivationThreshold;
            }
        }
Esempio n. 10
0
        public void AddTransactions_TransactionAlreadyInInblock_DoesNotAddTransactionToBlock()
        {
            var newOptions = new ConsensusOptions();

            this.ExecuteWithConsensusOptions(newOptions, () =>
            {
                ChainIndexer chainIndexer = GenerateChainWithHeight(5, this.testNet, this.key);
                this.consensusManager.Setup(c => c.Tip)
                .Returns(chainIndexer.GetHeader(5));
                Transaction transaction = CreateTransaction(this.testNet, this.key, 5, new Money(400 * 1000 * 1000), new Key(), new uint256(124124));
                var txFee = new Money(1000);
                TxMempoolEntry[] entries = SetupTxMempool(chainIndexer, newOptions, txFee, transaction);

                var blockDefinition = new PowTestBlockDefinition(this.consensusManager.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object, new MempoolSchedulerLock(), this.minerSettings, this.testNet, this.consensusRules.Object, new NodeDeployments(this.testNet, chainIndexer));
                blockDefinition.AddInBlockTxEntries(entries);

                (Block Block, int Selected, int Updated)result = blockDefinition.AddTransactions();

                Assert.Empty(result.Block.Transactions);
                Assert.Equal(0, result.Selected);
                Assert.Equal(0, result.Updated);
            });
        }
Esempio n. 11
0
        public void AddTransactions_WithoutTransactionsInMempool_DoesNotAddEntriesToBlock()
        {
            var newOptions = new ConsensusOptions();

            this.ExecuteWithConsensusOptions(newOptions, () =>
            {
                ChainIndexer chainIndexer = GenerateChainWithHeight(5, this.testNet, new Key());
                this.consensusManager.Setup(c => c.Tip)
                .Returns(chainIndexer.GetHeader(5));
                var indexedTransactionSet = new TxMempool.IndexedTransactionSet();
                this.txMempool.Setup(t => t.MapTx)
                .Returns(indexedTransactionSet);

                var blockDefinition = new PowTestBlockDefinition(this.consensusManager.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object,
                                                                 new MempoolSchedulerLock(), this.minerSettings, this.testNet, this.consensusRules.Object, new NodeDeployments(this.testNet, chainIndexer));

                (Block Block, int Selected, int Updated)result = blockDefinition.AddTransactions();

                Assert.Empty(result.Block.Transactions);
                Assert.Equal(0, result.Selected);
                Assert.Equal(0, result.Updated);
            });
        }
Esempio n. 12
0
        public void ComputeBlockVersion_UsingChainTipAndConsensus_Bip9DeploymentActive_UpdatesHeightAndVersion()
        {
            var options = this.network.Consensus.Options;
            var minerConfirmationWindow       = this.network.Consensus.MinerConfirmationWindow;
            var ruleChangeActivationThreshold = this.network.Consensus.RuleChangeActivationThreshold;

            try
            {
                var newOptions = new PowConsensusOptions();
                this.network.Consensus.Options            = newOptions;
                this.network.Consensus.BIP9Deployments[0] = new BIP9DeploymentsParameters(19,
                                                                                          new DateTimeOffset(new DateTime(2016, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
                                                                                          new DateTimeOffset(new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc)));
                this.network.Consensus.MinerConfirmationWindow       = 2;
                this.network.Consensus.RuleChangeActivationThreshold = 2;

                var chain = GenerateChainWithHeightAndActivatedBip9(5, this.network, new Key(), this.network.Consensus.BIP9Deployments[0]);

                var blockDefinition = new PowTestBlockDefinition(this.consensusLoop.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.txMempool.Object, new MempoolSchedulerLock(), this.network, this.consensusRules.Object);

                var result = blockDefinition.ComputeBlockVersion(chain.GetBlock(4));

                Assert.Equal(5, result.Height);
                uint version         = ThresholdConditionCache.VersionbitsTopBits;
                int  expectedVersion = (int)(version |= (((uint)1) << 19));
                //Assert.Equal(version, result.Version);
                Assert.NotEqual((int)ThresholdConditionCache.VersionbitsTopBits, result.Version);
            }
            finally
            {
                // This is a static in the global context so be careful updating it. I'm resetting it after being done testing so I don't influence other tests.
                this.network.Consensus.Options                       = options;
                this.network.Consensus.BIP9Deployments[0]            = null;
                this.network.Consensus.MinerConfirmationWindow       = minerConfirmationWindow;
                this.network.Consensus.RuleChangeActivationThreshold = ruleChangeActivationThreshold;
            }
        }