Exemple #1
0
        public async Task <UTXOChanges> GetUTXOs(
            string cryptoCode,
            [ModelBinder(BinderType = typeof(DestinationModelBinder))]
            DerivationStrategyBase extPubKey,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> confirmedBookmarks = null,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> unconfirmedBookmarks = null,
            bool longPolling = false)
        {
            unconfirmedBookmarks = unconfirmedBookmarks ?? new HashSet <Bookmark>();
            confirmedBookmarks   = confirmedBookmarks ?? new HashSet <Bookmark>();
            if (extPubKey == null)
            {
                throw new ArgumentNullException(nameof(extPubKey));
            }
            var         network            = GetNetwork(cryptoCode);
            var         chain              = ChainProvider.GetChain(network);
            var         repo               = RepositoryProvider.GetRepository(network);
            var         waitingTransaction = longPolling ? WaitingTransaction(extPubKey) : Task.FromResult(false);
            UTXOChanges changes            = null;

            while (true)
            {
                changes = new UTXOChanges();
                changes.CurrentHeight = chain.Height;
                var transactions = GetAnnotatedTransactions(repo, chain, extPubKey);
                Func <Script[], bool[]> matchScript = (scripts) => scripts.Select(s => transactions.GetKeyPath(s) != null).ToArray();

                var states = UTXOStateResult.CreateStates(matchScript,
                                                          unconfirmedBookmarks,
                                                          transactions.UnconfirmedTransactions.Values.Select(c => c.Record.Transaction),
                                                          confirmedBookmarks,
                                                          transactions.ConfirmedTransactions.Values.Select(c => c.Record.Transaction));

                changes.Confirmed   = SetUTXOChange(states.Confirmed);
                changes.Unconfirmed = SetUTXOChange(states.Unconfirmed, states.Confirmed.Actual);



                FillUTXOsInformation(changes.Confirmed.UTXOs, transactions, changes.CurrentHeight);
                FillUTXOsInformation(changes.Unconfirmed.UTXOs, transactions, changes.CurrentHeight);

                if (changes.HasChanges || !(await waitingTransaction))
                {
                    break;
                }
                waitingTransaction = Task.FromResult(false);                 //next time, will not wait
            }
            changes.DerivationStrategy = extPubKey;
            return(changes);
        }
Exemple #2
0
        public async Task <FileContentResult> Sync(
            [ModelBinder(BinderType = typeof(DestinationModelBinder))]
            DerivationStrategyBase extPubKey,
            [ModelBinder(BinderType = typeof(UInt256ModelBinding))]
            uint256 confHash = null,
            [ModelBinder(BinderType = typeof(UInt256ModelBinding))]
            uint256 unconfHash = null,
            bool noWait        = false)
        {
            if (extPubKey == null)
            {
                throw new ArgumentNullException(nameof(extPubKey));
            }

            var         waitingTransaction = noWait ? Task.FromResult(false) : WaitingTransaction(extPubKey);
            UTXOChanges changes            = null;
            var         getKeyPaths        = GetKeyPaths(extPubKey);
            var         matchScript        = MatchKeyPaths(getKeyPaths);

            while (true)
            {
                changes = new UTXOChanges();
                changes.CurrentHeight = Chain.Height;
                var transactions = GetAnnotatedTransactions(extPubKey);

                var unconf = transactions.Where(tx => tx.Height == MempoolHeight);
                var conf   = transactions.Where(tx => tx.Height != MempoolHeight);
                conf   = conf.TopologicalSort(DependsOn(conf.ToList())).ToList();
                unconf = unconf.OrderByDescending(t => t.Record.Inserted)
                         .TopologicalSort(DependsOn(unconf.ToList())).ToList();


                var states = UTXOStateResult.CreateStates(matchScript, unconfHash, unconf.Select(c => c.Record.Transaction), confHash, conf.Select(c => c.Record.Transaction));

                var conflicted = states.Unconfirmed.Actual.Conflicts
                                 .SelectMany(c => c.Value)
                                 .SelectMany(txid => transactions.GetByTxId(txid))
                                 .Where(a => a.Height == MempoolHeight)
                                 .Select(a => a.Record)
                                 .Distinct()
                                 .ToList();

                if (conflicted.Count != 0)
                {
                    Logs.Explorer.LogInformation($"Clean {conflicted.Count} conflicted transactions");
                    if (Logs.Explorer.IsEnabled(LogLevel.Debug))
                    {
                        foreach (var conflict in conflicted)
                        {
                            Logs.Explorer.LogDebug($"Transaction {conflict.Transaction.GetHash()} is conflicted");
                        }
                    }
                    Repository.CleanTransactions(extPubKey, conflicted);
                }

                changes.Confirmed   = SetUTXOChange(states.Confirmed);
                changes.Unconfirmed = SetUTXOChange(states.Unconfirmed, states.Confirmed.Actual);



                FillUTXOsInformation(changes.Confirmed.UTXOs, getKeyPaths, transactions, changes.CurrentHeight);
                FillUTXOsInformation(changes.Unconfirmed.UTXOs, getKeyPaths, transactions, changes.CurrentHeight);

                if (changes.HasChanges || !(await waitingTransaction))
                {
                    break;
                }
                waitingTransaction = Task.FromResult(false);                 //next time, will not wait
            }

            return(new FileContentResult(changes.ToBytes(), "application/octet-stream"));
        }