mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-11-17 00:07:49 +00:00
set open offer's reserve tx fields once known and repost if invalid
This commit is contained in:
parent
2e13bc0051
commit
dbd8db0e88
3 changed files with 44 additions and 36 deletions
|
@ -1101,11 +1101,6 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol(model,
|
PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol(model,
|
||||||
transaction -> {
|
transaction -> {
|
||||||
|
|
||||||
// set reserve tx on open offer
|
|
||||||
openOffer.setReserveTxHash(model.getReserveTx().getHash());
|
|
||||||
openOffer.setReserveTxHex(model.getReserveTx().getFullHex());
|
|
||||||
openOffer.setReserveTxKey(model.getReserveTx().getKey());
|
|
||||||
|
|
||||||
// set offer state
|
// set offer state
|
||||||
openOffer.setState(OpenOffer.State.AVAILABLE);
|
openOffer.setState(OpenOffer.State.AVAILABLE);
|
||||||
openOffer.setScheduledTxHashes(null);
|
openOffer.setScheduledTxHashes(null);
|
||||||
|
@ -1609,9 +1604,19 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
|
|
||||||
private void republishOffer(OpenOffer openOffer, @Nullable Runnable completeHandler) {
|
private void republishOffer(OpenOffer openOffer, @Nullable Runnable completeHandler) {
|
||||||
|
|
||||||
// re-add to offer book if signature is valid
|
// determine if offer is valid
|
||||||
|
boolean isValid = true;
|
||||||
Arbitrator arbitrator = user.getAcceptedArbitratorByAddress(openOffer.getOffer().getOfferPayload().getArbitratorSigner());
|
Arbitrator arbitrator = user.getAcceptedArbitratorByAddress(openOffer.getOffer().getOfferPayload().getArbitratorSigner());
|
||||||
boolean isValid = arbitrator != null && HavenoUtils.isArbitratorSignatureValid(openOffer.getOffer().getOfferPayload(), arbitrator);
|
if (arbitrator == null || !HavenoUtils.isArbitratorSignatureValid(openOffer.getOffer().getOfferPayload(), arbitrator)) {
|
||||||
|
log.warn("Offer {} has invalid arbitrator signature, reposting", openOffer.getId());
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
if (openOffer.getOffer().getOfferPayload().getReserveTxKeyImages() != null && (openOffer.getReserveTxHash() == null || openOffer.getReserveTxHash().isEmpty())) {
|
||||||
|
log.warn("Offer {} is missing reserve tx hash but has reserved key images, reposting", openOffer.getId());
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if valid, re-add offer to book
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
offerBookService.addOffer(openOffer.getOffer(),
|
offerBookService.addOffer(openOffer.getOffer(),
|
||||||
() -> {
|
() -> {
|
||||||
|
@ -1635,35 +1640,34 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
if (completeHandler != null) completeHandler.run();
|
if (completeHandler != null) completeHandler.run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
} else {
|
||||||
|
|
||||||
|
// cancel and recreate offer
|
||||||
|
onCancelled(openOffer);
|
||||||
|
Offer updatedOffer = new Offer(openOffer.getOffer().getOfferPayload());
|
||||||
|
updatedOffer.setPriceFeedService(priceFeedService);
|
||||||
|
OpenOffer updatedOpenOffer = new OpenOffer(updatedOffer, openOffer.getTriggerPrice());
|
||||||
|
|
||||||
|
// repost offer
|
||||||
|
new Thread(() -> {
|
||||||
|
synchronized (processOffersLock) {
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
processUnpostedOffer(getOpenOffers(), updatedOpenOffer, (transaction) -> {
|
||||||
|
addOpenOffer(updatedOpenOffer);
|
||||||
|
requestPersistence();
|
||||||
|
latch.countDown();
|
||||||
|
if (completeHandler != null) completeHandler.run();
|
||||||
|
}, (errorMessage) -> {
|
||||||
|
log.warn("Error reposting offer {}: {}", updatedOpenOffer.getId(), errorMessage);
|
||||||
|
onCancelled(updatedOpenOffer);
|
||||||
|
updatedOffer.setErrorMessage(errorMessage);
|
||||||
|
latch.countDown();
|
||||||
|
if (completeHandler != null) completeHandler.run();
|
||||||
|
});
|
||||||
|
HavenoUtils.awaitLatch(latch);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// cancel and recreate offer
|
|
||||||
log.warn("Offer {} has invalid arbitrator signature, reposting", openOffer.getId());
|
|
||||||
onCancelled(openOffer);
|
|
||||||
Offer updatedOffer = new Offer(openOffer.getOffer().getOfferPayload());
|
|
||||||
updatedOffer.setPriceFeedService(priceFeedService);
|
|
||||||
OpenOffer updatedOpenOffer = new OpenOffer(updatedOffer, openOffer.getTriggerPrice());
|
|
||||||
|
|
||||||
// repost offer
|
|
||||||
new Thread(() -> {
|
|
||||||
synchronized (processOffersLock) {
|
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
processUnpostedOffer(getOpenOffers(), updatedOpenOffer, (transaction) -> {
|
|
||||||
addOpenOffer(updatedOpenOffer);
|
|
||||||
requestPersistence();
|
|
||||||
latch.countDown();
|
|
||||||
if (completeHandler != null) completeHandler.run();
|
|
||||||
}, (errorMessage) -> {
|
|
||||||
log.warn("Error reposting offer {} with invalid signature: {}", updatedOpenOffer.getId(), errorMessage);
|
|
||||||
onCancelled(updatedOpenOffer);
|
|
||||||
updatedOffer.setErrorMessage(errorMessage);
|
|
||||||
latch.countDown();
|
|
||||||
if (completeHandler != null) completeHandler.run();
|
|
||||||
});
|
|
||||||
HavenoUtils.awaitLatch(latch);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startPeriodicRepublishOffersTimer() {
|
private void startPeriodicRepublishOffersTimer() {
|
||||||
|
|
|
@ -70,6 +70,9 @@ public class MakerReserveOfferFunds extends Task<PlaceOfferModel> {
|
||||||
|
|
||||||
// save offer state
|
// save offer state
|
||||||
model.setReserveTx(reserveTx);
|
model.setReserveTx(reserveTx);
|
||||||
|
model.getOpenOffer().setReserveTxHash(reserveTx.getHash());
|
||||||
|
model.getOpenOffer().setReserveTxHex(reserveTx.getFullHex());
|
||||||
|
model.getOpenOffer().setReserveTxKey(reserveTx.getKey());
|
||||||
offer.getOfferPayload().setReserveTxKeyImages(reservedKeyImages);
|
offer.getOfferPayload().setReserveTxKeyImages(reservedKeyImages);
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
|
@ -43,10 +43,11 @@ public class MakerSendInitTradeRequest extends TradeTask {
|
||||||
try {
|
try {
|
||||||
runInterceptHook();
|
runInterceptHook();
|
||||||
|
|
||||||
// verify trade
|
// verify trade state
|
||||||
InitTradeRequest makerRequest = (InitTradeRequest) processModel.getTradeMessage(); // arbitrator's InitTradeRequest to maker
|
InitTradeRequest makerRequest = (InitTradeRequest) processModel.getTradeMessage(); // arbitrator's InitTradeRequest to maker
|
||||||
checkNotNull(makerRequest);
|
checkNotNull(makerRequest);
|
||||||
checkTradeId(processModel.getOfferId(), makerRequest);
|
checkTradeId(processModel.getOfferId(), makerRequest);
|
||||||
|
if (trade.getSelf().getReserveTxHash() == null || trade.getSelf().getReserveTxHash().isEmpty()) throw new IllegalStateException("Reserve tx id is not initialized: " + trade.getSelf().getReserveTxHash());
|
||||||
|
|
||||||
// create request to arbitrator
|
// create request to arbitrator
|
||||||
Offer offer = processModel.getOffer();
|
Offer offer = processModel.getOffer();
|
||||||
|
|
Loading…
Reference in a new issue