Example #1
0
		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
		}
Example #2
0
		public BlockchainBuilder()
		{
			Chain = new ConcurrentChain(Network.TestNet);
			Mempool = new Dictionary<uint256, Transaction>();
			Blocks = new Dictionary<uint256, Block>();
			Broadcast = true;
		}
		//[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);

		}
Example #4
0
		public ChainBehavior(ConcurrentChain chain)
		{
			if(chain == null)
				throw new ArgumentNullException("chain");
			_Chain = chain;
			AutoSync = true;
			CanSync = true;
			CanRespondToGetHeaders = true;
		}
Example #5
0
		/// <summary>
		/// Create a new TrackerBehavior instance
		/// </summary>
		/// <param name="tracker">The Tracker registering transactions and confirmations</param>
		/// <param name="chain">The chain used to fetch height of incoming blocks, if null, use the chain of ChainBehavior</param>
		public TrackerBehavior(Tracker tracker, ConcurrentChain chain = null)
		{
			if(tracker == null)
				throw new ArgumentNullException("tracker");
			FalsePositiveRate = 0.000005;
			_Chain = chain;
			_ExplicitChain = chain;
			_Tracker = tracker;
		}
Example #6
0
		public void CanCloneConcurrentChain()
		{
			var chain = new ConcurrentChain(Network.Main);
			var common = AppendBlock(chain);
			var fork = AppendBlock(chain);
			var fork2 = AppendBlock(chain);

			Assert.True(chain.Tip == fork2);
			var clone = chain.Clone();
			Assert.True(clone.Tip == fork2);
		}
Example #7
0
		public void CanSaveChain()
		{
			ConcurrentChain chain = new ConcurrentChain(Network.Main);
			AppendBlock(chain);
			AppendBlock(chain);
			var fork = AppendBlock(chain);
			AppendBlock(chain);



			var chain2 = new ConcurrentChain(chain.ToBytes());
			Assert.True(chain.SameTip(chain2));
		}
Example #8
0
		protected override void AttachCore()
		{
			if(_Chain == null)
			{
				var chainBehavior = AttachedNode.Behaviors.Find<ChainBehavior>();
				if(chainBehavior == null)
					throw new InvalidOperationException("A chain should either be passed in the constructor of TrackerBehavior, or a ChainBehavior should be attached on the node");
				_Chain = chainBehavior.Chain;
			}
			if(AttachedNode.State == Protocol.NodeState.HandShaked)
				SetBloomFilter();
			AttachedNode.StateChanged += AttachedNode_StateChanged;
			AttachedNode.MessageReceived += AttachedNode_MessageReceived;
			Timer timer = new Timer(StartScan, null, 5000, 10000);
			RegisterDisposable(timer);
		}
Example #9
0
		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));
		}
Example #10
0
		public void CanBuildChain()
		{
			ConcurrentChain chain = new ConcurrentChain(Network.Main);
			AppendBlock(chain);
			AppendBlock(chain);
			AppendBlock(chain);
			var b = AppendBlock(chain);
			Assert.Equal(4, chain.Height);
			Assert.Equal(4, b.Height);
			Assert.Equal(b.HashBlock, chain.Tip.HashBlock);
		}
        public void CanImportMainChain()
        {
            using(var tester = CreateTester())
            {
                var node = tester.CreateLocalNode();
                var chain = new ConcurrentChain(tester.Client.Configuration.Network);

                node.ChainBuilder.Generate();
                var fork = node.ChainBuilder.Generate();
                var firstTip = node.ChainBuilder.Generate();
                tester.Indexer.IndexNodeMainChain();

                var result = tester.Client.GetChainChangesUntilFork(chain.Tip, true).ToList();
                Assert.Equal(result[0].BlockId, firstTip.GetHash());
                Assert.Equal(result.Last().BlockId, chain.Tip.HashBlock);
                Assert.Equal(result.Last().Height, chain.Tip.Height);
                Assert.Equal(result.Count, 4);

                result = tester.Client.GetChainChangesUntilFork(chain.Tip, false).ToList();
                Assert.Equal(result[0].BlockId, firstTip.GetHash());
                Assert.NotEqual(result.Last().BlockId, chain.Tip.HashBlock);
                Assert.Equal(result.Count, 3);

                Assert.Equal(firstTip.GetHash(), tester.Client.GetBestBlock().BlockId);

                result.UpdateChain(chain);

                Assert.Equal(firstTip.GetHash(), chain.Tip.HashBlock);

                node.ChainBuilder.Chain.SetTip(fork.Header);
                node.ChainBuilder.Generate();
                node.ChainBuilder.Generate();
                var secondTip = node.ChainBuilder.Generate();

                tester.Indexer.IndexNodeMainChain();
                Assert.Equal(secondTip.GetHash(), tester.Client.GetBestBlock().BlockId);

                result = tester.Client.GetChainChangesUntilFork(chain.Tip, false).ToList();
                result.UpdateChain(chain);
                Assert.Equal(secondTip.GetHash(), chain.Tip.HashBlock);

                var ultimateTip = node.ChainBuilder.Generate(100);
                tester.Indexer.IndexNodeMainChain();
                result = tester.Client.GetChainChangesUntilFork(chain.Tip, false).ToList();

                Assert.Equal(ultimateTip.Header.GetHash(), result[0].BlockId);
                Assert.Equal(tester.Client.GetBestBlock().BlockId, result[0].BlockId);
                result.UpdateChain(chain);
                Assert.Equal(ultimateTip.Header.GetHash(), chain.Tip.HashBlock);

                ConcurrentChain chain2 = new ConcurrentChain();
                var changes = tester.Client.GetChainChangesUntilFork(chain2.Tip, false);
                changes.UpdateChain(chain2);
                Assert.True(chain2.Tip.Height == chain.Tip.Height);
            }
        }
Example #12
0
		public static void Play()
		{
			for(int i = 0 ; i < 400000 ; i++)
			{
				var node = Node.Connect(Network.Main, "23.102.26.138:1273");
				node.StateChanged += (s, a) =>
				{
					if(node.State == NodeState.HandShaked)
					{
						ConcurrentChain chain = new ConcurrentChain(Network.Main);
						node.SynchronizeChain(chain);
					}
				};
				node.VersionHandshake();
				node.DisconnectAsync();
			}
			

			//Parallel.ForEach(Enumerable.Range(0, 10), _ =>
			//{
			//	ConcurrentChain chain = new ConcurrentChain(Network.Main);
			//	node.SynchronizeChain(chain);
			//});

			//Wallet wallet = new Wallet(new ExtKey(), Network.Main);
			//wallet.Connect(addrman: AddressManager.LoadPeerFile(@"E:\Program Files\Bitcoin\peers.dat", Network.Main));
			//while(true)
			//{
			//	Thread.Sleep(1000);
			//	Console.WriteLine(wallet.ConnectedNodes + " " + wallet.State);

			//}

			//var node = Node.ConnectToLocal(Network.Main);
			//node.VersionHandshake();
			//var chain = node.GetChain();
			//var v3 = chain.Tip
			//	.EnumerateToGenesis()
			//	.Take(1000)
			//	.Aggregate(0, (a, b) => b.Header.Version == 3 ? a+1 : a);

			//var r = (double)v3 / (double)1000;

			Stopwatch watch = new Stopwatch();
			watch.Start();
			System.Net.ServicePointManager.DefaultConnectionLimit = 100;
			System.Net.ServicePointManager.Expect100Continue = false;
			var repo = new QBitNinjaTransactionRepository("http://rapidbase-test.azurewebsites.net/");
			var colored = new OpenAsset.NoSqlColoredTransactionRepository(repo);


			var result = repo
				.Get("c3462373f1a722c66cbb1b93712df94aa7b3731f4142cd8413f10c9e872927de")
				.GetColoredTransaction(colored);
			watch.Stop();
			//for(int i = 0 ; i < 100 ; i++)
			//{
			//	using(var node = Node.ConnectToLocal(Network.Main))
			//	{
			//		node.VersionHandshake();
			//		var chain = new ConcurrentChain(Network.Main);
			//		node.SynchronizeChain(chain);
			//	}
			//}
		}
        public void BuildTransactionFeeTooLowThrowsWalletException()
        {
            Assert.Throws <WalletException>(() =>
            {
                var walletFeePolicy = new Mock <IWalletFeePolicy>();
                walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations()))
                .Returns(new FeeRate(0));

                Wallet wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
                (ExtKey ExtKey, string ExtPubKey)accountKeys = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
                (PubKey PubKey, BitcoinPubKeyAddress Address)spendingKeys    = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
                (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");
                (PubKey PubKey, BitcoinPubKeyAddress Address)changeKeys      = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "1/0");

                var address = new HdAddress
                {
                    Index        = 0,
                    HdPath       = $"m/44'/0'/0'/0/0",
                    Address      = spendingKeys.Address.ToString(),
                    Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                    ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                    Transactions = new List <TransactionData>()
                };

                var chain = new ConcurrentChain(wallet.Network);
                WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.Network, chain, address);

                wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
                {
                    Index             = 0,
                    Name              = "account1",
                    HdPath            = "m/44'/0'/0'",
                    ExtendedPubKey    = accountKeys.ExtPubKey,
                    ExternalAddresses = new List <HdAddress> {
                        address
                    },
                    InternalAddresses = new List <HdAddress>
                    {
                        new HdAddress {
                            Index        = 0,
                            HdPath       = $"m/44'/0'/0'/1/0",
                            Address      = changeKeys.Address.ToString(),
                            Pubkey       = changeKeys.PubKey.ScriptPubKey,
                            ScriptPubKey = changeKeys.Address.ScriptPubKey,
                            Transactions = new List <TransactionData>()
                        }
                    }
                });

                string dataDir    = "TestData/WalletTransactionHandlerTest/BuildTransactionFeeTooLowThrowsWalletException";
                var walletManager = new WalletManager(this.LoggerFactory.Object, this.network, chain, NodeSettings.Default(), new Mock <WalletSettings>().Object,
                                                      new DataFolder(new NodeSettings(args: new string[] { $"-datadir={dataDir}" }).DataDir), walletFeePolicy.Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);
                var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.network, this.standardTransactionPolicy);

                walletManager.Wallets.Add(wallet);

                var walletReference = new WalletAccountReference
                {
                    AccountName = "account1",
                    WalletName  = "myWallet1"
                };

                walletTransactionHandler.BuildTransaction(CreateContext(walletReference, "password", destinationKeys.PubKey.ScriptPubKey, new Money(7500), FeeType.Low, 0));
            });
        }
        internal static (ChainedBlock ChainedBlock, Block Block) AppendBlock(ChainedBlock previous, ConcurrentChain chain)
        {
            ChainedBlock last  = null;
            var          nonce = RandomUtils.GetUInt32();
            var          block = new Block();

            block.AddTransaction(new Transaction());
            block.UpdateMerkleRoot();
            block.Header.HashPrevBlock = previous == null ? chain.Tip.HashBlock : previous.HashBlock;
            block.Header.Nonce         = nonce;
            if (!chain.TrySetTip(block.Header, out last))
            {
                throw new InvalidOperationException("Previous not existing");
            }

            return(last, block);
        }
Example #15
0
		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);
		}
Example #16
0
 public WatchOnlyWalletFeature(IWatchOnlyWalletManager walletManager, Signals.Signals signals, ConcurrentChain chain)
 {
     this.walletManager = walletManager;
     this.signals       = signals;
 }
 public WalletSyncManager(ILoggerFactory loggerFactory, IWalletManager walletManager, ConcurrentChain chain, Network network)
 {
     this.walletManager = walletManager as WalletManager;
     this.chain         = chain;
     this.coinType      = (CoinType)network.Consensus.CoinType;
     this.logger        = loggerFactory.CreateLogger(this.GetType().FullName);
 }
Example #18
0
        /// <summary>
        /// Initializes an instance of the object.
        /// </summary>
        protected ConsensusRules(Network network, ILoggerFactory loggerFactory, IDateTimeProvider dateTimeProvider, ConcurrentChain chain, NodeDeployments nodeDeployments, ConsensusSettings consensusSettings, ICheckpoints checkpoints)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));
            Guard.NotNull(chain, nameof(chain));
            Guard.NotNull(nodeDeployments, nameof(nodeDeployments));
            Guard.NotNull(consensusSettings, nameof(consensusSettings));
            Guard.NotNull(checkpoints, nameof(checkpoints));

            this.Network            = network;
            this.DateTimeProvider   = dateTimeProvider;
            this.Chain              = chain;
            this.NodeDeployments    = nodeDeployments;
            this.loggerFactory      = loggerFactory;
            this.ConsensusSettings  = consensusSettings;
            this.Checkpoints        = checkpoints;
            this.ConsensusParams    = this.Network.Consensus;
            this.logger             = loggerFactory.CreateLogger(this.GetType().FullName);
            this.PerformanceCounter = new ConsensusPerformanceCounter(this.DateTimeProvider);

            this.consensusRules  = new Dictionary <string, ConsensusRuleDescriptor>();
            this.validationRules = new List <ConsensusRuleDescriptor>();
            this.executionRules  = new List <ConsensusRuleDescriptor>();
        }
Example #19
0
 /// <summary>
 /// Initializes an instance of the object.
 /// </summary>
 public PosConsensusRules(Network network, ILoggerFactory loggerFactory, IDateTimeProvider dateTimeProvider, ConcurrentChain chain, NodeDeployments nodeDeployments, ConsensusSettings consensusSettings, ICheckpoints checkpoints, CoinView utxoSet, ILookaheadBlockPuller puller, IStakeChain stakeChain, IStakeValidator stakeValidator)
     : base(network, loggerFactory, dateTimeProvider, chain, nodeDeployments, consensusSettings, checkpoints, utxoSet, puller)
 {
     this.StakeChain     = stakeChain;
     this.StakeValidator = stakeValidator;
 }
Example #20
0
 /// <summary>
 /// Initializes an instance of the object.
 /// </summary>
 public PowConsensusRules(Network network, ILoggerFactory loggerFactory, IDateTimeProvider dateTimeProvider, ConcurrentChain chain, NodeDeployments nodeDeployments, ConsensusSettings consensusSettings, ICheckpoints checkpoints, CoinView utxoSet, ILookaheadBlockPuller puller)
     : base(network, loggerFactory, dateTimeProvider, chain, nodeDeployments, consensusSettings, checkpoints)
 {
     this.UtxoSet = utxoSet;
     this.Puller  = puller;
 }
        public PosConsensusValidator(StakeValidator stakeValidator, ICheckpoints checkpoints, Network network, StakeChain stakeChain, ConcurrentChain chain, CoinView coinView, IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory)
            : base(network, checkpoints, dateTimeProvider, loggerFactory)
        {
            Guard.NotNull(network.Consensus.Option <PosConsensusOptions>(), nameof(network.Consensus.Options));

            this.logger           = loggerFactory.CreateLogger(this.GetType().FullName);
            this.stakeValidator   = stakeValidator;
            this.stakeChain       = stakeChain;
            this.chain            = chain;
            this.coinView         = coinView;
            this.consensusOptions = network.Consensus.Option <PosConsensusOptions>();
        }
 public LightWalletSyncManagerOverride(ILoggerFactory loggerFactory, IWalletManager walletManager, ConcurrentChain chain,
                                       Network network, IBlockNotification blockNotification, ISignals signals, INodeLifetime nodeLifetime, IAsyncLoopFactory asyncLoopFactory)
     : base(loggerFactory, walletManager, chain, network, blockNotification, signals, nodeLifetime, asyncLoopFactory)
 {
 }
Example #23
0
        /// <summary>
        /// Creates a proof of work block assembler.
        /// </summary>
        /// <param name="network">Network running on.</param>
        /// <param name="consensus">Consensus loop.</param>
        /// <param name="chain">Block chain.</param>
        /// <param name="mempoolLock">Async lock for memory pool.</param>
        /// <param name="mempool">Memory pool for transactions.</param>
        /// <param name="date">Date and time provider.</param>
        /// <returns>Proof of work block assembler.</returns>
        private static PowBlockAssembler CreatePowBlockAssembler(Network network, ConsensusLoop consensus, ConcurrentChain chain, MempoolSchedulerLock mempoolLock, TxMempool mempool, IDateTimeProvider date, LoggerFactory loggerFactory)
        {
            AssemblerOptions options = new AssemblerOptions();

            options.BlockMaxWeight = network.Consensus.Option <PowConsensusOptions>().MaxBlockWeight;
            options.BlockMaxSize   = network.Consensus.Option <PowConsensusOptions>().MaxBlockSerializedSize;

            FeeRate blockMinFeeRate = new FeeRate(PowMining.DefaultBlockMinTxFee);

            options.BlockMinFeeRate = blockMinFeeRate;

            return(new PowBlockAssembler(consensus, network, mempoolLock, mempool, date, chain.Tip, loggerFactory, options));
        }
Example #24
0
		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);
		}
 public BlockNotificationFeature(BlockNotification blockNotification, IConnectionManager connectionManager,
                                 LookaheadBlockPuller blockPuller, ChainState chainState, ConcurrentChain chain)
 {
     this.blockNotification = blockNotification;
     this.connectionManager = connectionManager;
     this.blockPuller       = blockPuller;
     this.chainState        = chainState;
     this.chain             = chain;
 }
Example #26
0
		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;
		}
 public WalletSyncManagerOverride(ILoggerFactory loggerFactory, IWalletManager walletManager, ConcurrentChain chain,
                                  Network network, IBlockStore blockStore, StoreSettings storeSettings, ISignals signals)
     : base(loggerFactory, walletManager, chain, network, blockStore, storeSettings, signals)
 {
 }
Example #28
0
 public ProvenHeadersBlockStoreBehavior(Network network, ConcurrentChain chain, IChainState chainState, ILoggerFactory loggerFactory, IConsensusManager consensusManager)
     : base(chain, chainState, loggerFactory, consensusManager)
 {
     this.network = Guard.NotNull(network, nameof(network));
 }
 /// <summary>
 /// Determines whether the chain is downloaded and up to date.
 /// </summary>
 /// <param name="chain">The chain.</param>
 public static bool IsDownloaded(this ConcurrentChain chain)
 {
     return(chain.Tip.Header.BlockTime.ToUnixTimeSeconds() > (DateTimeOffset.Now.ToUnixTimeSeconds() - TimeSpan.FromHours(1).TotalSeconds));
 }
        public void FundTransaction_Given__a_wallet_has_enough_inputs__When__adding_inputs_to_an_existing_transaction__Then__the_transaction_is_funded_successfully()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            Wallet wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");

            (ExtKey ExtKey, string ExtPubKey)accountKeys = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
            (PubKey PubKey, BitcoinPubKeyAddress Address)spendingKeys     = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys1 = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");
            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys2 = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/2");
            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys3 = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/3");

            var address = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = spendingKeys.Address.ToString(),
                Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            // wallet with 4 coinbase outputs of 50 = 200 Bitcoin
            var chain = new ConcurrentChain(wallet.Network);

            WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.Network, chain, address, 4);

            wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account1",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    address
                },
                InternalAddresses = new List <HdAddress>()
            });

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations())).Returns(new FeeRate(20000));
            var overrideFeeRate = new FeeRate(20000);

            var walletManager = new WalletManager(this.LoggerFactory.Object, this.network, chain, NodeSettings.Default(), new Mock <WalletSettings>().Object,
                                                  dataFolder, walletFeePolicy.Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);
            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.network, this.standardTransactionPolicy);

            walletManager.Wallets.Add(wallet);

            var walletReference = new WalletAccountReference
            {
                AccountName = "account1",
                WalletName  = "myWallet1"
            };

            // create a trx with 3 outputs 50 + 50 + 49 = 149 BTC
            var context = new TransactionBuildContext(walletReference,
                                                      new[]
            {
                new Recipient {
                    Amount = new Money(50, MoneyUnit.BTC), ScriptPubKey = destinationKeys1.PubKey.ScriptPubKey
                },
                new Recipient {
                    Amount = new Money(50, MoneyUnit.BTC), ScriptPubKey = destinationKeys2.PubKey.ScriptPubKey
                },
                new Recipient {
                    Amount = new Money(49, MoneyUnit.BTC), ScriptPubKey = destinationKeys3.PubKey.ScriptPubKey
                }
            }
                                                      .ToList(), "password")
            {
                MinConfirmations = 0,
                FeeType          = FeeType.Low
            };

            Transaction fundTransaction = walletTransactionHandler.BuildTransaction(context);

            Assert.Equal(4, fundTransaction.Inputs.Count);  // 4 inputs
            Assert.Equal(4, fundTransaction.Outputs.Count); // 3 outputs with change

            // remove the change output
            fundTransaction.Outputs.Remove(fundTransaction.Outputs.First(f => f.ScriptPubKey == context.ChangeAddress.ScriptPubKey));
            // remove 3 inputs they will be added back by fund transaction
            fundTransaction.Inputs.RemoveAt(3);
            fundTransaction.Inputs.RemoveAt(2);
            fundTransaction.Inputs.RemoveAt(1);
            Assert.Single(fundTransaction.Inputs); // 4 inputs

            Transaction fundTransactionClone = this.network.CreateTransaction(fundTransaction.ToBytes());
            var         fundContext          = new TransactionBuildContext(walletReference, new List <Recipient>(), "password")
            {
                MinConfirmations = 0,
                FeeType          = FeeType.Low
            };

            fundContext.OverrideFeeRate = overrideFeeRate;
            walletTransactionHandler.FundTransaction(fundContext, fundTransaction);

            foreach (TxIn input in fundTransactionClone.Inputs) // all original inputs are still in the trx
            {
                Assert.Contains(fundTransaction.Inputs, a => a.PrevOut == input.PrevOut);
            }

            Assert.Equal(4, fundTransaction.Inputs.Count);  // we expect 4 inputs
            Assert.Equal(4, fundTransaction.Outputs.Count); // we expect 4 outputs
            Assert.Equal(new Money(200, MoneyUnit.BTC) - fundContext.TransactionFee, fundTransaction.TotalOut);

            Assert.Contains(fundTransaction.Outputs, a => a.ScriptPubKey == destinationKeys1.PubKey.ScriptPubKey);
            Assert.Contains(fundTransaction.Outputs, a => a.ScriptPubKey == destinationKeys2.PubKey.ScriptPubKey);
            Assert.Contains(fundTransaction.Outputs, a => a.ScriptPubKey == destinationKeys3.PubKey.ScriptPubKey);
        }
Example #31
0
        public FederationWalletSyncManager(ILoggerFactory loggerFactory, IFederationWalletManager walletManager, ConcurrentChain chain,
                                           Network network, IBlockStore blockStore, StoreSettings storeSettings, INodeLifetime nodeLifetime)
        {
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(walletManager, nameof(walletManager));
            Guard.NotNull(chain, nameof(chain));
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(blockStore, nameof(blockStore));
            Guard.NotNull(storeSettings, nameof(storeSettings));
            Guard.NotNull(nodeLifetime, nameof(nodeLifetime));

            this.walletManager = walletManager;
            this.chain         = chain;
            this.blockStore    = blockStore;
            this.coinType      = (CoinType)network.Consensus.CoinType;
            this.storeSettings = storeSettings;
            this.nodeLifetime  = nodeLifetime;
            this.logger        = loggerFactory.CreateLogger(this.GetType().FullName);
        }
            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.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      = NodeSettings.Default();
                var          consensusSettings = new ConsensusSettings(nodeSettings, loggerFactory)
                {
                    UseCheckpoints = this.useCheckpoints
                };

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

                var peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory);
                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, nodeSettings);
                NodeDeployments      deployments    = new NodeDeployments(this.network, this.chain);
                ConsensusRules       consensusRules = new ConsensusRules(this.network, loggerFactory, dateTimeProvider, this.chain, deployments, consensusSettings, new Checkpoints()).Register(new FullNodeBuilderConsensusExtension.CoreConsensusRules());

                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.date        = 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).CreateNewBlock(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).CreateNewBlock(this.scriptPubKey);
                Assert.NotNull(this.newBlock);
            }
Example #33
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
            });
        }
Example #34
0
		/// <summary>
		/// Configure the components of the wallet
		/// </summary>
		/// <param name="chain">The chain to keep in sync, if not provided the whole chain will be downloaded on the network (more than 30MB)</param>
		/// <param name="addrman">The Address Manager for speeding up peer discovery</param>
		/// <param name="tracker">The tracker responsible for providing bloom filters</param>
		public void Configure(ConcurrentChain chain = null,
							AddressManager addrman = null,
							Tracker tracker = null)
		{
			if(State != WalletState.Created)
				throw new InvalidOperationException("The wallet is already connecting or connected");

			var parameters = new NodeConnectionParameters();
			ConfigureDefaultNodeConnectionParameters(parameters);


			//Pick the behaviors
			if(addrman != null)
				parameters.TemplateBehaviors.Add(new AddressManagerBehavior(addrman));	//Listen addr, help for node discovery
			if(chain != null)
				parameters.TemplateBehaviors.Add(new ChainBehavior(chain));	//Keep chain in sync
			if(tracker != null)
				parameters.TemplateBehaviors.Add(new TrackerBehavior(tracker, chain)); //Set bloom filters and scan the blockchain

			Configure(parameters);
		}
 public TestPosConsensusRules(Network network, ILoggerFactory loggerFactory, IDateTimeProvider dateTimeProvider, ConcurrentChain chain, NodeDeployments nodeDeployments, ConsensusSettings consensusSettings, ICheckpoints checkpoints, CoinView uxtoSet, ILookaheadBlockPuller lookaheadBlockPuller, IStakeChain stakeChain, IStakeValidator stakeValidator)
     : base(network, loggerFactory, dateTimeProvider, chain, nodeDeployments, consensusSettings, checkpoints, uxtoSet, lookaheadBlockPuller, stakeChain, stakeValidator)
 {
     this.ruleRegistration = new Mock <IRuleRegistration>();
 }
Example #36
0
		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());
		}
 public TestConsensusRules(Network network, ILoggerFactory loggerFactory, IDateTimeProvider dateTimeProvider, ConcurrentChain chain, NodeDeployments nodeDeployments, ConsensusSettings consensusSettings, ICheckpoints checkpoints)
     : base(network, loggerFactory, dateTimeProvider, chain, nodeDeployments, consensusSettings, checkpoints)
 {
     this.ruleRegistration = new Mock <IRuleRegistration>();
 }
Example #38
0
		public void CanCalculateDifficulty()
		{
			var main = new ConcurrentChain(LoadMainChain());
			var histories = File.ReadAllText("data/targethistory.csv").Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

			foreach(var history in histories)
			{
				var height = int.Parse(history.Split(',')[0]);
				var expectedTarget = new Target(BigInteger.Parse(history.Split(',')[1]));

				var block = main.GetBlock(height).Header;

				Assert.Equal(expectedTarget, block.Bits);
				var target = main.GetWorkRequired(Network.Main, height);
				Assert.Equal(expectedTarget, target);
			}
		}
        /// <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(loggerFactory));

            var peerAddressManager  = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory, new SelfEndpointTracker(loggerFactory));
            var peerDiscovery       = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, network, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager);
            var connectionSettings  = new ConnectionManagerSettings(nodeSettings);
            var selfEndpointTracker = new SelfEndpointTracker(loggerFactory);
            var connectionManager   = new ConnectionManager(dateTimeProvider, loggerFactory, network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery, selfEndpointTracker, 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 #40
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());
		}
Example #41
0
        public void BuildTransactionNoChangeAdressesLeftCreatesNewChangeAddress()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            var wallet          = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
            var accountKeys     = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
            var spendingKeys    = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
            var destinationKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");

            var address = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = spendingKeys.Address.ToString(),
                Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            var chain = new ConcurrentChain(wallet.Network);

            WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.Network, chain, address);
            var addressTransaction = address.Transactions.First();

            wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account1",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    address
                },
                InternalAddresses = new List <HdAddress>()
            });

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations()))
            .Returns(new FeeRate(20000));

            var walletManager = new WalletManager(this.LoggerFactory.Object, Network.PurpleMain, chain, NodeSettings.Default(), dataFolder,
                                                  walletFeePolicy.Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default);
            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, Network.PurpleMain);

            walletManager.Wallets.Add(wallet);

            var walletReference = new WalletAccountReference
            {
                AccountName = "account1",
                WalletName  = "myWallet1"
            };

            var context           = CreateContext(walletReference, "password", destinationKeys.PubKey.ScriptPubKey, new Money(7500), FeeType.Low, 0);
            var transactionResult = walletTransactionHandler.BuildTransaction(context);

            var result = new Transaction(transactionResult.ToHex());
            var expectedChangeAddressKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "1/0");

            Assert.Single(result.Inputs);
            Assert.Equal(addressTransaction.Id, result.Inputs[0].PrevOut.Hash);

            Assert.Equal(2, result.Outputs.Count);
            var output = result.Outputs[0];

            Assert.Equal((addressTransaction.Amount - context.TransactionFee - 7500), output.Value);
            Assert.Equal(expectedChangeAddressKeys.Address.ScriptPubKey, output.ScriptPubKey);

            output = result.Outputs[1];
            Assert.Equal(7500, output.Value);
            Assert.Equal(destinationKeys.PubKey.ScriptPubKey, output.ScriptPubKey);

            Assert.Equal(addressTransaction.Amount - context.TransactionFee, result.TotalOut);
            Assert.NotNull(transactionResult.GetHash());
            Assert.Equal(result.GetHash(), transactionResult.GetHash());
        }
Example #42
0
		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));
		}
Example #43
0
        public void EstimateFeeWithLowFeeMatchesBuildTxLowFee()
        {
            var dataFolder = CreateDataFolder(this);

            Wallet wallet          = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
            var    accountKeys     = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
            var    spendingKeys    = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
            var    destinationKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");

            HdAddress address = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = spendingKeys.Address.ToString(),
                Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            ConcurrentChain chain = new ConcurrentChain(wallet.Network);

            WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.Network, chain, address);
            TransactionData addressTransaction = address.Transactions.First();

            wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account1",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    address
                },
                InternalAddresses = new List <HdAddress>()
            });

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations()))
            .Returns(new FeeRate(20000));

            var walletManager = new WalletManager(this.LoggerFactory.Object, Network.PurpleMain, chain, NodeSettings.Default(), dataFolder,
                                                  walletFeePolicy.Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default);
            WalletTransactionHandler walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, Network.PurpleMain);

            walletManager.Wallets.Add(wallet);

            WalletAccountReference walletReference = new WalletAccountReference
            {
                AccountName = "account1",
                WalletName  = "myWallet1"
            };

            // Context to build requires password in order to sign transaction.
            TransactionBuildContext buildContext = CreateContext(walletReference, "password", destinationKeys.PubKey.ScriptPubKey, new Money(7500), FeeType.Low, 0);

            walletTransactionHandler.BuildTransaction(buildContext);

            // Context for estimate does not need password.
            TransactionBuildContext estimateContext = CreateContext(walletReference, null, destinationKeys.PubKey.ScriptPubKey, new Money(7500), FeeType.Low, 0);
            Money fee = walletTransactionHandler.EstimateFee(estimateContext);

            Assert.Equal(fee, buildContext.TransactionFee);
        }
Example #44
0
		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));
		}
Example #45
0
		/// <summary>
		/// Remove old spent & confirmed TrackedOutpoint, old unconf operations, and old forked operations
		/// </summary>
		/// <param name="chain"></param>
		internal List<object> Prune(ConcurrentChain chain, int blockExpiration = 2000, TimeSpan? timeExpiration = null)
		{
			List<object> removed = new List<object>();
			timeExpiration = timeExpiration ?? TimeSpan.FromDays(7.0);
			foreach(var op in _Operations)
			{
				if(op.Value.BlockId != null)
				{
					var chained = chain.GetBlock(op.Value.BlockId);
					var isForked = chained == null;
					if(!isForked)
					{
						bool isOldConfirmed = chain.Height - chained.Height + 1 > blockExpiration;
						if(isOldConfirmed)
						{
							foreach(var spent in op.Value.SpentCoins) //Stop tracking the outpoints
							{
								TrackedOutpoint unused;
								if(_TrackedOutpoints.TryRemove(TrackedOutpoint.GetId(spent.Item1.Outpoint), out unused))
									removed.Add(unused);
							}
						}
					}
					else
					{
						var isOldFork = chain.Height - op.Value.Height + 1 > blockExpiration;
						if(isOldFork) //clear any operation belonging to an old fork
						{
							Operation unused;
							if(_Operations.TryRemove(op.Key, out unused))
								removed.Add(unused);
						}
					}
				}
				else
				{
					var isOldUnconf = (DateTimeOffset.UtcNow - op.Value.AddedDate) > timeExpiration;
					if(isOldUnconf) //clear any old unconfirmed
					{
						Operation unused;
						if(_Operations.TryRemove(op.Key, out unused))
							removed.Add(unused);
					}
				}
			}
			return removed;
		}
Example #46
0
        public async Task ReorgedBlocksAreDeletedFromRepositoryIfReorgDetectedAsync()
        {
            this.chain = CreateChain(1000);
            this.repositoryTipHashAndHeight = new HashHeightPair(this.chain.Genesis.HashBlock, 0);

            this.blockStoreQueue = new BlockStoreQueue(this.chain, this.chainState, new StoreSettings(),
                                                       this.nodeLifetime, this.blockRepositoryMock.Object, new LoggerFactory(), new Mock <INodeStats>().Object);

            await this.blockStoreQueue.InitializeAsync().ConfigureAwait(false);

            this.chainState.ConsensusTip = this.chain.Tip;

            // Sending 500 blocks to the queue.
            for (int i = 1; i < 500; i++)
            {
                Block block = this.network.Consensus.ConsensusFactory.CreateBlock();
                block.GetSerializedSize();

                this.blockStoreQueue.AddToPending(new ChainedHeaderBlock(block, this.chain.GetBlock(i)));
            }

            // Create alternative chain with fork point at 450.
            ChainedHeader prevBlock         = this.chain.GetBlock(450);
            var           alternativeBlocks = new List <ChainedHeader>();

            for (int i = 0; i < 100; i++)
            {
                BlockHeader header = this.network.Consensus.ConsensusFactory.CreateBlockHeader();
                header.Nonce         = RandomUtils.GetUInt32();
                header.HashPrevBlock = prevBlock.HashBlock;
                header.Bits          = Target.Difficulty1;

                var chainedHeader = new ChainedHeader(header, header.GetHash(), prevBlock);
                alternativeBlocks.Add(chainedHeader);
                prevBlock = chainedHeader;
            }

            ChainedHeader savedHeader = this.chain.Tip;

            this.chain.SetTip(alternativeBlocks.Last());
            this.chainState.ConsensusTip = this.chain.Tip;

            // Present alternative chain and trigger save.
            foreach (ChainedHeader header in alternativeBlocks)
            {
                Block block = this.network.Consensus.ConsensusFactory.CreateBlock();
                block.GetSerializedSize();

                if (header == alternativeBlocks.Last())
                {
                    this.chainState.IsAtBestChainTip = true;
                }

                this.blockStoreQueue.AddToPending(new ChainedHeaderBlock(block, header));
            }

            await WaitUntilQueueIsEmptyAsync().ConfigureAwait(false);

            this.chainState.IsAtBestChainTip = false;

            // Make sure only longest chain is saved.
            Assert.Equal(this.chain.Tip.Height, this.repositoryTotalBlocksSaved);

            // Present a new longer chain that will reorg the repository.
            this.chain.SetTip(savedHeader);
            this.chainState.ConsensusTip = this.chain.Tip;

            for (int i = 451; i <= this.chain.Height; i++)
            {
                Block block = this.network.Consensus.ConsensusFactory.CreateBlock();
                block.GetSerializedSize();

                if (i == this.chain.Height)
                {
                    this.chainState.IsAtBestChainTip = true;
                }

                this.blockStoreQueue.AddToPending(new ChainedHeaderBlock(block, this.chain.GetBlock(i)));
            }

            await WaitUntilQueueIsEmptyAsync().ConfigureAwait(false);

            // Make sure chain is saved.
            Assert.Equal(this.chain.Tip.Height + alternativeBlocks.Count, this.repositoryTotalBlocksSaved);
            Assert.Equal(alternativeBlocks.Count, this.repositoryTotalBlocksDeleted);

            // Dispose block store.
            this.nodeLifetime.StopApplication();
            this.blockStoreQueue.Dispose();
        }
            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(network);
                this.network.Consensus.Options = new PowConsensusOptions();
                this.cachedCoinView            = new CachedCoinView(new InMemoryCoinView(chain.Tip.HashBlock));
                this.consensus = new ConsensusLoop(new PowConsensusValidator(network), chain, cachedCoinView, new LookaheadBlockPuller(chain, new ConnectionManager(network, new NodeConnectionParameters(), new NodeSettings(), new LoggerFactory()), 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.scheduler = new MempoolScheduler();

                // 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 #48
0
        public PoAFeature(FederationManager federationManager, PayloadProvider payloadProvider, IConnectionManager connectionManager, ConcurrentChain chain,
                          IInitialBlockDownloadState initialBlockDownloadState, IConsensusManager consensusManager, IPeerBanning peerBanning, ILoggerFactory loggerFactory,
                          IPoAMiner miner, VotingManager votingManager, Network network, IWhitelistedHashesRepository whitelistedHashesRepository)
        {
            this.federationManager           = federationManager;
            this.connectionManager           = connectionManager;
            this.chain                       = chain;
            this.initialBlockDownloadState   = initialBlockDownloadState;
            this.consensusManager            = consensusManager;
            this.peerBanning                 = peerBanning;
            this.loggerFactory               = loggerFactory;
            this.miner                       = miner;
            this.votingManager               = votingManager;
            this.whitelistedHashesRepository = whitelistedHashesRepository;
            this.network                     = network;

            payloadProvider.DiscoverPayloads(this.GetType().Assembly);
        }
        public static (ChainedHeader ChainedHeader, Block Block) AppendBlock(Network network, ChainedHeader previous, ConcurrentChain chain)
        {
            ChainedHeader last  = null;
            uint          nonce = RandomUtils.GetUInt32();
            Block         block = network.CreateBlock();

            block.AddTransaction(network.CreateTransaction());
            block.UpdateMerkleRoot();
            block.Header.HashPrevBlock = previous == null ? chain.Tip.HashBlock : previous.HashBlock;
            block.Header.Nonce         = nonce;
            if (!chain.TrySetTip(block.Header, out last))
            {
                throw new InvalidOperationException("Previous not existing");
            }

            return(last, block);
        }
Example #50
0
		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);
		}
Example #51
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 = NodeSettings.FromArguments(new string[] { $"-datadir={dataDir}" }, network.Name, network);

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

            LoggerFactory     loggerFactory    = new LoggerFactory();
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

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

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

            ConsensusLoop consensus = new ConsensusLoop(new AsyncLoopFactory(loggerFactory), consensusValidator, new NodeLifetime(), chain, cachedCoinView, blockPuller, new NodeDeployments(network, chain), loggerFactory, new ChainState(new FullNode()), connectionManager, dateTimeProvider, new Signals.Signals(), new Checkpoints(network));
            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);
            consensus.ValidateAndExecuteBlock(new ContextInformation(new BlockValidationContext {
                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.ValidateAndExecuteBlock(new ContextInformation(new BlockValidationContext {
                    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, 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 #52
0
 public WalletSyncManagerOverride(ILoggerFactory loggerFactory, IWalletManager walletManager, ConcurrentChain chain,
                                  Network network, IBlockStoreCache blockStoreCache, StoreSettings storeSettings, INodeLifetime nodeLifetime)
     : base(loggerFactory, walletManager, chain, network, blockStoreCache, storeSettings, nodeLifetime)
 {
 }
Example #53
0
		/// <summary>
		/// Connect the wallet with the given connection parameters
		/// </summary>
		/// <param name="parameters"></param>
		public void Connect(NodeConnectionParameters parameters)
		{
			if(State != WalletState.Created)
				throw new InvalidOperationException("The wallet is already connecting or connected");
			var group = NodesGroup.GetNodeGroup(parameters);
			if(group == null)
			{
				group = new NodesGroup(_Parameters.Network, parameters);
			}
			parameters = group.NodeConnectionParameters;
			group.Requirements.MinVersion = ProtocolVersion.PROTOCOL_VERSION;
			group.Requirements.RequiredServices = NodeServices.Network;

			var chain = parameters.TemplateBehaviors.Find<ChainBehavior>();
			if(chain == null)
			{
				chain = new ChainBehavior(new ConcurrentChain(_Parameters.Network));
				parameters.TemplateBehaviors.Add(chain);
			}
			if(chain.Chain.Genesis.HashBlock != _Parameters.Network.GetGenesis().GetHash())
				throw new InvalidOperationException("ChainBehavior with invalid network chain detected");

			var addrman = parameters.TemplateBehaviors.Find<AddressManagerBehavior>();
			if(addrman == null)
			{
				addrman = new AddressManagerBehavior(new AddressManager());
				parameters.TemplateBehaviors.Add(addrman);
			}

			var tracker = parameters.TemplateBehaviors.Find<TrackerBehavior>();
			if(tracker == null)
			{
				tracker = new TrackerBehavior(new Tracker(), chain.Chain);
				parameters.TemplateBehaviors.Add(tracker);
			}

			_Chain = chain.Chain;
			_AddressManager = addrman.AddressManager;
			_Tracker = tracker.Tracker;
			_TrackerBehavior = tracker;
			_Group = group;
			if(AddKnownScriptToTracker())
				_Group.Purge("Bloom filter renew");
			_State = WalletState.Disconnected;
			_Group.Connect();
			_Group.ConnectedNodes.Added += ConnectedNodes_Added;
			_Group.ConnectedNodes.Removed += ConnectedNodes_Added;
			foreach(var node in _Group.ConnectedNodes)
			{
				node.Behaviors.Find<TrackerBehavior>().Scan(_ScanLocation, Created);
			}
		}
Example #54
0
 public BlockObserver(ConcurrentChain chain, CoinType coinType, IWalletManager walletManager)
 {
     this.chain         = chain;
     this.coinType      = coinType;
     this.walletManager = walletManager;
 }
 public ChainBase GetNodeChain(Node node)
 {
     var chain = new ConcurrentChain(Configuration.Network);
     IndexerTrace.Information("Synchronizing with local node");
     node.SynchronizeChain(chain);
     IndexerTrace.Information("Chain loaded with height " + chain.Height);
     return chain;
 }