コード例 #1
0
		//[Trait("UnitTest", "UnitTest")]
		public void CanCreateBrainAddress()
		{
			var repo = new NoSqlBlockRepository();
			var chain = new ConcurrentChain();

			Block b = new Block();
			b.Transactions.Add(new Transaction());
			b.Transactions.Add(new Transaction()
			{
				Outputs =
				{
					new TxOut(),
					new TxOut(Money.Zero,BitcoinAddress.Create("15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe"))
				}
			});
			b.UpdateMerkleRoot();
			repo.PutAsync(b).Wait();
			chain.SetTip(b.Header);


			MnemonicReference address = MnemonicReference.CreateAsync(chain, repo, 0, 1, 1).Result;
			MnemonicReference address2 = MnemonicReference.ParseAsync(chain, repo, Wordlist.English, address.ToString(Wordlist.English)).Result;
			Assert.Equal(address.ToString(), address2.ToString());


			chain = new ConcurrentChain(Network.Main);
			var block = Network.Main.GetGenesis();
			var mnemo = MnemonicReference.Create(chain, block.Transactions[0], block, 0);

		}
コード例 #2
0
ファイル: ChainTests.cs プロジェクト: crowar/NBitcoin
		public void CanLoadAndSaveConcurrentChain()
		{
			ConcurrentChain cchain = new ConcurrentChain();
			ConcurrentChain chain = new ConcurrentChain(Network.Main);
			AddBlock(chain);
			AddBlock(chain);
			AddBlock(chain);

			cchain.SetTip(chain);

			var bytes = cchain.ToBytes();
			cchain = new ConcurrentChain();
			cchain.Load(bytes);

			Assert.Equal(cchain.Tip, chain.Tip);
			Assert.NotNull(cchain.GetBlock(0));

			cchain = new ConcurrentChain(Network.TestNet);
			cchain.Load(cchain.ToBytes());
			Assert.NotNull(cchain.GetBlock(0));
		}
コード例 #3
0
        protected void AddBlocksToChain(ConcurrentChain chain, int blockAmount)
        {
            uint    nonce         = RandomUtils.GetUInt32();
            uint256 prevBlockHash = chain.Tip.HashBlock;

            (this.ruleContext as UtxoRuleContext).UnspentOutputSet = new UnspentOutputSet();
            (this.ruleContext as UtxoRuleContext).UnspentOutputSet.SetCoins(new UnspentOutputs[0]);

            for (int i = 0; i < blockAmount; i++)
            {
                Block       block       = chain.Network.Consensus.ConsensusFactory.CreateBlock();
                Transaction transaction = chain.Network.CreateTransaction();
                block.AddTransaction(transaction);
                block.UpdateMerkleRoot();
                block.Header.BlockTime     = new DateTimeOffset(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddDays(i));
                block.Header.HashPrevBlock = prevBlockHash;
                block.Header.Nonce         = nonce;
                chain.SetTip(block.Header);
                prevBlockHash = block.GetHash();
                (this.ruleContext as UtxoRuleContext).UnspentOutputSet.Update(transaction, i);
                this.lastAddedTransaction = transaction;
            }
        }
コード例 #4
0
        private static ConcurrentChain GenerateChainWithHeight(int blockAmount, Network network, Key key)
        {
            var chain         = new ConcurrentChain(network);
            var nonce         = RandomUtils.GetUInt32();
            var prevBlockHash = chain.Genesis.HashBlock;

            for (var i = 0; i < blockAmount; i++)
            {
                var         block     = network.Consensus.ConsensusFactory.CreateBlock();
                Transaction coinStake = CreateCoinStakeTransaction(network, key, chain.Height + 1, new uint256((ulong)12312312 + (ulong)i));

                block.AddTransaction(coinStake);
                block.UpdateMerkleRoot();
                block.Header.BlockTime     = new DateTimeOffset(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddDays(i));
                block.Header.HashPrevBlock = prevBlockHash;
                block.Header.Nonce         = nonce;

                chain.SetTip(block.Header);
                prevBlockHash = block.GetHash();
            }

            return(chain);
        }
コード例 #5
0
ファイル: ChainTests.cs プロジェクト: Lokad/BitcoinNet
        public void CanLoadAndSaveConcurrentChain()
        {
            var cchain = new ConcurrentChain();
            var chain  = new ConcurrentChain(Network.Main);

            AddBlock(chain);
            AddBlock(chain);
            AddBlock(chain);

            cchain.SetTip(chain);

            var bytes = cchain.ToBytes();

            cchain = new ConcurrentChain();
            cchain.Load(bytes, Consensus.Main.ConsensusFactory);

            Assert.Equal(cchain.Tip, chain.Tip);
            Assert.NotNull(cchain.GetBlock(0));

            cchain = new ConcurrentChain(Network.TestNet);
            cchain.Load(cchain.ToBytes(), Consensus.Main.ConsensusFactory);
            Assert.NotNull(cchain.GetBlock(0));
        }
コード例 #6
0
        public static ConcurrentChain GenerateChainWithBlockTimeAndHeight(int blockAmount, Network network, int incrementSeconds, uint nbits)
        {
            var chain         = new ConcurrentChain(network);
            var nonce         = RandomUtils.GetUInt32();
            var prevBlockHash = chain.Genesis.HashBlock;
            var blockTime     = Utils.UnixTimeToDateTime(chain.Genesis.Header.Time).UtcDateTime;

            for (var i = 0; i < blockAmount; i++)
            {
                var block = network.Consensus.ConsensusFactory.CreateBlock();
                block.AddTransaction(new Transaction());
                block.UpdateMerkleRoot();
                block.Header.BlockTime = new DateTimeOffset(blockTime);
                blockTime = blockTime.AddSeconds(incrementSeconds);
                block.Header.HashPrevBlock = prevBlockHash;
                block.Header.Nonce         = nonce;
                block.Header.Bits          = new Target(nbits);
                chain.SetTip(block.Header);
                prevBlockHash = block.GetHash();
            }

            return(chain);
        }
コード例 #7
0
ファイル: ChainTests.cs プロジェクト: glasgowdev/purple
        public void CanLoadAndSaveConcurrentChain()
        {
            ConcurrentChain cchain = new ConcurrentChain();
            ConcurrentChain chain  = new ConcurrentChain(Network.PurpleMain);

            AddBlock(chain);
            AddBlock(chain);
            AddBlock(chain);

            cchain.SetTip(chain);

            var bytes = cchain.ToBytes();

            cchain = new ConcurrentChain();
            cchain.Load(bytes);

            Assert.Equal(cchain.Tip, chain.Tip);
            Assert.NotNull(cchain.GetBlock(0));

            cchain = new ConcurrentChain(Network.PurpleTest);
            cchain.Load(cchain.ToBytes());
            Assert.NotNull(cchain.GetBlock(0));
        }
コード例 #8
0
        public void Mine(int blockCount)
        {
            List <Block>   blocks = new List <Block>();
            DateTimeOffset now    = DateTimeOffset.UtcNow;

            for (int i = 0; i < blockCount; i++)
            {
                uint  nonce = 0;
                Block block = new Block();
                block.Header.HashPrevBlock = _Chain.Tip.HashBlock;
                block.Header.Bits          = block.Header.GetWorkRequired(_Network, _Chain.Tip);
                block.Header.UpdateTime(now, _Network, _Chain.Tip);
                var coinbase = new Transaction();
                coinbase.AddInput(TxIn.CreateCoinbase(_Chain.Height + 1));
                coinbase.AddOutput(new TxOut(_Network.GetReward(_Chain.Height + 1), MinerScriptPubKey));
                block.AddTransaction(coinbase);
                foreach (var tx in _Transactions)
                {
                    block.AddTransaction(tx);
                }
                block.UpdateMerkleRoot();
                while (!block.CheckProofOfWork())
                {
                    block.Header.Nonce = ++nonce;
                }
                block.Header.CacheHashes();
                blocks.Add(block);
                _Transactions.Clear();
                _Chain.SetTip(block.Header);
            }

            foreach (var b in blocks)
            {
                _Blocks.Add(b.GetHash(), b);
            }
        }
コード例 #9
0
        public void CanEnumerateAfterChainedBlock()
        {
            var chain = new ConcurrentChain(this.network);

            this.AppendBlock(chain);
            ChainedHeader a = this.AppendBlock(chain);
            ChainedHeader b = this.AppendBlock(chain);
            ChainedHeader c = this.AppendBlock(chain);

            Assert.True(chain.EnumerateAfter(a).SequenceEqual(new[] { b, c }));

            ChainedHeader d = this.AppendBlock(chain);

            IEnumerator <ChainedHeader> enumerator = chain.EnumerateAfter(b).GetEnumerator();

            enumerator.MoveNext();
            Assert.True(enumerator.Current == c);

            chain.SetTip(b);
            ChainedHeader cc = this.AppendBlock(chain);
            ChainedHeader dd = this.AppendBlock(chain);

            Assert.False(enumerator.MoveNext());
        }
コード例 #10
0
        public BestChainSelectorTest()
        {
            this.chainedHeaders = new List <ChainedHeader>();
            var chain = new ConcurrentChain(Network.StratisMain);

            for (int i = 0; i < 20; ++i)
            {
                var header = new BlockHeader()
                {
                    Nonce         = RandomUtils.GetUInt32(),
                    HashPrevBlock = chain.Tip.HashBlock,
                    Bits          = Target.Difficulty1
                };

                var chainedHeader = new ChainedHeader(header, header.GetHash(), chain.Tip);

                chain.SetTip(chainedHeader);

                this.chainedHeaders.Add(chainedHeader);
            }

            // Let block #5 be the consensus tip.
            this.chainState = new Mock <IChainState>().SetupProperty(x => x.ConsensusTip, this.chainedHeaders[5]);
        }
コード例 #11
0
        public void CanEnumerateAfterChainedBlock()
        {
            ConcurrentChain chain = new ConcurrentChain(Network.Main);

            AppendBlock(chain);
            var a = AppendBlock(chain);
            var b = AppendBlock(chain);
            var c = AppendBlock(chain);

            Assert.True(chain.EnumerateAfter(a).SequenceEqual(new[] { b, c }));

            var d = AppendBlock(chain);

            var enumerator = chain.EnumerateAfter(b).GetEnumerator();

            enumerator.MoveNext();
            Assert.True(enumerator.Current == c);

            chain.SetTip(b);
            var cc = AppendBlock(chain);
            var dd = AppendBlock(chain);

            Assert.False(enumerator.MoveNext());
        }
コード例 #12
0
        /// <summary>Creates the and attaches a new <see cref="ConsensusManagerBehavior"/>.</summary>
        /// <param name="consensusTip">Consensus tip.</param>
        /// <param name="cache">List of cached headers with which behavior is initialized.</param>
        /// <param name="bestReceivedTip">Behavior's expected tip's initial value.</param>
        /// <param name="peerState">Peer connection state returned by the <see cref="INetworkPeer.State"/>.</param>
        /// <param name="connectNewHeadersMethod">Method which is invoked when behavior calls <see cref="IConsensusManager.HeadersPresented"/>.</param>
        /// <returns></returns>
        public ConsensusManagerBehavior CreateAndAttachBehavior(ChainedHeader consensusTip, List <BlockHeader> cache = null,
                                                                ChainedHeader bestReceivedTip = null, NetworkPeerState peerState = NetworkPeerState.HandShaked,
                                                                Func <List <BlockHeader>, bool, ConnectNewHeadersResult> connectNewHeadersMethod = null)
        {
            // Chain
            var chain = new ConcurrentChain(KnownNetworks.StratisMain);

            chain.SetTip(consensusTip);

            // Ibd
            var ibdState = new Mock <IInitialBlockDownloadState>();

            ibdState.Setup(x => x.IsInitialBlockDownload()).Returns(() => this.IsIBD);

            // Consensus manager
            var cmMock = new Mock <IConsensusManager>();

            cmMock.Setup(x => x.HeadersPresented(It.IsAny <INetworkPeer>(), It.IsAny <List <BlockHeader> >(), It.IsAny <bool>()))
            .Returns((INetworkPeer p, List <BlockHeader> presentedHeaders, bool triggerDownload) =>
            {
                this.HeadersPresentedCalledTimes++;

                return(connectNewHeadersMethod?.Invoke(presentedHeaders, triggerDownload));
            });

            cmMock.Setup(x => x.Tip).Returns(consensusTip);

            this.testPeerBanning = new TestPeerBanning();

            var connectionManagerMock = new Mock <IConnectionManager>();

            connectionManagerMock.SetupGet(x => x.ConnectionSettings).Returns(new ConnectionManagerSettings(new NodeSettings(KnownNetworks.StratisMain)));

            var cmBehavior = new ConsensusManagerBehavior(chain, ibdState.Object, cmMock.Object, this.testPeerBanning, this.loggerFactory);

            // Peer and behavior
            this.PeerMock = this.CreatePeerMock();

            cmBehavior.Attach(this.PeerMock.Object);

            this.PeerMock.Setup(x => x.Behavior <ConsensusManagerBehavior>()).Returns(() => cmBehavior);
            this.PeerMock.Setup(x => x.State).Returns(peerState);

            if (bestReceivedTip != null)
            {
                cmBehavior.SetPrivatePropertyValue(nameof(cmBehavior.BestReceivedTip), bestReceivedTip);
                cmBehavior.SetPrivatePropertyValue(nameof(cmBehavior.BestSentHeader), bestReceivedTip);
            }

            if (cache != null)
            {
                cmBehavior.SetPrivateVariableValue("cachedHeaders", cache);
            }

            this.GetHeadersPayloadSentTimes = 0;
            this.HeadersPayloadsSent        = new List <HeadersPayload>();
            this.GetHeadersPayloadsSent     = new List <GetHeadersPayload>();

            this.PeerMock.Setup(x => x.SendMessageAsync(It.IsAny <Payload>(), It.IsAny <CancellationToken>())).Returns((Payload payload, CancellationToken token) =>
            {
                if (payload is GetHeadersPayload getHeadersPayload)
                {
                    this.GetHeadersPayloadSentTimes++;
                    this.GetHeadersPayloadsSent.Add(getHeadersPayload);
                }

                if (payload is HeadersPayload headersPayload)
                {
                    this.HeadersPayloadsSent.Add(headersPayload);
                }

                return(Task.CompletedTask);
            });

            this.PeerMock.Setup(x => x.SendMessage(It.IsAny <Payload>())).Callback((Payload payload) =>
            {
                if (payload is GetHeadersPayload getHeadersPayload)
                {
                    this.GetHeadersPayloadSentTimes++;
                    this.GetHeadersPayloadsSent.Add(getHeadersPayload);
                }

                if (payload is HeadersPayload headersPayload)
                {
                    this.HeadersPayloadsSent.Add(headersPayload);
                }
            });

            return(cmBehavior);
        }
コード例 #13
0
        public void CanFindFork()
        {
            var chain1 = new ConcurrentChain(this.network);

            // Create the main chain with a commonChainSize blocks before the fork.
            int commonChainSize = 150000;

            for (int i = 0; i < commonChainSize; i++)
            {
                this.AppendBlock(chain1);
            }

            ChainedHeader fork = this.AppendBlock(chain1);

            // Add some blocks from the fork point to the tip.
            int chain1AppendixSize = 100;

            for (int i = 0; i < chain1AppendixSize; i++)
            {
                this.AppendBlock(chain1);
            }

            // Tip of the chain1.
            ChainedHeader chain1Tip = chain1.Tip;

            {
                // Test scenario 1:
                // chain2 is empty, so the fork point is supposed to be the Genesis.
                var chain2 = new ConcurrentChain(this.network);
                this.AssertFork(chain1, chain2, chain1.Genesis);
            }

            {
                // Test scenario 2:
                // chain2 is a chain on another network, null expected.
                var chain2 = new ConcurrentChain(this.networkTest);
                this.AssertFork(chain1, chain2, null);
            }

            {
                // Test scenario 3:
                // chain2 is a subset of chain1 and stops at the fork point "c", fork point expected.
                var chain2 = new ConcurrentChain(this.network);
                chain2.SetTip(fork);
                this.AssertFork(chain1, chain2, fork);
            }

            {
                // Test scenario 4:
                // chain2 is a forked chain (at the fork point "c") that has other blocks on top of it, fork point expected.
                var chain2 = new ConcurrentChain(this.network);
                chain2.SetTip(fork);

                var chain2ForkDepth = 200;
                for (int i = 0; i < chain2ForkDepth; i++)
                {
                    this.AppendBlock(chain2);
                }

                this.AssertFork(chain1, chain2, fork);
            }

            {
                // Test scenario 5:
                // chain2 is at the same tip of chain1, no fork happened, tip point expected.
                var chain2 = new ConcurrentChain(this.network);
                chain2.SetTip(chain1Tip);
                this.AssertFork(chain1, chain2, chain1Tip);
            }
        }
コード例 #14
0
ファイル: Program.cs プロジェクト: nketha/SubbuRep
        static void Main(string[] args)
        {
            decimal subbuCoin1 = 0;
            decimal subbuCoin2 = 0;
            decimal sendAmount = 0;
            int     blockCount = 0;
            int     option     = 0;

            RandomUtils.Random = new UnsecureRandom();

            List <Transaction> transactionList = new List <Transaction>();
            DateTimeOffset     current         = DateTimeOffset.UtcNow;
            ConcurrentChain    chain           = new ConcurrentChain(Network.Main);

            Key subbuPrivateKey = new Key(); Key swethaPrivateKey = new Key();
            Key adityaPrivateKey = new Key(); Key kavyaPrivateKey = new Key();

            BitcoinSecret subbu  = subbuPrivateKey.GetBitcoinSecret(Network.Main);
            BitcoinSecret swetha = swethaPrivateKey.GetBitcoinSecret(Network.Main);
            BitcoinSecret aditya = adityaPrivateKey.GetBitcoinSecret(Network.Main);
            BitcoinSecret kavya  = kavyaPrivateKey.GetBitcoinSecret(Network.Main);

            Console.WriteLine("\n Enter first coin value:");
            subbuCoin1 = Convert.ToDecimal(Console.ReadLine());

            Console.WriteLine("\n Enter second coin value:");
            subbuCoin2 = Convert.ToDecimal(Console.ReadLine());

            decimal totalAmount = subbuCoin1 + subbuCoin2;

            Console.WriteLine("\n Total Coins Value: " + totalAmount);

            while (blockCount != 5)
            {
                while (option != 1)
                {
                    Console.WriteLine("\n Enter Send amount:");
                    sendAmount = Convert.ToDecimal(Console.ReadLine());
                    Transaction subbuFunding = new Transaction()
                    {
                        Outputs =

                        {
                            new TxOut(subbuCoin1.ToString(), subbu.GetAddress()),
                            new TxOut(subbuCoin2.ToString(), subbu.PubKey)
                        }
                    };
                    Coin[] subbuCoins = subbuFunding
                                        .Outputs
                                        .Select((o, i) => new Coin(new OutPoint(subbuFunding.GetHash(), i), o))
                                        .ToArray();
                    var txBuilder = new TransactionBuilder();

                    var tx = txBuilder
                             .AddCoins(subbuCoins)
                             .AddKeys(subbu.PrivateKey)
                             .Send(swetha.GetAddress(), sendAmount.ToString())
                             .SendFees("0.001")
                             .SetChange(subbu.GetAddress())
                             .BuildTransaction(true);
                    Console.WriteLine(tx);
                    Console.ReadLine();
                    transactionList.Add(tx);
                    Console.WriteLine("Press 1 for Mine block or 2 go to next transaction:");
                    option = int.Parse(Console.ReadLine());
                }
                chain.SetTip(CreateBlock(current, blockCount, transactionList, chain));
                blockCount++;
                option = 0;
            }
        }
コード例 #15
0
ファイル: ChainTests.cs プロジェクト: Lokad/BitcoinNet
        public void CanPersistMainchain()
        {
            var main = new ConcurrentChain(LoadMainChain(), Consensus.Main.ConsensusFactory);
            var ms   = new MemoryStream();

            main.WriteTo(ms);
            ms.Position = 0;
            main.SetTip(main.Genesis);
            main.Load(ms);
            Assert.True(main.Tip.HasHeader);

            var original = main;

            foreach (var options in new[]
            {
                new ConcurrentChain.ChainSerializationFormat
                {
                    SerializeBlockHeader = true,
                    SerializePrecomputedBlockHash = true
                },
                new ConcurrentChain.ChainSerializationFormat
                {
                    SerializeBlockHeader = true,
                    SerializePrecomputedBlockHash = false
                },
                new ConcurrentChain.ChainSerializationFormat
                {
                    SerializeBlockHeader = false,
                    SerializePrecomputedBlockHash = true
                }
            })
            {
                main = new ConcurrentChain();
                main.SetTip(original.Tip);
                ms = new MemoryStream();
                main.WriteTo(ms, options);
                ms.Position = 0;
                main.SetTip(main.Genesis);
                main.Load(ms, Consensus.Main.ConsensusFactory, options);
                Assert.Equal(options.SerializeBlockHeader, main.Tip.HasHeader);
                if (main.Tip.HasHeader)
                {
                    Assert.True(main.Tip.TryGetHeader(out var unused));
                }
                else
                {
                    Assert.False(main.Tip.TryGetHeader(out var unused));
                    Assert.Throws <InvalidOperationException>(() => main.Tip.Header);
                }

                Assert.Equal(original.Tip.HashBlock, main.Tip.HashBlock);
            }

            Assert.Throws <InvalidOperationException>(() =>
            {
                main.WriteTo(new MemoryStream(), new ConcurrentChain.ChainSerializationFormat
                {
                    SerializeBlockHeader          = false,
                    SerializePrecomputedBlockHash = false
                });
            });
        }
コード例 #16
0
ファイル: ChainTests.cs プロジェクト: crowar/NBitcoin
		public void CanForkBackward()
		{
			ConcurrentChain chain = new ConcurrentChain(Network.Main);
			AppendBlock(chain);
			AppendBlock(chain);
			var fork = AppendBlock(chain);

			//Test single block back fork
			var last = AppendBlock(chain);
			Assert.Equal(4, chain.Height);
			Assert.Equal(4, last.Height);
			Assert.Equal(last.HashBlock, chain.Tip.HashBlock);
			Assert.Equal(fork.HashBlock, chain.SetTip(fork).HashBlock);
			Assert.Equal(3, chain.Height);
			Assert.Equal(3, fork.Height);
			Assert.Equal(fork.HashBlock, chain.Tip.HashBlock);
			Assert.Null(chain.GetBlock(last.HashBlock));
			Assert.NotNull(chain.GetBlock(fork.HashBlock));

			//Test 3 blocks back fork
			var b1 = AppendBlock(chain);
			var b2 = AppendBlock(chain);
			last = AppendBlock(chain);
			Assert.Equal(6, chain.Height);
			Assert.Equal(6, last.Height);
			Assert.Equal(last.HashBlock, chain.Tip.HashBlock);

			Assert.Equal(fork.HashBlock, chain.SetTip(fork).HashBlock);
			Assert.Equal(3, chain.Height);
			Assert.Equal(3, fork.Height);
			Assert.Equal(fork.HashBlock, chain.Tip.HashBlock);
			Assert.Null(chain.GetBlock(last.HashBlock));
			Assert.Null(chain.GetBlock(b1.HashBlock));
			Assert.Null(chain.GetBlock(b2.HashBlock));

			chain.SetTip(last);
			Assert.Equal(6, chain.Height);
			Assert.Equal(6, last.Height);
			Assert.Equal(last.HashBlock, chain.Tip.HashBlock);
		}
コード例 #17
0
ファイル: transaction_tests.cs プロジェクト: knocte/NBitcoin
		public void CanGetMedianBlock()
		{
			ConcurrentChain chain = new ConcurrentChain(Network.Main);
			DateTimeOffset now = DateTimeOffset.UtcNow;
			chain.SetTip(CreateBlock(now, 0, chain));
			chain.SetTip(CreateBlock(now, -1, chain));
			chain.SetTip(CreateBlock(now, 1, chain));
			Assert.Equal(CreateBlock(now, 0).Header.BlockTime, chain.Tip.GetMedianTimePast()); // x -1 0 1
			chain.SetTip(CreateBlock(now, 2, chain));
			Assert.Equal(CreateBlock(now, 0).Header.BlockTime, chain.Tip.GetMedianTimePast()); // x -1 0 1 2
			chain.SetTip(CreateBlock(now, 3, chain));
			Assert.Equal(CreateBlock(now, 1).Header.BlockTime, chain.Tip.GetMedianTimePast()); // x -1 0 1 2 3
			chain.SetTip(CreateBlock(now, 4, chain));
			chain.SetTip(CreateBlock(now, 5, chain));
			chain.SetTip(CreateBlock(now, 6, chain));
			chain.SetTip(CreateBlock(now, 7, chain));
			chain.SetTip(CreateBlock(now, 8, chain));

			Assert.Equal(CreateBlock(now, 3).Header.BlockTime, chain.Tip.GetMedianTimePast()); // x -1 0 1 2 3 4 5 6 7 8

			chain.SetTip(CreateBlock(now, 9, chain));
			Assert.Equal(CreateBlock(now, 4).Header.BlockTime, chain.Tip.GetMedianTimePast()); // x -1 0 1 2 3 4 5 6 7 8 9
			chain.SetTip(CreateBlock(now, 10, chain));
			Assert.Equal(CreateBlock(now, 5).Header.BlockTime, chain.Tip.GetMedianTimePast()); // x -1 0 1 2 3 4 5 6 7 8 9 10
		}
コード例 #18
0
ファイル: ChainTests.cs プロジェクト: crowar/NBitcoin
		private ChainedBlock AddBlock(ConcurrentChain chain)
		{
			BlockHeader header = new BlockHeader();
			header.Nonce = RandomUtils.GetUInt32();
			header.HashPrevBlock = chain.Tip.HashBlock;
			chain.SetTip(header);
			return chain.GetBlock(header.GetHash());
		}
コード例 #19
0
ファイル: TestChainFactory.cs プロジェクト: glasgowdev/purple
        /// <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
            });
        }
コード例 #20
0
ファイル: ChainTests.cs プロジェクト: crowar/NBitcoin
		private ConcurrentChain CreateChain(BlockHeader genesis, int height)
		{
			var chain = new ConcurrentChain(genesis);
			for(int i = 0; i < height; i++)
			{
				var b = TestUtils.CreateFakeBlock();
				b.Header.HashPrevBlock = chain.Tip.HashBlock;
				chain.SetTip(b.Header);
			}
			return chain;
		}
コード例 #21
0
ファイル: ChainTests.cs プロジェクト: crowar/NBitcoin
		public void CanForkSidePartialChain()
		{
			var genesis = TestUtils.CreateFakeBlock();
			ConcurrentChain side = new ConcurrentChain(genesis.Header);
			ConcurrentChain main = new ConcurrentChain(genesis.Header);
			AppendBlock(side, main);
			AppendBlock(side, main);
			var common = AppendBlock(side, main);
			var sideb = AppendBlock(side);
			var mainb1 = AppendBlock(main);
			var mainb2 = AppendBlock(main);
			var mainb3 = AppendBlock(main);
			Assert.Equal(common.HashBlock, side.SetTip(main.Tip).HashBlock);
			Assert.NotNull(side.GetBlock(mainb1.HashBlock));
			Assert.NotNull(side.GetBlock(mainb2.HashBlock));
			Assert.NotNull(side.GetBlock(mainb3.HashBlock));
			Assert.NotNull(side.GetBlock(common.HashBlock));
			Assert.Null(side.GetBlock(sideb.HashBlock));

			Assert.Equal(common.HashBlock, side.SetTip(sideb).HashBlock);
			Assert.Null(side.GetBlock(mainb1.HashBlock));
			Assert.Null(side.GetBlock(mainb2.HashBlock));
			Assert.Null(side.GetBlock(mainb3.HashBlock));
			Assert.NotNull(side.GetBlock(sideb.HashBlock));
		}
コード例 #22
0
ファイル: ChainTests.cs プロジェクト: crowar/NBitcoin
		public void CanForkSide()
		{
			ConcurrentChain side = new ConcurrentChain(Network.Main);
			ConcurrentChain main = new ConcurrentChain(Network.Main);
			AppendBlock(side, main);
			AppendBlock(side, main);
			var common = AppendBlock(side, main);
			var sideb = AppendBlock(side);
			var mainb1 = AppendBlock(main);
			var mainb2 = AppendBlock(main);
			var mainb3 = AppendBlock(main);
			Assert.Equal(common.HashBlock, side.SetTip(main.Tip).HashBlock);
			Assert.NotNull(side.GetBlock(mainb1.HashBlock));
			Assert.NotNull(side.GetBlock(mainb2.HashBlock));
			Assert.NotNull(side.GetBlock(mainb3.HashBlock));
			Assert.NotNull(side.GetBlock(common.HashBlock));
			Assert.Null(side.GetBlock(sideb.HashBlock));

			Assert.Equal(common.HashBlock, side.SetTip(sideb).HashBlock);
			Assert.Null(side.GetBlock(mainb1.HashBlock));
			Assert.Null(side.GetBlock(mainb2.HashBlock));
			Assert.Null(side.GetBlock(mainb3.HashBlock));
			Assert.NotNull(side.GetBlock(sideb.HashBlock));
		}
コード例 #23
0
ファイル: NodeBuilder.cs プロジェクト: subhankarg/NTumbleBit
        public Block[] Generate(int blockCount, bool includeUnbroadcasted = true, bool broadcast = true)
        {
            var             rpc       = CreateRPCClient();
            BitcoinSecret   dest      = GetFirstSecret(rpc);
            var             bestBlock = rpc.GetBestBlockHash();
            ConcurrentChain chain     = null;
            List <Block>    blocks    = new List <Block>();
            DateTimeOffset  now       = MockTime == null ? DateTimeOffset.UtcNow : MockTime.Value;

#if !NOSOCKET
            using (var node = CreateNodeClient())
            {
                node.VersionHandshake();
                chain = bestBlock == node.Network.GenesisHash ? new ConcurrentChain(node.Network) : node.GetChain();
                for (int i = 0; i < blockCount; i++)
                {
                    uint  nonce = 0;
                    Block block = new Block();
                    block.Header.HashPrevBlock = chain.Tip.HashBlock;
                    block.Header.Bits          = block.Header.GetWorkRequired(rpc.Network, chain.Tip);
                    block.Header.UpdateTime(now, rpc.Network, chain.Tip);
                    var coinbase = new Transaction();
                    coinbase.AddInput(TxIn.CreateCoinbase(chain.Height + 1));
                    coinbase.AddOutput(new TxOut(rpc.Network.GetReward(chain.Height + 1), dest.GetAddress()));
                    block.AddTransaction(coinbase);
                    if (includeUnbroadcasted)
                    {
                        foreach (var tx in transactions.ToList())
                        {
                            if (tx.Inputs.Any(input => _ToMalleate.Contains(input.PrevOut.Hash)))
                            {
                                transactions.Remove(tx);
                            }
                        }
                        transactions = Reorder(transactions);
                        block.Transactions.AddRange(transactions);
                        for (int y = 0; y < block.Transactions.Count; y++)
                        {
                            if (_ToMalleate.Contains(block.Transactions[y].GetHash()))
                            {
                                block.Transactions[y] = DoMalleate(block.Transactions[y]);
                            }
                        }
                        transactions.Clear();
                        _ToMalleate.Clear();
                    }
                    block.UpdateMerkleRoot();
                    while (!block.CheckProofOfWork())
                    {
                        block.Header.Nonce = ++nonce;
                    }
                    blocks.Add(block);
                    chain.SetTip(block.Header);
                }
                if (broadcast)
                {
                    BroadcastBlocks(blocks.ToArray(), node);
                }
            }
            return(blocks.ToArray());
#endif
        }
コード例 #24
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();
            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
            });
        }
コード例 #25
0
            public TestContext()
            {
                Logs.Configure(new LoggerFactory());

                this.blockinfo = new List <Blockinfo>();
                var lst = blockinfoarr.Cast <long>().ToList();

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

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

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

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

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

                date1.time    = DateTimeProvider.Default.GetTime();
                date1.timeutc = DateTimeProvider.Default.GetUtcNow();
                date          = date1;
                mempool       = new TxMempool(new FeeRate(0), new NodeSettings());
                scheduler     = new MempoolScheduler();

                // Simple block creation, nothing special yet:
                newBlock = AssemblerForTest(this).CreateNewBlock(scriptPubKey);
                chain.SetTip(newBlock.Block.Header);
                consensus.AcceptBlock(new ContextInformation(new BlockResult {
                    Block = newBlock.Block
                }, 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>();

                txFirst = new List <Transaction>();
                for (int i = 0; i < blockinfo.Count; ++i)
                {
                    var pblock = newBlock.Block.Clone();                     // pointer for convenience
                    pblock.Header.HashPrevBlock = chain.Tip.HashBlock;
                    pblock.Header.Version       = 1;
                    pblock.Header.Time          = Utils.DateTimeToUnixTime(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(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()));
                    pblock.Transactions[0] = txCoinbase;

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

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

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

                // Just to make sure we can still make simple blocks
                newBlock = AssemblerForTest(this).CreateNewBlock(scriptPubKey);
                Assert.NotNull(newBlock);
            }
コード例 #26
0
ファイル: transaction_tests.cs プロジェクト: knocte/NBitcoin
		private void CanVerifySequenceLockCore(Sequence[] sequences, int[] prevHeights, int currentHeight, DateTimeOffset first, bool expected, SequenceLock expectedLock)
		{
			ConcurrentChain chain = new ConcurrentChain(new BlockHeader()
			{
				BlockTime = first
			});
			first = first + TimeSpan.FromMinutes(10);
			while(currentHeight != chain.Height)
			{
				chain.SetTip(new BlockHeader()
				{
					BlockTime = first,
					HashPrevBlock = chain.Tip.HashBlock
				});
				first = first + TimeSpan.FromMinutes(10);
			}
			Transaction tx = new Transaction();
			tx.Version = 2;
			for(int i = 0 ; i < sequences.Length ; i++)
			{
				TxIn input = new TxIn();
				input.Sequence = sequences[i];
				tx.Inputs.Add(input);
			}
			Assert.Equal(expected, tx.CheckSequenceLocks(prevHeights, chain.Tip));
			var actualLock = tx.CalculateSequenceLocks(prevHeights, chain.Tip);
			Assert.Equal(expectedLock.MinTime, actualLock.MinTime);
			Assert.Equal(expectedLock.MinHeight, actualLock.MinHeight);
		}
コード例 #27
0
ファイル: ChainTests.cs プロジェクト: crowar/NBitcoin
		public void CanEnumerateAfterChainedBlock()
		{
			ConcurrentChain chain = new ConcurrentChain(Network.Main);
			AppendBlock(chain);
			var a = AppendBlock(chain);
			var b = AppendBlock(chain);
			var c = AppendBlock(chain);

			Assert.True(chain.EnumerateAfter(a).SequenceEqual(new[] { b, c }));

			var d = AppendBlock(chain);

			var enumerator = chain.EnumerateAfter(b).GetEnumerator();
			enumerator.MoveNext();
			Assert.True(enumerator.Current == c);

			chain.SetTip(b);
			var cc = AppendBlock(chain);
			var dd = AppendBlock(chain);

			Assert.False(enumerator.MoveNext());
		}
コード例 #28
0
ファイル: ChainTests.cs プロジェクト: crowar/NBitcoin
		public void CanBuildConcurrentChain()
		{
			ConcurrentChain cchain = new ConcurrentChain();
			ConcurrentChain chain = new ConcurrentChain(Network.Main);
			Assert.Null(cchain.SetTip(chain.Tip));
			var b0 = cchain.Tip;
			Assert.Equal(cchain.Tip, chain.Tip);

			var b1 = AddBlock(chain);
			var b2 = AddBlock(chain);
			AddBlock(chain);
			AddBlock(chain);
			var b5 = AddBlock(chain);

			Assert.Equal(cchain.SetTip(chain.Tip), b0);
			Assert.Equal(cchain.Tip, chain.Tip);

			Assert.Equal(cchain.GetBlock(5), chain.Tip);
			Assert.Equal(cchain.GetBlock(b5.HashBlock), chain.Tip);

			Assert.Equal(cchain.SetTip(b1), b1);
			Assert.Equal(cchain.GetBlock(b5.HashBlock), null);
			Assert.Equal(cchain.GetBlock(b2.HashBlock), null);

			Assert.Equal(cchain.SetTip(b5), b1);
			Assert.Equal(cchain.GetBlock(b5.HashBlock), chain.Tip);

			chain.SetTip(b2);
			AddBlock(chain);
			AddBlock(chain);
			var b5b = AddBlock(chain);
			var b6b = AddBlock(chain);

			Assert.Equal(cchain.SetTip(b6b), b2);

			Assert.Equal(cchain.GetBlock(b5.HashBlock), null);
			Assert.Equal(cchain.GetBlock(b2.HashBlock), b2);
			Assert.Equal(cchain.GetBlock(6), b6b);
			Assert.Equal(cchain.GetBlock(5), b5b);
		}
コード例 #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>
        /// <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
            });
        }
コード例 #30
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
            });
        }
コード例 #31
0
        /// <summary>
        /// Attempts to connect to a full BitCoin node and request any missing block headers.
        /// </summary>
        private static async Task <Node> ConnectNodeAndSyncHeaders(ConcurrentChain chain, CancellationToken ct)
        {
            logger.DebugFormat("Connecting to full node...");

            ct.ThrowIfCancellationRequested();

            ManualResetEventSlim headersSyncedSignal = new ManualResetEventSlim();
            var parameters = new NodeConnectionParameters();

            parameters.IsRelay = false;

            var scanLocation = new BlockLocator();

            scanLocation.Blocks.Add(chain.Tip != null ? chain.Tip.HashBlock : _network.GetGenesis().GetHash());

            var node = Node.ConnectToLocal(_network, parameters);

            logger.DebugFormat("Connected to node " + node.RemoteSocketEndpoint + ".");

            node.MessageReceived += (node1, message) =>
            {
                ct.ThrowIfCancellationRequested();

                switch (message.Message.Payload)
                {
                case HeadersPayload hdr:

                    if (hdr.Headers != null && hdr.Headers.Count > 0)
                    {
                        logger.DebugFormat("Received {0} blocks start {1} to {2} height {3}.", hdr.Headers.Count, hdr.Headers.First().BlockTime, hdr.Headers.Last().BlockTime, chain.Height);

                        scanLocation.Blocks.Clear();
                        scanLocation.Blocks.Add(hdr.Headers.Last().GetHash());

                        if (hdr != null)
                        {
                            var tip = chain.Tip;
                            foreach (var header in hdr.Headers)
                            {
                                var prev = tip.FindAncestorOrSelf(header.HashPrevBlock);
                                if (prev == null)
                                {
                                    break;
                                }
                                tip = new ChainedBlock(header, header.GetHash(), prev);
                                chain.SetTip(tip);

                                ct.ThrowIfCancellationRequested();
                            }
                        }

                        var getHeadersPayload = new GetHeadersPayload(scanLocation);
                        node.SendMessageAsync(getHeadersPayload);
                    }
                    else
                    {
                        // Headers synchronised.
                        logger.DebugFormat("Block headers synchronised.");
                        headersSyncedSignal.Set();
                    }

                    break;

                case InvPayload inv:
                    logger.DebugFormat("Inventory items {0}, first type {1}.", inv.Count(), inv.First().Type);

                    if (inv.Any(x => x.Type == InventoryType.MSG_BLOCK))
                    {
                        // New block available.
                        var getHeadersPayload = new GetHeadersPayload(scanLocation);
                        node.SendMessage(getHeadersPayload);
                    }

                    break;

                case MerkleBlockPayload merkleBlk:
                    break;

                case TxPayload tx:
                    break;

                default:
                    logger.DebugFormat(message.Message.Command);
                    break;
                }
            };

            node.Disconnected += n =>
            {
                logger.DebugFormat("Node disconnected, chain height " + chain.Height + ".");
            };

            node.VersionHandshake(ct);
            node.PingPong(ct);

            logger.DebugFormat("Requesting block headers greater than height {0}.", chain.Height);
            node.SendMessage(new GetHeadersPayload(scanLocation));

            logger.DebugFormat("Bitcoin node connected.");

            await Task.Run(() => {
                headersSyncedSignal.Wait(ct);
            });

            return(node);
        }