コード例 #1
0
        private static Transaction CreateCoinbaseTransaction(Network network, Key key, int height)
        {
            var coinbase = new Transaction();

            coinbase.AddInput(TxIn.CreateCoinbase(height));
            coinbase.AddOutput(new TxOut(network.GetReward(height), key.ScriptPubKey));
            return(coinbase);
        }
コード例 #2
0
        private Transaction CreateTransaction()
        {
            var transaction = new Transaction();

            transaction.AddInput(TxIn.CreateCoinbase(23523523));
            transaction.AddOutput(new TxOut(this.network.GetReward(23523523), new Key().ScriptPubKey));
            return(transaction);
        }
コード例 #3
0
        /// <summary>
        /// Create coinbase transaction.
        /// Set the coin base with zero money.
        /// Once we have the fee we can update the amount.
        /// </summary>
        protected virtual void CreateCoinbase()
        {
            this.coinbase = this.Network.CreateTransaction();
            this.coinbase.AddInput(TxIn.CreateCoinbase(this.ChainTip.Height + 1));
            this.coinbase.AddOutput(new TxOut(Money.Zero, this.scriptPubKey));

            this.block.AddTransaction(this.coinbase);
        }
コード例 #4
0
        /// <summary>
        /// Create coinbase transaction.
        /// Set the coin base with zero money.
        /// Once we have the fee we can update the amount.
        /// </summary>
        protected virtual void CreateCoinbase()
        {
            this.coinbase      = this.Network.CreateTransaction();
            this.coinbase.Time = (uint)this.DateTimeProvider.GetAdjustedTimeAsUnixTimestamp();
            this.coinbase.AddInput(TxIn.CreateCoinbase(this.ChainTip.Height + 1));
            this.coinbase.AddOutput(new TxOut(Money.Zero, this.scriptPubKey));

            this.block.AddTransaction(this.coinbase);
        }
コード例 #5
0
        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);
            });
        }
コード例 #6
0
        public async Task <Block[]> GenerateAsync(int blockCount, bool includeUnbroadcasted = true, bool broadcast = true)
        {
            RPCClient       rpc       = this.CreateRPCClient();
            BitcoinSecret   dest      = this.GetFirstSecret(rpc);
            uint256         bestBlock = rpc.GetBestBlockHash();
            ConcurrentChain chain     = null;
            var             blocks    = new List <Block>();
            DateTimeOffset  now       = this.MockTime == null ? DateTimeOffset.UtcNow : this.MockTime.Value;

            using (INetworkPeer peer = this.CreateNetworkPeerClient())
            {
                peer.VersionHandshakeAsync().GetAwaiter().GetResult();

                chain = bestBlock == this.runner.Network.GenesisHash ? new ConcurrentChain(this.runner.Network) : this.GetChain(peer);

                for (int i = 0; i < blockCount; i++)
                {
                    uint nonce = 0;

                    var block = this.runner.Network.Consensus.ConsensusFactory.CreateBlock();
                    block.Header.HashPrevBlock = chain.Tip.HashBlock;
                    block.Header.Bits          = block.Header.GetWorkRequired(rpc.Network, chain.Tip);
                    block.Header.UpdateTime(now, rpc.Network, chain.Tip);

                    var coinbase = this.runner.Network.Consensus.ConsensusFactory.CreateTransaction();
                    coinbase.AddInput(TxIn.CreateCoinbase(chain.Height + 1));
                    coinbase.AddOutput(new TxOut(rpc.Network.GetReward(chain.Height + 1), dest.GetAddress()));
                    block.AddTransaction(coinbase);

                    if (includeUnbroadcasted)
                    {
                        this.transactions = this.Reorder(this.transactions);
                        block.Transactions.AddRange(this.transactions);
                        this.transactions.Clear();
                    }

                    block.UpdateMerkleRoot();

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

                    blocks.Add(block);
                    chain.SetTip(block.Header);
                }

                if (broadcast)
                {
                    await this.BroadcastBlocksAsync(blocks.ToArray(), peer);
                }
            }

            return(blocks.ToArray());
        }
コード例 #7
0
        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);
            });
        }
コード例 #8
0
        /// <summary>
        /// Create coinbase transaction.
        /// Set the coin base with zero money.
        /// Once we have the fee we can update the amount.
        /// </summary>
        internal static Transaction CreateCoinbase(int currentHeight, Script scriptPubKey, FakeFactory fakeFactory, out long reward)
        {
            var coinbase = fakeFactory.Network.CreateTransaction();

            reward = currentHeight == fakeFactory.Network.Consensus.PremineHeight
                ? fakeFactory.Network.Consensus.PremineReward
                : fakeFactory.Network.Consensus.ProofOfWorkReward;
            coinbase.AddInput(TxIn.CreateCoinbase(currentHeight + 1));
            coinbase.AddOutput(new TxOut(reward, scriptPubKey));
            return(coinbase);
        }
コード例 #9
0
        /// <summary>
        /// Create coinbase transaction.
        /// Set the coin base with zero money.
        /// Once we have the fee we can update the amount.
        /// </summary>
        protected virtual void CreateCoinbase()
        {
            this.coinbase      = this.Network.Consensus.ConsensusFactory.CreateTransaction();
            this.coinbase.Time = (uint)this.DateTimeProvider.GetAdjustedTimeAsUnixTimestamp();
            this.coinbase.AddInput(TxIn.CreateCoinbase(this.ChainTip.Height + 1));
            this.coinbase.AddOutput(new TxOut(Money.Zero, this.scriptPubKey));

            this.block.AddTransaction(this.coinbase);
            this.BlockTemplate.VTxFees.Add(-1);      // Updated at end.
            this.BlockTemplate.TxSigOpsCost.Add(-1); // Updated at end.
        }
コード例 #10
0
 protected virtual void CreateCoinbase()
 {
     // Create coinbase transaction.
     // set the coin base with zero money
     // once we have the fee we can update the amount
     this.coinbase = new Transaction();
     coinbase.AddInput(TxIn.CreateCoinbase(this.chain.Height + 1));
     coinbase.AddOutput(new TxOut(Money.Zero, scriptPubKeyIn));
     pblock.AddTransaction(coinbase);
     pblocktemplate.VTxFees.Add(-1);             // updated at end
     pblocktemplate.TxSigOpsCost.Add(-1);        // updated at end
 }
コード例 #11
0
 protected virtual void CreateCoinbase()
 {
     // Create coinbase transaction.
     // Set the coin base with zero money.
     // Once we have the fee we can update the amount.
     this.coinbase = new Transaction();
     this.coinbase.AddInput(TxIn.CreateCoinbase(this.ChainTip.Height + 1));
     this.coinbase.AddOutput(new TxOut(Money.Zero, this.scriptPubKeyIn));
     this.pblock.AddTransaction(this.coinbase);
     this.pblocktemplate.VTxFees.Add(-1);      // Updated at end.
     this.pblocktemplate.TxSigOpsCost.Add(-1); // Updated at end.
 }
コード例 #12
0
ファイル: NodeBuilder.cs プロジェクト: ioann-voronov/NBitcoin
        public void Generate(int blockCount, bool includeMempool = true)
        {
            var             rpc       = CreateRPCClient();
            BitcoinSecret   dest      = GetFirstSecret(rpc);
            var             bestBlock = rpc.GetBestBlockHash();
            ConcurrentChain chain     = null;
            Random          nonce     = new Random();
            List <Block>    blocks    = new List <Block>();

#if !NOSOCKET
            using (var node = CreateNodeClient())
            {
                node.VersionHandshake();
                chain = bestBlock == node.Network.GenesisHash ? new ConcurrentChain(node.Network) : node.GetChain();
                for (int i = 0; i < blockCount; i++)
                {
                    Block block = new Block();
                    block.Header.HashPrevBlock = chain.Tip.HashBlock;
                    block.Header.Bits          = block.Header.GetWorkRequired(rpc.Network, chain.Tip);
                    block.Header.UpdateTime(rpc.Network, chain.Tip);
                    var coinbase = new Transaction();
                    coinbase.AddInput(TxIn.CreateCoinbase(chain.Height + 1));
                    coinbase.AddOutput(new TxOut(rpc.Network.GetReward(chain.Height + 1), dest.GetAddress()));
                    block.AddTransaction(coinbase);
                    if (includeMempool)
                    {
                        transactions = Reorder(transactions);
                        block.Transactions.AddRange(transactions);
                        transactions.Clear();
                    }
                    block.UpdateMerkleRoot();
                    while (!block.CheckProofOfWork())
                    {
                        block.Header.Nonce = (uint)nonce.Next();
                    }
                    blocks.Add(block);
                    if (chain.Height + 1 == 4032)
                    {
                    }
                    chain.SetTip(block.Header);
                }
                Block lastSent = null;
                foreach (var block in blocks)
                {
                    node.SendMessageAsync(new InvPayload(block));
                    node.SendMessageAsync(new BlockPayload(block));
                    lastSent = block;
                }
                node.PingPong();
            }
#endif
        }
コード例 #13
0
        private Transaction CreateTransaction(Money amount, bool isOpReturn = false)
        {
            var transaction = this.network.CreateTransaction();

            transaction.AddInput(TxIn.CreateCoinbase(1));

            if (isOpReturn)
                transaction.AddOutput(new TxOut(0, new Script(OpcodeType.OP_RETURN, Op.GetPushOp(new Key().PubKey.Compress().ToBytes()))));
            else
                transaction.AddOutput(new TxOut(amount, new Script()));

            return transaction;
        }
コード例 #14
0
    protected override Transaction CreateOutputTransaction()
    {
        rewardToPool = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

        var tx = Transaction.Create(network);

        // pool reward (t-addr)
        tx.Outputs.Add(rewardToPool, poolAddressDestination);

        tx.Inputs.Add(TxIn.CreateCoinbase((int)BlockTemplate.Height));

        return(tx);
    }
コード例 #15
0
        public void CreateNewBlock_WithScript_ReturnsBlockTemplate()
        {
            this.ExecuteWithConsensusOptions(new PowConsensusOptions(), () =>
            {
                ConcurrentChain chain = GenerateChainWithHeight(5, this.network, this.key);
                this.SetupRulesEngine(chain);
                this.consensusLoop.Setup(s => s.Tip).Returns(chain.Tip);
                this.dateTimeProvider.Setup(d => d.GetAdjustedTimeAsUnixTimestamp())
                .Returns(new DateTime(2017, 1, 7, 0, 0, 1, DateTimeKind.Utc).ToUnixTimestamp());
                Transaction 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 PowConsensusOptions, txFee, transaction);
                this.consensusRules
                .Setup(s => s.CreateRuleContext(It.IsAny <ValidationContext>(), It.IsAny <ChainedHeader>()))
                .Returns(new PowRuleContext());

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

                BlockTemplate blockTemplate = blockDefinition.Build(chain.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(this.powReward + txFee, resultingTransaction.TotalOut);
                Assert.Equal(this.key.ScriptPubKey, resultingTransaction.Outputs[0].ScriptPubKey);
                Assert.Equal(this.powReward + txFee, 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);
            });
        }
コード例 #16
0
        /// <summary>
        /// Constructs a chain of valid and if so specified and invalid block at a given height.
        /// <para>
        /// Each block will also be submitted to consensus.
        /// </para>
        /// </summary>
        public async Task <ChainedHeader> BuildAsync()
        {
            var chainTip       = this.coreNode.FullNode.ConsensusManager().Tip;
            var chainTipHeight = chainTip.Height;

            var dateTimeProvider = this.coreNode.FullNode.NodeService <IDateTimeProvider>();

            for (int height = chainTipHeight + 1; height <= chainTipHeight + this.amountOfBlocks; height++)
            {
                // Create the block and set the header properties.
                var block = this.coreNode.FullNode.Network.CreateBlock();
                block.Header.HashPrevBlock = chainTip.HashBlock;
                block.Header.UpdateTime(dateTimeProvider.GetTimeOffset(), this.coreNode.FullNode.Network, chainTip);
                block.Header.Bits = block.Header.GetWorkRequired(this.coreNode.FullNode.Network, chainTip);

                // Create a valid coinbase transaction.
                var coinbase = this.coreNode.FullNode.Network.CreateTransaction();
                if (coinbase is IPosTransactionWithTime posTx)
                {
                    posTx.Time = (uint)dateTimeProvider.GetAdjustedTimeAsUnixTimestamp();
                }
                coinbase.AddInput(TxIn.CreateCoinbase(chainTip.Height + 1));
                coinbase.AddOutput(new TxOut(this.coreNode.FullNode.Network.Consensus.ProofOfWorkReward, this.coreNode.MinerSecret.GetAddress()));
                block.AddTransaction(coinbase);

                // Check to see whether or not the block should be invalid.
                if (height == this.invalidBlockHeight)
                {
                    block = this.invalidBlock(this.coreNode, block);
                }

                block.UpdateMerkleRoot();

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

                // This will set the block's BlockSize property.
                block = Block.Load(block.ToBytes(), this.coreNode.FullNode.Network.Consensus.ConsensusFactory);

                // Submit the block to consensus so that the chain's tip can be updated.
                await this.coreNode.FullNode.NodeService <IConsensusManager>().BlockMinedAsync(block).ConfigureAwait(false);

                chainTip = this.coreNode.FullNode.ConsensusManager().Tip;
            }

            return(chainTip);
        }
コード例 #17
0
        public void CreateNewBlock_WithScript_ReturnsBlockTemplate()
        {
            this.ExecuteWithConsensusOptions(new PowConsensusOptions(), () =>
            {
                var chain       = GenerateChainWithHeight(5, this.network, this.key);
                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 PowConsensusOptions, txFee, transaction);

                var powBlockAssembler = new PowBlockAssembler(this.consensusLoop.Object, this.network, new MempoolSchedulerLock(), this.txMempool.Object,
                                                              this.dateTimeProvider.Object, chain.Tip, this.LoggerFactory.Object);

                var blockTemplate = powBlockAssembler.CreateNewBlock(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.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(this.powReward + txFee, resultingTransaction.TotalOut);
                Assert.Equal(this.key.ScriptPubKey, resultingTransaction.Outputs[0].ScriptPubKey);
                Assert.Equal(this.powReward + txFee, 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);
            });
        }
コード例 #18
0
        private static BlockTemplate CreateBlockTemplate(TestChainContext testChainContext, Script scriptPubKey,
                                                         TxMempool mempool, MempoolSchedulerLock mempoolLock)
        {
            PowBlockDefinition blockAssembler = new PowBlockDefinition(testChainContext.Consensus,
                                                                       testChainContext.DateTimeProvider, testChainContext.LoggerFactory as LoggerFactory, mempool, mempoolLock,
                                                                       new MinerSettings(testChainContext.NodeSettings), testChainContext.Network, testChainContext.ConsensusRules);

            BlockTemplate newBlock = blockAssembler.Build(testChainContext.Chain.Tip, scriptPubKey);

            int         nHeight    = testChainContext.Chain.Tip.Height + 1; // Height first in coinbase required for block.version=2
            Transaction txCoinbase = newBlock.Block.Transactions[0];

            txCoinbase.Inputs[0] = TxIn.CreateCoinbase(nHeight);
            return(newBlock);
        }
コード例 #19
0
ファイル: NodeBuilder.cs プロジェクト: andyfreer/NDash
        public Block[] Generate(int blockCount, bool includeUnbroadcasted = true, bool broadcast = true)
        {
            var             rpc       = CreateRPCClient();
            BitcoinSecret   dest      = GetFirstSecret(rpc);
            var             bestBlock = rpc.GetBestBlockHash();
            ConcurrentChain chain     = null;
            List <Block>    blocks    = new List <Block>();
            DateTimeOffset  now       = MockTime == null ? DateTimeOffset.UtcNow : MockTime.Value;

#if !NOSOCKET
            using (var node = CreateNodeClient())
            {
                node.VersionHandshake();
                chain = bestBlock == node.Network.GenesisHash ? new ConcurrentChain(node.Network) : node.GetChain();
                for (int i = 0; i < blockCount; i++)
                {
                    uint  nonce = 0;
                    Block block = new Block();
                    block.Header.HashPrevBlock = chain.Tip.HashBlock;
                    block.Header.Bits          = block.Header.GetWorkRequired(rpc.Network, chain.Tip);
                    block.Header.UpdateTime(now, rpc.Network, chain.Tip);
                    var coinbase = new Transaction();
                    coinbase.AddInput(TxIn.CreateCoinbase(chain.Height + 1));
                    coinbase.AddOutput(new TxOut(rpc.Network.GetReward(chain.Height + 1), dest.GetAddress()));
                    block.AddTransaction(coinbase);
                    if (includeUnbroadcasted)
                    {
                        transactions = Reorder(transactions);
                        block.Transactions.AddRange(transactions);
                        transactions.Clear();
                    }
                    block.UpdateMerkleRoot();
                    while (!block.CheckProofOfWork())
                    {
                        block.Header.Nonce = ++nonce;
                    }
                    blocks.Add(block);
                    chain.SetTip(block.Header);
                }
                if (broadcast)
                {
                    BroadcastBlocks(blocks.ToArray(), node);
                }
            }
            return(blocks.ToArray());
#endif
        }
コード例 #20
0
        /// <summary>
        /// Mine new blocks in to the consensus database and the chain.
        /// </summary>
        public static async Task <List <Block> > MineBlocksAsync(TestChainContext testChainContext, int count, Script scriptPubKey)
        {
            BlockPolicyEstimator blockPolicyEstimator = new BlockPolicyEstimator(new MempoolSettings(testChainContext.NodeSettings), testChainContext.LoggerFactory, testChainContext.NodeSettings);
            TxMempool            mempool     = new TxMempool(testChainContext.DateTimeProvider, blockPolicyEstimator, testChainContext.LoggerFactory, testChainContext.NodeSettings);
            MempoolSchedulerLock mempoolLock = new MempoolSchedulerLock();

            // Simple block creation, nothing special yet:

            List <Block> blocks = new List <Block>();

            for (int i = 0; i < count; ++i)
            {
                PowBlockAssembler blockAssembler = CreatePowBlockAssembler(testChainContext.Network, testChainContext.Consensus, testChainContext.Chain, mempoolLock, mempool, testChainContext.DateTimeProvider, testChainContext.LoggerFactory as LoggerFactory);

                BlockTemplate newBlock = blockAssembler.CreateNewBlock(scriptPubKey);

                int         nHeight    = testChainContext.Chain.Tip.Height + 1; // Height first in coinbase required for block.version=2
                Transaction txCoinbase = newBlock.Block.Transactions[0];
                txCoinbase.Inputs[0] = TxIn.CreateCoinbase(nHeight);
                newBlock.Block.UpdateMerkleRoot();

                var maxTries = int.MaxValue;

                while (maxTries > 0 && !newBlock.Block.CheckProofOfWork())
                {
                    ++newBlock.Block.Header.Nonce;
                    --maxTries;
                }

                if (maxTries == 0)
                {
                    throw new XunitException("Test failed no blocks found");
                }

                var context = new BlockValidationContext {
                    Block = newBlock.Block
                };
                await testChainContext.Consensus.AcceptBlockAsync(context);

                Assert.Null(context.Error);

                blocks.Add(newBlock.Block);
            }

            return(blocks);
        }
コード例 #21
0
        protected override void BuildCoinbase()
        {
            // output transaction
            txOut = CreateOutputTransaction();
            txOut.AddInput(TxIn.CreateCoinbase((int)BlockTemplate.Height));

            using (var stream = new MemoryStream())
            {
                var bs = new ZcashStream(stream, true);
                bs.ReadWrite(ref txOut);

                // done
                coinbaseInitial     = stream.ToArray();
                coinbaseInitialHex  = coinbaseInitial.ToHexString();
                coinbaseInitialHash = sha256D.Digest(coinbaseInitial);
            }
        }
コード例 #22
0
        public void IncrementExtraNonce(Block pblock, ChainedBlock pindexPrev, int nExtraNonce)
        {
            // Update nExtraNonce
            if (this.hashPrevBlock != pblock.Header.HashPrevBlock)
            {
                nExtraNonce        = 0;
                this.hashPrevBlock = pblock.Header.HashPrevBlock;
            }
            ++nExtraNonce;
            int nHeight    = pindexPrev.Height + 1;          // Height first in coinbase required for block.version=2
            var txCoinbase = pblock.Transactions[0];

            txCoinbase.Inputs[0] = TxIn.CreateCoinbase(nHeight);

            Guard.Assert(txCoinbase.Inputs[0].ScriptSig.Length <= 100);
            pblock.UpdateMerkleRoot();
        }
コード例 #23
0
        public async Task TxOutSmartContractExec_CoinbaseWithSmartContracts_ValidationFailAsync()
        {
            TestRulesContext           testContext = TestRulesContextFactory.CreateAsync(this.network);
            TxOutSmartContractExecRule rule        = testContext.CreateRule <TxOutSmartContractExecRule>();

            var context = new RuleContext(new ValidationContext(), testContext.DateTimeProvider.GetTimeOffset());

            context.ValidationContext.BlockToValidate = testContext.Network.Consensus.ConsensusFactory.CreateBlock();
            context.ValidationContext.BlockToValidate.Header.HashPrevBlock = testContext.Chain.Tip.HashBlock;

            var transactions = new List <Transaction>
            {
                new Transaction()
                {
                    Outputs =
                    {
                        new TxOut(Money.Zero, new Script(new [] { (byte)ScOpcodeType.OP_CALLCONTRACT }))
                    },
                    Inputs =
                    {
                        TxIn.CreateCoinbase(0)
                    }
                }
            };

            context.ValidationContext.BlockToValidate.Transactions = transactions;
            await Assert.ThrowsAsync <ConsensusErrorException>(async() => await rule.RunAsync(context));

            transactions = new List <Transaction>
            {
                new Transaction()
                {
                    Outputs =
                    {
                        new TxOut(Money.Zero, new Script()),
                    },
                    Inputs =
                    {
                        TxIn.CreateCoinbase(0)
                    }
                }
            };

            context.ValidationContext.BlockToValidate.Transactions = transactions;
            await rule.RunAsync(context);
        }
コード例 #24
0
        public void OnlySplitValidAmounts()
        {
            // Can't split small amount
            Script      receiver      = PayToScriptHashTemplate.Instance.GenerateScriptPubKey(new ScriptId());
            TxIn        coinbaseInput = TxIn.CreateCoinbase((int)this.network.Consensus.PremineHeight);
            Transaction tx            = this.network.CreateTransaction();

            tx.Inputs.Add(coinbaseInput);
            tx.Outputs.Add(new TxOut(PremineCoinbaseSplitter.FederationWalletOutputs - 1, receiver));
            Assert.Throws <Exception>(() => this.premineSplitter.SplitReward(tx));

            // Can't split non-divisible amount
            tx = this.network.CreateTransaction();
            tx.Inputs.Add(coinbaseInput);
            tx.Outputs.Add(new TxOut(PremineCoinbaseSplitter.FederationWalletOutputs * 100 + 6, receiver));
            Assert.Throws <Exception>(() => this.premineSplitter.SplitReward(tx));
        }
コード例 #25
0
        protected virtual void BuildCoinbase()
        {
            // output transaction
            txOut = CreateOutputTransaction();
            txOut.Inputs.Add(TxIn.CreateCoinbase((int)BlockTemplate.Height));

            using (var stream = new MemoryStream())
            {
                var bs = new ZcashStream(stream, true);
                bs.ReadWrite(ref txOut);

                // done
                coinbaseInitial = stream.ToArray();

                coinbaseInitialHash = new byte[32];
                sha256D.Digest(coinbaseInitial, coinbaseInitialHash);
            }
        }
コード例 #26
0
        //<inheritdoc/>
        public int IncrementExtraNonce(Block block, ChainedHeader previousHeader, int extraNonce)
        {
            if (this.hashPrevBlock != block.Header.HashPrevBlock)
            {
                extraNonce         = 0;
                this.hashPrevBlock = block.Header.HashPrevBlock;
            }

            extraNonce++;
            int         height     = previousHeader.Height + 1; // Height first in coinbase required for block.version=2
            Transaction txCoinbase = block.Transactions[0];

            txCoinbase.Inputs[0] = TxIn.CreateCoinbase(height);

            Guard.Assert(txCoinbase.Inputs[0].ScriptSig.Length <= 100);
            block.UpdateMerkleRoot();

            return(extraNonce);
        }
コード例 #27
0
        /// <summary>Creates invalid PoW block with coinbase transaction.</summary>
        public static Block CreateDummyBlockWithTransaction(Network network, ChainedHeader tip)
        {
            Block block    = network.Consensus.ConsensusFactory.CreateBlock();
            var   coinbase = new Transaction();

            coinbase.AddInput(TxIn.CreateCoinbase(tip.Height + 1));
            coinbase.AddOutput(new TxOut(new Money(100 * Money.COIN), new Key()));
            block.AddTransaction(coinbase);

            block.Header.Version = (int)ThresholdConditionCache.VersionbitsTopBits;

            block.Header.HashPrevBlock = tip.HashBlock;
            block.Header.UpdateTime(DateTimeProvider.Default.GetTimeOffset(), network, tip);
            block.Header.Bits  = block.Header.GetWorkRequired(network, tip);
            block.Header.Nonce = (uint)random.Next();

            block.GetHash();

            return(block);
        }
コード例 #28
0
        /// <summary>
        /// This should only be used if we need to create a block manually, in all other cases please use
        /// <see cref="CoreNode.GenerateStratisWithMiner"/>
        /// </summary>
        /// <param name="coreNode">The node we want to create the block with.</param>
        /// <param name="transactions">Transactions we want to manually include in the block.</param>
        public static Block GenerateBlockManually(this CoreNode coreNode, List <Transaction> transactions)
        {
            uint nonce = 0;

            var block = coreNode.FullNode.Network.CreateBlock();

            block.Header.HashPrevBlock = coreNode.FullNode.Chain.Tip.HashBlock;
            block.Header.Bits          = block.Header.GetWorkRequired(coreNode.FullNode.Network, coreNode.FullNode.Chain.Tip);
            block.Header.UpdateTime(DateTimeOffset.UtcNow, coreNode.FullNode.Network, coreNode.FullNode.Chain.Tip);

            var coinbase = coreNode.FullNode.Network.CreateTransaction();

            coinbase.AddInput(TxIn.CreateCoinbase(coreNode.FullNode.Chain.Height + 1));
            coinbase.AddOutput(new TxOut(coreNode.FullNode.Network.GetReward(coreNode.FullNode.Chain.Height + 1), coreNode.MinerSecret.GetAddress()));
            block.AddTransaction(coinbase);

            if (transactions.Any())
            {
                transactions = Reorder(transactions);
                block.Transactions.AddRange(transactions);
            }

            block.UpdateMerkleRoot();

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

            uint256       blockHash     = block.GetHash();
            var           chainedHeader = new ChainedHeader(block.Header, blockHash, coreNode.FullNode.Chain.Tip);
            ChainedHeader oldTip        = coreNode.FullNode.Chain.SetTip(chainedHeader);

            coreNode.FullNode.ConsensusLoop().Puller.InjectBlock(blockHash, new DownloadedBlock {
                Length = block.GetSerializedSize(), Block = block
            }, CancellationToken.None);

            return(block);
        }
コード例 #29
0
        public Block PrepareValidBlock(ChainedHeader prevBlock, int newHeight, Script ScriptPubKey)
        {
            uint nonce = 0;

            var block = this.Network.Consensus.ConsensusFactory.CreateBlock();

            block.Header.HashPrevBlock = prevBlock.HashBlock;

            var transaction = this.Network.Consensus.ConsensusFactory.CreateTransaction();

            transaction.AddInput(TxIn.CreateCoinbase(newHeight));
            transaction.AddOutput(new TxOut(new Money(1, MoneyUnit.BTC), ScriptPubKey));
            block.Transactions.Add(transaction);

            block.Header.Bits = block.Header.GetWorkRequired(this.Network, prevBlock);
            block.UpdateMerkleRoot();
            while (!block.CheckProofOfWork())
            {
                block.Header.Nonce = ++nonce;
            }

            return(block);
        }
コード例 #30
0
        public void Mine(int blockCount)
        {
            var            blocks = new List <Block>();
            DateTimeOffset now    = DateTimeOffset.UtcNow;

            for (int i = 0; i < blockCount; i++)
            {
                uint nonce = 0;
                var  block = this.network.CreateBlock();
                block.Header.HashPrevBlock = this.ChainIndexer.Tip.HashBlock;
                block.Header.Bits          = block.Header.GetWorkRequired(this.network, this.ChainIndexer.Tip);
                block.Header.UpdateTime(now, this.network, this.ChainIndexer.Tip);

                var coinbase = this.network.CreateTransaction();
                coinbase.AddInput(TxIn.CreateCoinbase(this.ChainIndexer.Height + 1));
                coinbase.AddOutput(new TxOut(this.network.GetReward(this.ChainIndexer.Height + 1), this.MinerScriptPubKey));
                block.AddTransaction(coinbase);
                foreach (Transaction tx in this.transactions)
                {
                    block.AddTransaction(tx);
                }
                block.UpdateMerkleRoot();
                while (!block.CheckProofOfWork())
                {
                    block.Header.Nonce = ++nonce;
                }
                block.Header.PrecomputeHash();
                blocks.Add(block);
                this.transactions.Clear();
                this.ChainIndexer.SetTip(block.Header);
            }

            foreach (Block b in blocks)
            {
                this.Blocks.Add(b.GetHash(), b);
            }
        }