private Dictionary <YearMonth, Money> CalculateNeverMixedFromTx0s(RPCClient rpc, IEnumerable <VerboseTransactionInfo> samuriCjs, IEnumerable <VerboseTransactionInfo> samuriTx0s) { KnotsStatus.CheckAsync(rpc).GetAwaiter().GetResult(); // Go through all the outputs of TX0 transactions. // If an output is spent and didn't go to coinjoins or other TX0s, then it didn't get remixed. var samuriTx0CjInputs = samuriCjs .SelectMany(x => x.Inputs) .Select(x => x.OutPoint) .Union( samuriTx0s .SelectMany(x => x.Inputs) .Select(x => x.OutPoint)) .ToHashSet(); var myDic = new Dictionary <YearMonth, Money>(); VerboseTransactionInfo[] samuriTx0sArray = samuriTx0s.ToArray(); for (int i = 0; i < samuriTx0sArray.Length; i++) { var reportProgress = ((i + 1) % 100) == 0; if (reportProgress) { Logger.LogInfo($"{i + 1}/{samuriTx0sArray.Length}"); } VerboseTransactionInfo tx = samuriTx0sArray[i]; var blockTime = tx.BlockInfo.BlockTime; if (blockTime.HasValue) { var blockTimeValue = blockTime.Value; var yearMonth = new YearMonth(blockTimeValue.Year, blockTimeValue.Month); var sum = Money.Zero; VerboseOutputInfo[] outputArray = tx.Outputs.ToArray(); for (int j = 0; j < outputArray.Length; j++) { var output = outputArray[j]; OutPoint outPoint = new OutPoint(tx.Id, j); if (!samuriTx0CjInputs.Contains(outPoint) && rpc.GetTxOut(outPoint.Hash, (int)outPoint.N, includeMempool: false) is null) { sum += output.Value; } } if (myDic.TryGetValue(yearMonth, out Money current)) { myDic[yearMonth] = current + sum; } else { myDic.Add(yearMonth, sum); } } } return(myDic); }
private Dictionary <YearMonth, Money> CalculateNeverMixed(RPCClient rpc, IEnumerable <VerboseTransactionInfo> coinJoins) { KnotsStatus.CheckAsync(rpc).GetAwaiter().GetResult(); // Go through all the coinjoins. // If a change output is spent and didn't go to coinjoins, then it didn't get remixed. var coinJoinInputs = coinJoins .SelectMany(x => x.Inputs) .Select(x => x.OutPoint) .ToHashSet(); var myDic = new Dictionary <YearMonth, Money>(); VerboseTransactionInfo[] coinJoinsArray = coinJoins.ToArray(); for (int i = 0; i < coinJoinsArray.Length; i++) { var reportProgress = ((i + 1) % 100) == 0; if (reportProgress) { Logger.LogInfo($"{i + 1}/{coinJoinsArray.Length}"); } VerboseTransactionInfo tx = coinJoinsArray[i]; var blockTime = tx.BlockInfo.BlockTime; if (blockTime.HasValue) { var blockTimeValue = blockTime.Value; var yearMonth = new YearMonth(blockTimeValue.Year, blockTimeValue.Month); var sum = Money.Zero; var changeOutputValues = tx.GetIndistinguishableOutputs(includeSingle: true).Where(x => x.count == 1).Select(x => x.value).ToHashSet(); VerboseOutputInfo[] outputArray = tx.Outputs.ToArray(); for (int j = 0; j < outputArray.Length; j++) { var output = outputArray[j]; // If it's a change and it didn't get remixed right away. OutPoint outPoint = new OutPoint(tx.Id, j); if (changeOutputValues.Contains(output.Value) && !coinJoinInputs.Contains(outPoint) && rpc.GetTxOut(outPoint.Hash, (int)outPoint.N, includeMempool: false) is null) { sum += output.Value; } } if (myDic.TryGetValue(yearMonth, out Money current)) { myDic[yearMonth] = current + sum; } else { myDic.Add(yearMonth, sum); } } } return(myDic); }
public Scanner(RPCClient rpc) { Rpc = rpc; Directory.CreateDirectory(WorkFolder); KnotsStatus.CheckAsync(rpc).GetAwaiter().GetResult(); }