async Task EnsureMineToAddresses() { var mineToAddresses = new List <BitcoinWitPubKeyAddress>(); if (this.appConfiguration.MineToAddress != null) { mineToAddresses.Add(this.appConfiguration.MineToAddress); this.logger.LogInformation($"Mining to address {this.appConfiguration.MineToAddress} (set in x1-producer.config)."); AddressCache.SetMineToAddresses(mineToAddresses); return; } this.logger.LogInformation("Trying to extract mine-to-addresses from the wallet. The wallet must contain at least one unspent output."); while (true) { try { var getUnspentOutputsResponse = await this.rpcClient.GetUnspentOutputs(); if (getUnspentOutputsResponse.Status != 200) { throw new InvalidOperationException(getUnspentOutputsResponse.StatusText); } var unspentOutputs = getUnspentOutputsResponse.Result.result .Where(x => x.address != null) .DistinctBy(x => x.address).ToArray(); if (unspentOutputs.Length == 0) { throw new InvalidOperationException($"Unable to extract addresses for mining from the wallet because it doesn't contain unspent outputs. " + $"You can set an address in x1-producer config: minetoaddress=x11..."); } bool useMiningLabelPrefix = unspentOutputs.Any(x => HasMiningLabelPrefix(x.label)); this.logger.LogInformation(useMiningLabelPrefix ? $"Extracting mine-to addresses where its label is prefixed with '{MiningLabelPrefix}'." : $"Using all addresses as mine-to addresses, because no address has its label prefixed with '{MiningLabelPrefix}'."); foreach (var output in unspentOutputs) { if (!output.spendable || !output.solvable) { continue; } if (useMiningLabelPrefix && !HasMiningLabelPrefix(output.label)) { continue; } try { // use every address that is a valid WPKH address. mineToAddresses.Add(new BitcoinWitPubKeyAddress(output.address, C.Network)); } // ReSharper disable once EmptyGeneralCatchClause catch { } } if (mineToAddresses.Count > 0) { this.logger.LogInformation($"Imported {mineToAddresses.Count} addresses for mining."); AddressCache.SetMineToAddresses(mineToAddresses); return; } throw new InvalidOperationException("No addresses for mining."); } catch (Exception e) { this.logger.LogError($"Error retrieving addresses for mining: {e.Message} Retrying..."); await Task.Delay(2000); } } }