fix fee calculation taking offer within range
This commit is contained in:
parent
0251b49d61
commit
b90163baa5
@ -512,10 +512,11 @@ public class CoreApi {
|
|||||||
|
|
||||||
public void takeOffer(String offerId,
|
public void takeOffer(String offerId,
|
||||||
String paymentAccountId,
|
String paymentAccountId,
|
||||||
|
long amountAsLong,
|
||||||
Consumer<Trade> resultHandler,
|
Consumer<Trade> resultHandler,
|
||||||
ErrorMessageHandler errorMessageHandler) {
|
ErrorMessageHandler errorMessageHandler) {
|
||||||
Offer offer = coreOffersService.getOffer(offerId);
|
Offer offer = coreOffersService.getOffer(offerId);
|
||||||
coreTradesService.takeOffer(offer, paymentAccountId, resultHandler, errorMessageHandler);
|
coreTradesService.takeOffer(offer, paymentAccountId, amountAsLong, resultHandler, errorMessageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void confirmPaymentSent(String tradeId,
|
public void confirmPaymentSent(String tradeId,
|
||||||
|
@ -89,6 +89,7 @@ class CoreTradesService {
|
|||||||
|
|
||||||
void takeOffer(Offer offer,
|
void takeOffer(Offer offer,
|
||||||
String paymentAccountId,
|
String paymentAccountId,
|
||||||
|
long amountAsLong,
|
||||||
Consumer<Trade> resultHandler,
|
Consumer<Trade> resultHandler,
|
||||||
ErrorMessageHandler errorMessageHandler) {
|
ErrorMessageHandler errorMessageHandler) {
|
||||||
try {
|
try {
|
||||||
@ -101,18 +102,21 @@ class CoreTradesService {
|
|||||||
|
|
||||||
var useSavingsWallet = true;
|
var useSavingsWallet = true;
|
||||||
|
|
||||||
|
// default to offer amount
|
||||||
|
BigInteger amount = amountAsLong == 0 ? offer.getAmount() : BigInteger.valueOf(amountAsLong);
|
||||||
|
|
||||||
// synchronize access to take offer model // TODO (woodser): to avoid synchronizing, don't use stateful model
|
// synchronize access to take offer model // TODO (woodser): to avoid synchronizing, don't use stateful model
|
||||||
BigInteger takerFee;
|
BigInteger takerFee;
|
||||||
BigInteger fundsNeededForTrade;
|
BigInteger fundsNeededForTrade;
|
||||||
synchronized (takeOfferModel) {
|
synchronized (takeOfferModel) {
|
||||||
takeOfferModel.initModel(offer, paymentAccount, useSavingsWallet);
|
takeOfferModel.initModel(offer, paymentAccount, amount, useSavingsWallet);
|
||||||
takerFee = takeOfferModel.getTakerFee();
|
takerFee = takeOfferModel.getTakerFee();
|
||||||
fundsNeededForTrade = takeOfferModel.getFundsNeededForTrade();
|
fundsNeededForTrade = takeOfferModel.getFundsNeededForTrade();
|
||||||
log.info("Initiating take {} offer, {}", offer.isBuyOffer() ? "buy" : "sell", takeOfferModel);
|
log.info("Initiating take {} offer, {}", offer.isBuyOffer() ? "buy" : "sell", takeOfferModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// take offer
|
// take offer
|
||||||
tradeManager.onTakeOffer(offer.getAmount(),
|
tradeManager.onTakeOffer(amount,
|
||||||
takerFee,
|
takerFee,
|
||||||
fundsNeededForTrade,
|
fundsNeededForTrade,
|
||||||
offer,
|
offer,
|
||||||
|
@ -32,6 +32,8 @@ import haveno.network.p2p.P2PService;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class OfferAvailabilityModel implements Model {
|
public class OfferAvailabilityModel implements Model {
|
||||||
@ -54,6 +56,8 @@ public class OfferAvailabilityModel implements Model {
|
|||||||
@Getter
|
@Getter
|
||||||
private String paymentAccountId;
|
private String paymentAccountId;
|
||||||
@Getter
|
@Getter
|
||||||
|
private BigInteger tradeAmount;
|
||||||
|
@Getter
|
||||||
private OfferUtil offerUtil;
|
private OfferUtil offerUtil;
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@ -76,6 +80,7 @@ public class OfferAvailabilityModel implements Model {
|
|||||||
TradeStatisticsManager tradeStatisticsManager,
|
TradeStatisticsManager tradeStatisticsManager,
|
||||||
boolean isTakerApiUser,
|
boolean isTakerApiUser,
|
||||||
String paymentAccountId,
|
String paymentAccountId,
|
||||||
|
BigInteger tradeAmount,
|
||||||
OfferUtil offerUtil) {
|
OfferUtil offerUtil) {
|
||||||
this.offer = offer;
|
this.offer = offer;
|
||||||
this.pubKeyRing = pubKeyRing;
|
this.pubKeyRing = pubKeyRing;
|
||||||
@ -86,6 +91,7 @@ public class OfferAvailabilityModel implements Model {
|
|||||||
this.tradeStatisticsManager = tradeStatisticsManager;
|
this.tradeStatisticsManager = tradeStatisticsManager;
|
||||||
this.isTakerApiUser = isTakerApiUser;
|
this.isTakerApiUser = isTakerApiUser;
|
||||||
this.paymentAccountId = paymentAccountId;
|
this.paymentAccountId = paymentAccountId;
|
||||||
|
this.tradeAmount = tradeAmount;
|
||||||
this.offerUtil = offerUtil;
|
this.offerUtil = offerUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +69,9 @@ public class SendOfferAvailabilityRequest extends Task<OfferAvailabilityModel> {
|
|||||||
offer.getId(),
|
offer.getId(),
|
||||||
P2PService.getMyNodeAddress(),
|
P2PService.getMyNodeAddress(),
|
||||||
p2PService.getKeyRing().getPubKeyRing(),
|
p2PService.getKeyRing().getPubKeyRing(),
|
||||||
offer.getAmount().longValueExact(),
|
model.getTradeAmount().longValueExact(),
|
||||||
price.getValue(),
|
price.getValue(),
|
||||||
HavenoUtils.getTakerFee(offer.getAmount()).longValueExact(),
|
HavenoUtils.getTakerFee(model.getTradeAmount()).longValueExact(),
|
||||||
user.getAccountId(),
|
user.getAccountId(),
|
||||||
paymentAccountId,
|
paymentAccountId,
|
||||||
paymentMethodId,
|
paymentMethodId,
|
||||||
|
@ -92,6 +92,7 @@ public class TakeOfferModel implements Model {
|
|||||||
|
|
||||||
public void initModel(Offer offer,
|
public void initModel(Offer offer,
|
||||||
PaymentAccount paymentAccount,
|
PaymentAccount paymentAccount,
|
||||||
|
BigInteger tradeAmount,
|
||||||
boolean useSavingsWallet) {
|
boolean useSavingsWallet) {
|
||||||
this.clearModel();
|
this.clearModel();
|
||||||
this.offer = offer;
|
this.offer = offer;
|
||||||
@ -100,7 +101,7 @@ public class TakeOfferModel implements Model {
|
|||||||
validateModelInputs();
|
validateModelInputs();
|
||||||
|
|
||||||
this.useSavingsWallet = useSavingsWallet;
|
this.useSavingsWallet = useSavingsWallet;
|
||||||
this.amount = offer.getAmount().min(BigInteger.valueOf(getMaxTradeLimit()));
|
this.amount = tradeAmount.min(BigInteger.valueOf(getMaxTradeLimit()));
|
||||||
this.securityDeposit = offer.getDirection() == SELL
|
this.securityDeposit = offer.getDirection() == SELL
|
||||||
? offer.getBuyerSecurityDeposit()
|
? offer.getBuyerSecurityDeposit()
|
||||||
: offer.getSellerSecurityDeposit();
|
: offer.getSellerSecurityDeposit();
|
||||||
|
@ -561,11 +561,11 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get expected taker fee
|
// get expected taker fee
|
||||||
BigInteger takerFee = HavenoUtils.getTakerFee(BigInteger.valueOf(offer.getOfferPayload().getAmount()));
|
BigInteger takerFee = HavenoUtils.getTakerFee(BigInteger.valueOf(request.getTradeAmount()));
|
||||||
|
|
||||||
// create arbitrator trade
|
// create arbitrator trade
|
||||||
trade = new ArbitratorTrade(offer,
|
trade = new ArbitratorTrade(offer,
|
||||||
BigInteger.valueOf(offer.getOfferPayload().getAmount()),
|
BigInteger.valueOf(request.getTradeAmount()),
|
||||||
takerFee,
|
takerFee,
|
||||||
offer.getOfferPayload().getPrice(),
|
offer.getOfferPayload().getPrice(),
|
||||||
xmrWalletService,
|
xmrWalletService,
|
||||||
@ -630,12 +630,12 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
openOfferManager.reserveOpenOffer(openOffer);
|
openOfferManager.reserveOpenOffer(openOffer);
|
||||||
|
|
||||||
// get expected taker fee
|
// get expected taker fee
|
||||||
BigInteger takerFee = HavenoUtils.getTakerFee(BigInteger.valueOf(offer.getOfferPayload().getAmount()));
|
BigInteger takerFee = HavenoUtils.getTakerFee(BigInteger.valueOf(request.getTradeAmount()));
|
||||||
|
|
||||||
Trade trade;
|
Trade trade;
|
||||||
if (offer.isBuyOffer())
|
if (offer.isBuyOffer())
|
||||||
trade = new BuyerAsMakerTrade(offer,
|
trade = new BuyerAsMakerTrade(offer,
|
||||||
BigInteger.valueOf(offer.getOfferPayload().getAmount()),
|
BigInteger.valueOf(request.getTradeAmount()),
|
||||||
takerFee,
|
takerFee,
|
||||||
offer.getOfferPayload().getPrice(),
|
offer.getOfferPayload().getPrice(),
|
||||||
xmrWalletService,
|
xmrWalletService,
|
||||||
@ -646,7 +646,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
request.getArbitratorNodeAddress());
|
request.getArbitratorNodeAddress());
|
||||||
else
|
else
|
||||||
trade = new SellerAsMakerTrade(offer,
|
trade = new SellerAsMakerTrade(offer,
|
||||||
BigInteger.valueOf(offer.getOfferPayload().getAmount()),
|
BigInteger.valueOf(request.getTradeAmount()),
|
||||||
takerFee,
|
takerFee,
|
||||||
offer.getOfferPayload().getPrice(),
|
offer.getOfferPayload().getPrice(),
|
||||||
xmrWalletService,
|
xmrWalletService,
|
||||||
@ -788,9 +788,10 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
public void checkOfferAvailability(Offer offer,
|
public void checkOfferAvailability(Offer offer,
|
||||||
boolean isTakerApiUser,
|
boolean isTakerApiUser,
|
||||||
String paymentAccountId,
|
String paymentAccountId,
|
||||||
|
BigInteger tradeAmount,
|
||||||
ResultHandler resultHandler,
|
ResultHandler resultHandler,
|
||||||
ErrorMessageHandler errorMessageHandler) {
|
ErrorMessageHandler errorMessageHandler) {
|
||||||
offer.checkOfferAvailability(getOfferAvailabilityModel(offer, isTakerApiUser, paymentAccountId), resultHandler, errorMessageHandler);
|
offer.checkOfferAvailability(getOfferAvailabilityModel(offer, isTakerApiUser, paymentAccountId, tradeAmount), resultHandler, errorMessageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
// First we check if offer is still available then we create the trade with the protocol
|
// First we check if offer is still available then we create the trade with the protocol
|
||||||
@ -806,7 +807,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
|
|
||||||
checkArgument(!wasOfferAlreadyUsedInTrade(offer.getId()));
|
checkArgument(!wasOfferAlreadyUsedInTrade(offer.getId()));
|
||||||
|
|
||||||
OfferAvailabilityModel model = getOfferAvailabilityModel(offer, isTakerApiUser, paymentAccountId);
|
OfferAvailabilityModel model = getOfferAvailabilityModel(offer, isTakerApiUser, paymentAccountId, amount);
|
||||||
offer.checkOfferAvailability(model,
|
offer.checkOfferAvailability(model,
|
||||||
() -> {
|
() -> {
|
||||||
if (offer.getState() == Offer.State.AVAILABLE) {
|
if (offer.getState() == Offer.State.AVAILABLE) {
|
||||||
@ -886,7 +887,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
processModelServiceProvider.getKeyRing().getPubKeyRing());
|
processModelServiceProvider.getKeyRing().getPubKeyRing());
|
||||||
}
|
}
|
||||||
|
|
||||||
private OfferAvailabilityModel getOfferAvailabilityModel(Offer offer, boolean isTakerApiUser, String paymentAccountId) {
|
private OfferAvailabilityModel getOfferAvailabilityModel(Offer offer, boolean isTakerApiUser, String paymentAccountId, BigInteger tradeAmount) {
|
||||||
return new OfferAvailabilityModel(
|
return new OfferAvailabilityModel(
|
||||||
offer,
|
offer,
|
||||||
keyRing.getPubKeyRing(),
|
keyRing.getPubKeyRing(),
|
||||||
@ -897,6 +898,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||||||
tradeStatisticsManager,
|
tradeStatisticsManager,
|
||||||
isTakerApiUser,
|
isTakerApiUser,
|
||||||
paymentAccountId,
|
paymentAccountId,
|
||||||
|
tradeAmount,
|
||||||
offerUtil);
|
offerUtil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ public class MakerSendInitTradeRequest extends TradeTask {
|
|||||||
offer.getId(),
|
offer.getId(),
|
||||||
processModel.getMyNodeAddress(),
|
processModel.getMyNodeAddress(),
|
||||||
processModel.getPubKeyRing(),
|
processModel.getPubKeyRing(),
|
||||||
offer.getAmount().longValueExact(),
|
trade.getAmount().longValueExact(),
|
||||||
trade.getPrice().getValue(),
|
trade.getPrice().getValue(),
|
||||||
offer.getMakerFee().longValueExact(),
|
offer.getMakerFee().longValueExact(),
|
||||||
trade.getProcessModel().getAccountId(),
|
trade.getProcessModel().getAccountId(),
|
||||||
|
@ -122,6 +122,7 @@ class GrpcTradesService extends TradesImplBase {
|
|||||||
try {
|
try {
|
||||||
coreApi.takeOffer(req.getOfferId(),
|
coreApi.takeOffer(req.getOfferId(),
|
||||||
req.getPaymentAccountId(),
|
req.getPaymentAccountId(),
|
||||||
|
req.getAmount(),
|
||||||
trade -> {
|
trade -> {
|
||||||
TradeInfo tradeInfo = toTradeInfo(trade);
|
TradeInfo tradeInfo = toTradeInfo(trade);
|
||||||
var reply = TakeOfferReply.newBuilder()
|
var reply = TakeOfferReply.newBuilder()
|
||||||
|
@ -156,6 +156,7 @@ class TakeOfferDataModel extends OfferDataModel {
|
|||||||
tradeManager.checkOfferAvailability(offer,
|
tradeManager.checkOfferAvailability(offer,
|
||||||
false,
|
false,
|
||||||
paymentAccount.getId(),
|
paymentAccount.getId(),
|
||||||
|
this.amount.get(),
|
||||||
() -> {
|
() -> {
|
||||||
},
|
},
|
||||||
errorMessage -> new Popup().warning(errorMessage).show());
|
errorMessage -> new Popup().warning(errorMessage).show());
|
||||||
|
@ -746,6 +746,7 @@ service Trades {
|
|||||||
message TakeOfferRequest {
|
message TakeOfferRequest {
|
||||||
string offer_id = 1;
|
string offer_id = 1;
|
||||||
string payment_account_id = 2;
|
string payment_account_id = 2;
|
||||||
|
uint64 amount = 3 [jstype = JS_STRING];
|
||||||
}
|
}
|
||||||
|
|
||||||
message TakeOfferReply {
|
message TakeOfferReply {
|
||||||
|
Loading…
Reference in New Issue
Block a user