mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-10-01 01:35:48 -04:00
reprocess scheduled offers on new block
This commit is contained in:
parent
a1e554473a
commit
35f275805b
@ -103,6 +103,12 @@ public final class OpenOffer implements Tradable {
|
||||
@Setter
|
||||
transient private long mempoolStatus = -1;
|
||||
transient final private ObjectProperty<State> stateProperty = new SimpleObjectProperty<>(state);
|
||||
@Getter
|
||||
@Setter
|
||||
transient boolean isProcessing = false;
|
||||
@Getter
|
||||
@Setter
|
||||
transient int numProcessingAttempts = 0;
|
||||
|
||||
public OpenOffer(Offer offer) {
|
||||
this(offer, 0, false);
|
||||
@ -193,9 +199,9 @@ public final class OpenOffer implements Tradable {
|
||||
proto.getScheduledTxHashesList(),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getSplitOutputTxHash()),
|
||||
proto.getSplitOutputTxFee(),
|
||||
proto.getReserveTxHash(),
|
||||
proto.getReserveTxHex(),
|
||||
proto.getReserveTxKey());
|
||||
ProtoUtil.stringOrNullFromProto(proto.getReserveTxHash()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getReserveTxHex()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getReserveTxKey()));
|
||||
return openOffer;
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
private static final long REPUBLISH_AGAIN_AT_STARTUP_DELAY_SEC = 30;
|
||||
private static final long REPUBLISH_INTERVAL_MS = TimeUnit.MINUTES.toMillis(30);
|
||||
private static final long REFRESH_INTERVAL_MS = OfferPayload.TTL / 2;
|
||||
private static final int MAX_PROCESS_ATTEMPTS = 5;
|
||||
|
||||
private final CoreContext coreContext;
|
||||
private final KeyRing keyRing;
|
||||
@ -156,7 +157,6 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
private final SignedOfferList signedOffers = new SignedOfferList();
|
||||
private final PersistenceManager<SignedOfferList> signedOfferPersistenceManager;
|
||||
private final Map<String, PlaceOfferProtocol> placeOfferProtocols = new HashMap<String, PlaceOfferProtocol>();
|
||||
private BigInteger lastUnlockedBalance;
|
||||
private boolean stopped;
|
||||
private Timer periodicRepublishOffersTimer, periodicRefreshOffersTimer, retryRepublishOffersTimer;
|
||||
@Getter
|
||||
@ -471,17 +471,13 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
log.warn("Error processing unposted offers: " + errorMessage);
|
||||
});
|
||||
|
||||
// register to process unposted offers when unlocked balance increases
|
||||
if (xmrWalletService.getWallet() != null) lastUnlockedBalance = xmrWalletService.getAvailableBalance();
|
||||
// register to process unposted offers on new block
|
||||
xmrWalletService.addWalletListener(new MoneroWalletListener() {
|
||||
@Override
|
||||
public void onBalancesChanged(BigInteger newBalance, BigInteger newUnlockedBalance) {
|
||||
if (lastUnlockedBalance == null || lastUnlockedBalance.compareTo(newUnlockedBalance) < 0) {
|
||||
processScheduledOffers((transaction) -> {}, (errorMessage) -> {
|
||||
log.warn("Error processing unposted offers on new unlocked balance: " + errorMessage); // TODO: popup to notify user that offer did not post
|
||||
});
|
||||
}
|
||||
lastUnlockedBalance = newUnlockedBalance;
|
||||
public void onNewBlock(long height) {
|
||||
processScheduledOffers((transaction) -> {}, (errorMessage) -> {
|
||||
log.warn("Error processing unposted offers on new block {}: {}", height, errorMessage);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -860,8 +856,12 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
processUnpostedOffer(openOffers, scheduledOffer, (transaction) -> {
|
||||
latch.countDown();
|
||||
}, errorMessage -> {
|
||||
log.warn("Error processing unposted offer {}: {}", scheduledOffer.getId(), errorMessage);
|
||||
onCancelled(scheduledOffer);
|
||||
log.warn("Error processing unposted offer, offerId={}, attempt={}/{}, error={}", scheduledOffer.getId(), scheduledOffer.getNumProcessingAttempts(), MAX_PROCESS_ATTEMPTS, errorMessage);
|
||||
if (scheduledOffer.getNumProcessingAttempts() >= MAX_PROCESS_ATTEMPTS) {
|
||||
log.warn("Offer canceled after {} attempts, offerId={}, error={}", scheduledOffer.getNumProcessingAttempts(), scheduledOffer.getId(), errorMessage);
|
||||
HavenoUtils.havenoSetup.getTopErrorMsg().set("Offer canceled after " + scheduledOffer.getNumProcessingAttempts() + " attempts. Please switch to a better Monero connection and try again.\n\nOffer ID: " + scheduledOffer.getId() + "\nError: " + errorMessage);
|
||||
onCancelled(scheduledOffer);
|
||||
}
|
||||
errorMessages.add(errorMessage);
|
||||
latch.countDown();
|
||||
});
|
||||
@ -875,6 +875,26 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
}
|
||||
|
||||
private void processUnpostedOffer(List<OpenOffer> openOffers, OpenOffer openOffer, TransactionResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||
|
||||
// skip if already processing
|
||||
if (openOffer.isProcessing()) {
|
||||
resultHandler.handleResult(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// process offer
|
||||
openOffer.setProcessing(true);
|
||||
doProcessUnpostedOffer(openOffers, openOffer, (transaction) -> {
|
||||
openOffer.setProcessing(false);
|
||||
resultHandler.handleResult(transaction);
|
||||
}, (errorMsg) -> {
|
||||
openOffer.setProcessing(false);
|
||||
openOffer.setNumProcessingAttempts(openOffer.getNumProcessingAttempts() + 1);
|
||||
errorMessageHandler.handleErrorMessage(errorMsg);
|
||||
});
|
||||
}
|
||||
|
||||
private void doProcessUnpostedOffer(List<OpenOffer> openOffers, OpenOffer openOffer, TransactionResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
|
||||
|
@ -36,7 +36,6 @@ import haveno.network.p2p.P2PService;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import monero.wallet.model.MoneroTxWallet;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@ -71,8 +70,6 @@ public class PlaceOfferModel implements Model {
|
||||
@Setter
|
||||
private Transaction transaction;
|
||||
@Setter
|
||||
private MoneroTxWallet reserveTx;
|
||||
@Setter
|
||||
private SignOfferResponse signOfferResponse;
|
||||
@Setter
|
||||
@Getter
|
||||
|
@ -51,6 +51,13 @@ public class MakerReserveOfferFunds extends Task<PlaceOfferModel> {
|
||||
try {
|
||||
runInterceptHook();
|
||||
|
||||
// skip if reserve tx already created
|
||||
if (openOffer.getReserveTxHash() != null && !openOffer.getReserveTxHash().isEmpty()) {
|
||||
log.info("Reserve tx already created for offerId={}", openOffer.getShortId());
|
||||
complete();
|
||||
return;
|
||||
}
|
||||
|
||||
// verify monero connection
|
||||
model.getXmrWalletService().getConnectionService().verifyConnection();
|
||||
|
||||
@ -102,7 +109,6 @@ public class MakerReserveOfferFunds extends Task<PlaceOfferModel> {
|
||||
openOffer.setReserveTxHex(reserveTx.getFullHex());
|
||||
openOffer.setReserveTxKey(reserveTx.getKey());
|
||||
offer.getOfferPayload().setReserveTxKeyImages(reservedKeyImages);
|
||||
model.setReserveTx(reserveTx);
|
||||
}
|
||||
complete();
|
||||
} catch (Throwable t) {
|
||||
|
@ -24,6 +24,7 @@ import haveno.common.handlers.ResultHandler;
|
||||
import haveno.common.taskrunner.Task;
|
||||
import haveno.common.taskrunner.TaskRunner;
|
||||
import haveno.core.offer.Offer;
|
||||
import haveno.core.offer.OpenOffer;
|
||||
import haveno.core.offer.availability.DisputeAgentSelection;
|
||||
import haveno.core.offer.messages.SignOfferRequest;
|
||||
import haveno.core.offer.placeoffer.PlaceOfferModel;
|
||||
@ -47,8 +48,6 @@ import java.util.UUID;
|
||||
public class MakerSendSignOfferRequest extends Task<PlaceOfferModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(MakerSendSignOfferRequest.class);
|
||||
|
||||
private boolean failed = false;
|
||||
|
||||
@SuppressWarnings({"unused"})
|
||||
public MakerSendSignOfferRequest(TaskRunner taskHandler, PlaceOfferModel model) {
|
||||
super(taskHandler, model);
|
||||
@ -56,7 +55,8 @@ public class MakerSendSignOfferRequest extends Task<PlaceOfferModel> {
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
Offer offer = model.getOpenOffer().getOffer();
|
||||
OpenOffer openOffer = model.getOpenOffer();
|
||||
Offer offer = openOffer.getOffer();
|
||||
try {
|
||||
runInterceptHook();
|
||||
|
||||
@ -71,9 +71,9 @@ public class MakerSendSignOfferRequest extends Task<PlaceOfferModel> {
|
||||
UUID.randomUUID().toString(),
|
||||
Version.getP2PMessageVersion(),
|
||||
new Date().getTime(),
|
||||
model.getReserveTx().getHash(),
|
||||
model.getReserveTx().getFullHex(),
|
||||
model.getReserveTx().getKey(),
|
||||
openOffer.getReserveTxHash(),
|
||||
openOffer.getReserveTxHex(),
|
||||
openOffer.getReserveTxKey(),
|
||||
offer.getOfferPayload().getReserveTxKeyImages(),
|
||||
returnAddress);
|
||||
|
||||
@ -81,8 +81,7 @@ public class MakerSendSignOfferRequest extends Task<PlaceOfferModel> {
|
||||
sendSignOfferRequests(request, () -> {
|
||||
complete();
|
||||
}, (errorMessage) -> {
|
||||
appendToErrorMessage("Error signing offer " + request.getOfferId() + ": " + errorMessage);
|
||||
failed(errorMessage);
|
||||
failed("Error signing offer " + request.getOfferId() + ": " + errorMessage);
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
offer.setErrorMessage("An error occurred.\n" +
|
||||
|
Loading…
Reference in New Issue
Block a user