Handle burning man selection height edge-cases

If trader A's block height is 134 his burning man selection height is
120, and if trader B's block height is 135 his burning man selection
height is 130.

The current burning man selection height verification code doesn't
handle these edge-cases.
This commit is contained in:
Alva Swanson 2025-02-13 22:56:00 +00:00
parent 353ff6d06f
commit 96355d7a3c
No known key found for this signature in database
GPG key ID: 004760E77F753090
4 changed files with 73 additions and 3 deletions

View file

@ -217,7 +217,7 @@ public class DelayedPayoutTxReceiverService implements DaoStateListener {
// Borrowed from DaoStateSnapshotService. We prefer to not reuse to avoid dependency to an unrelated domain.
@VisibleForTesting
static int getSnapshotHeight(int genesisHeight, int height, int grid, int minSnapshotHeight) {
public static int getSnapshotHeight(int genesisHeight, int height, int grid, int minSnapshotHeight) {
if (height > (genesisHeight + 3 * grid)) {
int ratio = (int) Math.round(height / (double) grid);
return Math.max(minSnapshotHeight, ratio * grid - grid);

View file

@ -47,6 +47,7 @@ import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.trade.ClosedTradableManager;
import bisq.core.trade.bisq_v1.TransactionResultHandler;
import bisq.core.trade.model.TradableList;
import bisq.core.trade.protocol.bisq_v1.tasks.maker.MakerProcessesInputsForDepositTxRequest;
import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.core.user.Preferences;
import bisq.core.user.User;
@ -857,7 +858,10 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
checkArgument(takersBurningManSelectionHeight > 0, "takersBurningManSelectionHeight must not be 0");
int makersBurningManSelectionHeight = delayedPayoutTxReceiverService.getBurningManSelectionHeight();
checkArgument(takersBurningManSelectionHeight == makersBurningManSelectionHeight,
boolean areBurningManSelectionHeightsValid = MakerProcessesInputsForDepositTxRequest
.verifyBurningManSelectionHeight(takersBurningManSelectionHeight, makersBurningManSelectionHeight);
checkArgument(areBurningManSelectionHeightsValid,
"takersBurningManSelectionHeight does no match makersBurningManSelectionHeight. " +
"takersBurningManSelectionHeight=" + takersBurningManSelectionHeight + "; makersBurningManSelectionHeight=" + makersBurningManSelectionHeight);
} catch (Throwable t) {

View file

@ -17,6 +17,7 @@
package bisq.core.trade.protocol.bisq_v1.tasks.maker;
import bisq.core.dao.burningman.DelayedPayoutTxReceiverService;
import bisq.core.exceptions.TradePriceOutOfToleranceException;
import bisq.core.offer.Offer;
import bisq.core.support.dispute.mediation.mediator.Mediator;
@ -83,8 +84,12 @@ public class MakerProcessesInputsForDepositTxRequest extends TradeTask {
checkArgument(takersBurningManSelectionHeight > 0, "takersBurningManSelectionHeight must not be 0");
int makersBurningManSelectionHeight = processModel.getDelayedPayoutTxReceiverService().getBurningManSelectionHeight();
checkArgument(takersBurningManSelectionHeight == makersBurningManSelectionHeight,
boolean areBurningManSelectionHeightsValid = verifyBurningManSelectionHeight(
takersBurningManSelectionHeight, makersBurningManSelectionHeight);
checkArgument(areBurningManSelectionHeightsValid,
"takersBurningManSelectionHeight does no match makersBurningManSelectionHeight");
processModel.setBurningManSelectionHeight(makersBurningManSelectionHeight);
// We set the taker fee only in the processModel yet not in the trade as the tx was only created but not
@ -132,4 +137,21 @@ public class MakerProcessesInputsForDepositTxRequest extends TradeTask {
failed(t);
}
}
public static boolean verifyBurningManSelectionHeight(int takersBurningManSelectionHeight,
int makersBurningManSelectionHeight) {
if (takersBurningManSelectionHeight == makersBurningManSelectionHeight) {
return true;
} else if (takersBurningManSelectionHeight < makersBurningManSelectionHeight) {
int takersNextBlockBurningManSelectionHeight =
takersBurningManSelectionHeight + DelayedPayoutTxReceiverService.SNAPSHOT_SELECTION_GRID_SIZE;
return takersNextBlockBurningManSelectionHeight == makersBurningManSelectionHeight;
} else {
int makersNextBlockBurningManSelectionHeight =
makersBurningManSelectionHeight + DelayedPayoutTxReceiverService.SNAPSHOT_SELECTION_GRID_SIZE;
return takersBurningManSelectionHeight == makersNextBlockBurningManSelectionHeight;
}
}
}

View file

@ -0,0 +1,44 @@
package bisq.core.trade.protocol.bisq_v1.tasks.maker;
import bisq.core.dao.burningman.DelayedPayoutTxReceiverService;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class MakerProcessesInputsForDepositTxRequestTest {
private static final int GENESIS_HEIGHT = 102;
private static final int GRID_SIZE = DelayedPayoutTxReceiverService.SNAPSHOT_SELECTION_GRID_SIZE;
@Test
void burningManSelectionHeightSameBlock() {
assertEquals(130,
DelayedPayoutTxReceiverService.getSnapshotHeight(GENESIS_HEIGHT, 139, GRID_SIZE, 0));
boolean isValid = MakerProcessesInputsForDepositTxRequest
.verifyBurningManSelectionHeight(130, 130);
assertTrue(isValid);
}
@Test
void burningManSelectionHeightMakerOneBlockInFuture() {
assertEquals(120,
DelayedPayoutTxReceiverService.getSnapshotHeight(GENESIS_HEIGHT, 134, GRID_SIZE, 0));
assertEquals(130,
DelayedPayoutTxReceiverService.getSnapshotHeight(GENESIS_HEIGHT, 135, GRID_SIZE, 0));
boolean isValid = MakerProcessesInputsForDepositTxRequest
.verifyBurningManSelectionHeight(120, 130);
assertTrue(isValid);
}
@Test
void burningManSelectionHeightTakerOneBlockInFuture() {
assertEquals(120,
DelayedPayoutTxReceiverService.getSnapshotHeight(GENESIS_HEIGHT, 134, GRID_SIZE, 0));
assertEquals(130,
DelayedPayoutTxReceiverService.getSnapshotHeight(GENESIS_HEIGHT, 135, GRID_SIZE, 0));
boolean isValid = MakerProcessesInputsForDepositTxRequest
.verifyBurningManSelectionHeight(130, 120);
assertTrue(isValid);
}
}