fix startup when missing multisig wallets

This commit is contained in:
woodser 2025-04-11 17:51:05 -04:00 committed by woodser
parent 5bff265cca
commit 454fc91298
5 changed files with 36 additions and 31 deletions

View File

@ -753,11 +753,9 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
importMultisigHexIfScheduled();
});
// trade is initialized
isInitialized = true;
// done if deposit not requested or payout unlocked
if (!isDepositRequested() || isPayoutUnlocked()) {
isInitialized = true;
isFullyInitialized = true;
return;
}
@ -769,14 +767,17 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
if (payoutTx != null && payoutTx.getNumConfirmations() >= XmrWalletService.NUM_BLOCKS_UNLOCK) {
log.warn("Payout state for {} {} is {} but payout is unlocked, updating state", getClass().getSimpleName(), getId(), getPayoutState());
setPayoutStateUnlocked();
isInitialized = true;
isFullyInitialized = true;
return;
} else {
log.warn("Missing trade wallet for {} {}, state={}, marked completed={}", getClass().getSimpleName(), getShortId(), getState(), isCompleted());
return;
throw new RuntimeException("Missing trade wallet for " + getClass().getSimpleName() + " " + getShortId() + ", state=" + getState() + ", marked completed=" + isCompleted());
}
}
// trade is initialized
isInitialized = true;
// init syncing if deposit requested
if (isDepositRequested()) {
tryInitSyncing();

View File

@ -470,6 +470,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
if (!isShutDownStarted) {
log.warn("Error initializing {} {}: {}\n", trade.getClass().getSimpleName(), trade.getId(), e.getMessage(), e);
trade.setInitError(e);
trade.prependErrorMessage(e.getMessage());
}
}
});
@ -1041,18 +1042,17 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
if (isShutDownStarted) return;
synchronized (tradableList.getList()) {
for (Trade trade : tradableList.getList()) {
if (!trade.isPayoutPublished()) {
Date maxTradePeriodDate = trade.getMaxTradePeriodDate();
Date halfTradePeriodDate = trade.getHalfTradePeriodDate();
if (maxTradePeriodDate != null && halfTradePeriodDate != null) {
Date now = new Date();
if (now.after(maxTradePeriodDate)) {
trade.setPeriodState(Trade.TradePeriodState.TRADE_PERIOD_OVER);
requestPersistence();
} else if (now.after(halfTradePeriodDate)) {
trade.setPeriodState(Trade.TradePeriodState.SECOND_HALF);
requestPersistence();
}
if (!trade.isInitialized() || trade.isPayoutPublished()) continue;
Date maxTradePeriodDate = trade.getMaxTradePeriodDate();
Date halfTradePeriodDate = trade.getHalfTradePeriodDate();
if (maxTradePeriodDate != null && halfTradePeriodDate != null) {
Date now = new Date();
if (now.after(maxTradePeriodDate)) {
trade.setPeriodState(Trade.TradePeriodState.TRADE_PERIOD_OVER);
requestPersistence();
} else if (now.after(halfTradePeriodDate)) {
trade.setPeriodState(Trade.TradePeriodState.SECOND_HALF);
requestPersistence();
}
}
}

View File

@ -689,22 +689,24 @@ public class XmrWalletService extends XmrWalletBase {
}
private MoneroTxWallet createTradeTxFromSubaddress(BigInteger feeAmount, String feeAddress, BigInteger sendAmount, String sendAddress, Integer subaddressIndex) {
synchronized (walletLock) {
// create tx
MoneroTxConfig txConfig = new MoneroTxConfig()
.setAccountIndex(0)
.setSubaddressIndices(subaddressIndex)
.addDestination(sendAddress, sendAmount)
.setSubtractFeeFrom(0) // pay mining fee from send amount
.setPriority(XmrWalletService.PROTOCOL_FEE_PRIORITY);
if (!BigInteger.valueOf(0).equals(feeAmount)) txConfig.addDestination(feeAddress, feeAmount);
MoneroTxWallet tradeTx = createTx(txConfig);
// create tx
MoneroTxConfig txConfig = new MoneroTxConfig()
.setAccountIndex(0)
.setSubaddressIndices(subaddressIndex)
.addDestination(sendAddress, sendAmount)
.setSubtractFeeFrom(0) // pay mining fee from send amount
.setPriority(XmrWalletService.PROTOCOL_FEE_PRIORITY);
if (!BigInteger.valueOf(0).equals(feeAmount)) txConfig.addDestination(feeAddress, feeAmount);
MoneroTxWallet tradeTx = createTx(txConfig);
// freeze inputs
List<String> keyImages = new ArrayList<String>();
for (MoneroOutput input : tradeTx.getInputs()) keyImages.add(input.getKeyImage().getHex());
freezeOutputs(keyImages);
return tradeTx;
// freeze inputs
List<String> keyImages = new ArrayList<String>();
for (MoneroOutput input : tradeTx.getInputs()) keyImages.add(input.getKeyImage().getHex());
freezeOutputs(keyImages);
return tradeTx;
}
}
public MoneroTx verifyReserveTx(String offerId, BigInteger penaltyFee, BigInteger tradeFee, BigInteger sendTradeAmount, BigInteger securityDeposit, String returnAddress, String txHash, String txHex, String txKey, List<String> keyImages) {

View File

@ -228,6 +228,7 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
new Popup().warning("Error initializing trade" + " " + trade.getShortId() + "\n\n" +
trade.getInitError().getMessage())
.show();
return;
}
// check trade period

View File

@ -405,6 +405,7 @@ public abstract class TradeStepView extends AnchorPane {
}
private void updateTimeLeft() {
if (!trade.isInitialized()) return;
if (timeLeftTextField != null) {
// TODO (woodser): extra TradeStepView created but not deactivated on trade.setState(), so deactivate when model's trade is null