Set WalletsManager key if missing

This change sets the WalletsManager key the first time `unlockwallet` is called.
This is necessary because the key cannot be set during api daemon startup, as it
normally is at UI startup.  See commit eb15fda229.
This commit is contained in:
ghubstan 2021-03-20 18:38:33 -03:00
parent eb15fda229
commit 838595cb03
No known key found for this signature in database
GPG key ID: E35592D6800A861E

View file

@ -22,6 +22,7 @@ import bisq.core.api.model.BalancesInfo;
import bisq.core.api.model.BsqBalanceInfo; import bisq.core.api.model.BsqBalanceInfo;
import bisq.core.api.model.BtcBalanceInfo; import bisq.core.api.model.BtcBalanceInfo;
import bisq.core.api.model.TxFeeRateInfo; import bisq.core.api.model.TxFeeRateInfo;
import bisq.core.app.AppStartupState;
import bisq.core.btc.Balances; import bisq.core.btc.Balances;
import bisq.core.btc.exceptions.AddressEntryException; import bisq.core.btc.exceptions.AddressEntryException;
import bisq.core.btc.exceptions.BsqChangeBelowDustException; import bisq.core.btc.exceptions.BsqChangeBelowDustException;
@ -30,6 +31,7 @@ import bisq.core.btc.exceptions.TransactionVerificationException;
import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.exceptions.WalletException;
import bisq.core.btc.model.AddressEntry; import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.model.BsqTransferModel; import bisq.core.btc.model.BsqTransferModel;
import bisq.core.btc.setup.WalletsSetup;
import bisq.core.btc.wallet.BsqTransferService; import bisq.core.btc.wallet.BsqTransferService;
import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.BtcWalletService;
@ -89,8 +91,11 @@ import static java.util.concurrent.TimeUnit.SECONDS;
@Slf4j @Slf4j
class CoreWalletsService { class CoreWalletsService {
private final AppStartupState appStartupState;
private final CoreContext coreContext;
private final Balances balances; private final Balances balances;
private final WalletsManager walletsManager; private final WalletsManager walletsManager;
private final WalletsSetup walletsSetup;
private final BsqWalletService bsqWalletService; private final BsqWalletService bsqWalletService;
private final BsqTransferService bsqTransferService; private final BsqTransferService bsqTransferService;
private final BsqFormatter bsqFormatter; private final BsqFormatter bsqFormatter;
@ -108,8 +113,11 @@ class CoreWalletsService {
private final ListeningExecutorService executor = Utilities.getSingleThreadListeningExecutor("CoreWalletsService"); private final ListeningExecutorService executor = Utilities.getSingleThreadListeningExecutor("CoreWalletsService");
@Inject @Inject
public CoreWalletsService(Balances balances, public CoreWalletsService(AppStartupState appStartupState,
CoreContext coreContext,
Balances balances,
WalletsManager walletsManager, WalletsManager walletsManager,
WalletsSetup walletsSetup,
BsqWalletService bsqWalletService, BsqWalletService bsqWalletService,
BsqTransferService bsqTransferService, BsqTransferService bsqTransferService,
BsqFormatter bsqFormatter, BsqFormatter bsqFormatter,
@ -117,8 +125,11 @@ class CoreWalletsService {
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter, @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter,
FeeService feeService, FeeService feeService,
Preferences preferences) { Preferences preferences) {
this.appStartupState = appStartupState;
this.coreContext = coreContext;
this.balances = balances; this.balances = balances;
this.walletsManager = walletsManager; this.walletsManager = walletsManager;
this.walletsSetup = walletsSetup;
this.bsqWalletService = bsqWalletService; this.bsqWalletService = bsqWalletService;
this.bsqTransferService = bsqTransferService; this.bsqTransferService = bsqTransferService;
this.bsqFormatter = bsqFormatter; this.bsqFormatter = bsqFormatter;
@ -433,6 +444,9 @@ class CoreWalletsService {
lockTimer = null; lockTimer = null;
} }
if (coreContext.isApiUser())
maybeInitWallet();
lockTimer = UserThread.runAfter(() -> { lockTimer = UserThread.runAfter(() -> {
if (tempAesKey != null) { if (tempAesKey != null) {
// The unlockwallet timeout has expired; re-lock the wallet. // The unlockwallet timeout has expired; re-lock the wallet.
@ -458,12 +472,16 @@ class CoreWalletsService {
// Throws a RuntimeException if wallets are not available (encrypted or not). // Throws a RuntimeException if wallets are not available (encrypted or not).
void verifyWalletsAreAvailable() { void verifyWalletsAreAvailable() {
verifyWalletAndNetworkIsReady();
if (!walletsManager.areWalletsAvailable()) if (!walletsManager.areWalletsAvailable())
throw new IllegalStateException("wallet is not yet available"); throw new IllegalStateException("wallet is not yet available");
} }
// Throws a RuntimeException if wallets are not available or not encrypted. // Throws a RuntimeException if wallets are not available or not encrypted.
void verifyWalletIsAvailableAndEncrypted() { void verifyWalletIsAvailableAndEncrypted() {
verifyWalletAndNetworkIsReady();
if (!walletsManager.areWalletsAvailable()) if (!walletsManager.areWalletsAvailable())
throw new IllegalStateException("wallet is not yet available"); throw new IllegalStateException("wallet is not yet available");
@ -477,6 +495,18 @@ class CoreWalletsService {
throw new IllegalStateException("wallet is locked"); throw new IllegalStateException("wallet is locked");
} }
// Throws a RuntimeException if wallets and network are not ready.
void verifyWalletAndNetworkIsReady() {
if (!appStartupState.isWalletAndNetworkReady())
throw new IllegalStateException("wallet and network is not yet initialized");
}
// Throws a RuntimeException if application is not fully initialized.
void verifyApplicationIsFullyInitialized() {
if (!appStartupState.isApplicationFullyInitialized())
throw new IllegalStateException("server is not fully initialized");
}
// Throws a RuntimeException if wallet currency code is not BSQ or BTC. // Throws a RuntimeException if wallet currency code is not BSQ or BTC.
private void verifyWalletCurrencyCodeIsValid(String currencyCode) { private void verifyWalletCurrencyCodeIsValid(String currencyCode) {
if (currencyCode == null || currencyCode.isEmpty()) if (currencyCode == null || currencyCode.isEmpty())
@ -487,6 +517,20 @@ class CoreWalletsService {
throw new IllegalStateException(format("wallet does not support %s", currencyCode)); throw new IllegalStateException(format("wallet does not support %s", currencyCode));
} }
private void maybeInitWallet() {
// Unlike the UI, a daemon cannot capture the user's wallet encryption password
// during startup. This method will set the wallet service's aesKey if necessary.
log.info("Init wallet");
if (tempAesKey == null)
throw new IllegalStateException("cannot init encrypted wallet without key");
if (btcWalletService.getAesKey() == null || bsqWalletService.getAesKey() == null) {
KeyParameter aesKey = new KeyParameter(tempAesKey.getKey());
walletsManager.setAesKey(aesKey);
walletsSetup.getWalletConfig().maybeAddSegwitKeychain(walletsSetup.getWalletConfig().btcWallet(), aesKey);
}
}
private BsqBalanceInfo getBsqBalances() { private BsqBalanceInfo getBsqBalances() {
verifyWalletsAreAvailable(); verifyWalletsAreAvailable();
verifyEncryptedWalletIsUnlocked(); verifyEncryptedWalletIsUnlocked();