public Transaction GetTransaction(uint256 txId) { RPCWalletEntry entry = null; if (_WalletEntries.TryGetValue(txId, out entry)) { return(entry.Transaction); } return(null); }
private void RemoveTxByScriptId(RPCWalletEntry entry) { IEnumerable <Script> scripts = GetScriptsOf(entry.Transaction); lock (_TxByScriptId) { foreach (var s in scripts) { _TxByScriptId.Remove(s, entry); } } }
private void AddTxByScriptId(uint256 txId, RPCWalletEntry entry) { IEnumerable <Script> scripts = GetScriptsOf(entry.Transaction); lock (_TxByScriptId) { foreach (var s in scripts) { _TxByScriptId.Add(s, entry); } } }
public void ImportTransaction(Transaction transaction, int confirmations) { var txId = transaction.GetHash(); var entry = new RPCWalletEntry() { Confirmations = confirmations, TransactionId = transaction.GetHash(), Transaction = transaction }; if (_WalletEntries.TryAdd(txId, entry)) { AddTxByScriptId(txId, entry); } }
List <RPCWalletEntry> ListTransactions(ref HashSet <uint256> knownTransactions) { List <RPCWalletEntry> array = new List <RPCWalletEntry>(); knownTransactions = new HashSet <uint256>(); var removeFromCache = new HashSet <uint256>(_TransactionsByTxId.Values.Select(tx => tx.GetHash())); int count = 100; int skip = 0; int highestConfirmation = 0; while (true) { var result = _RPCClient.SendCommandNoThrows("listtransactions", "*", count, skip, true); skip += count; if (result.Error != null) { return(null); } var transactions = (JArray)result.Result; foreach (var obj in transactions) { var entry = new RPCWalletEntry(); entry.Confirmations = obj["confirmations"] == null ? 0 : (int)obj["confirmations"]; entry.TransactionId = new uint256((string)obj["txid"]); removeFromCache.Remove(entry.TransactionId); if (knownTransactions.Add(entry.TransactionId)) { array.Add(entry); } if (obj["confirmations"] != null) { highestConfirmation = Math.Max(highestConfirmation, (int)obj["confirmations"]); } } if (transactions.Count < count || highestConfirmation >= 1400) { break; } } foreach (var remove in removeFromCache) { Transaction opt; _TransactionsByTxId.TryRemove(remove, out opt); } return(array); }
void ListTransactions() { var removeFromWalletEntries = new HashSet <uint256>(_WalletEntries.Keys); int count = 100; int skip = 0; int highestConfirmation = 0; while (true) { var result = _RPCClient.SendCommand("listtransactions", "*", count, skip, true); skip += count; var transactions = (JArray)result.Result; var batch = _RPCClient.PrepareBatch(); var fetchingTransactions = new List <Tuple <RPCWalletEntry, Task <Transaction> > >(); foreach (var obj in transactions) { var entry = new RPCWalletEntry(); entry.Confirmations = obj["confirmations"] == null ? 0 : (int)obj["confirmations"]; entry.TransactionId = new uint256((string)obj["txid"]); removeFromWalletEntries.Remove(entry.TransactionId); RPCWalletEntry existing; if (_WalletEntries.TryGetValue(entry.TransactionId, out existing)) { existing.Confirmations = entry.Confirmations; entry = existing; } if (entry.Transaction == null) { fetchingTransactions.Add(Tuple.Create(entry, FetchTransactionAsync(batch, entry.TransactionId))); } if (obj["confirmations"] != null) { highestConfirmation = Math.Max(highestConfirmation, (int)obj["confirmations"]); } } batch.SendBatchAsync(); foreach (var fetching in fetchingTransactions) { var entry = fetching.Item1; entry.Transaction = fetching.Item2.GetAwaiter().GetResult(); if (entry.Transaction != null) { if (_WalletEntries.TryAdd(entry.TransactionId, entry)) { AddTxByScriptId(entry.TransactionId, entry); } } } if (transactions.Count < count || highestConfirmation >= 1400) { break; } } foreach (var remove in removeFromWalletEntries) { RPCWalletEntry opt; _WalletEntries.TryRemove(remove, out opt); } }
void ListTransactions() { var removeFromWalletEntries = new HashSet <uint256>(_WalletEntries.Keys); int count = 100; int skip = 0; HashSet <uint256> processedTransacions = new HashSet <uint256>(); int updatedConfirmationGap = -1; //If this one is true after asking for a batch, just update every "removeFromWalletEntries" transactions by updatedConfirmationGap bool canMakeSimpleUpdate = false; bool transactionTooOld = false; while (true) { updatedConfirmationGap = -1; canMakeSimpleUpdate = false; var result = _RPCClient.SendCommand("listtransactions", "*", count, skip, true); skip += count; var transactions = (JArray)result.Result; if (transactions.Count < count) { updatedConfirmationGap = 0; canMakeSimpleUpdate = false; } var batch = _RPCClient.PrepareBatch(); var fetchingTransactions = new List <Tuple <RPCWalletEntry, Task <Transaction> > >(); foreach (var obj in transactions) { var entry = new RPCWalletEntry(); entry.Confirmations = obj["confirmations"] == null ? 0 : (int)obj["confirmations"]; if (entry.Confirmations >= MaxConfirmations) { transactionTooOld = true; break; } entry.TransactionId = new uint256((string)obj["txid"]); if (!processedTransacions.Add(entry.TransactionId)) { continue; } removeFromWalletEntries.Remove(entry.TransactionId); RPCWalletEntry existing; if (_WalletEntries.TryGetValue(entry.TransactionId, out existing)) { var confirmationGap = entry.Confirmations - existing.Confirmations; if (entry.Confirmations == 0) { updatedConfirmationGap = 0; canMakeSimpleUpdate = false; } if (updatedConfirmationGap != -1 && updatedConfirmationGap != confirmationGap) { canMakeSimpleUpdate = false; } if (updatedConfirmationGap == -1) { canMakeSimpleUpdate = true; updatedConfirmationGap = confirmationGap; } existing.Confirmations = entry.Confirmations; entry = existing; } if (entry.Transaction == null) { fetchingTransactions.Add(Tuple.Create(entry, FetchTransactionAsync(batch, entry.TransactionId))); } } batch.SendBatchAsync(); foreach (var fetching in fetchingTransactions) { var entry = fetching.Item1; entry.Transaction = fetching.Item2.GetAwaiter().GetResult(); if (entry.Transaction != null) { if (_WalletEntries.TryAdd(entry.TransactionId, entry)) { AddTxByScriptId(entry.TransactionId, entry); } } } if (transactions.Count < count || transactionTooOld || canMakeSimpleUpdate) { break; } } if (canMakeSimpleUpdate) { foreach (var tx in removeFromWalletEntries.ToList()) { RPCWalletEntry entry = null; if (_WalletEntries.TryGetValue(tx, out entry)) { if (entry.Confirmations != 0) { entry.Confirmations += updatedConfirmationGap; if (entry.Confirmations <= MaxConfirmations) { removeFromWalletEntries.Remove(entry.TransactionId); } } } } } foreach (var remove in removeFromWalletEntries) { RPCWalletEntry opt; if (_WalletEntries.TryRemove(remove, out opt)) { RemoveTxByScriptId(opt); } } }