Ejemplo n.º 1
0
        public async Task <GetTransactionsResponse> GetTransactions(
            string cryptoCode,
            [ModelBinder(BinderType = typeof(DestinationModelBinder))]
            DerivationStrategyBase extPubKey,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> unconfirmedBookmarks = null,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> confirmedBookmarks = null,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> replacedBookmarks = null,
            bool includeTransaction = true,
            bool longPolling        = false)
        {
            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);
            GetTransactionsResponse response = null;

            while (true)
            {
                response = new GetTransactionsResponse();
                int currentHeight = chain.Height;
                response.Height = currentHeight;
                var txs = GetAnnotatedTransactions(repo, chain, extPubKey);
                foreach (var item in new[]
                {
                    new
                    {
                        TxSet = response.ConfirmedTransactions,
                        KnownBookmarks = confirmedBookmarks ?? new HashSet <Bookmark>(),
                        AnnotatedTx = txs.ConfirmedTransactions
                    },
                    new
                    {
                        TxSet = response.UnconfirmedTransactions,
                        KnownBookmarks = unconfirmedBookmarks ?? new HashSet <Bookmark>(),
                        AnnotatedTx = txs.UnconfirmedTransactions
                    },
                    new
                    {
                        TxSet = response.ReplacedTransactions,
                        KnownBookmarks = replacedBookmarks ?? new HashSet <Bookmark>(),
                        AnnotatedTx = txs.ReplacedTransactions
                    },
                })
                {
                    item.TxSet.Bookmark      = Bookmark.Start;
                    item.TxSet.KnownBookmark = item.KnownBookmarks.Contains(Bookmark.Start) ? Bookmark.Start : null;

                    BookmarkProcessor processor = new BookmarkProcessor(32 + 32 + 25);
                    foreach (var tx in item.AnnotatedTx.Values)
                    {
                        processor.PushNew();
                        processor.AddData(tx.Record.Transaction.GetHash());
                        processor.AddData(tx.Record.BlockHash ?? uint256.Zero);
                        processor.UpdateBookmark();

                        var txInfo = new TransactionInformation()
                        {
                            BlockHash     = tx.Record.BlockHash,
                            Height        = tx.Record.BlockHash == null ? null : tx.Height,
                            TransactionId = tx.Record.Transaction.GetHash(),
                            Transaction   = includeTransaction ? tx.Record.Transaction : null,
                            Confirmations = tx.Record.BlockHash == null ? 0 : currentHeight - tx.Height.Value + 1,
                            Timestamp     = txs.GetByTxId(tx.Record.Transaction.GetHash()).Select(t => t.Record.FirstSeen).First(),
                            Inputs        = ToMatch(txs, tx.Record.Transaction.Inputs.Select(o => txs.GetUTXO(o.PrevOut)).ToList(), extPubKey, tx.Record.TransactionMatch.Inputs),
                            Outputs       = ToMatch(txs, tx.Record.Transaction.Outputs, extPubKey, tx.Record.TransactionMatch.Outputs)
                        };

                        item.TxSet.Transactions.Add(txInfo);

                        txInfo.BalanceChange = txInfo.Outputs.Select(o => o.Value).Sum() - txInfo.Inputs.Select(o => o.Value).Sum();

                        item.TxSet.Bookmark = processor.CurrentBookmark;
                        if (item.KnownBookmarks.Contains(processor.CurrentBookmark))
                        {
                            item.TxSet.KnownBookmark = processor.CurrentBookmark;
                            item.TxSet.Transactions.Clear();
                        }
                    }
                }

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

            return(response);
        }
Ejemplo n.º 2
0
        public async Task <GetTransactionsResponse> GetTransactions(
            string cryptoCode,
            [ModelBinder(BinderType = typeof(DerivationStrategyModelBinder))]
            DerivationStrategyBase derivationScheme,
            [ModelBinder(BinderType = typeof(BitcoinAddressModelBinder))]
            BitcoinAddress address,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> unconfirmedBookmarks = null,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> confirmedBookmarks = null,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> replacedBookmarks = null,
            bool includeTransaction = true,
            bool longPolling        = false)
        {
            var trackedSource = GetTrackedSource(derivationScheme, address);

            if (trackedSource == null)
            {
                throw new ArgumentNullException(nameof(trackedSource));
            }
            GetTransactionsResponse response = null;

            using (CancellationTokenSource cts = new CancellationTokenSource())
            {
                if (longPolling)
                {
                    cts.CancelAfter(LongPollTimeout);
                }
                var network = GetNetwork(cryptoCode, false);
                var chain   = ChainProvider.GetChain(network);
                var repo    = RepositoryProvider.GetRepository(network);

                while (true)
                {
                    response = new GetTransactionsResponse();
                    int currentHeight = chain.Height;
                    response.Height = currentHeight;
                    var txs = await GetAnnotatedTransactions(repo, chain, trackedSource);

                    foreach (var item in new[]
                    {
                        new
                        {
                            TxSet = response.ConfirmedTransactions,
                            KnownBookmarks = confirmedBookmarks ?? new HashSet <Bookmark>(),
                            AnnotatedTx = txs.ConfirmedTransactions
                        },
                        new
                        {
                            TxSet = response.UnconfirmedTransactions,
                            KnownBookmarks = unconfirmedBookmarks ?? new HashSet <Bookmark>(),
                            AnnotatedTx = txs.UnconfirmedTransactions
                        },
                        new
                        {
                            TxSet = response.ReplacedTransactions,
                            KnownBookmarks = replacedBookmarks ?? new HashSet <Bookmark>(),
                            AnnotatedTx = txs.ReplacedTransactions
                        },
                    })
                    {
                        item.TxSet.Bookmark      = Bookmark.Start;
                        item.TxSet.KnownBookmark = item.KnownBookmarks.Contains(Bookmark.Start) ? Bookmark.Start : null;

                        BookmarkProcessor processor = new BookmarkProcessor(32 + 32 + 25);
                        foreach (var tx in item.AnnotatedTx)
                        {
                            processor.PushNew();
                            processor.AddData(tx.Record.TransactionHash);
                            processor.AddData(tx.Record.BlockHash ?? uint256.Zero);
                            processor.UpdateBookmark();

                            var txInfo = new TransactionInformation()
                            {
                                BlockHash     = tx.Height.HasValue ? tx.Record.BlockHash : null,
                                Height        = tx.Height,
                                TransactionId = tx.Record.TransactionHash,
                                Transaction   = includeTransaction ? tx.Record.Transaction : null,
                                Confirmations = tx.Height.HasValue ? currentHeight - tx.Height.Value + 1 : 0,
                                Timestamp     = txs.GetByTxId(tx.Record.TransactionHash).Select(t => t.Record.FirstSeen).First(),
                                Inputs        = tx.Record.SpentOutpoints.Select(o => txs.GetUTXO(o)).Where(o => o != null).ToList(),
                                Outputs       = tx.Record.GetReceivedOutputs(trackedSource).ToList()
                            };

                            item.TxSet.Transactions.Add(txInfo);

                            txInfo.BalanceChange = txInfo.Outputs.Select(o => o.Value).Sum() - txInfo.Inputs.Select(o => o.Value).Sum();

                            item.TxSet.Bookmark = processor.CurrentBookmark;
                            if (item.KnownBookmarks.Contains(processor.CurrentBookmark))
                            {
                                item.TxSet.KnownBookmark = processor.CurrentBookmark;
                                item.TxSet.Transactions.Clear();
                            }
                        }
                    }

                    if (!longPolling || response.HasChanges())
                    {
                        break;
                    }
                    if (!await WaitingTransaction(trackedSource, cts.Token))
                    {
                        break;
                    }
                }
            }
            return(response);
        }