public void CreateNewBlock_WithScript_DoesNotValidateTemplateUsingRuleContext()
        {
            var newOptions = new PosConsensusOptions();

            this.ExecuteWithConsensusOptions(newOptions, () =>
            {
                ConcurrentChain chain = GenerateChainWithHeight(5, this.stratisTest, this.key);
                this.SetupRulesEngine(chain);
                this.dateTimeProvider.Setup(d => d.GetAdjustedTimeAsUnixTimestamp()).Returns(new DateTime(2017, 1, 7, 0, 0, 1, DateTimeKind.Utc).ToUnixTimestamp());
                this.consensusManager.Setup(c => c.Tip).Returns(chain.GetBlock(5));

                this.stakeValidator.Setup(s => s.GetNextTargetRequired(this.stakeChain.Object, chain.Tip, this.stratisTest.Consensus, true))
                .Returns(new Target(new uint256(1123123123)))
                .Verifiable();

                Transaction transaction = CreateTransaction(this.stratisTest, this.key, 5, new Money(400 * 1000 * 1000), new Key(), new uint256(124124));
                var txFee = new Money(1000);

                SetupTxMempool(chain, newOptions, txFee, transaction);

                var posBlockAssembler = new PosBlockDefinition(this.consensusManager.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.mempool.Object, new MempoolSchedulerLock(), this.minerSettings, this.stratisTest, this.stakeChain.Object, this.stakeValidator.Object);

                BlockTemplate blockTemplate = posBlockAssembler.Build(chain.Tip, this.key.ScriptPubKey);

                this.consensusManager.Verify(c => c.ConsensusRules.PartialValidationAsync(It.IsAny <ChainedHeader>(), It.IsAny <Block>()), Times.Exactly(0));
                Assert.Null(this.callbackRuleContext);
                this.stakeValidator.Verify();
            });
        }
        public void CreateNewBlock_WithScript_ReturnsBlockTemplate()
        {
            this.ExecuteWithConsensusOptions(new PosConsensusOptions(), () =>
            {
                var chain = GenerateChainWithHeight(5, this.network, this.key);
                this.SetupRulesEngine(chain);
                this.dateTimeProvider.Setup(d => d.GetAdjustedTimeAsUnixTimestamp()).Returns(new DateTime(2017, 1, 7, 0, 0, 1, DateTimeKind.Utc).ToUnixTimestamp());
                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, this.network.Consensus.Options as PosConsensusOptions, txFee, transaction);

                this.stakeValidator.Setup(s => s.GetNextTargetRequired(this.stakeChain.Object, chain.Tip, this.network.Consensus, true))
                .Returns(new Target(new uint256(1123123123)))
                .Verifiable();

                var posBlockAssembler = new PosBlockDefinition(this.consensusLoop.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.mempool.Object, new MempoolSchedulerLock(), this.network, this.stakeChain.Object, this.stakeValidator.Object);
                var blockTemplate     = posBlockAssembler.Build(chain.Tip, this.key.ScriptPubKey);

                Assert.Null(blockTemplate.CoinbaseCommitment);
                Assert.Equal(new Money(1000), blockTemplate.TotalFee);
                Assert.Equal(2, blockTemplate.TxSigOpsCost.Count);
                Assert.Equal(-1, blockTemplate.TxSigOpsCost[0]);
                Assert.Equal(2, blockTemplate.TxSigOpsCost[1]);
                Assert.Equal(2, blockTemplate.VTxFees.Count);
                Assert.Equal(new Money(-1000), blockTemplate.VTxFees[0]);
                Assert.Equal(new Money(1000), blockTemplate.VTxFees[1]);
                Assert.Equal(2, blockTemplate.Block.Transactions.Count);
                Assert.Equal(536870912, blockTemplate.Block.Header.Version);

                Assert.Equal(2, blockTemplate.Block.Transactions.Count);

                var resultingTransaction = blockTemplate.Block.Transactions[0];
                Assert.Equal((uint)new DateTime(2017, 1, 7, 0, 0, 1, DateTimeKind.Utc).ToUnixTimestamp(), resultingTransaction.Time);
                Assert.NotEmpty(resultingTransaction.Inputs);
                Assert.NotEmpty(resultingTransaction.Outputs);
                Assert.True(resultingTransaction.IsCoinBase);
                Assert.False(resultingTransaction.IsCoinStake);
                Assert.Equal(TxIn.CreateCoinbase(6).ScriptSig, resultingTransaction.Inputs[0].ScriptSig);
                Assert.Equal(new Money(0), resultingTransaction.TotalOut);
                Assert.Equal(new Script(), resultingTransaction.Outputs[0].ScriptPubKey);
                Assert.Equal(new Money(0), resultingTransaction.Outputs[0].Value);

                resultingTransaction = blockTemplate.Block.Transactions[1];
                Assert.NotEmpty(resultingTransaction.Inputs);
                Assert.NotEmpty(resultingTransaction.Outputs);
                Assert.False(resultingTransaction.IsCoinBase);
                Assert.False(resultingTransaction.IsCoinStake);
                Assert.Equal(new Money(400 * 1000 * 1000), resultingTransaction.TotalOut);
                Assert.Equal(transaction.Inputs[0].PrevOut.Hash, resultingTransaction.Inputs[0].PrevOut.Hash);
                Assert.Equal(transaction.Inputs[0].ScriptSig, transaction.Inputs[0].ScriptSig);

                Assert.Equal(transaction.Outputs[0].ScriptPubKey, resultingTransaction.Outputs[0].ScriptPubKey);
                Assert.Equal(new Money(400 * 1000 * 1000), resultingTransaction.Outputs[0].Value);
            });
        }
        public void CreateNewBlock_WithScript_ReturnsBlockTemplate()
        {
            this.ExecuteWithConsensusOptions(new PosConsensusOptions(), () =>
            {
                ChainIndexer chainIndexer = GenerateChainWithHeight(5, this.stratisTest, this.key);
                this.SetupRulesEngine(chainIndexer);
                var datetime = new DateTime(2017, 1, 7, 0, 0, 1, DateTimeKind.Utc);
                this.dateTimeProvider.Setup(d => d.GetAdjustedTimeAsUnixTimestamp()).Returns(datetime.ToUnixTimestamp());
                Transaction transaction = CreateTransaction(this.stratisTest, this.key, 5, new Money(400 * 1000 * 1000), new Key(), new uint256(124124));
                if (transaction is IPosTransactionWithTime posTrx)
                {
                    posTrx.Time = Utils.DateTimeToUnixTime(datetime);
                }
                var txFee = new Money(1000);

                SetupTxMempool(chainIndexer, this.stratisTest.Consensus.Options as PosConsensusOptions, txFee, transaction);

                this.stakeValidator.Setup(s => s.GetNextTargetRequired(this.stakeChain.Object, chainIndexer.Tip, this.stratisTest.Consensus, true))
                .Returns(new Target(new uint256(1123123123)))
                .Verifiable();

                var posBlockAssembler       = new PosBlockDefinition(this.consensusManager.Object, this.dateTimeProvider.Object, this.LoggerFactory.Object, this.mempool.Object, new MempoolSchedulerLock(), this.minerSettings, this.stratisTest, this.stakeChain.Object, this.stakeValidator.Object, new NodeDeployments(this.Network, chainIndexer));
                BlockTemplate blockTemplate = posBlockAssembler.Build(chainIndexer.Tip, this.key.ScriptPubKey);

                Assert.Equal(new Money(1000), blockTemplate.TotalFee);
                Assert.Equal(2, blockTemplate.Block.Transactions.Count);
                Assert.Equal(536870912, blockTemplate.Block.Header.Version);

                Assert.Equal(2, blockTemplate.Block.Transactions.Count);

                Transaction resultingTransaction = blockTemplate.Block.Transactions[0];
                //Assert.Equal((uint)new DateTime(2017, 1, 7, 0, 0, 1, DateTimeKind.Utc).ToUnixTimestamp(), resultingTransaction.Time);
                Assert.NotEmpty(resultingTransaction.Inputs);
                Assert.NotEmpty(resultingTransaction.Outputs);
                Assert.True(resultingTransaction.IsCoinBase);
                Assert.False(resultingTransaction.IsCoinStake);
                Assert.Equal(TxIn.CreateCoinbase(6).ScriptSig, resultingTransaction.Inputs[0].ScriptSig);
                Assert.Equal(new Money(0), resultingTransaction.TotalOut);
                Assert.Equal(new Script(), resultingTransaction.Outputs[0].ScriptPubKey);
                Assert.Equal(new Money(0), resultingTransaction.Outputs[0].Value);

                resultingTransaction = blockTemplate.Block.Transactions[1];
                Assert.NotEmpty(resultingTransaction.Inputs);
                Assert.NotEmpty(resultingTransaction.Outputs);
                Assert.False(resultingTransaction.IsCoinBase);
                Assert.False(resultingTransaction.IsCoinStake);
                Assert.Equal(new Money(400 * 1000 * 1000), resultingTransaction.TotalOut);
                Assert.Equal(transaction.Inputs[0].PrevOut.Hash, resultingTransaction.Inputs[0].PrevOut.Hash);
                Assert.Equal(transaction.Inputs[0].ScriptSig, transaction.Inputs[0].ScriptSig);

                Assert.Equal(transaction.Outputs[0].ScriptPubKey, resultingTransaction.Outputs[0].ScriptPubKey);
                Assert.Equal(new Money(400 * 1000 * 1000), resultingTransaction.Outputs[0].Value);
            });
        }
 public MockPosBlockProvider(PosBlockDefinition blockDefinition)
 {
     this.blockDefinition = blockDefinition;
 }