apply timeout for arbitrator to sign offer and init trade

This commit is contained in:
woodser 2024-03-22 11:41:07 -04:00
parent 10a5b55dfe
commit db12f1c2cb
5 changed files with 117 additions and 99 deletions

View file

@ -28,6 +28,7 @@ import haveno.core.offer.availability.DisputeAgentSelection;
import haveno.core.offer.messages.SignOfferRequest; import haveno.core.offer.messages.SignOfferRequest;
import haveno.core.offer.placeoffer.PlaceOfferModel; import haveno.core.offer.placeoffer.PlaceOfferModel;
import haveno.core.support.dispute.arbitration.arbitrator.Arbitrator; import haveno.core.support.dispute.arbitration.arbitrator.Arbitrator;
import haveno.core.trade.HavenoUtils;
import haveno.core.xmr.model.XmrAddressEntry; import haveno.core.xmr.model.XmrAddressEntry;
import haveno.network.p2p.AckMessage; import haveno.network.p2p.AckMessage;
import haveno.network.p2p.DecryptedDirectMessageListener; import haveno.network.p2p.DecryptedDirectMessageListener;
@ -164,7 +165,8 @@ public class MakerSendSignOfferRequest extends Task<PlaceOfferModel> {
arbitratorNodeAddress, arbitratorNodeAddress,
arbitrator.getPubKeyRing(), arbitrator.getPubKeyRing(),
request, request,
listener listener,
HavenoUtils.ARBITRATOR_ACK_TIMEOUT_SECONDS
); );
} }
} }

View file

@ -66,6 +66,7 @@ public class HavenoUtils {
private static final String RELEASE_DATE = "01-03-2024 00:00:00"; // optionally set to release date of the network in format dd-mm-yyyy to impose temporary limits, etc. e.g. "01-03-2024 00:00:00" private static final String RELEASE_DATE = "01-03-2024 00:00:00"; // optionally set to release date of the network in format dd-mm-yyyy to impose temporary limits, etc. e.g. "01-03-2024 00:00:00"
public static final int RELEASE_LIMIT_DAYS = 60; // number of days to limit sell offers to max buy limit for new accounts public static final int RELEASE_LIMIT_DAYS = 60; // number of days to limit sell offers to max buy limit for new accounts
public static final int WARN_ON_OFFER_EXCEEDS_UNSIGNED_BUY_LIMIT_DAYS = 182; // number of days to warn if sell offer exceeds unsigned buy limit public static final int WARN_ON_OFFER_EXCEEDS_UNSIGNED_BUY_LIMIT_DAYS = 182; // number of days to warn if sell offer exceeds unsigned buy limit
public static final int ARBITRATOR_ACK_TIMEOUT_SECONDS = 15;
// non-configurable // non-configurable
public static final DecimalFormatSymbols DECIMAL_FORMAT_SYMBOLS = DecimalFormatSymbols.getInstance(Locale.US); // use the US locale as a base for all DecimalFormats (commas should be omitted from number strings) public static final DecimalFormatSymbols DECIMAL_FORMAT_SYMBOLS = DecimalFormatSymbols.getInstance(Locale.US); // use the US locale as a base for all DecimalFormats (commas should be omitted from number strings)

View file

@ -23,6 +23,7 @@ import haveno.common.handlers.ResultHandler;
import haveno.common.taskrunner.TaskRunner; import haveno.common.taskrunner.TaskRunner;
import haveno.core.offer.availability.DisputeAgentSelection; import haveno.core.offer.availability.DisputeAgentSelection;
import haveno.core.support.dispute.arbitration.arbitrator.Arbitrator; import haveno.core.support.dispute.arbitration.arbitrator.Arbitrator;
import haveno.core.trade.HavenoUtils;
import haveno.core.trade.Trade; import haveno.core.trade.Trade;
import haveno.core.trade.messages.InitTradeRequest; import haveno.core.trade.messages.InitTradeRequest;
import haveno.network.p2p.NodeAddress; import haveno.network.p2p.NodeAddress;
@ -144,7 +145,8 @@ public class TakerSendInitTradeRequestToArbitrator extends TradeTask {
arbitratorNodeAddress, arbitratorNodeAddress,
arbitrator.getPubKeyRing(), arbitrator.getPubKeyRing(),
arbitratorRequest, arbitratorRequest,
listener listener,
HavenoUtils.ARBITRATOR_ACK_TIMEOUT_SECONDS
); );
} }
} }

View file

@ -382,12 +382,16 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
// DirectMessages // DirectMessages
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// TODO OfferAvailabilityResponse is called twice!
public void sendEncryptedDirectMessage(NodeAddress peerNodeAddress, PubKeyRing pubKeyRing, NetworkEnvelope message, public void sendEncryptedDirectMessage(NodeAddress peerNodeAddress, PubKeyRing pubKeyRing, NetworkEnvelope message,
SendDirectMessageListener sendDirectMessageListener) { SendDirectMessageListener sendDirectMessageListener) {
sendEncryptedDirectMessage(peerNodeAddress, pubKeyRing, message, sendDirectMessageListener, null);
}
public void sendEncryptedDirectMessage(NodeAddress peerNodeAddress, PubKeyRing pubKeyRing, NetworkEnvelope message,
SendDirectMessageListener sendDirectMessageListener, Integer timeoutSeconds) {
checkNotNull(peerNodeAddress, "PeerAddress must not be null (sendEncryptedDirectMessage)"); checkNotNull(peerNodeAddress, "PeerAddress must not be null (sendEncryptedDirectMessage)");
if (isBootstrapped()) { if (isBootstrapped()) {
doSendEncryptedDirectMessage(peerNodeAddress, pubKeyRing, message, sendDirectMessageListener); doSendEncryptedDirectMessage(peerNodeAddress, pubKeyRing, message, sendDirectMessageListener, timeoutSeconds);
} else { } else {
throw new NetworkNotReadyException(); throw new NetworkNotReadyException();
} }
@ -396,7 +400,8 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
private void doSendEncryptedDirectMessage(@NotNull NodeAddress peersNodeAddress, private void doSendEncryptedDirectMessage(@NotNull NodeAddress peersNodeAddress,
PubKeyRing pubKeyRing, PubKeyRing pubKeyRing,
NetworkEnvelope message, NetworkEnvelope message,
SendDirectMessageListener sendDirectMessageListener) { SendDirectMessageListener sendDirectMessageListener,
Integer timeoutSeconds) {
log.debug("Send encrypted direct message {} to peer {}", log.debug("Send encrypted direct message {} to peer {}",
message.getClass().getSimpleName(), peersNodeAddress); message.getClass().getSimpleName(), peersNodeAddress);
@ -417,7 +422,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
networkNode.getNodeAddress(), networkNode.getNodeAddress(),
encryptionService.encryptAndSign(pubKeyRing, message)); encryptionService.encryptAndSign(pubKeyRing, message));
SettableFuture<Connection> future = networkNode.sendMessage(peersNodeAddress, sealedMsg); SettableFuture<Connection> future = networkNode.sendMessage(peersNodeAddress, sealedMsg, timeoutSeconds);
Futures.addCallback(future, new FutureCallback<>() { Futures.addCallback(future, new FutureCallback<>() {
@Override @Override
public void onSuccess(@Nullable Connection connection) { public void onSuccess(@Nullable Connection connection) {

View file

@ -48,6 +48,7 @@ import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -120,6 +121,11 @@ public abstract class NetworkNode implements MessageListener {
public SettableFuture<Connection> sendMessage(@NotNull NodeAddress peersNodeAddress, public SettableFuture<Connection> sendMessage(@NotNull NodeAddress peersNodeAddress,
NetworkEnvelope networkEnvelope) { NetworkEnvelope networkEnvelope) {
return sendMessage(peersNodeAddress, networkEnvelope, null);
}
public SettableFuture<Connection> sendMessage(@NotNull NodeAddress peersNodeAddress,
NetworkEnvelope networkEnvelope, Integer timeoutSeconds) {
log.debug("Send {} to {}. Message details: {}", log.debug("Send {} to {}. Message details: {}",
networkEnvelope.getClass().getSimpleName(), peersNodeAddress, networkEnvelope.getClass().getSimpleName(), peersNodeAddress,
Utilities.toTruncatedString(networkEnvelope)); Utilities.toTruncatedString(networkEnvelope));
@ -137,7 +143,8 @@ public abstract class NetworkNode implements MessageListener {
"We will create a new outbound connection.", peersNodeAddress); "We will create a new outbound connection.", peersNodeAddress);
SettableFuture<Connection> resultFuture = SettableFuture.create(); SettableFuture<Connection> resultFuture = SettableFuture.create();
ListenableFuture<Connection> future = connectionExecutor.submit(() -> { CompletableFuture<Connection> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.currentThread().setName("NetworkNode.connectionExecutor:SendMessage-to-" Thread.currentThread().setName("NetworkNode.connectionExecutor:SendMessage-to-"
+ Utilities.toTruncatedString(peersNodeAddress.getFullAddress(), 15)); + Utilities.toTruncatedString(peersNodeAddress.getFullAddress(), 15));
if (peersNodeAddress.equals(getNodeAddress())) { if (peersNodeAddress.equals(getNodeAddress())) {
@ -220,14 +227,14 @@ public abstract class NetworkNode implements MessageListener {
outboundConnection.sendMessage(networkEnvelope); outboundConnection.sendMessage(networkEnvelope);
return outboundConnection; return outboundConnection;
} }
}); } catch (Exception e) {
throw new RuntimeException(e);
Futures.addCallback(future, new FutureCallback<>() {
public void onSuccess(Connection connection) {
UserThread.execute(() -> resultFuture.set(connection));
} }
}, connectionExecutor);
public void onFailure(@NotNull Throwable throwable) { // handle future with timeout
if (timeoutSeconds != null) future.orTimeout(timeoutSeconds, TimeUnit.SECONDS);
future.exceptionally(throwable -> {
log.debug("onFailure at sendMessage: peersNodeAddress={}\n\tmessage={}\n\tthrowable={}", peersNodeAddress, networkEnvelope.getClass().getSimpleName(), throwable.toString()); log.debug("onFailure at sendMessage: peersNodeAddress={}\n\tmessage={}\n\tthrowable={}", peersNodeAddress, networkEnvelope.getClass().getSimpleName(), throwable.toString());
UserThread.execute(() -> { UserThread.execute(() -> {
if (!resultFuture.setException(throwable)) { if (!resultFuture.setException(throwable)) {
@ -235,8 +242,9 @@ public abstract class NetworkNode implements MessageListener {
resultFuture.cancel(true); resultFuture.cancel(true);
} }
}); });
} return null;
}, MoreExecutors.directExecutor()); });
future.thenAccept(resultFuture::set);
return resultFuture; return resultFuture;
} }