add mining fee padding to maker and taker reserve txs

This commit is contained in:
woodser 2022-08-14 22:18:25 -04:00
parent 2f1f1a788b
commit 54eee73c04
3 changed files with 26 additions and 10 deletions

View file

@ -234,7 +234,6 @@ public class XmrWalletService {
} }
} }
/** /**
* Create the reserve tx and freeze its inputs. The deposit amount is returned * Create the reserve tx and freeze its inputs. The deposit amount is returned
* to the sender's payout address. Additional funds are reserved to allow * to the sender's payout address. Additional funds are reserved to allow
@ -244,7 +243,7 @@ public class XmrWalletService {
* @param depositAmount the amount needed for the trade minus the trade fee * @param depositAmount the amount needed for the trade minus the trade fee
* @return a transaction to reserve a trade * @return a transaction to reserve a trade
*/ */
public MoneroTxWallet createReserveTx(BigInteger tradeFee, String returnAddress, BigInteger depositAmount) { public MoneroTxWallet createReserveTx(BigInteger tradeFee, String returnAddress, BigInteger depositAmount, boolean freezeInputs) {
MoneroWallet wallet = getWallet(); MoneroWallet wallet = getWallet();
synchronized (wallet) { synchronized (wallet) {
@ -262,8 +261,10 @@ public class XmrWalletService {
.addDestination(returnAddress, depositAmount.add(miningFee.multiply(BigInteger.valueOf(3l))))); // add thrice the mining fee // TODO (woodser): really require more funds on top of security deposit? .addDestination(returnAddress, depositAmount.add(miningFee.multiply(BigInteger.valueOf(3l))))); // add thrice the mining fee // TODO (woodser): really require more funds on top of security deposit?
// freeze inputs // freeze inputs
for (MoneroOutput input : reserveTx.getInputs()) { if (freezeInputs) {
wallet.freezeOutput(input.getKeyImage().getHex()); for (MoneroOutput input : reserveTx.getInputs()) {
wallet.freezeOutput(input.getKeyImage().getHex());
}
} }
return reserveTx; return reserveTx;
@ -343,7 +344,7 @@ public class XmrWalletService {
if (!check.getReceivedAmount().equals(tradeFee)) throw new RuntimeException("Trade fee is incorrect amount, expected " + tradeFee + " but was " + check.getReceivedAmount()); if (!check.getReceivedAmount().equals(tradeFee)) throw new RuntimeException("Trade fee is incorrect amount, expected " + tradeFee + " but was " + check.getReceivedAmount());
// verify mining fee // verify mining fee
BigInteger feeEstimate = daemon.getFeeEstimate().multiply(BigInteger.valueOf(txHex.length())); // TODO (woodser): fee estimates are too high, use more accurate estimate BigInteger feeEstimate = getFeeEstimate(txHex);
BigInteger feeThreshold = feeEstimate.multiply(BigInteger.valueOf(1l)).divide(BigInteger.valueOf(2l)); // must be at least 50% of estimated fee BigInteger feeThreshold = feeEstimate.multiply(BigInteger.valueOf(1l)).divide(BigInteger.valueOf(2l)); // must be at least 50% of estimated fee
tx = daemon.getTx(txHash); tx = daemon.getTx(txHash);
if (tx.getFee().compareTo(feeThreshold) < 0) { if (tx.getFee().compareTo(feeThreshold) < 0) {
@ -366,6 +367,11 @@ public class XmrWalletService {
} }
} }
// TODO (woodser): fee estimates are too high, use more accurate estimate
public BigInteger getFeeEstimate(String txHex) {
return getDaemon().getFeeEstimate().multiply(BigInteger.valueOf(txHex.length()));
}
public void shutDown() { public void shutDown() {
closeAllWallets(); closeAllWallets();
} }

View file

@ -43,11 +43,16 @@ public class MakerReservesOfferFunds extends Task<PlaceOfferModel> {
try { try {
runInterceptHook(); runInterceptHook();
// freeze offer funds and get reserve tx // create tx to estimate fee
String returnAddress = model.getXmrWalletService().getOrCreateAddressEntry(offer.getId(), XmrAddressEntry.Context.TRADE_PAYOUT).getAddressString(); String returnAddress = model.getXmrWalletService().getOrCreateAddressEntry(offer.getId(), XmrAddressEntry.Context.TRADE_PAYOUT).getAddressString();
BigInteger makerFee = ParsingUtils.coinToAtomicUnits(offer.getMakerFee()); BigInteger makerFee = ParsingUtils.coinToAtomicUnits(offer.getMakerFee());
BigInteger depositAmount = ParsingUtils.coinToAtomicUnits(model.getReservedFundsForOffer()); BigInteger depositAmount = ParsingUtils.coinToAtomicUnits(model.getReservedFundsForOffer());
MoneroTxWallet reserveTx = model.getXmrWalletService().createReserveTx(makerFee, returnAddress, depositAmount); MoneroTxWallet feeEstimateTx = model.getXmrWalletService().createReserveTx(makerFee, returnAddress, depositAmount, false);
// create reserve tx and freeze inputs
BigInteger feeEstimate = model.getXmrWalletService().getFeeEstimate(feeEstimateTx.getFullHex());
depositAmount = depositAmount.add(feeEstimate.multiply(BigInteger.valueOf(3)));
MoneroTxWallet reserveTx = model.getXmrWalletService().createReserveTx(makerFee, returnAddress, depositAmount, true);
// collect reserved key images // TODO (woodser): switch to proof of reserve? // collect reserved key images // TODO (woodser): switch to proof of reserve?
List<String> reservedKeyImages = new ArrayList<String>(); List<String> reservedKeyImages = new ArrayList<String>();

View file

@ -39,11 +39,16 @@ public class TakerReservesTradeFunds extends TradeTask {
try { try {
runInterceptHook(); runInterceptHook();
// freeze trade funds and get reserve tx // create tx to estimate fee
String returnAddress = model.getXmrWalletService().getOrCreateAddressEntry(trade.getOffer().getId(), XmrAddressEntry.Context.TRADE_PAYOUT).getAddressString(); String returnAddress = model.getXmrWalletService().getOrCreateAddressEntry(trade.getOffer().getId(), XmrAddressEntry.Context.TRADE_PAYOUT).getAddressString();
BigInteger takerFee = ParsingUtils.coinToAtomicUnits(trade.getTakerFee()); BigInteger takerFee = ParsingUtils.coinToAtomicUnits(trade.getTakerFee());
BigInteger depositAmount = ParsingUtils.centinerosToAtomicUnits(processModel.getFundsNeededForTradeAsLong()); BigInteger depositAmount = ParsingUtils.centinerosToAtomicUnits(processModel.getFundsNeededForTradeAsLong());
MoneroTxWallet reserveTx = model.getXmrWalletService().createReserveTx(takerFee, returnAddress, depositAmount); MoneroTxWallet feeEstimateTx = model.getXmrWalletService().createReserveTx(takerFee, returnAddress, depositAmount, false);
// create reserve tx and freeze inputs
BigInteger feeEstimate = model.getXmrWalletService().getFeeEstimate(feeEstimateTx.getFullHex());
depositAmount = depositAmount.add(feeEstimate.multiply(BigInteger.valueOf(3)));
MoneroTxWallet reserveTx = model.getXmrWalletService().createReserveTx(takerFee, returnAddress, depositAmount, true);
// collect reserved key images // TODO (woodser): switch to proof of reserve? // collect reserved key images // TODO (woodser): switch to proof of reserve?
List<String> reservedKeyImages = new ArrayList<String>(); List<String> reservedKeyImages = new ArrayList<String>();