Still experimenting. This donation is randomly attached so as to not have a consistent fingerprint, and is also occasionally split into 2 outputs.

This also sets the foundation for a pay-to-many feature in the future for users.
This commit is contained in:
pokkst 2022-12-03 23:25:06 -06:00
parent fd84f11848
commit 8782d212a3
No known key found for this signature in database
GPG key ID: 90C2ED85E67A50FF
5 changed files with 33 additions and 12 deletions

View file

@ -246,7 +246,6 @@ std::vector<std::uint64_t> java2cpp_long(JNIEnv *env, jlongArray longArray) {
for (jint i = 0; i < len; i++) {
jlong amount = getElement(env, longArray, i);
result.emplace_back(amount);
env->ReleaseLongArrayElements(longArray, reinterpret_cast<jlong *>(amount), i);
}
return result;
}

View file

@ -310,7 +310,7 @@ public class Wallet {
return pendingTransaction;
}
public PendingTransaction createTransactionMultDest(ArrayList<TransactionOutput> outputs, PendingTransaction.Priority priority, ArrayList<String> key_images) {
public PendingTransaction createTransactionMultDest(List<TransactionOutput> outputs, PendingTransaction.Priority priority, ArrayList<String> key_images) {
disposePendingTransaction();
int _priority = priority.getValue();
ArrayList<String> destinations = new ArrayList<>();

View file

@ -30,6 +30,7 @@ import net.mynero.wallet.util.Constants;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
/**
@ -131,47 +132,62 @@ public class MoneroHandlerThread extends Thread implements WalletListener {
public PendingTransaction createTx(String address, String amountStr, boolean sendAll, PendingTransaction.Priority feePriority, ArrayList<String> selectedUtxos) throws Exception {
long amount = Wallet.getAmountFromString(amountStr);
System.out.println("AMOUNT:: " + amount);
ArrayList<String> preferredInputs;
if (selectedUtxos.isEmpty()) {
// no inputs manually selected, we are sending from home screen most likely, or user somehow broke the app
preferredInputs = UTXOService.getInstance().selectUtxos(amount, sendAll);
} else {
preferredInputs = selectedUtxos;
checkSelectedAmounts(selectedUtxos, amount, sendAll);
checkSelectedAmounts(preferredInputs, amount, sendAll);
}
if(sendAll) {
return wallet.createSweepTransaction(address, feePriority, preferredInputs);
}
boolean donatePerTx = PrefService.getInstance().getBoolean(Constants.PREF_DONATE_PER_TX, false);
ArrayList<TransactionOutput> outputs = new ArrayList<>();
outputs.add(new TransactionOutput(address, amount));
if(donatePerTx) {
List<TransactionOutput> finalOutputs = maybeAddDonationOutputs(amount, outputs, preferredInputs);
return wallet.createTransactionMultDest(finalOutputs, feePriority, preferredInputs);
}
private List<TransactionOutput> maybeAddDonationOutputs(long amount, List<TransactionOutput> outputs, List<String> preferredInputs) throws Exception {
TransactionOutput mainDestination = outputs.get(0); // at this point, for now, we should only have one item in the list
String paymentId = Wallet.getPaymentIdFromAddress(mainDestination.getDestination(), WalletManager.getInstance().getNetworkType().getValue());
System.out.println("PAYMENT ID:: " + paymentId + ".");
ArrayList<TransactionOutput> newOutputs = new ArrayList<>(outputs);
boolean donatePerTx = true;
if(donatePerTx && paymentId.isEmpty()) {
float randomDonatePct = getRandomDonateAmount(0.0075f, 0.015f); // occasionally attaches a 0.75% to 1.5% fee. It is random so that not even I know how much exactly you are sending.
/*
It's also not entirely "per tx". It won't always attach it so as to not have a consistent fingerprint on-chain. When it does attach a donation,
it will periodically split it up into 2 outputs instead of 1.
*/
System.out.println("RANDOM DONATE PCT:: " + randomDonatePct);
int attachDonationRoll = new SecureRandom().nextInt(100);
if(attachDonationRoll > 75) {
if(attachDonationRoll > 1) {
int splitDonationRoll = new SecureRandom().nextInt(100);
long donateAmount = (long) (amount*randomDonatePct);
System.out.println("DONATE AMOUNT:: " + donateAmount);
if(splitDonationRoll > 50) {
// split
long splitAmount = donateAmount / 2;
outputs.add(new TransactionOutput(Constants.DONATE_ADDRESS, splitAmount));
outputs.add(new TransactionOutput(Constants.DONATE_ADDRESS, splitAmount));
newOutputs.add(new TransactionOutput(Constants.DONATE_ADDRESS, splitAmount));
newOutputs.add(new TransactionOutput(Constants.DONATE_ADDRESS_2, splitAmount));
} else {
outputs.add(new TransactionOutput(Constants.DONATE_ADDRESS, donateAmount));
newOutputs.add(new TransactionOutput(Constants.DONATE_ADDRESS, donateAmount));
}
checkSelectedAmounts(selectedUtxos, amount+donateAmount, false); // check that the selected UTXOs satisfy the new amount total
long total = amount + donateAmount;
System.out.println("TOTAL:: " + total);
checkSelectedAmounts(preferredInputs, total, false); // check that the selected UTXOs satisfy the new amount total
}
}
return wallet.createTransactionMultDest(outputs, feePriority, preferredInputs);
return newOutputs;
}
private void checkSelectedAmounts(ArrayList<String> selectedUtxos, long amount, boolean sendAll) throws Exception {
private void checkSelectedAmounts(List<String> selectedUtxos, long amount, boolean sendAll) throws Exception {
if (!sendAll) {
long amountSelected = 0;
for (CoinsInfo coinsInfo : UTXOService.getInstance().getUtxos()) {
@ -181,6 +197,9 @@ public class MoneroHandlerThread extends Thread implements WalletListener {
}
if (amountSelected <= amount) {
System.out.println("/////// CHECK");
System.out.println("AMOUNT SELECTED:: " + amountSelected);
System.out.println("AMOUNT:: " + amount);
throw new Exception("insufficient wallet balance");
}
}

View file

@ -63,6 +63,8 @@ public class UTXOService extends ServiceBase {
}
}
System.out.println("AMOUNT WITH BASIC FEE:: " + amountWithBasicFee);
System.out.println("AMOUNT SELECTED:: " + amountSelected);
if (amountSelected < amountWithBasicFee && !sendAll) {
throw new Exception("insufficient wallet balance");
}

View file

@ -20,5 +20,6 @@ public class Constants {
public static final String NAV_ARG_TXINFO = "nav_arg_txinfo";
public static final String STREET_MODE_BALANCE = "#.############";
public static final String DONATE_ADDRESS_2 = "89Yym1JTqiM7PMgra3XP1oMtGkiAQHBrFE7VJFAVYU1DTpAqviTsNewM2KoBw5fLLufaNMfJZq9bNhyPmfWq62hy4T9jzQF";
public static final String DONATE_ADDRESS = "87MRtZPrWUCVUgcFHdsVb5MoZUcLtqfD3FvQVGwftFb8eSdMnE39JhAJcbuSW8X2vRaRsB9RQfuCpFciybJFHaz3QYPhCLw";
}