示例#1
0
        public void UnconfirmedTransactionsWithoutReceivedCoinsShouldNotShowUp()
        {
            BlockchainBuilder builder = new BlockchainBuilder();
            Tracker           tracker = new Tracker();

            Key bob = new Key();

            tracker.Add(bob);
            Key alice = new Key();

            var tx1 = builder.GiveMoney(bob, Money.Coins(1.0m));
            var b   = builder.FindBlock();

            tracker.NotifyTransaction(tx1, builder.Chain.Tip, b);

            var tx2 = builder.SpendCoin(tx1.Outputs.AsCoins().First(), alice, Money.Coins(0.1m));

            b = builder.FindBlock();
            tracker.NotifyTransaction(tx2, builder.Chain.Tip, b);

            var tx3 = builder.SpendCoin(tx2.Outputs.AsCoins().Skip(1).First(), alice, Money.Coins(0.2m));

            Assert.True(tracker.NotifyTransaction(tx3));

            var transactions = tracker.GetWalletTransactions(builder.Chain);

            Assert.True(transactions.Count == 3);
            Assert.True(transactions.Summary.UnConfirmed.TransactionCount == 1);
            Assert.True(transactions.Summary.UnConfirmed.Amount == -Money.Coins(0.2m));

            Assert.True(transactions.Summary.Confirmed.TransactionCount == 2);
            Assert.True(transactions.Summary.Confirmed.Amount == Money.Coins(0.9m));

            Assert.True(transactions.Summary.Spendable.TransactionCount == 3);
            Assert.True(transactions.Summary.Spendable.Amount == Money.Coins(0.7m));

            builder.Chain.SetTip(builder.Chain.GetBlock(1));

            transactions = tracker.GetWalletTransactions(builder.Chain);

            Action _ = () =>
            {
                Assert.True(transactions.Count == 3);
                Assert.True(transactions.Summary.Confirmed.TransactionCount == 1);
                Assert.True(transactions.Summary.Confirmed.Amount == Money.Coins(1.0m));
                Assert.True(transactions.Summary.Spendable.TransactionCount == 3);
                Assert.True(transactions.Summary.Spendable.Amount == Money.Coins(0.7m));
                Assert.True(transactions.Summary.UnConfirmed.TransactionCount == 2);
                Assert.True(transactions.Summary.UnConfirmed.Amount == -Money.Coins(0.3m));
            };

            _();
            tracker.NotifyTransaction(tx2);             //Notifying tx2 should have no effect, since it already is accounted because it was orphaned
            _();
        }
示例#2
0
        public void CanPrune()
        {
            BlockchainBuilder builder = new BlockchainBuilder();
            Tracker           tracker = new Tracker();
            Key bob   = new Key();
            Key alice = new Key();

            tracker.Add(bob);

            var oldUnconf = builder.GiveMoney(bob, Money.Coins(1.0m));

            Assert.True(tracker.NotifyTransaction(oldUnconf));

            builder.Mempool.Clear();

            var oldConf      = builder.GiveMoney(bob, Money.Coins(0.9m));
            var oldConfSpent = builder.SpendCoin(oldConf.Outputs.AsCoins().First(), alice, Money.Coins(0.01m));

            var block = builder.FindBlock();

            Assert.True(tracker.NotifyTransaction(oldConf, builder.Chain.Tip, block));
            Assert.True(tracker.NotifyTransaction(oldConfSpent, builder.Chain.Tip, block));

            for (int i = 0; i < 9; i++)
            {
                builder.FindBlock();
            }
            Assert.True(tracker.Prune(builder.Chain, 10).Count == 0);
            builder.FindBlock();

            //Prune tracked outpoint
            var pruned = tracker.Prune(builder.Chain, 10);

            Assert.Equal(1, pruned.Count);
            Assert.True(pruned.First() is Tracker.TrackedOutpoint);

            //Prune old unconf
            pruned = tracker.Prune(builder.Chain, timeExpiration: TimeSpan.Zero);
            Assert.Equal(1, pruned.Count);
            var op = pruned.OfType <Tracker.Operation>().First();

            Assert.True(op.BlockId == null);

            var conf = builder.GiveMoney(bob, Money.Coins(0.9m));

            block = builder.FindBlock();
            Assert.True(tracker.NotifyTransaction(conf, builder.Chain.Tip, block));

            var oldSpentForked = builder.SpendCoin(conf.Outputs.AsCoins().First(), alice, Money.Coins(0.021m));

            block = builder.FindBlock();
            Assert.True(tracker.NotifyTransaction(oldSpentForked, builder.Chain.Tip, block));

            var forked = builder.Chain.Tip;

            builder.Chain.SetTip(builder.Chain.Tip.Previous);

            for (int i = 0; i < 10; i++)
            {
                builder.FindBlock();
            }

            pruned = tracker.Prune(builder.Chain, 10);
            Assert.True(pruned.Count == 1);             //Tracked outpoint of conf
            Assert.True(pruned.First() is Tracker.TrackedOutpoint);
            block = builder.FindBlock();

            pruned = tracker.Prune(builder.Chain, 10);             //Old forked spent
            Assert.Equal(1, pruned.Count);
            op = pruned.OfType <Tracker.Operation>().First();
            Assert.Equal(forked.HashBlock, op.BlockId);
        }
示例#3
0
        public void CanTrackKey()
        {
            BlockchainBuilder builder = new BlockchainBuilder();
            Key     bob     = new Key();
            Tracker tracker = new Tracker();

            tracker.Add(bob);
            var tx1  = builder.GiveMoney(bob, Money.Coins(1.0m));
            var coin = tx1.Outputs.AsCoins().First();

            Assert.True(tracker.NotifyTransaction(tx1));
            Thread.Sleep(10);
            Key alice = new Key();
            var tx2   = builder.SpendCoin(coin, alice, Money.Coins(0.6m));

            Assert.True(tracker.NotifyTransaction(tx2));

            var block = builder.FindBlock();

            foreach (var btx in block.Transactions)
            {
                if (!btx.IsCoinBase)
                {
                    Assert.True(tracker.NotifyTransaction(btx, builder.Chain.GetBlock(block.GetHash()), block));
                    Assert.True(tracker.NotifyTransaction(btx, builder.Chain.GetBlock(block.GetHash()), block));                     //Idempotent
                }
            }

            var transactions = tracker.GetWalletTransactions(builder.Chain);

            Assert.True(transactions.Count == 2);
            Assert.True(transactions[0].Transaction.GetHash() == tx2.GetHash());
            Assert.True(transactions[1].Transaction.GetHash() == tx1.GetHash());
            Assert.True(transactions[0].Balance == -Money.Coins(0.6m));

            var tx3 = builder.GiveMoney(bob, Money.Coins(0.01m));

            coin  = tx3.Outputs.AsCoins().First();
            block = builder.FindBlock();
            Assert.True(tracker.NotifyTransaction(block.Transactions[1], builder.Chain.GetBlock(block.GetHash()), block));

            transactions = tracker.GetWalletTransactions(builder.Chain);
            Assert.True(transactions.Count == 3);
            Assert.True(transactions.Summary.UnConfirmed.TransactionCount == 0);
            Assert.True(transactions[0].Transaction.GetHash() == block.Transactions[1].GetHash());

            Assert.Equal(2, transactions.GetSpendableCoins().Count());             // the 1 change + 1 gift

            builder.Chain.SetTip(builder.Chain.Tip.Previous);
            transactions = tracker.GetWalletTransactions(builder.Chain);
            Assert.True(transactions.Count == 3);
            Assert.True(transactions.Summary.UnConfirmed.TransactionCount == 1);

            //Test roundtrip serialization
            var          filterBefore = tracker.CreateBloomFilter(0.005);
            MemoryStream ms           = new MemoryStream();

            tracker.Save(ms);
            tracker      = new Tracker();
            ms.Position  = 0;
            tracker      = Tracker.Load(ms);
            transactions = tracker.GetWalletTransactions(builder.Chain);
            Assert.True(transactions.Count == 3);
            Assert.True(transactions.Summary.UnConfirmed.TransactionCount == 1);
            var filterAfter = tracker.CreateBloomFilter(0.005);

            Assert.True(filterBefore.ToBytes().SequenceEqual(filterAfter.ToBytes()));
            /////
        }
示例#4
0
		public void UnconfirmedTransactionsWithoutReceivedCoinsShouldNotShowUp()
		{
			BlockchainBuilder builder = new BlockchainBuilder();
			Tracker tracker = new Tracker();

			Key bob = new Key();
			tracker.Add(bob);
			Key alice = new Key();

			var tx1 = builder.GiveMoney(bob, Money.Coins(1.0m));
			var b = builder.FindBlock();
			tracker.NotifyTransaction(tx1, builder.Chain.Tip, b);

			var tx2 = builder.SpendCoin(tx1.Outputs.AsCoins().First(), alice, Money.Coins(0.1m));
			b = builder.FindBlock();
			tracker.NotifyTransaction(tx2, builder.Chain.Tip, b);

			var tx3 = builder.SpendCoin(tx2.Outputs.AsCoins().Skip(1).First(), alice, Money.Coins(0.2m));
			Assert.True(tracker.NotifyTransaction(tx3));

			var transactions = tracker.GetWalletTransactions(builder.Chain);
			Assert.True(transactions.Count == 3);
			Assert.True(transactions.Summary.UnConfirmed.TransactionCount == 1);
			Assert.True(transactions.Summary.UnConfirmed.Amount == -Money.Coins(0.2m));

			Assert.True(transactions.Summary.Confirmed.TransactionCount == 2);
			Assert.True(transactions.Summary.Confirmed.Amount == Money.Coins(0.9m));

			Assert.True(transactions.Summary.Spendable.TransactionCount == 3);
			Assert.True(transactions.Summary.Spendable.Amount == Money.Coins(0.7m));

			builder.Chain.SetTip(builder.Chain.GetBlock(1));

			transactions = tracker.GetWalletTransactions(builder.Chain);

			Action _ = () =>
			{
				Assert.True(transactions.Count == 3);
				Assert.True(transactions.Summary.Confirmed.TransactionCount == 1);
				Assert.True(transactions.Summary.Confirmed.Amount == Money.Coins(1.0m));
				Assert.True(transactions.Summary.Spendable.TransactionCount == 3);
				Assert.True(transactions.Summary.Spendable.Amount == Money.Coins(0.7m));
				Assert.True(transactions.Summary.UnConfirmed.TransactionCount == 2);
				Assert.True(transactions.Summary.UnConfirmed.Amount == -Money.Coins(0.3m));
			};
			_();
			tracker.NotifyTransaction(tx2);	//Notifying tx2 should have no effect, since it already is accounted because it was orphaned
			_();
		}
示例#5
0
		public void CanPrune()
		{
			BlockchainBuilder builder = new BlockchainBuilder();
			Tracker tracker = new Tracker();
			Key bob = new Key();
			Key alice = new Key();
			tracker.Add(bob);

			var oldUnconf = builder.GiveMoney(bob, Money.Coins(1.0m));
			Assert.True(tracker.NotifyTransaction(oldUnconf));

			builder.Mempool.Clear();

			var oldConf = builder.GiveMoney(bob, Money.Coins(0.9m));
			var oldConfSpent = builder.SpendCoin(oldConf.Outputs.AsCoins().First(), alice, Money.Coins(0.01m));

			var block = builder.FindBlock();

			Assert.True(tracker.NotifyTransaction(oldConf, builder.Chain.Tip, block));
			Assert.True(tracker.NotifyTransaction(oldConfSpent, builder.Chain.Tip, block));

			for(int i = 0 ; i < 9 ; i++)
			{
				builder.FindBlock();
			}
			Assert.True(tracker.Prune(builder.Chain, 10).Count == 0);
			builder.FindBlock();

			//Prune tracked outpoint
			var pruned = tracker.Prune(builder.Chain, 10);
			Assert.Equal(1, pruned.Count);
			Assert.True(pruned.First() is Tracker.TrackedOutpoint);

			//Prune old unconf
			pruned = tracker.Prune(builder.Chain, timeExpiration: TimeSpan.Zero);
			Assert.Equal(1, pruned.Count);
			var op = pruned.OfType<Tracker.Operation>().First();
			Assert.True(op.BlockId == null);

			var conf = builder.GiveMoney(bob, Money.Coins(0.9m));
			block = builder.FindBlock();
			Assert.True(tracker.NotifyTransaction(conf, builder.Chain.Tip, block));

			var oldSpentForked = builder.SpendCoin(conf.Outputs.AsCoins().First(), alice, Money.Coins(0.021m));
			block = builder.FindBlock();
			Assert.True(tracker.NotifyTransaction(oldSpentForked, builder.Chain.Tip, block));

			var forked = builder.Chain.Tip;
			builder.Chain.SetTip(builder.Chain.Tip.Previous);

			for(int i = 0 ; i < 10 ; i++)
			{
				builder.FindBlock();
			}

			pruned = tracker.Prune(builder.Chain, 10);
			Assert.True(pruned.Count == 1); //Tracked outpoint of conf
			Assert.True(pruned.First() is Tracker.TrackedOutpoint);
			block = builder.FindBlock();

			pruned = tracker.Prune(builder.Chain, 10); //Old forked spent
			Assert.Equal(1, pruned.Count);
			op = pruned.OfType<Tracker.Operation>().First();
			Assert.Equal(forked.HashBlock, op.BlockId);
		}
示例#6
0
		public void CanTrackKey()
		{
			BlockchainBuilder builder = new BlockchainBuilder();
			Key bob = new Key();
			Tracker tracker = new Tracker();
			tracker.Add(bob);
			var tx1 = builder.GiveMoney(bob, Money.Coins(1.0m));
			var coin = tx1.Outputs.AsCoins().First();
			Assert.True(tracker.NotifyTransaction(tx1));
			Thread.Sleep(10);
			Key alice = new Key();
			var tx2 = builder.SpendCoin(coin, alice, Money.Coins(0.6m));
			Assert.True(tracker.NotifyTransaction(tx2));

			var block = builder.FindBlock();

			foreach(var btx in block.Transactions)
			{
				if(!btx.IsCoinBase)
				{
					Assert.True(tracker.NotifyTransaction(btx, builder.Chain.GetBlock(block.GetHash()), block));
					Assert.True(tracker.NotifyTransaction(btx, builder.Chain.GetBlock(block.GetHash()), block)); //Idempotent
				}
			}

			var transactions = tracker.GetWalletTransactions(builder.Chain);

			Assert.True(transactions.Count == 2);
			Assert.True(transactions[0].Transaction.GetHash() == tx2.GetHash());
			Assert.True(transactions[1].Transaction.GetHash() == tx1.GetHash());
			Assert.True(transactions[0].Balance == -Money.Coins(0.6m));

			var tx3 = builder.GiveMoney(bob, Money.Coins(0.01m));
			coin = tx3.Outputs.AsCoins().First();
			block = builder.FindBlock();
			Assert.True(tracker.NotifyTransaction(block.Transactions[1], builder.Chain.GetBlock(block.GetHash()), block));

			transactions = tracker.GetWalletTransactions(builder.Chain);
			Assert.True(transactions.Count == 3);
			Assert.True(transactions.Summary.UnConfirmed.TransactionCount == 0);
			Assert.True(transactions[0].Transaction.GetHash() == block.Transactions[1].GetHash());

			Assert.Equal(2, transactions.GetSpendableCoins().Count()); // the 1 change + 1 gift

			builder.Chain.SetTip(builder.Chain.Tip.Previous);
			transactions = tracker.GetWalletTransactions(builder.Chain);
			Assert.True(transactions.Count == 3);
			Assert.True(transactions.Summary.UnConfirmed.TransactionCount == 1);

			//Test roundtrip serialization
			var filterBefore = tracker.CreateBloomFilter(0.005);
			MemoryStream ms = new MemoryStream();
			tracker.Save(ms);
			tracker = new Tracker();
			ms.Position = 0;
			tracker = Tracker.Load(ms);
			transactions = tracker.GetWalletTransactions(builder.Chain);
			Assert.True(transactions.Count == 3);
			Assert.True(transactions.Summary.UnConfirmed.TransactionCount == 1);
			var filterAfter = tracker.CreateBloomFilter(0.005);
			Assert.True(filterBefore.ToBytes().SequenceEqual(filterAfter.ToBytes()));
			/////
		}