Fix api getfundingaddresses bug

This change uses recently added walletService.isAddressUnused to ensure
the api's CoreWalletsService creates an unused address if none exists.

- grpc.proto:  Add bool isAddressUnused field to message AddressBalanceInfo.
- AddressBalanceInfo:  Adjust AddressBalanceInfo proto wrapper.
- CoreWalletsService:  Use walletService.isAddressUnused in getFundingAddresses.
- GrpcClient:  Adjust to modified AddressBalanceInfo.
- TableFormat, ColumnHeaderConstants:  Add 'Is Used' column to getfundingaddresses output.

Note: bugfix is out of scope for this PR, but the test case helped expose this bug.
This commit is contained in:
ghubstan 2021-03-15 16:15:06 -03:00
parent 588541ed15
commit 8783889c36
No known key found for this signature in database
GPG key ID: E35592D6800A861E
6 changed files with 36 additions and 14 deletions

View file

@ -42,6 +42,7 @@ class ColumnHeaderConstants {
static final String COL_HEADER_UNLOCKING_BONDS_BALANCE = "Unlocking Bonds Balance";
static final String COL_HEADER_UNVERIFIED_BALANCE = "Unverified Balance";
static final String COL_HEADER_CONFIRMATIONS = "Confirmations";
static final String COL_HEADER_IS_USED_ADDRESS = "Is Used";
static final String COL_HEADER_CREATION_DATE = padEnd("Creation Date (UTC)", 20, ' ');
static final String COL_HEADER_CURRENCY = "Currency";
static final String COL_HEADER_DIRECTION = "Buy/Sell";

View file

@ -135,11 +135,11 @@ public final class GrpcClient {
public String getUnusedBtcAddress() {
var request = GetFundingAddressesRequest.newBuilder().build();
var addressBalances = grpcStubs.walletsService.getFundingAddresses(request)
.getAddressBalanceInfoList();
//noinspection OptionalGetWithoutIsPresent
return grpcStubs.walletsService.getFundingAddresses(request)
.getAddressBalanceInfoList()
.stream()
.filter(a -> a.getBalance() == 0 && a.getNumConfirmations() == 0)
return addressBalances.stream()
.filter(AddressBalanceInfo::getIsAddressUnused)
.findFirst()
.get()
.getAddress();

View file

@ -51,18 +51,21 @@ public class TableFormat {
public static String formatAddressBalanceTbl(List<AddressBalanceInfo> addressBalanceInfo) {
String headerFormatString = COL_HEADER_ADDRESS + COL_HEADER_DELIMITER
+ COL_HEADER_AVAILABLE_BALANCE + COL_HEADER_DELIMITER
+ COL_HEADER_CONFIRMATIONS + COL_HEADER_DELIMITER + "\n";
+ COL_HEADER_CONFIRMATIONS + COL_HEADER_DELIMITER
+ COL_HEADER_IS_USED_ADDRESS + COL_HEADER_DELIMITER + "\n";
String headerLine = format(headerFormatString, "BTC");
String colDataFormat = "%-" + COL_HEADER_ADDRESS.length() + "s" // lt justify
+ " %" + (COL_HEADER_AVAILABLE_BALANCE.length() - 1) + "s" // rt justify
+ " %" + COL_HEADER_CONFIRMATIONS.length() + "d"; // lt justify
+ " %" + COL_HEADER_CONFIRMATIONS.length() + "d" // lt justify
+ " %" + COL_HEADER_IS_USED_ADDRESS.length() + "s"; // lt justify
return headerLine
+ addressBalanceInfo.stream()
.map(info -> format(colDataFormat,
info.getAddress(),
formatSatoshis(info.getBalance()),
info.getNumConfirmations()))
info.getNumConfirmations(),
info.getIsAddressUnused() ? "NO" : "YES"))
.collect(Collectors.joining("\n"));
}

View file

@ -159,15 +159,22 @@ class CoreWalletsService {
AddressBalanceInfo getAddressBalanceInfo(String addressString) {
var satoshiBalance = getAddressBalance(addressString);
var numConfirmations = getNumConfirmationsForMostRecentTransaction(addressString);
return new AddressBalanceInfo(addressString, satoshiBalance, numConfirmations);
Address address = getAddressEntry(addressString).getAddress();
return new AddressBalanceInfo(addressString,
satoshiBalance,
numConfirmations,
btcWalletService.isAddressUnused(address));
}
List<AddressBalanceInfo> getFundingAddresses() {
verifyWalletsAreAvailable();
verifyEncryptedWalletIsUnlocked();
// Create a new funding address if none exists.
if (btcWalletService.getAvailableAddressEntries().isEmpty())
// Create a new unused funding address if none exists.
boolean unusedAddressExists = btcWalletService.getAvailableAddressEntries()
.stream()
.anyMatch(a -> btcWalletService.isAddressUnused(a.getAddress()));
if (!unusedAddressExists)
btcWalletService.getFreshAddressEntry();
List<String> addressStrings = btcWalletService
@ -192,7 +199,8 @@ class CoreWalletsService {
return addressStrings.stream().map(address ->
new AddressBalanceInfo(address,
balances.getUnchecked(address),
getNumConfirmationsForMostRecentTransaction(address)))
getNumConfirmationsForMostRecentTransaction(address),
btcWalletService.isAddressUnused(getAddressEntry(address).getAddress())))
.collect(Collectors.toList());
}

View file

@ -24,11 +24,16 @@ public class AddressBalanceInfo implements Payload {
private final String address;
private final long balance; // address' balance in satoshis
private final long numConfirmations; // # confirmations for address' most recent tx
private final boolean isAddressUnused;
public AddressBalanceInfo(String address, long balance, long numConfirmations) {
public AddressBalanceInfo(String address,
long balance,
long numConfirmations,
boolean isAddressUnused) {
this.address = address;
this.balance = balance;
this.numConfirmations = numConfirmations;
this.isAddressUnused = isAddressUnused;
}
///////////////////////////////////////////////////////////////////////////////////////////
@ -40,13 +45,16 @@ public class AddressBalanceInfo implements Payload {
return bisq.proto.grpc.AddressBalanceInfo.newBuilder()
.setAddress(address)
.setBalance(balance)
.setNumConfirmations(numConfirmations).build();
.setNumConfirmations(numConfirmations)
.setIsAddressUnused(isAddressUnused)
.build();
}
public static AddressBalanceInfo fromProto(bisq.proto.grpc.AddressBalanceInfo proto) {
return new AddressBalanceInfo(proto.getAddress(),
proto.getBalance(),
proto.getNumConfirmations());
proto.getNumConfirmations(),
proto.getIsAddressUnused());
}
@Override
@ -55,6 +63,7 @@ public class AddressBalanceInfo implements Payload {
"address='" + address + '\'' +
", balance=" + balance +
", numConfirmations=" + numConfirmations +
", isAddressUnused=" + isAddressUnused +
'}';
}
}

View file

@ -540,6 +540,7 @@ message AddressBalanceInfo {
string address = 1;
int64 balance = 2;
int64 numConfirmations = 3;
bool isAddressUnused = 4;
}
///////////////////////////////////////////////////////////////////////////////////////////