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); }); }
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); }); }
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); }); }
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); }); }
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); }); }
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; } }
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); }); }
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); }); }
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; } }