Sort getBtcFeeReceiverAddress by amount and address.

Increase minOutputAmount to 1000 sat.
Cleanups

Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
This commit is contained in:
HenrikJannsen 2022-11-04 10:56:10 -05:00
parent fa857b39ec
commit 731363d128
No known key found for this signature in database
GPG Key ID: 02AA2BAE387C8307
8 changed files with 26 additions and 31 deletions

View File

@ -29,7 +29,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Getter
@EqualsAndHashCode
public final class BurningManCandidate implements Comparable<BurningManCandidate> {
public final class BurningManCandidate {
private long accumulatedCompensationAmount;
private long accumulatedDecayedCompensationAmount;
private long accumulatedBurnAmount;
@ -39,7 +39,6 @@ public final class BurningManCandidate implements Comparable<BurningManCandidate
private double boostedIssuanceShare;
private double burnOutputShare; // share of accumulated decayed burn amounts in relation to total burned amounts
private double effectiveBurnOutputShare; // limited to boostedIssuanceShare
private final List<CompensationModel> compensationModels = new ArrayList<>();
private final List<BurnOutputModel> burnOutputModels = new ArrayList<>();
@ -92,21 +91,11 @@ public final class BurningManCandidate implements Comparable<BurningManCandidate
.map(CompensationModel::getAddress);
}
//todo do sorting where its needed for better control
@Override
public int compareTo(BurningManCandidate o) {
int result = Double.compare(getBurnOutputShare(), o.getBurnOutputShare());
if (result == 0 && !compensationModels.isEmpty() && !o.compensationModels.isEmpty()) {
result = compensationModels.get(0).getTxId().compareTo(o.compensationModels.get(0).getTxId());
}
return result;
}
@Override
public String toString() {
return "BurningManCandidate{" +
"\r\n accumulatedIssuanceAmount=" + accumulatedCompensationAmount +
",\r\n accumulatedDecayedIssuanceAmount=" + accumulatedDecayedCompensationAmount +
"\r\n accumulatedCompensationAmount=" + accumulatedCompensationAmount +
",\r\n accumulatedDecayedCompensationAmount=" + accumulatedDecayedCompensationAmount +
",\r\n accumulatedBurnAmount=" + accumulatedBurnAmount +
",\r\n accumulatedDecayedBurnAmount=" + accumulatedDecayedBurnAmount +
",\r\n allowedBurnAmount=" + allowedBurnAmount +

View File

@ -456,7 +456,7 @@ public class BurningManService implements DaoStateListener {
// Legacy BurningMan
///////////////////////////////////////////////////////////////////////////////////////////
public String getBurningManAddressFromParam(int chainHeight) {
public String getLegacyBurningManAddress(int chainHeight) {
return daoStateService.getParamValue(Param.RECIPIENT_BTC_ADDRESS, chainHeight);
}
@ -469,7 +469,7 @@ public class BurningManService implements DaoStateListener {
Map<String, BurningManCandidate> burningManCandidatesByName = getCurrentBurningManCandidatesByName();
if (burningManCandidatesByName.isEmpty()) {
// If there are no compensation requests (e.g. at dev testing) we fall back to the default address
return getBurningManAddressFromParam(currentChainHeight);
return getLegacyBurningManAddress(currentChainHeight);
}
// It might be that we do not reach 100% if some entries had a capped effectiveBurnOutputShare.
@ -484,14 +484,14 @@ public class BurningManService implements DaoStateListener {
.map(effectiveBurnOutputShare -> (long) Math.floor(effectiveBurnOutputShare * 10000))
.collect(Collectors.toList());
if (amountList.isEmpty()) {
return getBurningManAddressFromParam(currentChainHeight);
return getLegacyBurningManAddress(currentChainHeight);
}
int winnerIndex = getRandomIndex(amountList, new Random());
if (winnerIndex == -1) {
return getBurningManAddressFromParam(currentChainHeight);
return getLegacyBurningManAddress(currentChainHeight);
}
return burningManCandidates.get(winnerIndex).getMostRecentAddress()
.orElse(getBurningManAddressFromParam(currentChainHeight));
.orElse(getLegacyBurningManAddress(currentChainHeight));
}
@ -513,7 +513,7 @@ public class BurningManService implements DaoStateListener {
Collection<BurningManCandidate> burningManCandidates = getBurningManCandidatesByName(burningManSelectionHeight).values();
if (burningManCandidates.isEmpty()) {
// If there are no compensation requests (e.g. at dev testing) we fall back to the legacy BM
return List.of(new Tuple2<>(inputAmount, getBurningManAddressFromParam(burningManSelectionHeight)));
return List.of(new Tuple2<>(inputAmount, getLegacyBurningManAddress(burningManSelectionHeight)));
}
// We need to use the same txFeePerVbyte value for both traders.
@ -530,15 +530,17 @@ public class BurningManService implements DaoStateListener {
double txSize = 278;
long txFeePerVbyte = Math.max(10, Math.round(tradeTxFee / txSize));
long spendableAmount = getSpendableAmount(burningManCandidates.size(), inputAmount, txFeePerVbyte);
// We only use outputs > 500 sat or at least 2 times the cost for the output (32 bytes).
// We only use outputs > 1000 sat or at least 2 times the cost for the output (32 bytes).
// If we remove outputs it will be spent as miner fee.
long minOutputAmount = Math.max(500, txFeePerVbyte * 32 * 2);
long minOutputAmount = Math.max(1000, txFeePerVbyte * 32 * 2);
List<Tuple2<Long, String>> receivers = burningManCandidates.stream()
.filter(candidate -> candidate.getMostRecentAddress().isPresent())
.map(candidates -> new Tuple2<>(Math.round(candidates.getEffectiveBurnOutputShare() * spendableAmount),
candidates.getMostRecentAddress().get()))
.filter(tuple -> tuple.first >= minOutputAmount)
.sorted(Comparator.comparing(tuple -> tuple.first))
.sorted(Comparator.<Tuple2<Long, String>, Long>comparing(tuple -> tuple.first)
.thenComparing(tuple -> tuple.second))
.collect(Collectors.toList());
long totalOutputValue = receivers.stream().mapToLong(e -> e.first).sum();
if (totalOutputValue < spendableAmount) {
@ -546,7 +548,7 @@ public class BurningManService implements DaoStateListener {
// If the available is larger than 100000 sat (about 20 USD) we send it to legacy BM
// Otherwise we use it as miner fee
if (available > 100000) {
receivers.add(new Tuple2<>(available, getBurningManAddressFromParam(burningManSelectionHeight)));
receivers.add(new Tuple2<>(available, getLegacyBurningManAddress(burningManSelectionHeight)));
}
}
return receivers;

View File

@ -529,7 +529,7 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
// Dispute agents might receive disputes created before activation date.
// By checking if burningManSelectionHeight is > 0 we can detect if the trade was created with
// the new burningmen receivers or not.
// the new burningmen receivers or with legacy BM.
public boolean isUsingLegacyBurningMan() {
return burningManSelectionHeight == 0;
}

View File

@ -115,6 +115,7 @@ public class DisputeValidation {
}
}
public static void validateSenderNodeAddress(Dispute dispute,
NodeAddress senderNodeAddress) throws NodeAddressException {
if (!senderNodeAddress.equals(dispute.getContract().getBuyerNodeAddress())
@ -309,6 +310,7 @@ public class DisputeValidation {
}
}
public static class AddressException extends ValidationException {
AddressException(Dispute dispute, String msg) {
super(dispute, msg);

View File

@ -71,6 +71,7 @@ public class TradeDataValidation {
throw new InvalidTxException(errorMsg);
}
// connectedOutput is null and input.getValue() is null at that point as the tx is not committed to the wallet
// yet. So we cannot check that the input matches but we did the amount check earlier in the trade protocol.
@ -113,8 +114,8 @@ public class TradeDataValidation {
}
NetworkParameters params = btcWalletService.getParams();
String delayedPayoutTxOutputAddress = output.getScriptPubKey().getToAddress(params).toString();
if (addressConsumer != null) {
String delayedPayoutTxOutputAddress = output.getScriptPubKey().getToAddress(params).toString();
addressConsumer.accept(delayedPayoutTxOutputAddress);
}
}

View File

@ -1067,12 +1067,13 @@ public abstract class Trade extends TradeModel {
return offer != null && offer.isBsqSwapOffer();
}
// By checking if burningManSelectionHeight is > 0 we can detect if the trade was created with
// the new burningmen receivers or not.
// By checking if burningManSelectionHeight is 0 we can detect if the trade was created with
// the new burningmen receivers or with legacy BM.
public boolean isUsingLegacyBurningMan() {
return processModel.getBurningManSelectionHeight() == 0;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -125,6 +125,7 @@ public class BurningmenView extends ActivatableView<ScrollPane, Void> implements
private int gridRow = 0;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@ -473,7 +474,7 @@ public class BurningmenView extends ActivatableView<ScrollPane, Void> implements
TableColumn<BurningmenListItem, BurningmenListItem> column;
column = new AutoTooltipTableColumn<>(Res.get("dao.burningmen.table.name"));
column.setMinWidth(80);
column.setMinWidth(120);
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
column.getStyleClass().add("first-column");
column.setCellFactory(new Callback<>() {

View File

@ -151,9 +151,8 @@ public abstract class DisputeAgentView extends DisputeView implements MultipleHo
}
private String getValidationExceptionMessage(DisputeValidation.ValidationException exception) {
Dispute dispute = exception.getDispute();
if (exception instanceof DisputeValidation.AddressException) {
return getAddressExceptionMessage(dispute);
return getAddressExceptionMessage(exception.getDispute());
} else if (exception.getMessage() != null && !exception.getMessage().isEmpty()) {
return exception.getMessage();
} else {