mirror of
https://github.com/boldsuck/haveno.git
synced 2025-01-03 14:49:25 +00:00
validate pending offer
This commit is contained in:
parent
8f5e56b9dc
commit
0450900b37
3 changed files with 73 additions and 57 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,55 +43,7 @@ public class ValidateOffer extends Task<PlaceOfferModel> {
|
||||||
try {
|
try {
|
||||||
runInterceptHook();
|
runInterceptHook();
|
||||||
|
|
||||||
// Coins
|
validateOffer(offer, model.getAccountAgeWitnessService(), model.getUser());
|
||||||
checkBINotNullOrZero(offer.getAmount(), "Amount");
|
|
||||||
checkBINotNullOrZero(offer.getMinAmount(), "MinAmount");
|
|
||||||
//checkCoinNotNullOrZero(offer.getTxFee(), "txFee"); // TODO: remove from data model
|
|
||||||
checkBINotNullOrZero(offer.getMaxTradeLimit(), "MaxTradeLimit");
|
|
||||||
if (offer.getMakerFeePct() < 0) throw new IllegalArgumentException("Maker fee must be >= 0% but was " + offer.getMakerFeePct());
|
|
||||||
if (offer.getTakerFeePct() < 0) throw new IllegalArgumentException("Taker fee must be >= 0% but was " + offer.getTakerFeePct());
|
|
||||||
if (offer.getBuyerSecurityDepositPct() <= 0) throw new IllegalArgumentException("Buyer security deposit percent must be positive but was " + offer.getBuyerSecurityDepositPct());
|
|
||||||
if (offer.getSellerSecurityDepositPct() <= 0) throw new IllegalArgumentException("Seller security deposit percent must be positive but was " + offer.getSellerSecurityDepositPct());
|
|
||||||
|
|
||||||
// We remove those checks to be more flexible with future changes.
|
|
||||||
/*checkArgument(offer.getMakerFee().value >= FeeService.getMinMakerFee(offer.isCurrencyForMakerFeeBtc()).value,
|
|
||||||
"createOfferFee must not be less than FeeService.MIN_CREATE_OFFER_FEE_IN_BTC. " +
|
|
||||||
"MakerFee=" + offer.getMakerFee().toFriendlyString());*/
|
|
||||||
/*checkArgument(offer.getBuyerSecurityDeposit().value >= ProposalConsensus.getMinBuyerSecurityDeposit().value,
|
|
||||||
"buyerSecurityDeposit must not be less than ProposalConsensus.MIN_BUYER_SECURITY_DEPOSIT. " +
|
|
||||||
"buyerSecurityDeposit=" + offer.getBuyerSecurityDeposit().toFriendlyString());
|
|
||||||
checkArgument(offer.getBuyerSecurityDeposit().value <= ProposalConsensus.getMaxBuyerSecurityDeposit().value,
|
|
||||||
"buyerSecurityDeposit must not be larger than ProposalConsensus.MAX_BUYER_SECURITY_DEPOSIT. " +
|
|
||||||
"buyerSecurityDeposit=" + offer.getBuyerSecurityDeposit().toFriendlyString());
|
|
||||||
checkArgument(offer.getSellerSecurityDeposit().value == ProposalConsensus.getSellerSecurityDeposit().value,
|
|
||||||
"sellerSecurityDeposit must be equal to ProposalConsensus.SELLER_SECURITY_DEPOSIT. " +
|
|
||||||
"sellerSecurityDeposit=" + offer.getSellerSecurityDeposit().toFriendlyString());*/
|
|
||||||
/*checkArgument(offer.getMinAmount().compareTo(ProposalConsensus.getMinTradeAmount()) >= 0,
|
|
||||||
"MinAmount is less than " + ProposalConsensus.getMinTradeAmount().toFriendlyString());*/
|
|
||||||
|
|
||||||
long maxAmount = model.getAccountAgeWitnessService().getMyTradeLimit(model.getUser().getPaymentAccount(offer.getMakerPaymentAccountId()), offer.getCurrencyCode(), offer.getDirection());
|
|
||||||
checkArgument(offer.getAmount().longValueExact() <= maxAmount,
|
|
||||||
"Amount is larger than " + HavenoUtils.atomicUnitsToXmr(offer.getPaymentMethod().getMaxTradeLimit(offer.getCurrencyCode())) + " XMR");
|
|
||||||
checkArgument(offer.getAmount().compareTo(offer.getMinAmount()) >= 0, "MinAmount is larger than Amount");
|
|
||||||
|
|
||||||
checkNotNull(offer.getPrice(), "Price is null");
|
|
||||||
if (!offer.isUseMarketBasedPrice()) checkArgument(offer.getPrice().isPositive(),
|
|
||||||
"Price must be positive unless using market based price. price=" + offer.getPrice().toFriendlyString());
|
|
||||||
|
|
||||||
checkArgument(offer.getDate().getTime() > 0,
|
|
||||||
"Date must not be 0. date=" + offer.getDate().toString());
|
|
||||||
|
|
||||||
checkNotNull(offer.getCurrencyCode(), "Currency is null");
|
|
||||||
checkNotNull(offer.getDirection(), "Direction is null");
|
|
||||||
checkNotNull(offer.getId(), "Id is null");
|
|
||||||
checkNotNull(offer.getPubKeyRing(), "pubKeyRing is null");
|
|
||||||
checkNotNull(offer.getMinAmount(), "MinAmount is null");
|
|
||||||
checkNotNull(offer.getPrice(), "Price is null");
|
|
||||||
checkNotNull(offer.getVersionNr(), "VersionNr is null");
|
|
||||||
checkArgument(offer.getMaxTradePeriod() > 0,
|
|
||||||
"maxTradePeriod must be positive. maxTradePeriod=" + offer.getMaxTradePeriod());
|
|
||||||
// TODO check upper and lower bounds for fiat
|
|
||||||
// TODO check rest of new parameters
|
|
||||||
|
|
||||||
complete();
|
complete();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -100,42 +54,95 @@ public class ValidateOffer extends Task<PlaceOfferModel> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkBINotNullOrZero(BigInteger value, String name) {
|
public static void validateOffer(Offer offer, AccountAgeWitnessService accountAgeWitnessService, User user) {
|
||||||
|
|
||||||
|
// Coins
|
||||||
|
checkBINotNullOrZero(offer.getAmount(), "Amount");
|
||||||
|
checkBINotNullOrZero(offer.getMinAmount(), "MinAmount");
|
||||||
|
//checkCoinNotNullOrZero(offer.getTxFee(), "txFee"); // TODO: remove from data model
|
||||||
|
checkBINotNullOrZero(offer.getMaxTradeLimit(), "MaxTradeLimit");
|
||||||
|
if (offer.getMakerFeePct() < 0) throw new IllegalArgumentException("Maker fee must be >= 0% but was " + offer.getMakerFeePct());
|
||||||
|
if (offer.getTakerFeePct() < 0) throw new IllegalArgumentException("Taker fee must be >= 0% but was " + offer.getTakerFeePct());
|
||||||
|
if (offer.getBuyerSecurityDepositPct() <= 0) throw new IllegalArgumentException("Buyer security deposit percent must be positive but was " + offer.getBuyerSecurityDepositPct());
|
||||||
|
if (offer.getSellerSecurityDepositPct() <= 0) throw new IllegalArgumentException("Seller security deposit percent must be positive but was " + offer.getSellerSecurityDepositPct());
|
||||||
|
|
||||||
|
// We remove those checks to be more flexible with future changes.
|
||||||
|
/*checkArgument(offer.getMakerFee().value >= FeeService.getMinMakerFee(offer.isCurrencyForMakerFeeBtc()).value,
|
||||||
|
"createOfferFee must not be less than FeeService.MIN_CREATE_OFFER_FEE_IN_BTC. " +
|
||||||
|
"MakerFee=" + offer.getMakerFee().toFriendlyString());*/
|
||||||
|
/*checkArgument(offer.getBuyerSecurityDeposit().value >= ProposalConsensus.getMinBuyerSecurityDeposit().value,
|
||||||
|
"buyerSecurityDeposit must not be less than ProposalConsensus.MIN_BUYER_SECURITY_DEPOSIT. " +
|
||||||
|
"buyerSecurityDeposit=" + offer.getBuyerSecurityDeposit().toFriendlyString());
|
||||||
|
checkArgument(offer.getBuyerSecurityDeposit().value <= ProposalConsensus.getMaxBuyerSecurityDeposit().value,
|
||||||
|
"buyerSecurityDeposit must not be larger than ProposalConsensus.MAX_BUYER_SECURITY_DEPOSIT. " +
|
||||||
|
"buyerSecurityDeposit=" + offer.getBuyerSecurityDeposit().toFriendlyString());
|
||||||
|
checkArgument(offer.getSellerSecurityDeposit().value == ProposalConsensus.getSellerSecurityDeposit().value,
|
||||||
|
"sellerSecurityDeposit must be equal to ProposalConsensus.SELLER_SECURITY_DEPOSIT. " +
|
||||||
|
"sellerSecurityDeposit=" + offer.getSellerSecurityDeposit().toFriendlyString());*/
|
||||||
|
/*checkArgument(offer.getMinAmount().compareTo(ProposalConsensus.getMinTradeAmount()) >= 0,
|
||||||
|
"MinAmount is less than " + ProposalConsensus.getMinTradeAmount().toFriendlyString());*/
|
||||||
|
|
||||||
|
long maxAmount = accountAgeWitnessService.getMyTradeLimit(user.getPaymentAccount(offer.getMakerPaymentAccountId()), offer.getCurrencyCode(), offer.getDirection());
|
||||||
|
checkArgument(offer.getAmount().longValueExact() <= maxAmount,
|
||||||
|
"Amount is larger than " + HavenoUtils.atomicUnitsToXmr(offer.getPaymentMethod().getMaxTradeLimit(offer.getCurrencyCode())) + " XMR");
|
||||||
|
checkArgument(offer.getAmount().compareTo(offer.getMinAmount()) >= 0, "MinAmount is larger than Amount");
|
||||||
|
|
||||||
|
checkNotNull(offer.getPrice(), "Price is null");
|
||||||
|
if (!offer.isUseMarketBasedPrice()) checkArgument(offer.getPrice().isPositive(),
|
||||||
|
"Price must be positive unless using market based price. price=" + offer.getPrice().toFriendlyString());
|
||||||
|
|
||||||
|
checkArgument(offer.getDate().getTime() > 0,
|
||||||
|
"Date must not be 0. date=" + offer.getDate().toString());
|
||||||
|
|
||||||
|
checkNotNull(offer.getCurrencyCode(), "Currency is null");
|
||||||
|
checkNotNull(offer.getDirection(), "Direction is null");
|
||||||
|
checkNotNull(offer.getId(), "Id is null");
|
||||||
|
checkNotNull(offer.getPubKeyRing(), "pubKeyRing is null");
|
||||||
|
checkNotNull(offer.getMinAmount(), "MinAmount is null");
|
||||||
|
checkNotNull(offer.getPrice(), "Price is null");
|
||||||
|
checkNotNull(offer.getVersionNr(), "VersionNr is null");
|
||||||
|
checkArgument(offer.getMaxTradePeriod() > 0,
|
||||||
|
"maxTradePeriod must be positive. maxTradePeriod=" + offer.getMaxTradePeriod());
|
||||||
|
// TODO check upper and lower bounds for fiat
|
||||||
|
// TODO check rest of new parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue