示例#1
0
		public void CanSyncWalletCore(WalletCreation creation)
		{
			using(NodeServerTester servers = new NodeServerTester(Network.TestNet))
			{
				var notifiedTransactions = new List<WalletTransaction>();
				var chainBuilder = new BlockchainBuilder();
				SetupSPVBehavior(servers, chainBuilder);
				NodesGroup connected = CreateGroup(servers, 1);
				Wallet wallet = new Wallet(creation, keyPoolSize: 11);
				wallet.NewWalletTransaction += (s, a) => notifiedTransactions.Add(a);
				Assert.True(wallet.State == WalletState.Created);
				wallet.Configure(connected);
				wallet.Connect();
				Assert.True(wallet.State == WalletState.Disconnected);
				TestUtils.Eventually(() => connected.ConnectedNodes.Count == 1);
				Assert.True(wallet.State == WalletState.Connected);

				chainBuilder.FindBlock();
				TestUtils.Eventually(() => wallet.Chain.Height == 1);
				for(int i = 0 ; i < 9 ; i++)
				{
					wallet.GetNextScriptPubKey();
				}
				wallet.GetNextScriptPubKey(); //Should provoke purge
				TestUtils.Eventually(() => wallet.State == WalletState.Disconnected && wallet.ConnectedNodes == 0);
				TestUtils.Eventually(() => wallet.ConnectedNodes == 1);
				TestUtils.Eventually(() => servers.Server1.ConnectedNodes.Count == 1);
				var spv = servers.Server1.ConnectedNodes.First().Behaviors.Find<SPVBehavior>();
				TestUtils.Eventually(() => spv._Filter != null);
				var k = wallet.GetNextScriptPubKey();
				Assert.NotNull(wallet.GetKeyPath(k));
				if(creation.UseP2SH)
				{
					var p2sh = k.GetDestinationAddress(Network.TestNet) as BitcoinScriptAddress;
					Assert.NotNull(p2sh);
					var redeem = wallet.GetRedeemScript(p2sh);
					Assert.NotNull(redeem);
					Assert.Equal(redeem.Hash, p2sh.Hash);
				}

				Assert.Equal(creation.UseP2SH, k.GetDestinationAddress(Network.TestNet) is BitcoinScriptAddress);
				chainBuilder.GiveMoney(k, Money.Coins(1.0m));
				TestUtils.Eventually(() => wallet.GetTransactions().Count == 1);
				Assert.Equal(1, notifiedTransactions.Count);
				chainBuilder.FindBlock();
				TestUtils.Eventually(() => wallet.GetTransactions().Where(t => t.BlockInformation != null).Count() == 1);
				Assert.Equal(2, notifiedTransactions.Count);

				chainBuilder.Broadcast = false;
				chainBuilder.GiveMoney(k, Money.Coins(1.5m));
				chainBuilder.Broadcast = true;
				chainBuilder.FindBlock();
				TestUtils.Eventually(() => wallet.GetTransactions().Summary.Confirmed.TransactionCount == 2);
				Assert.Equal(3, notifiedTransactions.Count);

				chainBuilder.Broadcast = false;
				for(int i = 0 ; i < 30 ; i++)
				{
					chainBuilder.FindBlock();
				}
				chainBuilder.GiveMoney(k, Money.Coins(0.001m));
				chainBuilder.FindBlock();
				chainBuilder.Broadcast = true;
				chainBuilder.FindBlock();
				//Sync automatically
				TestUtils.Eventually(() => wallet.GetTransactions().Summary.Confirmed.TransactionCount == 3);

				//Save and restore wallet
				MemoryStream ms = new MemoryStream();
				wallet.Save(ms);
				ms.Position = 0;
				var wallet2 = Wallet.Load(ms);
				//////

				//Save and restore tracker
				ms = new MemoryStream();
				var tracker = connected.NodeConnectionParameters.TemplateBehaviors.Find<TrackerBehavior>();
				connected.NodeConnectionParameters.TemplateBehaviors.Remove(tracker);
				tracker.Tracker.Save(ms);
				ms.Position = 0;
				tracker = new TrackerBehavior(Tracker.Load(ms), wallet.Chain);
				connected.NodeConnectionParameters.TemplateBehaviors.Add(tracker);
				//////

				wallet2.Configure(connected);
				wallet2.Connect();
				Assert.Equal(wallet.Created, wallet2.Created);
				Assert.Equal(wallet.GetNextScriptPubKey(), wallet2.GetNextScriptPubKey());
				Assert.True(wallet.GetKnownScripts().Length == wallet2.GetKnownScripts().Length);
				TestUtils.Eventually(() => wallet2.GetTransactions().Summary.Confirmed.TransactionCount == 3);

				var fork = wallet.Chain.FindFork(wallet2._ScanLocation);
				Assert.True(fork.Height == chainBuilder.Chain.Height);
			}
		}