Example #1
0
 public Build(BlockTemplate BlockType, Coordinate Location)
     : base(Location)
 {
     this.BlockType = BlockType;
     MarkerTile = TileNames.TaskIconBlank;
     GnomeIcon = TileNames.TaskIconBuild;
 }
Example #2
0
        public override void Selected(Game Game, Gem.Gui.UIItem GuiRoot)
        {
            this.SelectedBlock = null;

            BlockContainer = new Gem.Gui.UIItem(Gem.Gui.Shape.CreateQuad(96, 8, 512, 128),
                new Gem.Gui.GuiProperties
                {
                    Transparent = false,
                    BackgroundColor = new Microsoft.Xna.Framework.Vector3(0.8f, 0.2f, 0.2f)
                });

            GuiRoot.AddChild(BlockContainer);

            var x = 96 + 8;
            foreach (var template in Game.Sim.Blocks.Templates)
            {
                var lambdaTemplate = template;
                var child = HoverTest.CreateGuiSprite(new Rectangle(x, 16, 32, 32), template.Value.Preview, Game.Sim.Blocks.Tiles);
                child.Properties[0].Values.Upsert("click-action", new Action(() =>
                {
                    this.SelectedBlock = lambdaTemplate.Value;
                    GuiRoot.RemoveChild(BlockContainer);
                    BlockContainer = null;
                }));
                BlockContainer.AddChild(child);
                x += 32;
            }
        }
Example #3
0
        public async Task MinerCreateBlockSizeGreaterThenLimitAsync()
        {
            var context = new TestContext();
            await context.InitializeAsync();

            var tx = context.network.CreateTransaction();

            tx.AddInput(new TxIn());
            tx.AddOutput(new TxOut());

            // block size > limit
            tx = context.network.CreateTransaction();
            tx.AddInput(new TxIn());
            tx.AddOutput(new TxOut());
            tx.Inputs[0].ScriptSig = new Script();
            // 18 * (520char + DROP) + OP_1 = 9433 bytes
            var vchData = new byte[520];

            for (int i = 0; i < 18; ++i)
            {
                tx.Inputs[0].ScriptSig = new Script(tx.Inputs[0].ScriptSig.ToBytes().Concat(vchData.Concat(new[] { (byte)OpcodeType.OP_DROP })));
            }
            tx.Inputs[0].ScriptSig    = new Script(tx.Inputs[0].ScriptSig.ToBytes().Concat(new[] { (byte)OpcodeType.OP_1 }));
            tx.Inputs[0].PrevOut.Hash = context.txFirst[0].GetHash();
            tx.Outputs[0].Value       = context.BLOCKSUBSIDY;
            for (int i = 0; i < 128; ++i)
            {
                tx.Outputs[0].Value -= context.LOWFEE;
                context.hash         = tx.GetHash();
                bool spendsCoinbase = (i == 0); // only first tx spends coinbase
                context.mempool.AddUnchecked(context.hash, context.entry.Fee(context.LOWFEE).Time(context.DateTimeProvider.GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
                tx = context.network.CreateTransaction(tx.ToBytes());
                tx.Inputs[0].PrevOut.Hash = context.hash;
            }
            BlockTemplate pblocktemplate = AssemblerForTest(context).Build(context.ChainIndexer.Tip, context.scriptPubKey);

            Assert.NotNull(pblocktemplate);
            context.mempool.Clear();
        }
Example #4
0
        public void GenerateBlocks_SingleBlock_ChainedBlockNotPresentInBlockValidationContext_ReturnsEmptyList()
        {
            this.ExecuteUsingNonProofOfStakeSettings(() =>
            {
                BlockValidationContext callbackBlockValidationContext = null;
                this.consensusLoop.Setup(c => c.AcceptBlockAsync(It.IsAny <BlockValidationContext>()))
                .Callback <BlockValidationContext>((context) =>
                {
                    context.ChainedBlock           = null;
                    callbackBlockValidationContext = context;
                })
                .Returns(Task.CompletedTask);

                BlockTemplate blockTemplate = CreateBlockTemplate(this.fixture.block1);
                this.blockAssembler.Setup(b => b.CreateNewBlock(It.Is <Script>(r => r == this.fixture.reserveScript.ReserveFullNodeScript), true))
                .Returns(blockTemplate);

                var blockHashes = this.powMining.GenerateBlocks(this.fixture.reserveScript, 1, uint.MaxValue);

                Assert.Empty(blockHashes);
            });
        }
Example #5
0
        public override BlockTemplate Build(ChainedHeader chainTip, Script scriptPubKey)
        {
            // Note: When creating a new chain, ensure that the first nodes mining are the federated peg nodes,
            // so that the premine goes to the federated peg wallet.

            // The other nodes don't know about the federated wallet in the current design.
            // If this changes, a consensus rule should be built that enforces that the premine goes to that address.

            bool miningPremine = (chainTip.Height + 1) == this.Network.Consensus.PremineHeight;

            // If we are not mining the premine, then the reward should fall back to what was selected by the caller.
            Script rewardScript = miningPremine ? this.payToMultisigScript : scriptPubKey;

            BlockTemplate built = base.Build(chainTip, rewardScript);

            if (miningPremine)
            {
                this.premineSplitter.SplitReward(this.coinbase);
            }

            return(built);
        }
        public void GenerateBlocks_SingleBlock_BlockValidationContextErrorInvalidPrevTip_ContinuesExecution_ReturnsGeneratedBlock()
        {
            this.ExecuteUsingNonProofOfStakeSettings(() =>
            {
                BlockValidationContext callbackBlockValidationContext = null;

                ConsensusError lastError = null;

                this.consensusLoop.Setup(c => c.AcceptBlockAsync(It.IsAny <BlockValidationContext>())).Callback <BlockValidationContext>((context) =>
                {
                    context.ChainedHeader = new ChainedHeader(context.Block.Header, context.Block.GetHash(), this.chain.Tip);
                    if (lastError == null)
                    {
                        context.Error = ConsensusErrors.InvalidPrevTip;
                        lastError     = context.Error;
                    }
                    else if (lastError != null)
                    {
                        this.chain.SetTip(context.ChainedHeader);
                    }
                    callbackBlockValidationContext = context;
                }).Returns(Task.CompletedTask);

                BlockTemplate blockTemplate = this.CreateBlockTemplate(this.fixture.Block1);

                this.chain.SetTip(this.chain.GetBlock(0));

                var blockBuilder = this.CreateProofOfWorkBlockBuilder();
                blockBuilder.Setup(b => b.Build(It.IsAny <ChainedHeader>(), It.Is <Script>(r => r == this.fixture.ReserveScript.ReserveFullNodeScript))).Returns(blockTemplate);

                var miner       = this.CreateProofOfWorkMiner(blockBuilder.Object);
                var blockHashes = miner.GenerateBlocks(this.fixture.ReserveScript, 1, uint.MaxValue);

                Assert.NotEmpty(blockHashes);
                Assert.True(blockHashes.Count == 1);
                Assert.Equal(callbackBlockValidationContext.Block.GetHash(), blockHashes[0]);
            });
        }
Example #7
0
        public void CreateNewBlock_WithScript_ValidatesTemplateUsingRuleContext()
        {
            var newOptions = new PowConsensusOptions()
            {
                MaxBlockWeight = 1500
            };

            this.ExecuteWithConsensusOptions(newOptions, () =>
            {
                ConcurrentChain 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());
                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);
                SetupTxMempool(chain, this.network.Consensus.Options as PowConsensusOptions, txFee, transaction);
                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 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.NotNull(this.callbackRuleContext);

                Assert.True(this.callbackRuleContext.MinedBlock);
                Assert.Equal(blockTemplate.Block.GetHash(), validationContext.Block.GetHash());
                Assert.Equal(chain.GetBlock(5).HashBlock, powRuleContext.ConsensusTip.HashBlock);
                Assert.Equal(1500, this.callbackRuleContext.Consensus.Option <PowConsensusOptions>().MaxBlockWeight);
                this.consensusLoop.Verify();
            });
        }
        public void GenerateBlocks_MultipleBlocks_InvalidPreviousTip_ReturnsValidGeneratedBlocks()
        {
            BlockTemplate blockTemplate = this.CreateBlockTemplate(this.fixture.Block1);

            this.chain.SetTip(this.chain.GetBlock(0));

            var chainedHeader = new ChainedHeader(blockTemplate.Block.Header, blockTemplate.Block.GetHash(), this.chain.Tip);

            bool firstBlock = true;

            this.consensusManager.Setup(c => c.BlockMinedAsync(It.IsAny <Block>()))
            .ReturnsAsync(() =>
            {
                if (!firstBlock)
                {
                    return(null);
                }

                this.chain.SetTip(chainedHeader);
                firstBlock = false;
                return(chainedHeader);
            });

            BlockTemplate blockTemplate2 = this.CreateBlockTemplate(this.fixture.Block2);

            Mock <PowBlockDefinition> blockBuilder = this.CreateProofOfWorkBlockBuilder();

            blockBuilder.SetupSequence(b => b.Build(It.IsAny <ChainedHeader>(), It.Is <Script>(r => r == this.fixture.ReserveScript.ReserveFullNodeScript)))
            .Returns(blockTemplate)
            .Returns(blockTemplate2);

            PowMining      miner       = this.CreateProofOfWorkMiner(blockBuilder.Object);
            List <uint256> blockHashes = miner.GenerateBlocks(this.fixture.ReserveScript, 2, uint.MaxValue);

            Assert.NotEmpty(blockHashes);
            Assert.True(blockHashes.Count == 1);
            Assert.Equal(chainedHeader.HashBlock, blockHashes[0]);
        }
Example #9
0
        public void GenerateBlocks_MultipleBlocks_BlockValidationContextError_ReturnsValidGeneratedBlocks()
        {
            this.ExecuteUsingNonProofOfStakeSettings(() =>
            {
                List <BlockValidationContext> callbackBlockValidationContexts = new List <BlockValidationContext>();
                ChainedBlock lastChainedBlock = null;
                this.consensusLoop.Setup(c => c.AcceptBlockAsync(It.IsAny <BlockValidationContext>()))
                .Callback <BlockValidationContext>((context) =>
                {
                    if (lastChainedBlock == null)
                    {
                        context.ChainedBlock = this.fixture.ChainedBlock1;
                        this.chain.SetTip(context.ChainedBlock);
                        lastChainedBlock = context.ChainedBlock;
                    }
                    else
                    {
                        context.Error = ConsensusErrors.BadBlockLength;
                    }

                    callbackBlockValidationContexts.Add(context);
                })
                .Returns(Task.CompletedTask);

                BlockTemplate blockTemplate  = CreateBlockTemplate(this.fixture.Block1);
                BlockTemplate blockTemplate2 = CreateBlockTemplate(this.fixture.Block2);

                this.blockAssembler.SetupSequence(b => b.CreateNewBlock(It.Is <Script>(r => r == this.fixture.ReserveScript.ReserveFullNodeScript), true))
                .Returns(blockTemplate)
                .Returns(blockTemplate2);

                var blockHashes = this.powMining.GenerateBlocks(this.fixture.ReserveScript, 2, uint.MaxValue);

                Assert.NotEmpty(blockHashes);
                Assert.True(blockHashes.Count == 1);
                Assert.Equal(callbackBlockValidationContexts[0].Block.GetHash(), blockHashes[0]);
            });
        }
Example #10
0
        protected override void DescribeYourself()
        {
            _logger.Debug(
                "\nCoinbaseInitial={0}\nCoinbaseFinal={1}\nCreationTime={2}\n" +
                "Difficulty={3}\nEncodedDifficulty={4}\nNTime={5}\n" +
                "PreviousBlockHash={6}\nPreviousBlockHashReversed={7}\nVersion={8}",
                CoinbaseInitial,
                CoinbaseFinal,
                CreationTime,
                Difficulty,
                EncodedDifficulty,
                NTime,
                PreviousBlockHash,
                PreviousBlockHashReversed,
                Version
                );
            //LogMeSafely(Target, "Target");
            _logger.Debug("Target={0}", BitConverter.ToString(Target.ToByteArray()).Replace("-", string.Empty));

            MerkleTree.DescribeYourselfSafely();
            BlockTemplate.DescribeYourselfSafely();
            GenerationTransaction.DescribeYourselfSafely();
        }
        public void GenerateBlocks_SingleBlock_ReturnsGeneratedBlock()
        {
            BlockTemplate blockTemplate = this.CreateBlockTemplate(this.fixture.Block1);

            Block callbackBlock = null;

            this.chainIndexer.SetTip(this.chainIndexer.GetHeader(0));

            this.consensusManager.Setup(c => c.BlockMinedAsync(It.IsAny <Block>()))
            .Callback <Block>((block) => { callbackBlock = block; })
            .ReturnsAsync(new ChainedHeader(blockTemplate.Block.Header, blockTemplate.Block.GetHash(), this.chainIndexer.Tip));

            Mock <PowBlockDefinition> blockBuilder = this.CreateProofOfWorkBlockBuilder();

            blockBuilder.Setup(b => b.Build(It.IsAny <ChainedHeader>(), It.Is <Script>(r => r == this.fixture.ReserveScript.ReserveFullNodeScript))).Returns(blockTemplate);

            PowMining      miner       = this.CreateProofOfWorkMiner(blockBuilder.Object);
            List <uint256> blockHashes = miner.GenerateBlocks(this.fixture.ReserveScript, 1, uint.MaxValue);

            Assert.NotEmpty(blockHashes);
            Assert.True(blockHashes.Count == 1);
            Assert.Equal(callbackBlock.GetHash(), blockHashes[0]);
        }
Example #12
0
        public void GenerateBlocks_SingleBlock_MaxTriesReached_StopsGeneratingBlocks_ReturnsEmptyList()
        {
            this.ExecuteUsingNonProofOfStakeSettings(() =>
            {
                BlockValidationContext callbackBlockValidationContext = null;
                this.consensusLoop.Setup(c => c.AcceptBlockAsync(It.IsAny <BlockValidationContext>()))
                .Callback <BlockValidationContext>((context) =>
                {
                    context.ChainedBlock = new ChainedBlock(context.Block.Header, context.Block.GetHash(), this.chain.Tip);
                    this.chain.SetTip(context.ChainedBlock);
                    callbackBlockValidationContext = context;
                })
                .Returns(Task.CompletedTask);

                BlockTemplate blockTemplate      = CreateBlockTemplate(this.fixture.Block1);
                blockTemplate.Block.Header.Nonce = 0;
                this.blockAssembler.Setup(b => b.CreateNewBlock(It.Is <Script>(r => r == this.fixture.ReserveScript.ReserveFullNodeScript), true))
                .Returns(blockTemplate);

                var blockHashes = this.powMining.GenerateBlocks(this.fixture.ReserveScript, 1, 15);

                Assert.Empty(blockHashes);
            });
        }
Example #13
0
 public abstract bool handle_block_found(BlockTemplate b);
        public void GenerateBlocks_MultipleBlocks_ReturnsGeneratedBlocks()
        {
            var           blocksToValidate  = new List <uint256>();
            ChainedHeader lastChainedHeader = null;
            BlockTemplate blockTemplate     = this.CreateBlockTemplate(this.fixture.Block1);
            var           chainedHeader     = new ChainedHeader(blockTemplate.Block.Header, blockTemplate.Block.GetHash(), this.chainIndexer.Tip);

            this.consensusManager.Setup(c => c.BlockMinedAsync(It.IsAny <Block>()))
            .Callback <Block>((context) =>
            {
                if (lastChainedHeader == null)
                {
                    blocksToValidate.Add(this.fixture.ChainedHeader1.HashBlock);
                    lastChainedHeader = this.fixture.ChainedHeader1;
                }
                else
                {
                    blocksToValidate.Add(this.fixture.ChainedHeader2.HashBlock);
                }

                this.chainIndexer.SetTip(lastChainedHeader);
            })
            .ReturnsAsync(chainedHeader);

            BlockTemplate blockTemplate2 = this.CreateBlockTemplate(this.fixture.Block2);

            this.chainIndexer.SetTip(this.chainIndexer.GetHeader(0));

            int attempts = 0;

            Mock <PowBlockDefinition> blockBuilder = this.CreateProofOfWorkBlockBuilder();

            blockBuilder.Setup(b => b.Build(It.IsAny <ChainedHeader>(), It.Is <Script>(r => r == this.fixture.ReserveScript.ReserveFullNodeScript)))
            .Returns(() =>
            {
                if (lastChainedHeader == null)
                {
                    if (attempts == 10)
                    {
                        // sometimes the PoW nonce we generate in the fixture is not accepted resulting in an infinite loop. Retry.
                        this.fixture.Block1         = this.fixture.PrepareValidBlock(this.chainIndexer.Tip, 1, this.fixture.Key.ScriptPubKey);
                        this.fixture.ChainedHeader1 = new ChainedHeader(this.fixture.Block1.Header, this.fixture.Block1.GetHash(), this.chainIndexer.Tip);
                        this.fixture.Block2         = this.fixture.PrepareValidBlock(this.fixture.ChainedHeader1, 2, this.fixture.Key.ScriptPubKey);
                        this.fixture.ChainedHeader2 = new ChainedHeader(this.fixture.Block2.Header, this.fixture.Block2.GetHash(), this.fixture.ChainedHeader1);

                        blockTemplate  = CreateBlockTemplate(this.fixture.Block1);
                        blockTemplate2 = CreateBlockTemplate(this.fixture.Block2);
                        attempts       = 0;
                    }
                    attempts += 1;

                    return(blockTemplate);
                }

                return(blockTemplate2);
            });

            PowMining      miner       = this.CreateProofOfWorkMiner(blockBuilder.Object);
            List <uint256> blockHashes = miner.GenerateBlocks(this.fixture.ReserveScript, 2, uint.MaxValue);

            Assert.NotEmpty(blockHashes);
            Assert.Equal(2, blockHashes.Count);
            Assert.Equal(blocksToValidate[0], blockHashes[0]);
            Assert.Equal(blocksToValidate[1], blockHashes[1]);
        }
Example #15
0
        /// <summary>
        /// Creates the test chain with some default blocks and txs.
        /// </summary>
        /// <param name="network">Network to create the chain on.</param>
        /// <param name="scriptPubKey">Public key to create blocks/txs with.</param>
        /// <returns>Context object representing the test chain.</returns>
        public static ITestChainContext Create(Network network, Script scriptPubKey)
        {
            NodeSettings      nodeSettings     = NodeSettings.Default();
            LoggerFactory     loggerFactory    = new LoggerFactory();
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            network.Consensus.Options = new PowConsensusOptions();
            PowConsensusValidator consensusValidator = new PowConsensusValidator(network);
            ConcurrentChain       chain          = new ConcurrentChain(network);
            CachedCoinView        cachedCoinView = new CachedCoinView(new InMemoryCoinView(chain.Tip.HashBlock), loggerFactory);

            ConnectionManager    connectionManager = new ConnectionManager(network, new NodeConnectionParameters(), nodeSettings, loggerFactory, new NodeLifetime());
            LookaheadBlockPuller blockPuller       = new LookaheadBlockPuller(chain, connectionManager, new LoggerFactory());

            ConsensusLoop consensus = new ConsensusLoop(consensusValidator, chain, cachedCoinView, blockPuller, new NodeDeployments(network));

            consensus.Initialize();

            BlockPolicyEstimator blockPolicyEstimator = new BlockPolicyEstimator(new FeeRate(1000), nodeSettings, loggerFactory);
            TxMempool            mempool     = new TxMempool(new FeeRate(1000), dateTimeProvider, blockPolicyEstimator, loggerFactory);
            MempoolAsyncLock     mempoolLock = new MempoolAsyncLock();

            // Simple block creation, nothing special yet:
            PowBlockAssembler blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider);
            BlockTemplate     newBlock       = blockAssembler.CreateNewBlock(scriptPubKey);

            chain.SetTip(newBlock.Block.Header);
            consensus.AcceptBlock(new ContextInformation(new BlockResult {
                Block = newBlock.Block
            }, network.Consensus)
            {
                CheckPow = false, CheckMerkleRoot = false
            });

            List <BlockInfo> blockinfo = CreateBlockInfoList();

            // We can't make transactions until we have inputs
            // Therefore, load 100 blocks :)
            int                baseheight = 0;
            List <Block>       blocks     = new List <Block>();
            List <Transaction> srcTxs     = new List <Transaction>();

            for (int i = 0; i < blockinfo.Count; ++i)
            {
                Block currentBlock = newBlock.Block.Clone(); // pointer for convenience
                currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock;
                currentBlock.Header.Version       = 1;
                currentBlock.Header.Time          = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1;
                Transaction txCoinbase = currentBlock.Transactions[0].Clone();
                txCoinbase.Inputs.Clear();
                txCoinbase.Version = 1;
                txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) })));
                // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                currentBlock.Transactions[0] = txCoinbase;

                if (srcTxs.Count == 0)
                {
                    baseheight = chain.Height;
                }
                if (srcTxs.Count < 4)
                {
                    srcTxs.Add(currentBlock.Transactions[0]);
                }
                currentBlock.UpdateMerkleRoot();

                currentBlock.Header.Nonce = blockinfo[i].nonce;

                chain.SetTip(currentBlock.Header);
                consensus.AcceptBlock(new ContextInformation(new BlockResult {
                    Block = currentBlock
                }, network.Consensus)
                {
                    CheckPow = false, CheckMerkleRoot = false
                });
                blocks.Add(currentBlock);
            }

            // Just to make sure we can still make simple blocks
            blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider);
            newBlock       = blockAssembler.CreateNewBlock(scriptPubKey);

            MempoolValidator mempoolValidator = new MempoolValidator(mempool, mempoolLock, consensusValidator, dateTimeProvider, nodeSettings, chain, cachedCoinView, loggerFactory);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, SrcTxs = srcTxs
            });
        }
Example #16
0
        protected async Task <ChainedHeader> MineBlockAtTimestampAsync(uint timestamp)
        {
            ChainedHeader tip = this.consensusManager.Tip;

            // Timestamp should always be greater than prev one.
            if (timestamp <= tip.Header.Time)
            {
                // Can happen only when target spacing had crazy low value or key was compromised and someone is mining with our key.
                this.logger.LogWarning("Somehow another block was connected with greater timestamp. Dropping current block.");
                this.logger.LogTrace("(-)[ANOTHER_BLOCK_CONNECTED]:null");
                return(null);
            }

            Script walletScriptPubKey = this.GetScriptPubKeyFromWallet();

            if (walletScriptPubKey == null)
            {
                this.logger.LogWarning("Miner wasn't able to get address from the wallet! You will not receive any rewards.");
                walletScriptPubKey = new Script();
            }

            BlockTemplate blockTemplate = this.blockDefinition.Build(tip, walletScriptPubKey);

            this.FillBlockTemplate(blockTemplate, out bool dropTemplate);

            if (dropTemplate)
            {
                this.logger.LogTrace("(-)[DROPPED]:null");
                return(null);
            }

            blockTemplate.Block.Header.Time = timestamp;

            // Update merkle root.
            blockTemplate.Block.UpdateMerkleRoot();

            // Sign block with our private key.
            var header = blockTemplate.Block.Header as PoABlockHeader;

            this.poaHeaderValidator.Sign(this.federationManager.CurrentFederationKey, header);

            ChainedHeader chainedHeader = await this.consensusManager.BlockMinedAsync(blockTemplate.Block).ConfigureAwait(false);

            if (chainedHeader == null)
            {
                // Block wasn't accepted because we already connected block from the network.
                this.logger.LogTrace("(-)[FAILED_TO_CONNECT]:null");
                return(null);
            }

            ValidationContext result = this.integrityValidator.VerifyBlockIntegrity(chainedHeader, blockTemplate.Block);

            if (result.Error != null)
            {
                // Sanity check. Should never happen.
                this.logger.LogTrace("(-)[INTEGRITY_FAILURE]");
                throw new Exception(result.Error.ToString());
            }

            return(chainedHeader);
        }
Example #17
0
        private static void TryFindNonceForProofOfWork(TestChainContext testChainContext, BlockTemplate newBlock)
        {
            int 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");
            }
        }
Example #18
0
        public void Init(BlockTemplate blockTemplate, string jobId,
                         PoolConfig poolConfig, BitcoinPoolConfigExtra extraPoolConfig,
                         ClusterConfig clusterConfig, IMasterClock clock,
                         IDestination poolAddressDestination, Network network,
                         bool isPoS, double shareMultiplier, IHashAlgorithm coinbaseHasher,
                         IHashAlgorithm headerHasher, IHashAlgorithm blockHasher)
        {
            Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate));
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination));
            Contract.RequiresNonNull(coinbaseHasher, nameof(coinbaseHasher));
            Contract.RequiresNonNull(headerHasher, nameof(headerHasher));
            Contract.RequiresNonNull(blockHasher, nameof(blockHasher));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            this.poolConfig             = poolConfig;
            coin                        = poolConfig.Template.As <BitcoinTemplate>();
            networkParams               = coin.GetNetwork(network.NetworkType);
            txVersion                   = coin.CoinbaseTxVersion;
            this.network                = network;
            this.clock                  = clock;
            this.poolAddressDestination = poolAddressDestination;
            BlockTemplate               = blockTemplate;
            JobId                       = jobId;
            Difficulty                  = new Target(new NBitcoin.BouncyCastle.Math.BigInteger(BlockTemplate.Target, 16)).Difficulty;
            extraNoncePlaceHolderLength = BitcoinConstants.ExtranoncePlaceHolderLength;
            this.isPoS                  = isPoS;
            this.shareMultiplier        = shareMultiplier;

            txComment = !string.IsNullOrEmpty(extraPoolConfig?.CoinbaseTxComment) ?
                        extraPoolConfig.CoinbaseTxComment : coin.CoinbaseTxComment;

            if (coin.HasMasterNodes)
            {
                masterNodeParameters = BlockTemplate.Extra.SafeExtensionDataAs <MasterNodeBlockTemplateExtra>();

                if (!string.IsNullOrEmpty(masterNodeParameters.CoinbasePayload))
                {
                    txVersion = 3;
                    var txType = 5;
                    txVersion = txVersion + ((uint)(txType << 16));
                }
            }
            if (coin.HasCoinbasePayload)
            {
                coinbasepayloadParameters = BlockTemplate.Extra.SafeExtensionDataAs <CoinbasePayloadBlockTemplateExtra>();
            }

            if (coin.HasFounderFee)
            {
                FounderParameters = BlockTemplate.Extra.SafeExtensionDataAs <FounderBlockTemplateExtra>();
            }

            if (coin.HasCoinbaseDevReward)
            {
                CoinbaseDevRewardParams = BlockTemplate.Extra.SafeExtensionDataAs <CoinbaseDevRewardTemplateExtra>();
            }

            if (coin.HasTreasuryReward)
            {
                TreasuryParameters = BlockTemplate.Extra.SafeExtensionDataAs <TreasuryBlockTemplateExtra>();
            }

            if (coin.HasPayee)
            {
                payeeParameters = BlockTemplate.Extra.SafeExtensionDataAs <PayeeBlockTemplateExtra>();
            }

            this.coinbaseHasher = coinbaseHasher;
            this.headerHasher   = headerHasher;
            this.blockHasher    = blockHasher;

            if (!string.IsNullOrEmpty(BlockTemplate.Target))
            {
                blockTargetValue = new uint256(BlockTemplate.Target);
            }
            else
            {
                var tmp = new Target(BlockTemplate.Bits.HexToByteArray());
                blockTargetValue = tmp.ToUInt256();
            }

            previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash
                                           .HexToByteArray()
                                           .ReverseByteOrder()
                                           .ToHexString();

            BuildMerkleBranches();
            BuildCoinbase();

            jobParams = new object[]
            {
                JobId,
                previousBlockHashReversedHex,
                coinbaseInitialHex,
                coinbaseFinalHex,
                merkleBranchesHex,
                BlockTemplate.Version.ToStringHex8(),
                BlockTemplate.Bits,
                BlockTemplate.CurTime.ToStringHex8(),
                false
            };
        }
        /// <summary>
        /// Creates the test chain with some default blocks and txs.
        /// </summary>
        /// <param name="network">Network to create the chain on.</param>
        /// <param name="scriptPubKey">Public key to create blocks/txs with.</param>
        /// <returns>Context object representing the test chain.</returns>
        public static async Task <ITestChainContext> CreateAsync(Network network, Script scriptPubKey, string dataDir)
        {
            var nodeSettings = new NodeSettings(network, args: new string[] { $"-datadir={dataDir}" });

            ILoggerFactory    loggerFactory    = nodeSettings.LoggerFactory;
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            network.Consensus.Options = new ConsensusOptions();
            new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration().RegisterRules(network.Consensus);

            // Dont check PoW of a header in this test.
            network.Consensus.HeaderValidationRules.RemoveAll(x => x.GetType() == typeof(CheckDifficultyPowRule));

            var consensusSettings = new ConsensusSettings(nodeSettings);
            var chain             = new ConcurrentChain(network);
            var inMemoryCoinView  = new InMemoryCoinView(chain.Tip.HashBlock);

            var chainState  = new ChainState();
            var deployments = new NodeDeployments(network, chain);
            ConsensusRuleEngine consensusRules = new PowConsensusRuleEngine(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(),
                                                                            inMemoryCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider), new NodeStats(dateTimeProvider)).Register();

            ConsensusManager consensus = ConsensusManagerHelper.CreateConsensusManager(network, dataDir, chainState);

            var genesis = new ChainedHeader(network.GetGenesis().Header, network.GenesisHash, 0);

            chainState.BlockStoreTip = genesis;
            await consensus.InitializeAsync(genesis).ConfigureAwait(false);

            var blockPolicyEstimator = new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings);
            var mempool     = new TxMempool(dateTimeProvider, blockPolicyEstimator, loggerFactory, nodeSettings);
            var mempoolLock = new MempoolSchedulerLock();

            var minerSettings = new MinerSettings(nodeSettings);

            // Simple block creation, nothing special yet:
            var           blockDefinition = new PowBlockDefinition(consensus, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules);
            BlockTemplate newBlock        = blockDefinition.Build(chain.Tip, scriptPubKey);

            await consensus.BlockMinedAsync(newBlock.Block);

            List <BlockInfo> blockinfo = CreateBlockInfoList();

            // We can't make transactions until we have inputs therefore, load 100 blocks.
            var blocks = new List <Block>();
            var srcTxs = new List <Transaction>();

            for (int i = 0; i < blockinfo.Count; ++i)
            {
                Block currentBlock = Block.Load(newBlock.Block.ToBytes(network.Consensus.ConsensusFactory), network);
                currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock;
                currentBlock.Header.Version       = 1;
                currentBlock.Header.Time          = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1;

                Transaction txCoinbase = network.CreateTransaction(currentBlock.Transactions[0].ToBytes());
                txCoinbase.Inputs.Clear();
                txCoinbase.Version = 1;
                txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) })));
                // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                currentBlock.Transactions[0] = txCoinbase;

                if (srcTxs.Count < 4)
                {
                    srcTxs.Add(currentBlock.Transactions[0]);
                }

                currentBlock.UpdateMerkleRoot();

                currentBlock.Header.Nonce = blockinfo[i].nonce;

                chain.SetTip(currentBlock.Header);
            }

            // Just to make sure we can still make simple blocks
            blockDefinition = new PowBlockDefinition(consensus, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules);
            blockDefinition.Build(chain.Tip, scriptPubKey);

            var mempoolValidator = new MempoolValidator(mempool, mempoolLock, dateTimeProvider, new MempoolSettings(nodeSettings), chain, inMemoryCoinView, loggerFactory, nodeSettings, consensusRules);

            var outputs = new List <UnspentOutputs>();

            foreach (Transaction tx in srcTxs)
            {
                var output = new UnspentOutputs(0, tx);

                outputs.Add(output);
            }

            await inMemoryCoinView.SaveChangesAsync(outputs, new List <TxOut[]>(), chain.GetBlock(0).HashBlock, chain.GetBlock(1).HashBlock, chain.GetBlock(0).Height);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, SrcTxs = srcTxs
            });
        }
Example #20
0
    private AStarNode createRootNode(Vector2Int newCoordinate)
    {
        AStarNode     newNode   = ScriptableObject.CreateInstance <AStarNode>();
        BlockTemplate blockInfo = CombatExecutor.blockGrid[(int)newCoordinate.x, (int)newCoordinate.y].GetComponent <BlockTemplate>();

        float cheapestMove = 10000;

        if (characterInfo.CanWalk)
        {
            if (blockInfo.WalkCost < cheapestMove)
            {
                cheapestMove = blockInfo.WalkCost;
                newNode.move = FighterClass.CharacterPosition.Ground;
            }
        }
        if (characterInfo.CanSwim)
        {
            if (blockInfo.SwimCost < cheapestMove)
            {
                cheapestMove = blockInfo.SwimCost;
                newNode.move = FighterClass.CharacterPosition.Water;
            }
        }
        if (characterInfo.CanFly)
        {
            if (blockInfo.FlyCost < cheapestMove)
            {
                cheapestMove = blockInfo.FlyCost;
                newNode.move = FighterClass.CharacterPosition.Air;
            }
        }

        newNode.g = cheapestMove;
        float closestGoal = 10000;

        for (int goalIdx = 0; goalIdx < goalCoordinates.Count; goalIdx++)
        {
            Vector2Int goal     = goalCoordinates[goalIdx];
            float      distance = Mathf.Abs(goal.x - newCoordinate.x) + Mathf.Abs(goal.y - newCoordinate.y); //Mathf.Sqrt(Mathf.Pow((goal.x - newCoordinate.x), 2) + Mathf.Pow((goal.y - newCoordinate.y), 2));
            if (distance < closestGoal)
            {
                closestGoal = distance;
                if (distance == 0)
                {
                    finalGoalIdx = goalIdx;
                }
            }
            foreach (Vector2Int extPos in characterInfo.PotentialGridOccupation(newCoordinate))
            {
                distance = Mathf.Abs(goal.x - extPos.x) + Mathf.Abs(goal.y - extPos.y);
                if (distance < closestGoal)
                {
                    closestGoal = distance;
                    if (distance == 0)
                    {
                        finalGoalIdx = goalIdx;
                    }
                }
            }
        }

        newNode.h           = closestGoal;
        newNode.totalCost   = newNode.g + newNode.h;
        newNode.expanded    = false;
        newNode.coordinates = newCoordinate;
        newNode.parent      = new Vector2Int(-1, -1);
        return(newNode);
    }
    private void SetupTemplates()
    {
        blockTemplateList = new List <BlockTemplate>(7);
        BlockTemplate tempBT;



        //1
        tempBT = new BlockTemplate();
        tempBT.rotationOrigin = new Vector3(0.5f, 1.5f);
        tempBT.positions[0]   = new Vector3(0f, 0f);
        tempBT.positions[1]   = new Vector3(0f, 1f);
        tempBT.positions[2]   = new Vector3(0f, 2f);
        tempBT.positions[3]   = new Vector3(0f, 3f);
        blockTemplateList.Add(tempBT);

        //2
        tempBT = new BlockTemplate();
        tempBT.rotationOrigin = new Vector3(1f, 1f);
        tempBT.positions[0]   = new Vector3(0f, 0f);
        tempBT.positions[1]   = new Vector3(1f, 0f);
        tempBT.positions[2]   = new Vector3(1f, 1f);
        tempBT.positions[3]   = new Vector3(1f, 2f);
        blockTemplateList.Add(tempBT);
        //3
        tempBT = new BlockTemplate();
        tempBT.rotationOrigin = new Vector3(0f, 1f);
        tempBT.positions[0]   = new Vector3(0f, 0f);
        tempBT.positions[1]   = new Vector3(1f, 0f);
        tempBT.positions[2]   = new Vector3(0f, 1f);
        tempBT.positions[3]   = new Vector3(0f, 2f);
        blockTemplateList.Add(tempBT);
        //4
        tempBT = new BlockTemplate();
        tempBT.rotationOrigin = new Vector3(0.5f, 0.5f);
        tempBT.positions[0]   = new Vector3(0f, 0f);
        tempBT.positions[1]   = new Vector3(1f, 0f);
        tempBT.positions[2]   = new Vector3(0f, 1f);
        tempBT.positions[3]   = new Vector3(1f, 1f);
        blockTemplateList.Add(tempBT);
        //5
        tempBT = new BlockTemplate();
        tempBT.rotationOrigin = new Vector3(1f, 0f);
        tempBT.positions[0]   = new Vector3(0f, 0f);
        tempBT.positions[1]   = new Vector3(1f, 0f);
        tempBT.positions[2]   = new Vector3(1f, 1f);
        tempBT.positions[3]   = new Vector3(2f, 1f);
        blockTemplateList.Add(tempBT);
        //6
        tempBT = new BlockTemplate();
        tempBT.rotationOrigin = new Vector3(0f, 0f);
        tempBT.positions[0]   = new Vector3(0f, 0f);
        tempBT.positions[1]   = new Vector3(1f, 0f);
        tempBT.positions[2]   = new Vector3(-1f, 0f);
        tempBT.positions[3]   = new Vector3(0f, 1f);
        blockTemplateList.Add(tempBT);
        //7
        tempBT = new BlockTemplate();
        tempBT.rotationOrigin = new Vector3(0f, 0f);
        tempBT.positions[0]   = new Vector3(0f, 0f);
        tempBT.positions[1]   = new Vector3(1f, 0f);
        tempBT.positions[2]   = new Vector3(0f, 1f);
        tempBT.positions[3]   = new Vector3(-1f, 1f);
        blockTemplateList.Add(tempBT);
    }
Example #22
0
            public TestContext()
            {
                this.blockinfo = new List <Blockinfo>();
                var lst = blockinfoarr.Cast <long>().ToList();

                for (int i = 0; i < lst.Count; i += 2)
                {
                    this.blockinfo.Add(new Blockinfo()
                    {
                        extranonce = (int)lst[i], nonce = (uint)lst[i + 1]
                    });
                }

                // Note that by default, these tests run with size accounting enabled.
                this.network = Network.Main;
                var hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");

                this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG });
                this.newBlock     = new BlockTemplate();

                this.entry = new TestMemPoolEntryHelper();
                this.chain = new ConcurrentChain(this.network);
                this.network.Consensus.Options = new PowConsensusOptions();
                this.cachedCoinView            = new CachedCoinView(new InMemoryCoinView(this.chain.Tip.HashBlock), new LoggerFactory());
                this.consensus = new ConsensusLoop(new PowConsensusValidator(this.network), this.chain, this.cachedCoinView, new LookaheadBlockPuller(this.chain, new ConnectionManager(this.network, new NodeConnectionParameters(), new NodeSettings(), new LoggerFactory(), new NodeLifetime()), new LoggerFactory()), new NodeDeployments(this.network));
                this.consensus.Initialize();

                this.entry.Fee(11);
                this.entry.Height(11);
                var date1 = new MemoryPoolTests.DateTimeProviderSet();

                date1.time       = DateTimeProvider.Default.GetTime();
                date1.timeutc    = DateTimeProvider.Default.GetUtcNow();
                this.date        = date1;
                this.mempool     = new TxMempool(new FeeRate(1000), DateTimeProvider.Default, new BlockPolicyEstimator(new FeeRate(1000), NodeSettings.Default(), new LoggerFactory()), new LoggerFactory());;
                this.mempoolLock = new MempoolAsyncLock();

                // Simple block creation, nothing special yet:
                this.newBlock = AssemblerForTest(this).CreateNewBlock(this.scriptPubKey);
                this.chain.SetTip(this.newBlock.Block.Header);
                this.consensus.AcceptBlock(new ContextInformation(new BlockResult {
                    Block = this.newBlock.Block
                }, this.network.Consensus)
                {
                    CheckPow = false, CheckMerkleRoot = false
                });

                // We can't make transactions until we have inputs
                // Therefore, load 100 blocks :)
                this.baseheight = 0;
                List <Block> blocks = new List <Block>();

                this.txFirst = new List <Transaction>();
                for (int i = 0; i < this.blockinfo.Count; ++i)
                {
                    var pblock = this.newBlock.Block.Clone();                     // pointer for convenience
                    pblock.Header.HashPrevBlock = this.chain.Tip.HashBlock;
                    pblock.Header.Version       = 1;
                    pblock.Header.Time          = Utils.DateTimeToUnixTime(this.chain.Tip.GetMedianTimePast()) + 1;
                    Transaction txCoinbase = pblock.Transactions[0].Clone();
                    txCoinbase.Inputs.Clear();
                    txCoinbase.Version = 1;
                    txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(this.blockinfo[i].extranonce), Op.GetPushOp(this.chain.Height) })));
                    // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                    txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                    pblock.Transactions[0] = txCoinbase;

                    if (this.txFirst.Count == 0)
                    {
                        this.baseheight = this.chain.Height;
                    }
                    if (this.txFirst.Count < 4)
                    {
                        this.txFirst.Add(pblock.Transactions[0]);
                    }
                    pblock.UpdateMerkleRoot();

                    pblock.Header.Nonce = this.blockinfo[i].nonce;

                    this.chain.SetTip(pblock.Header);
                    this.consensus.AcceptBlock(new ContextInformation(new BlockResult {
                        Block = pblock
                    }, this.network.Consensus)
                    {
                        CheckPow = false, CheckMerkleRoot = false
                    });
                    blocks.Add(pblock);
                }

                // Just to make sure we can still make simple blocks
                this.newBlock = AssemblerForTest(this).CreateNewBlock(this.scriptPubKey);
                Assert.NotNull(this.newBlock);
            }
Example #23
0
        protected async Task <ChainedHeader> MineBlockAtTimestampAsync(uint timestamp)
        {
            ChainedHeader tip = this.consensusManager.Tip;

            // Timestamp should always be greater than prev one.
            if (timestamp <= tip.Header.Time)
            {
                // Can happen only when target spacing had crazy low value or key was compromised and someone is mining with our key.
                this.logger.LogWarning("Somehow another block was connected with greater timestamp. Dropping current block.");
                this.logger.LogTrace("(-)[ANOTHER_BLOCK_CONNECTED]:null");
                return(null);
            }

            // If an address is specified for mining then preferentially use that.
            // The private key for this address is not used for block signing, so it can be any valid address.
            // Since it is known which miner mines in each block already it does not change the privacy level that every block mines to the same address.
            if (!string.IsNullOrWhiteSpace(this.poaSettings.MineAddress))
            {
                this.walletScriptPubKey = BitcoinAddress.Create(this.poaSettings.MineAddress, this.network).ScriptPubKey;
            }
            else
            {
                // Get the first address from the wallet. In a network with an account-based model the mined UTXOs should all be sent to a predictable address.
                if (this.walletScriptPubKey == null || this.walletScriptPubKey == Script.Empty)
                {
                    this.walletScriptPubKey = this.GetScriptPubKeyFromWallet();

                    // The node could not have a wallet, or the first account/address could have been incorrectly created.
                    if (this.walletScriptPubKey == null)
                    {
                        this.logger.LogWarning("The miner wasn't able to get an address from the wallet, you will not receive any rewards (if no wallet exists, please create one).");
                        this.walletScriptPubKey = new Script();
                    }
                }
            }

            BlockTemplate blockTemplate = this.blockDefinition.Build(tip, this.walletScriptPubKey);

            this.FillBlockTemplate(blockTemplate, out bool dropTemplate);

            if (dropTemplate)
            {
                this.logger.LogTrace("(-)[DROPPED]:null");
                return(null);
            }

            blockTemplate.Block.Header.Time = timestamp;

            // Update merkle root.
            blockTemplate.Block.UpdateMerkleRoot();

            // Sign block with our private key.
            var header = blockTemplate.Block.Header as PoABlockHeader;

            this.poaHeaderValidator.Sign(this.federationManager.CurrentFederationKey, header);

            ChainedHeader chainedHeader = await this.consensusManager.BlockMinedAsync(blockTemplate.Block).ConfigureAwait(false);

            if (chainedHeader == null)
            {
                // Block wasn't accepted because we already connected block from the network.
                this.logger.LogTrace("(-)[FAILED_TO_CONNECT]:null");
                return(null);
            }

            ValidationContext result = this.integrityValidator.VerifyBlockIntegrity(chainedHeader, blockTemplate.Block);

            if (result.Error != null)
            {
                // Sanity check. Should never happen.
                this.logger.LogTrace("(-)[INTEGRITY_FAILURE]");
                throw new Exception(result.Error.ToString());
            }

            return(chainedHeader);
        }
Example #24
0
            public async Task InitializeAsync()
            {
                this.blockinfo = new List <Blockinfo>();
                List <long> lst = blockinfoarr.Cast <long>().ToList();

                for (int i = 0; i < lst.Count; i += 2)
                {
                    this.blockinfo.Add(new Blockinfo {
                        extranonce = (int)lst[i], nonce = (uint)lst[i + 1]
                    });
                }

                // Note that by default, these tests run with size accounting enabled.
                this.network = KnownNetworks.RegTest;
                byte[] hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
                this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG });

                this.entry = new TestMemPoolEntryHelper();
                this.chain = new ConcurrentChain(this.network);
                this.network.Consensus.Options = new ConsensusOptions();

                new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration().RegisterRules(this.network.Consensus);

                IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

                this.cachedCoinView = new CachedCoinView(new InMemoryCoinView(this.chain.Tip.HashBlock), dateTimeProvider, new LoggerFactory());

                var loggerFactory = new ExtendedLoggerFactory();

                loggerFactory.AddConsoleWithFilters();

                var nodeSettings      = new NodeSettings(args: new string[] { "-checkpoints" });
                var consensusSettings = new ConsensusSettings(nodeSettings);

                var networkPeerFactory = new NetworkPeerFactory(this.network, dateTimeProvider, loggerFactory, new PayloadProvider().DiscoverPayloads(), new SelfEndpointTracker(loggerFactory), new Mock <IInitialBlockDownloadState>().Object, new ConnectionManagerSettings());

                var peerAddressManager  = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory, new SelfEndpointTracker(loggerFactory));
                var peerDiscovery       = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, this.network, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager);
                var connectionSettings  = new ConnectionManagerSettings(nodeSettings);
                var selfEndpointTracker = new SelfEndpointTracker(loggerFactory);
                var connectionManager   = new ConnectionManager(dateTimeProvider, loggerFactory, this.network, networkPeerFactory,
                                                                nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { },
                                                                peerDiscovery, selfEndpointTracker, connectionSettings, new VersionProvider(), new Mock <INodeStats>().Object);

                var peerBanning = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, peerAddressManager);
                var deployments = new NodeDeployments(this.network, this.chain);

                var genesis = this.network.GetGenesis();

                var chainState = new ChainState()
                {
                    BlockStoreTip = new ChainedHeader(genesis.Header, genesis.GetHash(), 0)
                };

                this.ConsensusRules = new PowConsensusRuleEngine(this.network, loggerFactory, dateTimeProvider, this.chain, deployments, consensusSettings,
                                                                 new Checkpoints(), this.cachedCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider)).Register();

                this.consensus = ConsensusManagerHelper.CreateConsensusManager(this.network);
                await this.consensus.InitializeAsync(chainState.BlockStoreTip);

                this.entry.Fee(11);
                this.entry.Height(11);

                var dateTimeProviderSet = new MemoryPoolTests.DateTimeProviderSet
                {
                    time    = dateTimeProvider.GetTime(),
                    timeutc = dateTimeProvider.GetUtcNow()
                };

                this.DateTimeProvider = dateTimeProviderSet;
                this.mempool          = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings), loggerFactory, nodeSettings);
                this.mempoolLock      = new MempoolSchedulerLock();

                // We can't make transactions until we have inputs
                // Therefore, load 100 blocks :)
                this.baseheight = 0;
                var blocks = new List <Block>();

                this.txFirst = new List <Transaction>();

                this.nonce = 0;

                for (int i = 0; i < this.blockinfo.Count; ++i)
                {
                    Block block = this.network.CreateBlock();
                    block.Header.HashPrevBlock = this.chain.Tip.HashBlock;
                    block.Header.Version       = 1;
                    block.Header.Time          = Utils.DateTimeToUnixTime(this.chain.Tip.GetMedianTimePast()) + 1;

                    Transaction txCoinbase = this.network.CreateTransaction();
                    txCoinbase.Version = 1;
                    txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(this.blockinfo[i].extranonce), Op.GetPushOp(this.chain.Height) })));
                    // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                    txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                    block.AddTransaction(txCoinbase);

                    if (this.txFirst.Count == 0)
                    {
                        this.baseheight = this.chain.Height;
                    }

                    if (this.txFirst.Count < 4)
                    {
                        this.txFirst.Add(block.Transactions[0]);
                    }

                    block.Header.Bits = block.Header.GetWorkRequired(this.network, this.chain.Tip);

                    block.UpdateMerkleRoot();

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

                    // Serialization sets the BlockSize property.
                    block = Block.Load(block.ToBytes(), this.network);

                    await this.consensus.BlockMinedAsync(block);

                    blocks.Add(block);
                }

                // Just to make sure we can still make simple blocks
                this.newBlock = AssemblerForTest(this).Build(this.chain.Tip, this.scriptPubKey);
                Assert.NotNull(this.newBlock);
            }
Example #25
0
            public async Task InitializeAsync()
            {
                this.blockinfo = new List <Blockinfo>();
                List <long> lst = blockinfoarr.Cast <long>().ToList();

                for (int i = 0; i < lst.Count; i += 2)
                {
                    this.blockinfo.Add(new Blockinfo {
                        extranonce = (int)lst[i], nonce = (uint)lst[i + 1]
                    });
                }

                // Note that by default, these tests run with size accounting enabled.
                this.network = KnownNetworks.RegTest;
                byte[] hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
                this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG });

                this.entry        = new TestMemPoolEntryHelper();
                this.ChainIndexer = new ChainIndexer(this.network);
                this.network.Consensus.Options = new ConsensusOptions();

                IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

                var loggerFactory = ExtendedLoggerFactory.Create();

                var nodeSettings      = new NodeSettings(this.network, args: new string[] { "-checkpoints" });
                var consensusSettings = new ConsensusSettings(nodeSettings);

                var inMemoryCoinView = new InMemoryCoinView(new HashHeightPair(this.ChainIndexer.Tip));
                var nodeStats        = new NodeStats(dateTimeProvider, loggerFactory);

                this.cachedCoinView = new CachedCoinView(this.network, new Checkpoints(), inMemoryCoinView, dateTimeProvider, new LoggerFactory(), nodeStats, consensusSettings);

                var signals       = new Signals.Signals(loggerFactory, null);
                var asyncProvider = new AsyncProvider(loggerFactory, signals, new NodeLifetime());

                var deployments = new NodeDeployments(this.network, this.ChainIndexer);

                var genesis = this.network.GetGenesis();

                var chainState = new ChainState()
                {
                    BlockStoreTip = new ChainedHeader(genesis.Header, genesis.GetHash(), 0)
                };

                var consensusRulesContainer = new ConsensusRulesContainer();

                foreach (var ruleType in this.network.Consensus.ConsensusRules.HeaderValidationRules)
                {
                    consensusRulesContainer.HeaderValidationRules.Add(Activator.CreateInstance(ruleType) as HeaderValidationConsensusRule);
                }
                foreach (var ruleType in this.network.Consensus.ConsensusRules.FullValidationRules)
                {
                    FullValidationConsensusRule rule = null;
                    if (ruleType == typeof(FlushUtxosetRule))
                    {
                        rule = new FlushUtxosetRule(new Mock <IInitialBlockDownloadState>().Object);
                    }
                    else
                    {
                        rule = Activator.CreateInstance(ruleType) as FullValidationConsensusRule;
                    }

                    consensusRulesContainer.FullValidationRules.Add(rule);
                }

                this.ConsensusRules = new PowConsensusRuleEngine(this.network, loggerFactory, dateTimeProvider, this.ChainIndexer, deployments, consensusSettings,
                                                                 new Checkpoints(), this.cachedCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider), nodeStats, asyncProvider, consensusRulesContainer).SetupRulesEngineParent();

                this.consensus = ConsensusManagerHelper.CreateConsensusManager(this.network, chainState: chainState, inMemoryCoinView: inMemoryCoinView, chainIndexer: this.ChainIndexer, consensusRules: this.ConsensusRules);

                await this.consensus.InitializeAsync(chainState.BlockStoreTip);

                this.entry.Fee(11);
                this.entry.Height(11);

                var dateTimeProviderSet = new DateTimeProviderSet
                {
                    time    = dateTimeProvider.GetTime(),
                    timeutc = dateTimeProvider.GetUtcNow()
                };

                this.DateTimeProvider = dateTimeProviderSet;
                this.mempool          = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings), loggerFactory, nodeSettings);
                this.mempoolLock      = new MempoolSchedulerLock();

                // We can't make transactions until we have inputs
                // Therefore, load 100 blocks :)
                this.baseheight = 0;
                var blocks = new List <Block>();

                this.txFirst = new List <Transaction>();

                this.nonce = 0;

                for (int i = 0; i < this.blockinfo.Count; ++i)
                {
                    Block block = this.network.CreateBlock();
                    block.Header.HashPrevBlock = this.consensus.Tip.HashBlock;
                    block.Header.Version       = 1;
                    block.Header.Time          = Utils.DateTimeToUnixTime(this.ChainIndexer.Tip.GetMedianTimePast()) + 1;

                    Transaction txCoinbase = this.network.CreateTransaction();
                    txCoinbase.Version = 1;
                    txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(this.blockinfo[i].extranonce), Op.GetPushOp(this.ChainIndexer.Height) })));
                    // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                    txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                    block.AddTransaction(txCoinbase);

                    if (this.txFirst.Count == 0)
                    {
                        this.baseheight = this.ChainIndexer.Height;
                    }

                    if (this.txFirst.Count < 4)
                    {
                        this.txFirst.Add(block.Transactions[0]);
                    }

                    block.Header.Bits = block.Header.GetWorkRequired(this.network, this.ChainIndexer.Tip);

                    block.UpdateMerkleRoot();

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

                    // Serialization sets the BlockSize property.
                    block = Block.Load(block.ToBytes(), this.network.Consensus.ConsensusFactory);

                    var res = await this.consensus.BlockMinedAsync(block);

                    if (res == null)
                    {
                        throw new InvalidOperationException();
                    }

                    blocks.Add(block);
                }

                // Just to make sure we can still make simple blocks
                this.newBlock = AssemblerForTest(this).Build(this.ChainIndexer.Tip, this.scriptPubKey);
                Assert.NotNull(this.newBlock);
            }
Example #26
0
        /// <summary>
        /// Creates the test chain with some default blocks and txs.
        /// </summary>
        /// <param name="network">Network to create the chain on.</param>
        /// <param name="scriptPubKey">Public key to create blocks/txs with.</param>
        /// <returns>Context object representing the test chain.</returns>
        public static async Task <ITestChainContext> CreateAsync(Network network, Script scriptPubKey, string dataDir)
        {
            var nodeSettings = new NodeSettings(network, args: new string[] { $"-datadir={dataDir}" });

            ILoggerFactory    loggerFactory    = nodeSettings.LoggerFactory;
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            network.Consensus.Options = new ConsensusOptions();
            network.Consensus.Rules   = new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration().GetRules();

            var consensusSettings             = new ConsensusSettings(nodeSettings);
            var chain                         = new ConcurrentChain(network);
            InMemoryCoinView inMemoryCoinView = new InMemoryCoinView(chain.Tip.HashBlock);

            var cachedCoinView     = new CachedCoinView(inMemoryCoinView, DateTimeProvider.Default, loggerFactory);
            var networkPeerFactory = new NetworkPeerFactory(network, dateTimeProvider, loggerFactory, new PayloadProvider().DiscoverPayloads(), new SelfEndpointTracker());

            var peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory, new SelfEndpointTracker());
            var peerDiscovery      = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, network, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager);
            var connectionSettings = new ConnectionManagerSettings(nodeSettings);
            var connectionManager  = new ConnectionManager(dateTimeProvider, loggerFactory, network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery, connectionSettings, new VersionProvider());

            var            blockPuller    = new LookaheadBlockPuller(chain, connectionManager, new LoggerFactory());
            var            peerBanning    = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, peerAddressManager);
            var            deployments    = new NodeDeployments(network, chain);
            ConsensusRules consensusRules = new PowConsensusRules(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(), inMemoryCoinView, new Mock <ILookaheadBlockPuller>().Object).Register();
            var            consensusLoop  = new ConsensusLoop(new AsyncLoopFactory(loggerFactory), new NodeLifetime(), chain, cachedCoinView, blockPuller, deployments, loggerFactory, new ChainState(new InvalidBlockHashStore(dateTimeProvider)), connectionManager, dateTimeProvider, new Signals.Signals(), consensusSettings, nodeSettings, peerBanning, consensusRules);
            await consensusLoop.StartAsync();

            var blockPolicyEstimator = new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings);
            var mempool     = new TxMempool(dateTimeProvider, blockPolicyEstimator, loggerFactory, nodeSettings);
            var mempoolLock = new MempoolSchedulerLock();

            var minerSettings = new MinerSettings(nodeSettings);

            // Simple block creation, nothing special yet:
            PowBlockDefinition blockDefinition = new PowBlockDefinition(consensusLoop, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules);
            BlockTemplate      newBlock        = blockDefinition.Build(chain.Tip, scriptPubKey);

            chain.SetTip(newBlock.Block.Header);

            RuleContext ruleContext = consensusRules.CreateRuleContext(new ValidationContext {
                Block = newBlock.Block
            }, consensusLoop.Tip);

            ruleContext.MinedBlock = true;
            await consensusLoop.ValidateAndExecuteBlockAsync(ruleContext);

            List <BlockInfo> blockinfo = CreateBlockInfoList();

            // We can't make transactions until we have inputs
            // Therefore, load 100 blocks :)
            int baseheight = 0;
            var blocks     = new List <Block>();
            var srcTxs     = new List <Transaction>();

            for (int i = 0; i < blockinfo.Count; ++i)
            {
                Block currentBlock = Block.Load(newBlock.Block.ToBytes(network.Consensus.ConsensusFactory), network);
                currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock;
                currentBlock.Header.Version       = 1;
                currentBlock.Header.Time          = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1;

                Transaction txCoinbase = network.CreateTransaction(currentBlock.Transactions[0].ToBytes());
                txCoinbase.Inputs.Clear();
                txCoinbase.Version = 1;
                txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) })));
                // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                currentBlock.Transactions[0] = txCoinbase;

                if (srcTxs.Count == 0)
                {
                    baseheight = chain.Height;
                }
                if (srcTxs.Count < 4)
                {
                    srcTxs.Add(currentBlock.Transactions[0]);
                }

                currentBlock.UpdateMerkleRoot();

                currentBlock.Header.Nonce = blockinfo[i].nonce;

                chain.SetTip(currentBlock.Header);
                RuleContext ruleContextForBlock = consensusRules.CreateRuleContext(new ValidationContext {
                    Block = currentBlock
                }, consensusLoop.Tip);
                ruleContextForBlock.MinedBlock = true;
                await consensusLoop.ValidateAndExecuteBlockAsync(ruleContextForBlock);

                blocks.Add(currentBlock);
            }

            // Just to make sure we can still make simple blocks
            blockDefinition = new PowBlockDefinition(consensusLoop, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules);
            newBlock        = blockDefinition.Build(chain.Tip, scriptPubKey);

            var mempoolValidator = new MempoolValidator(mempool, mempoolLock, dateTimeProvider, new MempoolSettings(nodeSettings), chain, cachedCoinView, loggerFactory, nodeSettings, consensusRules);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, SrcTxs = srcTxs
            });
        }
Example #27
0
        /// <summary>
        /// Creates the test chain with some default blocks and txs.
        /// </summary>
        /// <param name="network">Network to create the chain on.</param>
        /// <param name="scriptPubKey">Public key to create blocks/txs with.</param>
        /// <returns>Context object representing the test chain.</returns>
        public static async Task <ITestChainContext> CreateAsync(Network network, Script scriptPubKey, string dataDir)
        {
            NodeSettings nodeSettings = new NodeSettings(network.Name, network).LoadArguments(new string[] { $"-datadir={dataDir}" });

            if (dataDir != null)
            {
                nodeSettings.DataDir = dataDir;
            }

            var loggerFactory = new ExtendedLoggerFactory();
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            network.Consensus.Options = new PowConsensusOptions();
            ConsensusSettings     consensusSettings  = new ConsensusSettings(nodeSettings, loggerFactory);
            PowConsensusValidator consensusValidator = new PowConsensusValidator(network, new Checkpoints(), dateTimeProvider, loggerFactory);
            ConcurrentChain       chain              = new ConcurrentChain(network);
            CachedCoinView        cachedCoinView     = new CachedCoinView(new InMemoryCoinView(chain.Tip.HashBlock), DateTimeProvider.Default, loggerFactory);
            NetworkPeerFactory    networkPeerFactory = new NetworkPeerFactory(network, dateTimeProvider, loggerFactory);

            var peerAddressManager = new PeerAddressManager(nodeSettings.DataFolder, loggerFactory);
            var peerDiscovery      = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, Network.PurpleMain, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager);
            var connectionManager  = new ConnectionManager(dateTimeProvider, loggerFactory, network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery);

            LookaheadBlockPuller blockPuller    = new LookaheadBlockPuller(chain, connectionManager, new LoggerFactory());
            PeerBanning          peerBanning    = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, nodeSettings);
            NodeDeployments      deployments    = new NodeDeployments(network, chain);
            ConsensusRules       consensusRules = new ConsensusRules(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints()).Register(new FullNodeBuilderConsensusExtension.CoreConsensusRules());
            ConsensusLoop        consensus      = new ConsensusLoop(new AsyncLoopFactory(loggerFactory), consensusValidator, new NodeLifetime(), chain, cachedCoinView, blockPuller, deployments, loggerFactory, new ChainState(new InvalidBlockHashStore(dateTimeProvider)), connectionManager, dateTimeProvider, new Signals.Signals(), consensusSettings, nodeSettings, peerBanning, consensusRules);
            await consensus.StartAsync();

            BlockPolicyEstimator blockPolicyEstimator = new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings);
            TxMempool            mempool     = new TxMempool(dateTimeProvider, blockPolicyEstimator, loggerFactory, nodeSettings);
            MempoolSchedulerLock mempoolLock = new MempoolSchedulerLock();

            // Simple block creation, nothing special yet:
            PowBlockAssembler blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider, loggerFactory);
            BlockTemplate     newBlock       = blockAssembler.CreateNewBlock(scriptPubKey);

            chain.SetTip(newBlock.Block.Header);
            await consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext {
                Block = newBlock.Block
            }, network.Consensus, consensus.Tip) { CheckPow = false, CheckMerkleRoot = false });

            List <BlockInfo> blockinfo = CreateBlockInfoList();

            // We can't make transactions until we have inputs
            // Therefore, load 100 blocks :)
            int                baseheight = 0;
            List <Block>       blocks     = new List <Block>();
            List <Transaction> srcTxs     = new List <Transaction>();

            for (int i = 0; i < blockinfo.Count; ++i)
            {
                Block currentBlock = newBlock.Block.Clone(); // pointer for convenience
                currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock;
                currentBlock.Header.Version       = 1;
                currentBlock.Header.Time          = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1;
                Transaction txCoinbase = currentBlock.Transactions[0].Clone();
                txCoinbase.Inputs.Clear();
                txCoinbase.Version = 1;
                txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) })));
                // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                currentBlock.Transactions[0] = txCoinbase;

                if (srcTxs.Count == 0)
                {
                    baseheight = chain.Height;
                }
                if (srcTxs.Count < 4)
                {
                    srcTxs.Add(currentBlock.Transactions[0]);
                }
                currentBlock.UpdateMerkleRoot();

                currentBlock.Header.Nonce = blockinfo[i].nonce;

                chain.SetTip(currentBlock.Header);
                await consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext {
                    Block = currentBlock
                }, network.Consensus, consensus.Tip) { CheckPow = false, CheckMerkleRoot = false });

                blocks.Add(currentBlock);
            }

            // Just to make sure we can still make simple blocks
            blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider, loggerFactory);
            newBlock       = blockAssembler.CreateNewBlock(scriptPubKey);

            MempoolValidator mempoolValidator = new MempoolValidator(mempool, mempoolLock, consensusValidator, dateTimeProvider, new MempoolSettings(nodeSettings), chain, cachedCoinView, loggerFactory, nodeSettings);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, SrcTxs = srcTxs
            });
        }
Example #28
0
            public async Task InitializeAsync()
            {
                this.blockinfo = new List <Blockinfo>();
                var lst = blockinfoarr.Cast <long>().ToList();

                for (int i = 0; i < lst.Count; i += 2)
                {
                    this.blockinfo.Add(new Blockinfo {
                        extranonce = (int)lst[i], nonce = (uint)lst[i + 1]
                    });
                }

                // Note that by default, these tests run with size accounting enabled.
                this.network = Network.Main;
                var hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");

                this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG });
                this.newBlock     = new BlockTemplate(this.network);

                this.entry = new TestMemPoolEntryHelper();
                this.chain = new ConcurrentChain(this.network);
                this.network.Consensus.Options = new PowConsensusOptions();
                IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

                this.cachedCoinView = new CachedCoinView(new InMemoryCoinView(this.chain.Tip.HashBlock), dateTimeProvider, new LoggerFactory());

                var loggerFactory = new ExtendedLoggerFactory();

                loggerFactory.AddConsoleWithFilters();

                NodeSettings nodeSettings      = new NodeSettings(args: new string[] { "-checkpoints" });
                var          consensusSettings = new ConsensusSettings().Load(nodeSettings);

                PowConsensusValidator consensusValidator = new PowConsensusValidator(this.network, new Checkpoints(), dateTimeProvider, loggerFactory);
                NetworkPeerFactory    networkPeerFactory = new NetworkPeerFactory(this.network, dateTimeProvider, loggerFactory, new PayloadProvider().DiscoverPayloads(), new SelfEndpointTracker());

                var peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory, new SelfEndpointTracker());
                var peerDiscovery      = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, Network.Main, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager);
                var connectionSettings = new ConnectionManagerSettings();

                connectionSettings.Load(nodeSettings);
                var connectionManager = new ConnectionManager(dateTimeProvider, loggerFactory, this.network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery, connectionSettings);

                LookaheadBlockPuller blockPuller    = new LookaheadBlockPuller(this.chain, connectionManager, new LoggerFactory());
                PeerBanning          peerBanning    = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, peerAddressManager);
                NodeDeployments      deployments    = new NodeDeployments(this.network, this.chain);
                ConsensusRules       consensusRules = new PowConsensusRules(this.network, loggerFactory, dateTimeProvider, this.chain, deployments, consensusSettings, new Checkpoints(), this.cachedCoinView, blockPuller).Register(new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration());

                this.consensus = new ConsensusLoop(new AsyncLoopFactory(loggerFactory), consensusValidator, new NodeLifetime(), this.chain, this.cachedCoinView, blockPuller, new NodeDeployments(this.network, this.chain), loggerFactory, new ChainState(new InvalidBlockHashStore(dateTimeProvider)), connectionManager, dateTimeProvider, new Signals.Signals(), consensusSettings, nodeSettings, peerBanning, consensusRules);
                await this.consensus.StartAsync();

                this.entry.Fee(11);
                this.entry.Height(11);
                var date1 = new MemoryPoolTests.DateTimeProviderSet();

                date1.time            = dateTimeProvider.GetTime();
                date1.timeutc         = dateTimeProvider.GetUtcNow();
                this.DateTimeProvider = date1;
                this.mempool          = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), new LoggerFactory(), nodeSettings), new LoggerFactory(), nodeSettings);
                this.mempoolLock      = new MempoolSchedulerLock();

                // Simple block creation, nothing special yet:
                this.newBlock = AssemblerForTest(this).Build(this.chain.Tip, this.scriptPubKey);
                this.chain.SetTip(this.newBlock.Block.Header);
                await this.consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext {
                    Block = this.newBlock.Block
                }, this.network.Consensus, this.consensus.Tip) { CheckPow = false, CheckMerkleRoot = false });

                // We can't make transactions until we have inputs
                // Therefore, load 100 blocks :)
                this.baseheight = 0;
                List <Block> blocks = new List <Block>();

                this.txFirst = new List <Transaction>();
                for (int i = 0; i < this.blockinfo.Count; ++i)
                {
                    var pblock = this.newBlock.Block.Clone(); // pointer for convenience
                    pblock.Header.HashPrevBlock = this.chain.Tip.HashBlock;
                    pblock.Header.Version       = 1;
                    pblock.Header.Time          = Utils.DateTimeToUnixTime(this.chain.Tip.GetMedianTimePast()) + 1;
                    Transaction txCoinbase = pblock.Transactions[0].Clone();
                    txCoinbase.Inputs.Clear();
                    txCoinbase.Version = 1;
                    txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(this.blockinfo[i].extranonce), Op.GetPushOp(this.chain.Height) })));
                    // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                    txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                    pblock.Transactions[0] = txCoinbase;

                    if (this.txFirst.Count == 0)
                    {
                        this.baseheight = this.chain.Height;
                    }
                    if (this.txFirst.Count < 4)
                    {
                        this.txFirst.Add(pblock.Transactions[0]);
                    }
                    pblock.UpdateMerkleRoot();

                    pblock.Header.Nonce = this.blockinfo[i].nonce;

                    this.chain.SetTip(pblock.Header);
                    await this.consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext {
                        Block = pblock
                    }, this.network.Consensus, this.consensus.Tip) { CheckPow = false, CheckMerkleRoot = false });

                    blocks.Add(pblock);
                }

                // Just to make sure we can still make simple blocks
                this.newBlock = AssemblerForTest(this).Build(this.chain.Tip, this.scriptPubKey);
                Assert.NotNull(this.newBlock);
            }
Example #29
0
        /// <summary>
        /// Creates the test chain with some default blocks and txs.
        /// </summary>
        /// <param name="network">Network to create the chain on.</param>
        /// <param name="scriptPubKey">Public key to create blocks/txs with.</param>
        /// <param name="requireStandard">By default testnet and regtest networks do not require transactions to be standard. This changes that default.</param>
        /// <returns>Context object representing the test chain.</returns>
        public static async Task <ITestChainContext> CreateAsync(Network network, Script scriptPubKey, string dataDir, bool requireStandard = true)
        {
            var nodeSettings = new NodeSettings(network, args: new string[] { $"-datadir={dataDir}" });

            ILoggerFactory    loggerFactory    = nodeSettings.LoggerFactory;
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            network.Consensus.Options = new ConsensusOptions();

            var consensusRulesContainer = new ConsensusRulesContainer();

            foreach (Type ruleType in network.Consensus.ConsensusRules.HeaderValidationRules)
            {
                // Don't check PoW of a header in this test.
                if (ruleType == typeof(CheckDifficultyPowRule))
                {
                    continue;
                }

                consensusRulesContainer.HeaderValidationRules.Add(Activator.CreateInstance(ruleType) as HeaderValidationConsensusRule);
            }
            foreach (Type ruleType in network.Consensus.ConsensusRules.PartialValidationRules)
            {
                consensusRulesContainer.PartialValidationRules.Add(Activator.CreateInstance(ruleType) as PartialValidationConsensusRule);
            }
            foreach (var ruleType in network.Consensus.ConsensusRules.FullValidationRules)
            {
                FullValidationConsensusRule rule = null;
                if (ruleType == typeof(FlushCoinviewRule))
                {
                    rule = new FlushCoinviewRule(new Mock <IInitialBlockDownloadState>().Object);
                }
                else
                {
                    rule = Activator.CreateInstance(ruleType) as FullValidationConsensusRule;
                }

                consensusRulesContainer.FullValidationRules.Add(rule);
            }

            var consensusSettings = new ConsensusSettings(nodeSettings);
            var chain             = new ChainIndexer(network);
            var inMemoryCoinView  = new InMemoryCoinView(new HashHeightPair(chain.Tip));

            var asyncProvider = new AsyncProvider(loggerFactory, new Mock <ISignals>().Object, new NodeLifetime());

            var chainState  = new ChainState();
            var deployments = new NodeDeployments(network, chain);

            ConsensusRuleEngine consensusRules = new PowConsensusRuleEngine(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(),
                                                                            inMemoryCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider), new NodeStats(dateTimeProvider, loggerFactory), asyncProvider, consensusRulesContainer).SetupRulesEngineParent();

            ConsensusManager consensus = ConsensusManagerHelper.CreateConsensusManager(network, dataDir, chainState, chainIndexer: chain, consensusRules: consensusRules, inMemoryCoinView: inMemoryCoinView);

            var genesis = new ChainedHeader(network.GetGenesis().Header, network.GenesisHash, 0);

            chainState.BlockStoreTip = genesis;
            await consensus.InitializeAsync(genesis).ConfigureAwait(false);

            var blockPolicyEstimator = new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings);
            var mempool     = new TxMempool(dateTimeProvider, blockPolicyEstimator, loggerFactory, nodeSettings);
            var mempoolLock = new MempoolSchedulerLock();

            var minerSettings = new MinerSettings(nodeSettings);

            // Simple block creation, nothing special yet:
            var           blockDefinition = new PowBlockDefinition(consensus, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules, deployments);
            BlockTemplate newBlock        = blockDefinition.Build(chain.Tip, scriptPubKey);

            await consensus.BlockMinedAsync(newBlock.Block);

            List <BlockInfo> blockinfo = CreateBlockInfoList();

            // We can't make transactions until we have inputs therefore, load 100 blocks.

            var srcTxs = new List <Transaction>();

            for (int i = 0; i < blockinfo.Count; ++i)
            {
                Block currentBlock = Block.Load(newBlock.Block.ToBytes(network.Consensus.ConsensusFactory), network.Consensus.ConsensusFactory);
                currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock;
                currentBlock.Header.Version       = 1;
                currentBlock.Header.Time          = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1;

                Transaction txCoinbase = network.CreateTransaction(currentBlock.Transactions[0].ToBytes());
                txCoinbase.Inputs.Clear();
                txCoinbase.Version = 1;
                txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) })));
                // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
                txCoinbase.AddOutput(new TxOut(Money.Zero, new Script()));
                currentBlock.Transactions[0] = txCoinbase;

                currentBlock.UpdateMerkleRoot();
                currentBlock.Header.Nonce = blockinfo[i].nonce;

                chain.SetTip(currentBlock.Header);
                srcTxs.Add(currentBlock.Transactions[0]);

                inMemoryCoinView.SaveChanges(new List <UnspentOutput>()
                {
                    new UnspentOutput(new OutPoint(currentBlock.Transactions[0], 0), new Coins((uint)(i + 1), currentBlock.Transactions[0].Outputs.First(), currentBlock.Transactions[0].IsCoinBase))
                }, new HashHeightPair(chain.Tip.Previous), new HashHeightPair(chain.Tip));
            }

            // Just to make sure we can still make simple blocks
            blockDefinition = new PowBlockDefinition(consensus, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules, deployments);
            blockDefinition.Build(chain.Tip, scriptPubKey);

            var mempoolSettings = new MempoolSettings(nodeSettings)
            {
                RequireStandard = requireStandard
            };

            // The mempool rule constructors aren't parameterless, so we have to manually inject the dependencies for every rule
            var mempoolRules = new List <MempoolRule>
            {
                new CheckConflictsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckCoinViewMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CreateMempoolEntryMempoolRule(network, mempool, mempoolSettings, chain, consensusRules, loggerFactory),
                new CheckSigOpsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckFeeMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckRateLimitMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckAncestorsMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckReplacementMempoolRule(network, mempool, mempoolSettings, chain, loggerFactory),
                new CheckAllInputsMempoolRule(network, mempool, mempoolSettings, chain, consensusRules, deployments, loggerFactory),
                new CheckTxOutDustRule(network, mempool, mempoolSettings, chain, loggerFactory),
            };

            // We also have to check that the manually instantiated rules match the ones in the network, or the test isn't valid
            for (int i = 0; i < network.Consensus.MempoolRules.Count; i++)
            {
                if (network.Consensus.MempoolRules[i] != mempoolRules[i].GetType())
                {
                    throw new Exception("Mempool rule type mismatch");
                }
            }

            Assert.Equal(network.Consensus.MempoolRules.Count, mempoolRules.Count);

            var mempoolValidator = new MempoolValidator(mempool, mempoolLock, dateTimeProvider, mempoolSettings, chain, inMemoryCoinView, loggerFactory, nodeSettings, consensusRules, mempoolRules, deployments);

            return(new TestChainContext {
                MempoolValidator = mempoolValidator, MempoolSettings = mempoolSettings, ChainIndexer = chain, SrcTxs = srcTxs
            });
        }
Example #30
0
        public async Task MinerTestPackageSelectionAsync()
        {
            var context = new TestContext();
            await context.InitializeAsync();

            // Test the ancestor feerate transaction selection.
            var entry = new TestMemPoolEntryHelper();

            // Test that a medium fee transaction will be selected after a higher fee
            // rate package with a low fee rate parent.
            var tx = context.network.CreateTransaction();

            tx.AddInput(new TxIn(new OutPoint(context.txFirst[0].GetHash(), 0), new Script(OpcodeType.OP_1)));
            tx.AddOutput(new TxOut(new Money(5000000000L - 1000), new Script()));

            // This tx has a low fee: 1000 satoshis
            uint256 hashParentTx = tx.GetHash(); // save this txid for later use

            context.mempool.AddUnchecked(hashParentTx, entry.Fee(1000).Time(context.DateTimeProvider.GetTime()).SpendsCoinbase(true).FromTx(tx));

            // This tx has a medium fee: 10000 satoshis
            tx = context.network.CreateTransaction(tx.ToBytes());
            tx.Inputs[0].PrevOut.Hash = context.txFirst[1].GetHash();
            tx.Outputs[0].Value       = 5000000000L - 10000;
            uint256 hashMediumFeeTx = tx.GetHash();

            context.mempool.AddUnchecked(hashMediumFeeTx, entry.Fee(10000).Time(context.DateTimeProvider.GetTime()).SpendsCoinbase(true).FromTx(tx));

            // This tx has a high fee, but depends on the first transaction
            tx = context.network.CreateTransaction(tx.ToBytes());
            tx.Inputs[0].PrevOut.Hash = hashParentTx;
            tx.Outputs[0].Value       = 5000000000L - 1000 - 50000; // 50k satoshi fee
            uint256 hashHighFeeTx = tx.GetHash();

            context.mempool.AddUnchecked(hashHighFeeTx, entry.Fee(50000).Time(context.DateTimeProvider.GetTime()).SpendsCoinbase(false).FromTx(tx));

            BlockTemplate pblocktemplate = AssemblerForTest(context).Build(context.ChainIndexer.Tip, context.scriptPubKey);

            Assert.True(pblocktemplate.Block.Transactions[1].GetHash() == hashParentTx);
            Assert.True(pblocktemplate.Block.Transactions[2].GetHash() == hashHighFeeTx);
            Assert.True(pblocktemplate.Block.Transactions[3].GetHash() == hashMediumFeeTx);

            // Test that a package below the block min tx fee doesn't get included
            tx = context.network.CreateTransaction(tx.ToBytes());
            tx.Inputs[0].PrevOut.Hash = hashHighFeeTx;
            tx.Outputs[0].Value       = 5000000000L - 1000 - 50000; // 0 fee
            uint256 hashFreeTx = tx.GetHash();

            context.mempool.AddUnchecked(hashFreeTx, entry.Fee(0).FromTx(tx));
            int freeTxSize = tx.GetSerializedSize();

            // Calculate a fee on child transaction that will put the package just
            // below the block min tx fee (assuming 1 child tx of the same size).
            Money feeToUse = blockMinFeeRate.GetFee(2 * freeTxSize) - 1;

            tx = context.network.CreateTransaction(tx.ToBytes());
            tx.Inputs[0].PrevOut.Hash = hashFreeTx;
            tx.Outputs[0].Value       = 5000000000L - 1000 - 50000 - feeToUse;
            uint256 hashLowFeeTx = tx.GetHash();

            context.mempool.AddUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx));
            pblocktemplate = AssemblerForTest(context).Build(context.ChainIndexer.Tip, context.scriptPubKey);
            // Verify that the free tx and the low fee tx didn't get selected
            for (int i = 0; i < pblocktemplate.Block.Transactions.Count; ++i)
            {
                Assert.True(pblocktemplate.Block.Transactions[i].GetHash() != hashFreeTx);
                Assert.True(pblocktemplate.Block.Transactions[i].GetHash() != hashLowFeeTx);
            }

            // Test that packages above the min relay fee do get included, even if one
            // of the transactions is below the min relay fee
            // Remove the low fee transaction and replace with a higher fee transaction
            context.mempool.RemoveRecursive(tx);
            tx = context.network.CreateTransaction(tx.ToBytes());
            tx.Outputs[0].Value -= 2; // Now we should be just over the min relay fee
            hashLowFeeTx         = tx.GetHash();
            context.mempool.AddUnchecked(hashLowFeeTx, entry.Fee(feeToUse + 2).FromTx(tx));
            pblocktemplate = AssemblerForTest(context).Build(context.ChainIndexer.Tip, context.scriptPubKey);
            Assert.True(pblocktemplate.Block.Transactions[4].GetHash() == hashFreeTx);
            Assert.True(pblocktemplate.Block.Transactions[5].GetHash() == hashLowFeeTx);

            // Test that transaction selection properly updates ancestor fee
            // calculations as ancestor transactions get included in a block.
            // Add a 0-fee transaction that has 2 outputs.
            tx = context.network.CreateTransaction(tx.ToBytes());
            tx.Inputs[0].PrevOut.Hash = context.txFirst[2].GetHash();
            tx.AddOutput(Money.Zero, new Script());
            tx.Outputs[0].Value = 5000000000L - 100000000;
            tx.Outputs[1].Value = 100000000; // 1BTC output
            uint256 hashFreeTx2 = tx.GetHash();

            context.mempool.AddUnchecked(hashFreeTx2, entry.Fee(0).SpendsCoinbase(true).FromTx(tx));

            // This tx can't be mined by itself
            tx = context.network.CreateTransaction(tx.ToBytes());
            tx.Inputs[0].PrevOut.Hash = hashFreeTx2;
            tx.Outputs.RemoveAt(1);
            feeToUse            = blockMinFeeRate.GetFee(freeTxSize);
            tx.Outputs[0].Value = 5000000000L - 100000000 - feeToUse;
            uint256 hashLowFeeTx2 = tx.GetHash();

            context.mempool.AddUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx));
            pblocktemplate = AssemblerForTest(context).Build(context.ChainIndexer.Tip, context.scriptPubKey);

            // Verify that this tx isn't selected.
            for (int i = 0; i < pblocktemplate.Block.Transactions.Count; ++i)
            {
                Assert.True(pblocktemplate.Block.Transactions[i].GetHash() != hashFreeTx2);
                Assert.True(pblocktemplate.Block.Transactions[i].GetHash() != hashLowFeeTx2);
            }

            // This tx will be mineable, and should cause hashLowFeeTx2 to be selected
            // as well.
            tx = context.network.CreateTransaction(tx.ToBytes());
            tx.Inputs[0].PrevOut.N = 1;
            tx.Outputs[0].Value    = 100000000 - 10000; // 10k satoshi fee
            context.mempool.AddUnchecked(tx.GetHash(), entry.Fee(10000).FromTx(tx));
            pblocktemplate = AssemblerForTest(context).Build(context.ChainIndexer.Tip, context.scriptPubKey);
            Assert.True(pblocktemplate.Block.Transactions[8].GetHash() == hashLowFeeTx2);
        }
Example #31
0
        private static async Task ValidateBlock(TestChainContext testChainContext, BlockTemplate newBlock)
        {
            var res = await testChainContext.Consensus.BlockMinedAsync(newBlock.Block);

            Assert.NotNull(res);
        }
        public void GenerateBlocks_MultipleBlocks_ReturnsGeneratedBlocks()
        {
            this.ExecuteUsingNonProofOfStakeSettings(() =>
            {
                List <BlockValidationContext> callbackBlockValidationContexts = new List <BlockValidationContext>();
                ChainedHeader lastChainedHeader = null;
                this.consensusLoop.Setup(c => c.AcceptBlockAsync(It.IsAny <BlockValidationContext>()))
                .Callback <BlockValidationContext>((context) =>
                {
                    if (lastChainedHeader == null)
                    {
                        context.ChainedHeader = this.fixture.ChainedHeader1;
                        lastChainedHeader     = context.ChainedHeader;
                    }
                    else
                    {
                        context.ChainedHeader = this.fixture.ChainedHeader2;
                    }

                    this.chain.SetTip(context.ChainedHeader);
                    callbackBlockValidationContexts.Add(context);
                })
                .Returns(Task.CompletedTask);

                BlockTemplate blockTemplate  = this.CreateBlockTemplate(this.fixture.Block1);
                BlockTemplate blockTemplate2 = this.CreateBlockTemplate(this.fixture.Block2);

                this.chain.SetTip(this.chain.GetBlock(0));

                int attempts = 0;

                var blockBuilder = this.CreateProofOfWorkBlockBuilder();
                blockBuilder.Setup(b => b.Build(It.IsAny <ChainedHeader>(), It.Is <Script>(r => r == this.fixture.ReserveScript.ReserveFullNodeScript)))
                .Returns(() =>
                {
                    if (lastChainedHeader == null)
                    {
                        if (attempts == 10)
                        {
                            // sometimes the PoW nonce we generate in the fixture is not accepted resulting in an infinite loop. Retry.
                            this.fixture.Block1         = this.fixture.PrepareValidBlock(this.chain.Tip, 1, this.fixture.Key.ScriptPubKey);
                            this.fixture.ChainedHeader1 = new ChainedHeader(this.fixture.Block1.Header, this.fixture.Block1.GetHash(), this.chain.Tip);
                            this.fixture.Block2         = this.fixture.PrepareValidBlock(this.fixture.ChainedHeader1, 2, this.fixture.Key.ScriptPubKey);
                            this.fixture.ChainedHeader2 = new ChainedHeader(this.fixture.Block2.Header, this.fixture.Block2.GetHash(), this.fixture.ChainedHeader1);

                            blockTemplate  = CreateBlockTemplate(this.fixture.Block1);
                            blockTemplate2 = CreateBlockTemplate(this.fixture.Block2);
                            attempts       = 0;
                        }
                        attempts += 1;

                        return(blockTemplate);
                    }

                    return(blockTemplate2);
                });

                var miner       = this.CreateProofOfWorkMiner(blockBuilder.Object);
                var blockHashes = miner.GenerateBlocks(this.fixture.ReserveScript, 2, uint.MaxValue);

                Assert.NotEmpty(blockHashes);
                Assert.Equal(2, blockHashes.Count);
                Assert.Equal(callbackBlockValidationContexts[0].Block.GetHash(), blockHashes[0]);
                Assert.Equal(callbackBlockValidationContexts[1].Block.GetHash(), blockHashes[1]);
            });
        }
Example #33
0
        private void SyncDictionary()
        {
            // Sync the table with the dict
            mDictionary.ClearAttributes();
            mDictionary.ClearTemplates();

            foreach (DataGridViewColumn col in blockDetails.Columns)
            {
                mDictionary.AddAttribute(col.Name);
            }

            foreach ( DataGridViewRow row in blockDetails.Rows )
            {
                if (!row.IsNewRow)
                {
                    BlockTemplate t = new BlockTemplate();

                    foreach ( DataGridViewCell cell in row.Cells )
                    {
                        String name = cell.OwningColumn.Name;
                        char attrType = name[0];
                        object attrValue = null;

                        switch (attrType)
                        {
                            case 's':
                                try
                                {
                                    attrValue = Convert.ToString(cell.Value);
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(String.Format("Error converting cell {0}:{1} to string.", cell.RowIndex, cell.ColumnIndex));
                                    attrValue = String.Empty;
                                }
                                break;
                            case 'i':
                                try
                                {
                                    attrValue = Convert.ToInt32(cell.Value);
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(String.Format("Error converting cell {0}:{1} to int.", cell.RowIndex, cell.ColumnIndex));
                                    attrValue = 0;
                                }
                                break;
                            case 'f':
                                try
                                {
                                    attrValue = Convert.ToSingle(cell.Value);
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(String.Format("Error converting cell {0}:{1} to float.", cell.RowIndex, cell.ColumnIndex));
                                    attrValue = 0.0f;
                                }
                                break;
                            case 'b':
                                try
                                {
                                    attrValue = Convert.ToBoolean(cell.Value);
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(String.Format("Error converting cell {0}:{1} to boolean.", cell.RowIndex, cell.ColumnIndex));
                                    attrValue = false;
                                }
                                break;
                        }

                        t.SetAttribute(name, attrValue);
                    }

                    mDictionary.SetTemplate(t.GetAttribute<int>("iID"), t);
                }
            }
        }