Skip to content

Commit

Permalink
Handle burning man selection height edge-cases
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
alvasw committed Feb 13, 2025
1 parent 353ff6d commit 96355d7
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ private static int getSnapshotHeight(int genesisHeight, int height, int grid) {

// 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);
Expand Down
6 changes: 5 additions & 1 deletion core/src/main/java/bisq/core/offer/OpenOfferManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
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;
Expand Down Expand Up @@ -857,7 +858,10 @@ private void handleOfferAvailabilityRequest(OfferAvailabilityRequest request, No
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -83,8 +84,12 @@ protected void run() {
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
Expand Down Expand Up @@ -132,4 +137,21 @@ protected void run() {
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;
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}

0 comments on commit 96355d7

Please sign in to comment.