public void MaxAmountTest() { Network network = Network.TestNet; SafeAccount account = new SafeAccount(1); string path = Path.Combine(Helpers.CommittedWalletsFolderPath, $"Sending{network}.json"); const string password = ""; Safe safe = Safe.Load(password, path); Assert.Equal(network, safe.Network); Debug.WriteLine($"Unique Safe ID: {safe.UniqueId}"); // create walletjob WalletJob walletJob = new WalletJob(Helpers.SocksPortHandler, Helpers.ControlPortClient, safe, trackDefaultSafe: false, accountsToTrack: account); // note some event WalletJob.ConnectedNodeCountChanged += delegate { if (WalletJob.MaxConnectedNodeCount == WalletJob.ConnectedNodeCount) { Debug.WriteLine( $"{nameof(WalletJob.MaxConnectedNodeCount)} reached: {WalletJob.MaxConnectedNodeCount}"); } else { Debug.WriteLine($"{nameof(WalletJob.ConnectedNodeCount)}: {WalletJob.ConnectedNodeCount}"); } }; walletJob.StateChanged += delegate { Debug.WriteLine($"{nameof(walletJob.State)}: {walletJob.State}"); }; // start syncing var cts = new CancellationTokenSource(); var walletJobTask = walletJob.StartAsync(cts.Token); Task reportTask = Helpers.ReportAsync(cts.Token, walletJob); try { // wait until blocks are synced while (walletJob.State <= WalletState.SyncingMemPool) { Task.Delay(1000).Wait(); } var receive = walletJob.GetUnusedScriptPubKeys(account, HdPathType.Receive).FirstOrDefault(); IDictionary <Coin, bool> unspentCoins; var bal = walletJob.GetBalance(out unspentCoins, account); var res = walletJob.BuildTransactionAsync(receive, Money.Zero, FeeType.Low, account, allowUnconfirmed: true).Result; Assert.True(res.Success); Assert.True(res.FailingReason == ""); Debug.WriteLine($"Fee: {res.Fee}"); Debug.WriteLine($"FeePercentOfSent: {res.FeePercentOfSent} %"); Debug.WriteLine($"SpendsUnconfirmed: {res.SpendsUnconfirmed}"); Debug.WriteLine($"Transaction: {res.Transaction}"); var foundReceive = false; Assert.InRange(res.Transaction.Outputs.Count, 1, 2); foreach (var output in res.Transaction.Outputs) { if (output.ScriptPubKey == receive) { foundReceive = true; Assert.True(bal.Confirmed + bal.Unconfirmed - res.Fee == output.Value); } } Assert.True(foundReceive); var txProbArrived = false; var prevCount = walletJob.Tracker.TrackedTransactions.Count; walletJob.Tracker.TrackedTransactions.CollectionChanged += delegate { var actCount = walletJob.Tracker.TrackedTransactions.Count; // if arrived if (actCount > prevCount) { txProbArrived = true; } else { prevCount = actCount; } }; var sendRes = walletJob.SendTransactionAsync(res.Transaction).Result; Assert.True(sendRes.Success); Assert.True(sendRes.FailingReason == ""); while (txProbArrived == false) { Debug.WriteLine("Waiting for transaction..."); Task.Delay(1000).Wait(); } Debug.WriteLine("TrackedTransactions collection changed"); Assert.True(walletJob.Tracker.TrackedTransactions.Any(x => x.Transaction.GetHash() == res.Transaction.GetHash())); Debug.WriteLine("Transaction arrived"); } finally { cts.Cancel(); Task.WhenAll(reportTask, walletJobTask).Wait(); } }
public void SendsFailGracefullyTest() { Network network = Network.TestNet; SafeAccount account = new SafeAccount(1); string path = Path.Combine(Helpers.CommittedWalletsFolderPath, $"Sending{network}.json"); const string password = ""; Safe safe = Safe.Load(password, path); Assert.Equal(network, safe.Network); Debug.WriteLine($"Unique Safe ID: {safe.UniqueId}"); // create walletjob WalletJob walletJob = new WalletJob(Helpers.SocksPortHandler, Helpers.ControlPortClient, safe, trackDefaultSafe: false, accountsToTrack: account); // note some event WalletJob.ConnectedNodeCountChanged += delegate { if (WalletJob.MaxConnectedNodeCount == WalletJob.ConnectedNodeCount) { Debug.WriteLine( $"{nameof(WalletJob.MaxConnectedNodeCount)} reached: {WalletJob.MaxConnectedNodeCount}"); } else { Debug.WriteLine($"{nameof(WalletJob.ConnectedNodeCount)}: {WalletJob.ConnectedNodeCount}"); } }; walletJob.StateChanged += delegate { Debug.WriteLine($"{nameof(walletJob.State)}: {walletJob.State}"); }; // start syncing var cts = new CancellationTokenSource(); var walletJobTask = walletJob.StartAsync(cts.Token); Task reportTask = Helpers.ReportAsync(cts.Token, walletJob); try { // wait until blocks are synced while (walletJob.State <= WalletState.SyncingMemPool) { Task.Delay(1000).Wait(); } var history = walletJob.GetSafeHistory(account); foreach (var record in history) { Debug.WriteLine($"{record.TransactionId} {record.Amount} {record.Confirmed}"); } var receive = walletJob.GetUnusedScriptPubKeys(account, HdPathType.Receive).FirstOrDefault(); IDictionary <Coin, bool> unspentCoins; var bal = walletJob.GetBalance(out unspentCoins, account); // Not enough fee Money amountToSend = (bal.Confirmed + bal.Unconfirmed) - new Money(1m, MoneyUnit.Satoshi); var res = walletJob.BuildTransactionAsync(receive, amountToSend, FeeType.Low, account, allowUnconfirmed: true).Result; Assert.True(res.Success == false); Assert.True(res.FailingReason != ""); Debug.WriteLine($"Expected FailingReason: {res.FailingReason}"); // That's not how you spend all amountToSend = (bal.Confirmed + bal.Unconfirmed); res = walletJob.BuildTransactionAsync(receive, amountToSend, FeeType.Low, account, allowUnconfirmed: true).Result; Assert.True(res.Success == false); Assert.True(res.FailingReason != ""); Debug.WriteLine($"Expected FailingReason: {res.FailingReason}"); // Too much amountToSend = (bal.Confirmed + bal.Unconfirmed) + new Money(1, MoneyUnit.BTC); res = walletJob.BuildTransactionAsync(receive, amountToSend, FeeType.Low, account, allowUnconfirmed: true).Result; Assert.True(res.Success == false); Assert.True(res.FailingReason != ""); Debug.WriteLine($"Expected FailingReason: {res.FailingReason}"); // Minus amountToSend = new Money(-1m, MoneyUnit.BTC); res = walletJob.BuildTransactionAsync(receive, amountToSend, FeeType.Low, account, allowUnconfirmed: true).Result; Assert.True(res.Success == false); Assert.True(res.FailingReason != ""); Debug.WriteLine($"Expected FailingReason: {res.FailingReason}"); // Default account is disabled amountToSend = (bal.Confirmed + bal.Unconfirmed) / 2; Assert.ThrowsAsync <NotSupportedException>(async() => await walletJob.BuildTransactionAsync(receive, amountToSend, FeeType.Low, allowUnconfirmed: true).ConfigureAwait(false)).ContinueWith(t => {}).Wait(); // No such account amountToSend = (bal.Confirmed + bal.Unconfirmed) / 2; Assert.ThrowsAsync <NotSupportedException>(async() => await walletJob.BuildTransactionAsync(receive, amountToSend, FeeType.Low, new SafeAccount(23421), allowUnconfirmed: true).ConfigureAwait(false)).ContinueWith(t => { }).Wait(); } finally { cts.Cancel(); Task.WhenAll(reportTask, walletJobTask).Wait(); } }
private void UpdateHistoryRelatedMembers() { // history var aliceHistory = _walletJob.GetSafeHistory(AliceAccount).OrderByDescending(x => x.TimeStamp); var bobHistory = _walletJob.GetSafeHistory(BobAccount).OrderByDescending(x => x.TimeStamp); var hra = new List <HistoryRecordModel>(); foreach (var rec in aliceHistory) { string height; if (rec.BlockHeight.Type == HeightType.Chain) { height = rec.BlockHeight.Value.ToString(); } else { height = ""; } hra.Add(new HistoryRecordModel { Amount = rec.Amount.ToString(true, true), Confirmed = rec.Confirmed, Height = height, TxId = rec.TransactionId.ToString() }); } _historyResponseAlice.History = hra.ToArray(); var hrb = new List <HistoryRecordModel>(); foreach (var rec in bobHistory) { string height; if (rec.BlockHeight.Type == HeightType.Chain) { height = rec.BlockHeight.Value.ToString(); } else { height = ""; } hrb.Add(new HistoryRecordModel { Amount = rec.Amount.ToString(true, true), Confirmed = rec.Confirmed, Height = height, TxId = rec.TransactionId.ToString() }); } _historyResponseBob.History = hrb.ToArray(); // balances var aa = _walletJob.GetBalance(out IDictionary <Coin, bool> unspentCoinsAlice, AliceAccount); _availableAlice = aa.Confirmed; _incomingAlice = aa.Unconfirmed; var ab = _walletJob.GetBalance(out IDictionary <Coin, bool> unspentCoinsBob, BobAccount); _availableBob = ab.Confirmed; _incomingBob = ab.Unconfirmed; // receive var ua = _walletJob.GetUnusedScriptPubKeys(AliceAccount, HdPathType.Receive).ToArray(); var ub = _walletJob.GetUnusedScriptPubKeys(BobAccount, HdPathType.Receive).ToArray(); _receiveResponseAlice.Addresses = new string[7]; _receiveResponseBob.Addresses = new string[7]; var network = _walletJob.Safe.Network; for (int i = 0; i < 7; i++) { if (ua[i] != null) { _receiveResponseAlice.Addresses[i] = ua[i].GetDestinationAddress(network).ToString(); } else { _receiveResponseAlice.Addresses[i] = ""; } if (ub[i] != null) { _receiveResponseBob.Addresses[i] = ub[i].GetDestinationAddress(network).ToString(); } else { _receiveResponseBob.Addresses[i] = ""; } } }