validate pending offer

This commit is contained in:
woodser 2024-10-16 15:19:34 -04:00
parent 8f5e56b9dc
commit 0450900b37
3 changed files with 73 additions and 57 deletions

View file

@ -200,7 +200,7 @@ public class Offer implements NetworkPayload, PersistablePayload {
return null; return null;
} }
} else { } else {
log.trace("We don't have a market price. " + log.warn("We don't have a market price. " +
"That case could only happen if you don't have a price feed."); "That case could only happen if you don't have a price feed.");
return null; return null;
} }

View file

@ -62,6 +62,7 @@ import haveno.core.offer.messages.SignOfferRequest;
import haveno.core.offer.messages.SignOfferResponse; import haveno.core.offer.messages.SignOfferResponse;
import haveno.core.offer.placeoffer.PlaceOfferModel; import haveno.core.offer.placeoffer.PlaceOfferModel;
import haveno.core.offer.placeoffer.PlaceOfferProtocol; import haveno.core.offer.placeoffer.PlaceOfferProtocol;
import haveno.core.offer.placeoffer.tasks.ValidateOffer;
import haveno.core.provider.price.PriceFeedService; import haveno.core.provider.price.PriceFeedService;
import haveno.core.support.dispute.arbitration.arbitrator.Arbitrator; import haveno.core.support.dispute.arbitration.arbitrator.Arbitrator;
import haveno.core.support.dispute.arbitration.arbitrator.ArbitratorManager; import haveno.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
@ -934,6 +935,14 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
return; return;
} }
// validate offer
try {
ValidateOffer.validateOffer(openOffer.getOffer(), accountAgeWitnessService, user);
} catch (Exception e) {
errorMessageHandler.handleErrorMessage("Failed to validate offer: " + e.getMessage());
return;
}
// cancel offer if scheduled txs unavailable // cancel offer if scheduled txs unavailable
if (openOffer.getScheduledTxHashes() != null) { if (openOffer.getScheduledTxHashes() != null) {
boolean scheduledTxsAvailable = true; boolean scheduledTxsAvailable = true;

View file

@ -19,10 +19,12 @@ package haveno.core.offer.placeoffer.tasks;
import haveno.common.taskrunner.Task; import haveno.common.taskrunner.Task;
import haveno.common.taskrunner.TaskRunner; import haveno.common.taskrunner.TaskRunner;
import haveno.core.account.witness.AccountAgeWitnessService;
import haveno.core.offer.Offer; import haveno.core.offer.Offer;
import haveno.core.offer.placeoffer.PlaceOfferModel; import haveno.core.offer.placeoffer.PlaceOfferModel;
import haveno.core.trade.HavenoUtils; import haveno.core.trade.HavenoUtils;
import haveno.core.trade.messages.TradeMessage; import haveno.core.trade.messages.TradeMessage;
import haveno.core.user.User;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import java.math.BigInteger; import java.math.BigInteger;
@ -41,6 +43,19 @@ public class ValidateOffer extends Task<PlaceOfferModel> {
try { try {
runInterceptHook(); runInterceptHook();
validateOffer(offer, model.getAccountAgeWitnessService(), model.getUser());
complete();
} catch (Exception e) {
offer.setErrorMessage("An error occurred.\n" +
"Error message:\n"
+ e.getMessage());
failed(e);
}
}
public static void validateOffer(Offer offer, AccountAgeWitnessService accountAgeWitnessService, User user) {
// Coins // Coins
checkBINotNullOrZero(offer.getAmount(), "Amount"); checkBINotNullOrZero(offer.getAmount(), "Amount");
checkBINotNullOrZero(offer.getMinAmount(), "MinAmount"); checkBINotNullOrZero(offer.getMinAmount(), "MinAmount");
@ -67,7 +82,7 @@ public class ValidateOffer extends Task<PlaceOfferModel> {
/*checkArgument(offer.getMinAmount().compareTo(ProposalConsensus.getMinTradeAmount()) >= 0, /*checkArgument(offer.getMinAmount().compareTo(ProposalConsensus.getMinTradeAmount()) >= 0,
"MinAmount is less than " + ProposalConsensus.getMinTradeAmount().toFriendlyString());*/ "MinAmount is less than " + ProposalConsensus.getMinTradeAmount().toFriendlyString());*/
long maxAmount = model.getAccountAgeWitnessService().getMyTradeLimit(model.getUser().getPaymentAccount(offer.getMakerPaymentAccountId()), offer.getCurrencyCode(), offer.getDirection()); long maxAmount = accountAgeWitnessService.getMyTradeLimit(user.getPaymentAccount(offer.getMakerPaymentAccountId()), offer.getCurrencyCode(), offer.getDirection());
checkArgument(offer.getAmount().longValueExact() <= maxAmount, checkArgument(offer.getAmount().longValueExact() <= maxAmount,
"Amount is larger than " + HavenoUtils.atomicUnitsToXmr(offer.getPaymentMethod().getMaxTradeLimit(offer.getCurrencyCode())) + " XMR"); "Amount is larger than " + HavenoUtils.atomicUnitsToXmr(offer.getPaymentMethod().getMaxTradeLimit(offer.getCurrencyCode())) + " XMR");
checkArgument(offer.getAmount().compareTo(offer.getMinAmount()) >= 0, "MinAmount is larger than Amount"); checkArgument(offer.getAmount().compareTo(offer.getMinAmount()) >= 0, "MinAmount is larger than Amount");
@ -90,52 +105,44 @@ public class ValidateOffer extends Task<PlaceOfferModel> {
"maxTradePeriod must be positive. maxTradePeriod=" + offer.getMaxTradePeriod()); "maxTradePeriod must be positive. maxTradePeriod=" + offer.getMaxTradePeriod());
// TODO check upper and lower bounds for fiat // TODO check upper and lower bounds for fiat
// TODO check rest of new parameters // TODO check rest of new parameters
complete();
} catch (Exception e) {
offer.setErrorMessage("An error occurred.\n" +
"Error message:\n"
+ e.getMessage());
failed(e);
}
} }
public static void checkBINotNullOrZero(BigInteger value, String name) { private static void checkBINotNullOrZero(BigInteger value, String name) {
checkNotNull(value, name + " is null"); checkNotNull(value, name + " is null");
checkArgument(value.compareTo(BigInteger.ZERO) > 0, checkArgument(value.compareTo(BigInteger.ZERO) > 0,
name + " must be positive. " + name + "=" + value); name + " must be positive. " + name + "=" + value);
} }
public static void checkCoinNotNullOrZero(Coin value, String name) { private static void checkCoinNotNullOrZero(Coin value, String name) {
checkNotNull(value, name + " is null"); checkNotNull(value, name + " is null");
checkArgument(value.isPositive(), checkArgument(value.isPositive(),
name + " must be positive. " + name + "=" + value.toFriendlyString()); name + " must be positive. " + name + "=" + value.toFriendlyString());
} }
public static String nonEmptyStringOf(String value) { private static String nonEmptyStringOf(String value) {
checkNotNull(value); checkNotNull(value);
checkArgument(value.length() > 0); checkArgument(value.length() > 0);
return value; return value;
} }
public static long nonNegativeLongOf(long value) { private static long nonNegativeLongOf(long value) {
checkArgument(value >= 0); checkArgument(value >= 0);
return value; return value;
} }
public static Coin nonZeroCoinOf(Coin value) { private static Coin nonZeroCoinOf(Coin value) {
checkNotNull(value); checkNotNull(value);
checkArgument(!value.isZero()); checkArgument(!value.isZero());
return value; return value;
} }
public static Coin positiveCoinOf(Coin value) { private static Coin positiveCoinOf(Coin value) {
checkNotNull(value); checkNotNull(value);
checkArgument(value.isPositive()); checkArgument(value.isPositive());
return value; return value;
} }
public static void checkTradeId(String tradeId, TradeMessage tradeMessage) { private static void checkTradeId(String tradeId, TradeMessage tradeMessage) {
checkArgument(tradeId.equals(tradeMessage.getOfferId())); checkArgument(tradeId.equals(tradeMessage.getOfferId()));
} }
} }