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); }
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); }
/// <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); }
/// <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); }
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 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()); }
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); }); }
/// <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); }
/// <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. }
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 }
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. }
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 }
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; }
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); }
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); }); }
/// <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); }
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); }); }
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); }
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 }
/// <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); }
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); } }
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(); }
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); }
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)); }
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); } }
//<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); }
/// <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); }
/// <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); }
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); }
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); } }