Skip to content

Commit 0a43b2b

Browse files
authored
recover from import multisig needed error (#1965)
1 parent f711bd5 commit 0a43b2b

File tree

3 files changed

+37
-24
lines changed

3 files changed

+37
-24
lines changed

core/src/main/java/haveno/core/trade/HavenoUtils.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,10 @@ public static boolean isTransactionRejected(Throwable e) {
642642
return e != null && e.getMessage().contains("was rejected");
643643
}
644644

645+
public static boolean isLRNotFound(Throwable e) {
646+
return e != null && e.getMessage().contains("LR not found for enough participants");
647+
}
648+
645649
public static boolean isIllegal(Throwable e) {
646650
return e instanceof IllegalArgumentException || e instanceof IllegalStateException;
647651
}

core/src/main/java/haveno/core/trade/Trade.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,22 +1247,20 @@ private void doImportMultisigHex() {
12471247
String errorMessage = "Multisig import still needed for " + getClass().getSimpleName() + " " + getShortId() + " after already importing, multisigHexes=" + multisigHexes;
12481248
log.warn(errorMessage);
12491249

1250-
// ignore multisig hex which is significantly shorter than others
1250+
// remove shortest multisig hex if applicable
12511251
int maxLength = 0;
1252-
boolean removed = false;
1253-
for (String hex : multisigHexes) maxLength = Math.max(maxLength, hex.length());
1254-
for (String hex : new ArrayList<>(multisigHexes)) {
1255-
if (hex.length() < maxLength / 2) {
1256-
String ignoringMessage = "Ignoring multisig hex from " + getMultisigHexRole(hex) + " for " + getClass().getSimpleName() + " " + getShortId() + " because it is too short, multisigHex=" + hex;
1257-
setErrorMessage(ignoringMessage);
1258-
log.warn(ignoringMessage);
1259-
multisigHexes.remove(hex);
1260-
removed = true;
1261-
}
1252+
String shortestMultisigHex = null;
1253+
for (String hex : multisigHexes) {
1254+
if (shortestMultisigHex == null || hex.length() < shortestMultisigHex.length()) shortestMultisigHex = hex;
1255+
if (hex.length() > maxLength) maxLength = hex.length();
1256+
}
1257+
if (shortestMultisigHex.length() < maxLength) {
1258+
log.warn("Removing multisig hex from " + getMultisigHexRole(shortestMultisigHex) + " for " + getClass().getSimpleName() + " " + getShortId() + " because it's the shortest, multisigHex=" + shortestMultisigHex);
1259+
multisigHexes.remove(shortestMultisigHex);
1260+
wallet.importMultisigHex(multisigHexes.toArray(new String[0]));
12621261
}
12631262

1264-
// re-import valid multisig hexes
1265-
if (removed) wallet.importMultisigHex(multisigHexes.toArray(new String[0]));
1263+
// throw if multisig import still needed
12661264
if (wallet.isMultisigImportNeeded()) throw new IllegalStateException(errorMessage);
12671265
}
12681266

@@ -1372,13 +1370,19 @@ private MoneroTxWallet doCreatePayoutTx() {
13721370
BigInteger sellerPayoutAmount = sellerDepositAmount.subtract(tradeAmount);
13731371

13741372
// create payout tx
1375-
MoneroTxWallet payoutTx = createTx(new MoneroTxConfig()
1373+
MoneroTxWallet payoutTx;
1374+
try {
1375+
payoutTx = createTx(new MoneroTxConfig()
13761376
.setAccountIndex(0)
13771377
.addDestination(buyerPayoutAddress, buyerPayoutAmount)
13781378
.addDestination(sellerPayoutAddress, sellerPayoutAmount)
13791379
.setSubtractFeeFrom(0, 1) // split tx fee
13801380
.setRelay(false)
13811381
.setPriority(XmrWalletService.PROTOCOL_FEE_PRIORITY));
1382+
} catch (Exception e) {
1383+
if (HavenoUtils.isLRNotFound(e)) throw new IllegalStateException(e);
1384+
else throw e;
1385+
}
13821386

13831387
// update state
13841388
BigInteger payoutTxFeeSplit = payoutTx.getFee().divide(BigInteger.valueOf(2));

core/src/main/java/haveno/core/trade/protocol/tasks/BuyerPreparePaymentSentMessage.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,21 @@ protected void run() {
8383
// synchronize on lock for wallet operations
8484
synchronized (trade.getWalletLock()) {
8585
synchronized (HavenoUtils.getWalletFunctionLock()) {
86-
87-
// import multisig hex
88-
trade.importMultisigHex();
89-
90-
// create payout tx
91-
log.info("Buyer creating unsigned payout tx for {} {} ", trade.getClass().getSimpleName(), trade.getShortId());
92-
MoneroTxWallet payoutTx = trade.createPayoutTx();
93-
trade.setPayoutTx(payoutTx);
94-
trade.getSelf().setUnsignedPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex());
95-
trade.requestPersistence();
86+
try {
87+
88+
// import multisig hex
89+
trade.importMultisigHex();
90+
91+
// create payout tx
92+
log.info("Buyer creating unsigned payout tx for {} {} ", trade.getClass().getSimpleName(), trade.getShortId());
93+
MoneroTxWallet payoutTx = trade.createPayoutTx();
94+
trade.setPayoutTx(payoutTx);
95+
trade.getSelf().setUnsignedPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex());
96+
trade.requestPersistence();
97+
} catch (Exception e) {
98+
if (HavenoUtils.isIllegal(e)) log.warn("Failed to create unsigned payout tx for " + trade.getClass().getSimpleName() + " " + trade.getShortId(), e); // continue to send message if illegal state
99+
else throw e;
100+
}
96101
}
97102
}
98103
}

0 commit comments

Comments
 (0)