Beispiel #1
0
        public static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                                .SetBasePath(Directory.GetCurrentDirectory())
                                .AddJsonFile("appsettings.json", optional: false)
                                .Build();

            var rpcConfig = configuration.GetSection("RpcConfig").Get <RpcConfig>();

            rpcClient = new WalletRpcClient(rpcConfig.Port, rpcConfig.User, rpcConfig.Password, rpcConfig.Passphrase);

            optionsBuilder = new DbContextOptionsBuilder <DataContext>();
            optionsBuilder.UseSqlServer(configuration.GetConnectionString("Database"));

            serviceBusConnectionString = configuration.GetConnectionString("ServiceBusConnectionString");
            sendCoinsQueueName         = configuration.GetConnectionString("SendCoinsQueueName");

            contractAddress = configuration.GetValue <string>("ContractAddress");
            network         = configuration.GetValue <string>("Network");
            nrOfCoins       = configuration.GetValue <decimal>("NrOfCoins");
            sleepTime       = configuration.GetValue <int>("SleepTime");

            sendCoinsQueueWriter = new QueueWriter <SendCoinsMessage>(serviceBusConnectionString, sendCoinsQueueName);

            dataManager = new DataManager(() => new DataContext(optionsBuilder.Options));

            MainAsync().GetAwaiter().GetResult();
        }
        private async Task OnWalletProcessOpenedWallet()
        {
            try
            {
                var sdiff = await WalletRpcClient.TicketPriceAsync();

                await App.Current.Dispatcher.InvokeAsync(() => TicketPrice = sdiff);

                var syncingWallet = await WalletRpcClient.Synchronize(OnWalletChangesProcessed);

                WalletMutex = syncingWallet.Item1;
                using (var guard = await WalletMutex.LockAsync())
                {
                    OnSyncedWallet(guard.Instance);
                }

                var   syncTask = syncingWallet.Item2;
                await syncTask;
            }
            catch (ConnectTimeoutException)
            {
                MessageBox.Show("Unable to connect to wallet");
            }
            catch (Grpc.Core.RpcException) when(WalletRpcClient.CancellationRequested)
            {
            }
            catch (Exception ex)
            {
                var ae = ex as AggregateException;
                if (ae != null)
                {
                    Exception inner;
                    if (ae.TryUnwrap(out inner))
                    {
                        ex = inner;
                    }
                }

                await HandleSyncFault(ex);
            }
            finally
            {
                if (WalletMutex != null)
                {
                    using (var walletGuard = await WalletMutex.LockAsync())
                    {
                        walletGuard.Instance.ChangesProcessed -= OnWalletChangesProcessed;
                    }
                }

                var shell = (ShellViewModel)ViewModelLocator.ShellViewModel;
                shell.StartupWizardVisible = true;
            }
        }
Beispiel #3
0
        private async Task OnWalletProcessOpenedWallet()
        {
            try
            {
                var syncingWallet = await WalletRpcClient.Synchronize(OnWalletChangesProcessed);

                Wallet = syncingWallet.Item1;
                OnSyncedWallet();

                var   syncTask = syncingWallet.Item2;
                await syncTask;
            }
            catch (ConnectTimeoutException)
            {
                MessageBox.Show("Unable to connect to wallet");
            }
            catch (Exception ex)
            {
                var ae = ex as AggregateException;
                if (ae != null)
                {
                    Exception inner;
                    if (ae.TryUnwrap(out inner))
                    {
                        ex = inner;
                    }
                }

                HandleSyncFault(ex);
            }
            finally
            {
                var wallet = Wallet;
                if (wallet != null)
                {
                    wallet.ChangesProcessed -= OnWalletChangesProcessed;
                }
                var shell = (ShellViewModel)ViewModelLocator.ShellViewModel;
                shell.StartupWizardVisible = true;
            }
        }
        public void Initialize()
        {
            if (ConfigService.DaemonPort != null)
            {
                if (!string.IsNullOrWhiteSpace(ConfigService.DaemonPasswordProxyHeader) && !string.IsNullOrWhiteSpace(ConfigService.DaemonPassword))
                {
                    DaemonRpcClient = new DaemonRpcClient(ConfigService.DaemonHost, ConfigService.DaemonPort.Value, null, null, null, client => client.DefaultRequestHeaders.Add(ConfigService.DaemonPasswordProxyHeader, ConfigService.DaemonPassword));
                }
                else
                {
                    DaemonRpcClient = new DaemonRpcClient(ConfigService.DaemonHost, ConfigService.DaemonPort.Value, ConfigService.DaemonUsername, ConfigService.DaemonPassword);
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(ConfigService.DaemonPasswordProxyHeader) && !string.IsNullOrWhiteSpace(ConfigService.DaemonPassword))
                {
                    DaemonRpcClient = new DaemonRpcClient(ConfigService.DaemonHost, null, null, null, client => client.DefaultRequestHeaders.Add(ConfigService.DaemonPasswordProxyHeader, ConfigService.DaemonPassword));
                }
                else
                {
                    DaemonRpcClient = new DaemonRpcClient(ConfigService.DaemonHost, ConfigService.DaemonUsername, ConfigService.DaemonPassword);
                }
            }

            if (ConfigService.WalletPort != null)
            {
                if (!string.IsNullOrWhiteSpace(ConfigService.WalletPasswordProxyHeader) && !string.IsNullOrWhiteSpace(ConfigService.WalletPassword))
                {
                    WalletRpcClient = new WalletRpcClient(ConfigService.WalletHost, ConfigService.WalletPort.Value, null, null, null, client => client.DefaultRequestHeaders.Add(ConfigService.WalletPasswordProxyHeader, ConfigService.WalletPassword));
                }
                else
                {
                    WalletRpcClient = new WalletRpcClient(ConfigService.WalletHost, ConfigService.WalletPort.Value, ConfigService.WalletUsername, ConfigService.WalletPassword);
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(ConfigService.WalletPasswordProxyHeader) && !string.IsNullOrWhiteSpace(ConfigService.WalletPassword))
                {
                    WalletRpcClient = new WalletRpcClient(ConfigService.WalletHost, null, null, null, client => client.DefaultRequestHeaders.Add(ConfigService.WalletPasswordProxyHeader, ConfigService.WalletPassword));
                }
                else
                {
                    WalletRpcClient = new WalletRpcClient(ConfigService.WalletHost, ConfigService.WalletUsername, ConfigService.WalletPassword);
                }
            }

            Program.TasksToAwait.Add(Task.Factory.StartNew(async() =>
            {
                NextCheck = DateTimeOffset.Now.AddMinutes(15);

                while (!Program.CancellationTokenSource.IsCancellationRequested)
                {
                    if (DateTimeOffset.Now < NextCheck)
                    {
                        await Task.Delay(1000).ConfigureAwait(false);
                        continue;
                    }

                    try
                    {
                        await LoggerService.LogMessageAsync("Attempting to save the wallet...").ConfigureAwait(false);
                        await WalletRpcClient.StoreAsync(Program.CancellationTokenSource.Token).ConfigureAwait(false);
                        await LoggerService.LogMessageAsync("Save complete!", ConsoleColor.Green).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        await LoggerService.LogErrorMessageAsync(ex).ConfigureAwait(false);
                    }
                    finally
                    {
                        NextCheck = DateTimeOffset.Now.AddMinutes(15);
                    }
                }
            }, Program.CancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current).Unwrap());
        }
 public void Dispose()
 {
     DaemonRpcClient?.Dispose();
     WalletRpcClient?.Dispose();
 }
        private void OnWalletChangesProcessed(object sender, Wallet.ChangesProcessedEventArgs e)
        {
            var wallet        = (Wallet)sender;
            var currentHeight = e.NewChainTip?.Height ?? SyncedBlockHeight;

            // TODO: The OverviewViewModel should probably connect to this event.  This could be
            // done after the wallet is synced.
            var overviewViewModel = ViewModelLocator.OverviewViewModel as OverviewViewModel;

            if (overviewViewModel != null)
            {
                var movedTxViewModels = overviewViewModel.RecentTransactions
                                        .Where(txvm => e.MovedTransactions.ContainsKey(txvm.TxHash))
                                        .Select(txvm => Tuple.Create(txvm, e.MovedTransactions[txvm.TxHash]));

                var newTxViewModels = e.AddedTransactions.Select(tx => new TransactionViewModel(wallet, tx.Item1, tx.Item2)).ToList();

                foreach (var movedTx in movedTxViewModels)
                {
                    var txvm     = movedTx.Item1;
                    var location = movedTx.Item2;

                    txvm.Location = location;
                    txvm.Depth    = BlockChain.Depth(currentHeight, location);
                }

                App.Current.Dispatcher.Invoke(() =>
                {
                    foreach (var txvm in newTxViewModels)
                    {
                        overviewViewModel.RecentTransactions.Insert(0, txvm);
                    }
                    while (overviewViewModel.RecentTransactions.Count > 10)
                    {
                        overviewViewModel.RecentTransactions.RemoveAt(10);
                    }
                });
            }

            // TODO: same.. in fact these tx viewmodels should be reused so changes don't need to be recalculated.
            // It would be a good idea for this synchronzier viewmodel to manage these and hand them out to other
            // viewmodels for sorting and organization.
            var transactionHistoryViewModel = ViewModelLocator.TransactionHistoryViewModel as TransactionHistoryViewModel;

            if (transactionHistoryViewModel != null)
            {
                foreach (var tx in transactionHistoryViewModel.Transactions)
                {
                    var           txvm = tx.Transaction;
                    BlockIdentity newLocation;
                    if (e.MovedTransactions.TryGetValue(txvm.TxHash, out newLocation))
                    {
                        txvm.Location = newLocation;
                    }
                    txvm.Depth = BlockChain.Depth(currentHeight, txvm.Location);
                }

                transactionHistoryViewModel.AppendNewTransactions(wallet, e.AddedTransactions);
            }

            foreach (var modifiedAccount in e.ModifiedAccountProperties)
            {
                var accountNumber     = checked ((int)modifiedAccount.Key.AccountNumber);
                var accountProperties = modifiedAccount.Value;

                if (accountNumber < Accounts.Count)
                {
                    Accounts[accountNumber].AccountProperties = accountProperties;
                }
            }

            // TODO: this would be better if all new accounts were a field in the event message.
            var newAccounts = e.ModifiedAccountProperties.
                              Where(kvp => kvp.Key.AccountNumber >= Accounts.Count && kvp.Key.AccountNumber != Wallet.ImportedAccountNumber).
                              OrderBy(kvp => kvp.Key.AccountNumber);

            foreach (var modifiedAccount in newAccounts)
            {
                var accountNumber     = checked ((int)modifiedAccount.Key.AccountNumber);
                var accountProperties = modifiedAccount.Value;

                // TODO: This is very inefficient because it recalculates balances of every account, for each new account.
                var accountBalance   = wallet.CalculateBalances(2)[accountNumber];
                var accountViewModel = new AccountViewModel(modifiedAccount.Key, accountProperties, accountBalance);
                App.Current.Dispatcher.Invoke(() => Accounts.Add(accountViewModel));
            }

            if (e.NewChainTip != null)
            {
                SyncedBlockHeight = e.NewChainTip.Value.Height;
                var oldRetarget = BlocksUntilTicketPriceRetarget;
                BlocksUntilTicketPriceRetarget = BlockChain.BlocksUntilTicketPriceRetarget(SyncedBlockHeight, wallet.ActiveChain);
                if (BlocksUntilTicketPriceRetarget > oldRetarget)
                {
                    Task.Run(async() =>
                    {
                        var sdiff = await WalletRpcClient.TicketPriceAsync();
                        await App.Current.Dispatcher.InvokeAsync(() => TicketPrice = sdiff);
                    }).ContinueWith(t =>
                    {
                        if (t.Exception != null)
                        {
                            MessageBox.Show(t.Exception.InnerException.Message, "Error querying ticket price");
                        }
                    });
                }
            }
            if (e.AddedTransactions.Count != 0 || e.RemovedTransactions.Count != 0 || e.NewChainTip != null)
            {
                TotalBalance      = wallet.TotalBalance;
                TransactionCount += e.AddedTransactions.Count - e.RemovedTransactions.Count;
                var balances = wallet.CalculateBalances(2); // TODO: don't hardcode confs
                for (var i = 0; i < balances.Length; i++)
                {
                    Accounts[i].Balances = balances[i];
                }
            }
        }