ignore payment sent nack if not seller, add logging

This commit is contained in:
woodser 2023-04-28 07:20:28 -04:00
parent 38cd3ab630
commit 4ebf0f7538
5 changed files with 30 additions and 15 deletions

View file

@ -26,6 +26,7 @@ import haveno.core.support.dispute.arbitration.arbitrator.Arbitrator;
import haveno.core.trade.HavenoUtils;
import haveno.core.user.Preferences;
import haveno.core.user.User;
import haveno.network.p2p.NodeAddress;
import javafx.collections.SetChangeListener;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@ -34,8 +35,10 @@ import org.bitcoinj.core.Coin;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@Slf4j
@Singleton
@ -217,6 +220,10 @@ public class OfferFilterService {
public boolean hasValidArbitrator(Offer offer) {
Arbitrator arbitrator = user.getAcceptedArbitratorByAddress(offer.getOfferPayload().getArbitratorSigner());
if (arbitrator == null) {
List<NodeAddress> arbitratorAddresses = user.getAcceptedArbitrators().stream().map(Arbitrator::getNodeAddress).collect(Collectors.toList());
log.warn("No arbitrator registered with offer's signer. offerId={}. Accepted arbitrators={}", offer.getOfferPayload().getArbitratorSigner(), arbitratorAddresses);
}
return arbitrator != null;
}

View file

@ -400,7 +400,7 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
if (!expectedLoserAmount.equals(actualLoserAmount)) throw new RuntimeException("Unexpected loser payout: " + expectedLoserAmount + " vs " + actualLoserAmount);
// check wallet's daemon connection
trade.checkWalletConnection();
trade.checkDaemonConnection();
// determine if we already signed dispute payout tx
// TODO: better way, such as by saving signed dispute payout tx hex in designated field instead of shared payoutTxHex field?

View file

@ -737,7 +737,11 @@ public abstract class Trade implements Tradable, Model {
return MONERO_TRADE_WALLET_PREFIX + getId();
}
public void checkWalletConnection() {
public MoneroRpcConnection getDaemonConnection() {
return wallet == null ? null : wallet.getDaemonConnection();
}
public void checkDaemonConnection() {
CoreMoneroConnectionsService connectionService = xmrWalletService.getConnectionsService();
connectionService.checkConnection();
connectionService.verifyConnection();
@ -746,7 +750,7 @@ public abstract class Trade implements Tradable, Model {
public boolean isWalletConnected() {
try {
checkWalletConnection();
checkDaemonConnection();
return true;
} catch (Exception e) {
return false;
@ -906,7 +910,7 @@ public abstract class Trade implements Tradable, Model {
public MoneroTxWallet createPayoutTx() {
// check connection to monero daemon
checkWalletConnection();
checkDaemonConnection();
// check multisig import
if (getWallet().isMultisigImportNeeded()) throw new RuntimeException("Cannot create payout tx because multisig import is needed");
@ -1005,7 +1009,7 @@ public abstract class Trade implements Tradable, Model {
if (!sellerPayoutDestination.getAmount().equals(expectedSellerPayout)) throw new IllegalArgumentException("Seller destination amount is not deposit amount - trade amount - 1/2 tx costs, " + sellerPayoutDestination.getAmount() + " vs " + expectedSellerPayout);
// check wallet connection
if (sign || publish) checkWalletConnection();
if (sign || publish) checkDaemonConnection();
// handle tx signing
if (sign) {
@ -1855,7 +1859,7 @@ public abstract class Trade implements Tradable, Model {
}
} catch (Exception e) {
if (!isShutDown && getWallet() != null && isWalletConnected()) {
log.warn("Error polling trade wallet {}: {}", getId(), e.getMessage());
log.warn("Error polling trade wallet for {} {}: {}. Monerod={}", getClass().getSimpleName(), getId(), e.getMessage(), getDaemonConnection());
}
}
}

View file

@ -601,20 +601,24 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
// ACK msg
///////////////////////////////////////////////////////////////////////////////////////////
// TODO (woodser): support notifications of ack messages
private void onAckMessage(AckMessage ackMessage, NodeAddress peer) {
// We handle the ack for PaymentSentMessage and DepositTxAndDelayedPayoutTxMessage
// as we support automatic re-send of the msg in case it was not ACKed after a certain time
if (ackMessage.getSourceMsgClassName().equals(PaymentSentMessage.class.getSimpleName()) && trade.getTradePeer(peer) == trade.getSeller()) {
processModel.setPaymentSentAckMessage(ackMessage);
// handle ack for PaymentSentMessage, which automatically re-sends if not ACKed in a certain time
if (ackMessage.getSourceMsgClassName().equals(PaymentSentMessage.class.getSimpleName())) {
if (trade.getTradePeer(peer) == trade.getSeller()) {
processModel.setPaymentSentAckMessage(ackMessage);
} else if (!ackMessage.isSuccess()) {
String err = "Received AckMessage with error state for " + ackMessage.getSourceMsgClassName() + " from "+ peer + " with tradeId " + trade.getId() + " and errorMessage=" + ackMessage.getErrorMessage();
log.warn(err);
return; // log error and ignore nack if not seller
}
}
if (ackMessage.isSuccess()) {
log.info("Received AckMessage for {} from {} with tradeId {} and uid {}",
ackMessage.getSourceMsgClassName(), peer, trade.getId(), ackMessage.getSourceUid());
} else {
String err = "Received AckMessage with error state for " + ackMessage.getSourceMsgClassName() +
" from "+ peer + " with tradeId " + trade.getId() + " and errorMessage=" + ackMessage.getErrorMessage();
String err = "Received AckMessage with error state for " + ackMessage.getSourceMsgClassName() + " from "+ peer + " with tradeId " + trade.getId() + " and errorMessage=" + ackMessage.getErrorMessage();
log.warn(err);
// set trade state on deposit request nack
@ -787,7 +791,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
}
void handleTaskRunnerFault(NodeAddress ackReceiver, @Nullable TradeMessage message, String source, String errorMessage) {
log.error("Task runner failed with error {}. Triggered from {}", errorMessage, source);
log.error("Task runner failed with error {}. Triggered from {}. Monerod={}" , errorMessage, source, trade.getDaemonConnection());
if (message != null) {
sendAckMessage(ackReceiver, message, false, errorMessage);

View file

@ -36,7 +36,7 @@ public class SellerPreparePaymentReceivedMessage extends TradeTask {
runInterceptHook();
// check connection
trade.checkWalletConnection();
trade.checkDaemonConnection();
// handle first time preparation
if (processModel.getPaymentReceivedMessage() == null) {