Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API method 'getavgbsqprice' #6250

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 101 additions & 10 deletions apitest/src/test/java/bisq/apitest/method/trade/AbstractTradeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import bisq.proto.grpc.TradeInfo;

import io.grpc.StatusRuntimeException;

import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
Expand Down Expand Up @@ -32,6 +34,7 @@
import bisq.cli.GrpcClient;
import bisq.cli.table.builder.TableBuilder;

@SuppressWarnings({"ConstantConditions", "unused"})
public class AbstractTradeTest extends AbstractOfferTest {

public static final ExpectedProtocolStatus EXPECTED_PROTOCOL_STATUS = new ExpectedProtocolStatus();
Expand All @@ -40,10 +43,16 @@ public class AbstractTradeTest extends AbstractOfferTest {
@Getter
protected static String tradeId;

protected final Supplier<Integer> maxTradeStateAndPhaseChecks = () -> isLongRunningTest ? 10 : 2;
protected final Supplier<Integer> maxTradeStateAndPhaseChecks = () ->
isLongRunningTest
? 10
: 2;
protected final Function<TradeInfo, String> toTradeDetailTable = (trade) ->
new TableBuilder(TRADE_DETAIL_TBL, trade).build().toString();
protected final Function<GrpcClient, String> toUserName = (client) -> client.equals(aliceClient) ? "Alice" : "Bob";
protected final Function<GrpcClient, String> toUserName = (client) ->
client.equals(aliceClient)
? "Alice"
: "Bob";

@BeforeAll
public static void initStaticFixtures() {
Expand Down Expand Up @@ -84,17 +93,17 @@ protected final TradeInfo takeAlicesOffer(String offerId,
return trade;
}

protected final void waitForDepositConfirmation(Logger log,
TestInfo testInfo,
GrpcClient grpcClient,
String tradeId) {
protected final void waitForTakerDepositConfirmation(Logger log,
TestInfo testInfo,
GrpcClient takerClient,
String tradeId) {
Predicate<TradeInfo> isTradeInDepositConfirmedStateAndPhase = (t) ->
t.getState().equals(DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN.name())
&& t.getPhase().equals(DEPOSIT_CONFIRMED.name());

String userName = toUserName.apply(grpcClient);
String userName = toUserName.apply(takerClient);
for (int i = 1; i <= maxTradeStateAndPhaseChecks.get(); i++) {
TradeInfo trade = grpcClient.getTrade(tradeId);
TradeInfo trade = takerClient.getTrade(tradeId);
if (!isTradeInDepositConfirmedStateAndPhase.test(trade)) {
log.warn("{} still waiting on trade {} tx {}: DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN, attempt # {}",
userName,
Expand All @@ -117,6 +126,15 @@ protected final void waitForDepositConfirmation(Logger log,
}
}

protected final void verifyTakerDepositNotConfirmed(TradeInfo trade) {
if (trade.getIsDepositConfirmed()) {
fail(format("INVALID_PHASE for trade %s in STATE=%s PHASE=%s, deposit tx should NOT be confirmed yet.",
trade.getShortId(),
trade.getState(),
trade.getPhase()));
}
}

protected final void verifyTakerDepositConfirmed(TradeInfo trade) {
if (!trade.getIsDepositConfirmed()) {
fail(format("INVALID_PHASE for trade %s in STATE=%s PHASE=%s, deposit tx never confirmed.",
Expand All @@ -126,7 +144,80 @@ protected final void verifyTakerDepositConfirmed(TradeInfo trade) {
}
}

protected final void waitForBuyerSeesPaymentInitiatedMessage(Logger log,
protected final void verifyPaymentSentMsgIsFromBtcBuyerPrecondition(Logger log, GrpcClient sellerClient) {
String userName = toUserName.apply(sellerClient);
log.debug("BTC seller {} incorrectly sends a confirmpaymentstarted message, for trade {}", userName, tradeId);
Throwable exception = assertThrows(StatusRuntimeException.class, () -> sellerClient.confirmPaymentStarted(tradeId));
String expectedExceptionMessage = "FAILED_PRECONDITION: you are the seller, and not sending payment";
assertEquals(expectedExceptionMessage, exception.getMessage());
}

protected final void verifyPaymentReceivedMsgIsFromBtcSellerPrecondition(Logger log, GrpcClient buyerClient) {
String userName = toUserName.apply(buyerClient);
log.debug("BTC buyer {} incorrectly sends a confirmpaymentreceived message, for trade {}", userName, tradeId);
Throwable exception = assertThrows(StatusRuntimeException.class, () -> buyerClient.confirmPaymentReceived(tradeId));
String expectedExceptionMessage = "FAILED_PRECONDITION: you are the buyer, and not receiving payment";
assertEquals(expectedExceptionMessage, exception.getMessage());
}

protected final void verifyPaymentSentMsgDepositTxConfirmedPrecondition(Logger log, GrpcClient buyerClient) {
var trade = buyerClient.getTrade(tradeId);
verifyTakerDepositNotConfirmed(trade);

String userName = toUserName.apply(buyerClient);
log.debug("BTC buyer {} sends a confirmpaymentstarted message before deposit tx is confirmed, for trade {}",
userName,
tradeId);
Throwable exception = assertThrows(StatusRuntimeException.class, () -> buyerClient.confirmPaymentStarted(tradeId));
String expectedExceptionMessage =
format("FAILED_PRECONDITION: cannot send a payment started message for trade '%s'", tradeId);
String failureReason = format("Expected exception message to start with '%s'%n, but got '%s'",
expectedExceptionMessage,
exception.getMessage());
assertTrue(exception.getMessage().startsWith(expectedExceptionMessage), failureReason);
expectedExceptionMessage = format("until trade deposit tx '%s' is confirmed", trade.getDepositTxId());
assertTrue(exception.getMessage().contains(expectedExceptionMessage));
}

protected final void verifyPaymentReceivedMsgDepositTxConfirmedPrecondition(Logger log, GrpcClient sellerClient) {
var trade = sellerClient.getTrade(tradeId);
verifyTakerDepositNotConfirmed(trade);

String userName = toUserName.apply(sellerClient);
log.debug("BTC seller {} sends a confirmpaymentreceived message before deposit tx is confirmed, for trade {}",
userName,
tradeId);
Throwable exception = assertThrows(StatusRuntimeException.class, () -> sellerClient.confirmPaymentReceived(tradeId));
String expectedExceptionMessage =
format("FAILED_PRECONDITION: cannot send a payment received message for trade '%s'", tradeId);
String failureReason = format("Expected exception message to start with '%s'%n, but got '%s'",
expectedExceptionMessage,
exception.getMessage());
assertTrue(exception.getMessage().startsWith(expectedExceptionMessage), failureReason);
expectedExceptionMessage = format("until trade deposit tx '%s' is confirmed", trade.getDepositTxId());
assertTrue(exception.getMessage().contains(expectedExceptionMessage));
}

protected final void verifyPaymentReceivedMsgAfterPaymentSentMsgPrecondition(Logger log, GrpcClient sellerClient) {
var trade = sellerClient.getTrade(tradeId);
verifyTakerDepositConfirmed(trade);

String userName = toUserName.apply(sellerClient);
log.debug("BTC seller {} sends a confirmpaymentreceived message before a payment started message has been sent, for trade {}",
userName,
tradeId);
Throwable exception = assertThrows(StatusRuntimeException.class, () -> sellerClient.confirmPaymentReceived(tradeId));
String expectedExceptionMessage =
format("FAILED_PRECONDITION: cannot send a payment received confirmation message for trade '%s'", tradeId);
String failureReason = format("Expected exception message to start with '%s'%n, but got '%s'",
expectedExceptionMessage,
exception.getMessage());
assertTrue(exception.getMessage().startsWith(expectedExceptionMessage), failureReason);
expectedExceptionMessage = "until after a trade payment started message has been sent";
assertTrue(exception.getMessage().contains(expectedExceptionMessage));
}

protected final void waitUntilBuyerSeesPaymentStartedMessage(Logger log,
TestInfo testInfo,
GrpcClient grpcClient,
String tradeId) {
Expand All @@ -153,7 +244,7 @@ protected final void waitForBuyerSeesPaymentInitiatedMessage(Logger log,
}
}

protected final void waitForSellerSeesPaymentInitiatedMessage(Logger log,
protected final void waitUntilSellerSeesPaymentStartedMessage(Logger log,
TestInfo testInfo,
GrpcClient grpcClient,
String tradeId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

// https://github.com/ghubstan/bisq/blob/master/cli/src/main/java/bisq/cli/TradeFormat.java

@Deprecated // Bisq v1 protocol BSQ trades have been replaced by BSQ Swaps.
@Disabled
@Slf4j
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
Expand Down Expand Up @@ -100,7 +101,7 @@ public void testTakeAlicesSellBTCForBSQOffer(final TestInfo testInfo) {
alicesBsqOffers = aliceClient.getMyOffersSortedByDate(BSQ);
assertEquals(0, alicesBsqOffers.size());

waitForDepositConfirmation(log, testInfo, bobClient, trade.getTradeId());
waitForTakerDepositConfirmation(log, testInfo, bobClient, trade.getTradeId());
genBtcBlocksThenWait(1, 2_500);

trade = bobClient.getTrade(tradeId);
Expand All @@ -122,7 +123,7 @@ public void testBobsConfirmPaymentStarted(final TestInfo testInfo) {
genBtcBlocksThenWait(1, 2_500);
bobClient.confirmPaymentStarted(trade.getTradeId());
sleep(6000);
waitForBuyerSeesPaymentInitiatedMessage(log, testInfo, bobClient, tradeId);
waitUntilBuyerSeesPaymentStartedMessage(log, testInfo, bobClient, tradeId);
logTrade(log, testInfo, "Alice's Maker/Buyer View (Payment Sent)", aliceClient.getTrade(tradeId));
logTrade(log, testInfo, "Bob's Taker/Seller View (Payment Sent)", bobClient.getTrade(tradeId));
} catch (StatusRuntimeException e) {
Expand All @@ -134,7 +135,7 @@ public void testBobsConfirmPaymentStarted(final TestInfo testInfo) {
@Order(3)
public void testAlicesConfirmPaymentReceived(final TestInfo testInfo) {
try {
waitForSellerSeesPaymentInitiatedMessage(log, testInfo, aliceClient, tradeId);
waitUntilSellerSeesPaymentStartedMessage(log, testInfo, aliceClient, tradeId);
sleep(2_000);
var trade = aliceClient.getTrade(tradeId);
verifyBsqPaymentHasBeenReceived(log, aliceClient, trade);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import static protobuf.OpenOffer.State.AVAILABLE;

@Disabled
@SuppressWarnings("ConstantConditions")
@Slf4j
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TakeBuyBTCOfferTest extends AbstractTradeTest {
Expand Down Expand Up @@ -82,11 +83,9 @@ public void testTakeAlicesBuyOffer(final TestInfo testInfo) {
sleep(2_500); // Allow available offer to be removed from offer book.
alicesUsdOffers = aliceClient.getMyOffersSortedByDate(BUY.name(), USD);
assertEquals(0, alicesUsdOffers.size());
genBtcBlocksThenWait(1, 2_500);
waitForDepositConfirmation(log, testInfo, bobClient, trade.getTradeId());

trade = bobClient.getTrade(tradeId);
verifyTakerDepositConfirmed(trade);
verifyTakerDepositNotConfirmed(trade);
logTrade(log, testInfo, "Alice's Maker/Buyer View", aliceClient.getTrade(tradeId));
logTrade(log, testInfo, "Bob's Taker/Seller View", bobClient.getTrade(tradeId));
} catch (StatusRuntimeException e) {
Expand All @@ -96,23 +95,47 @@ public void testTakeAlicesBuyOffer(final TestInfo testInfo) {

@Test
@Order(2)
public void testPaymentMessagingPreconditions(final TestInfo testInfo) {
try {
// Alice is maker / btc buyer, Bob is taker / btc seller.
// Verify payment sent and rcvd msgs are sent by the right peers: buyer and seller.
verifyPaymentSentMsgIsFromBtcBuyerPrecondition(log, bobClient);
verifyPaymentReceivedMsgIsFromBtcSellerPrecondition(log, aliceClient);

// Verify fiat payment sent and rcvd msgs cannot be sent before trade deposit tx is confirmed.
verifyPaymentSentMsgDepositTxConfirmedPrecondition(log, aliceClient);
verifyPaymentReceivedMsgDepositTxConfirmedPrecondition(log, bobClient);

// Now generate the BTC block to confirm the taker deposit tx.
genBtcBlocksThenWait(1, 2_500);
waitForTakerDepositConfirmation(log, testInfo, bobClient, tradeId);

// Verify the seller can only send a payment rcvd msg after the payment started msg.
verifyPaymentReceivedMsgAfterPaymentSentMsgPrecondition(log, bobClient);
} catch (StatusRuntimeException e) {
fail(e);
}
}

@Test
@Order(3)
public void testAlicesConfirmPaymentStarted(final TestInfo testInfo) {
try {
var trade = aliceClient.getTrade(tradeId);
waitForDepositConfirmation(log, testInfo, aliceClient, trade.getTradeId());
waitForTakerDepositConfirmation(log, testInfo, aliceClient, trade.getTradeId());
aliceClient.confirmPaymentStarted(trade.getTradeId());
sleep(6_000);
waitForBuyerSeesPaymentInitiatedMessage(log, testInfo, aliceClient, tradeId);
waitUntilBuyerSeesPaymentStartedMessage(log, testInfo, aliceClient, tradeId);
} catch (StatusRuntimeException e) {
fail(e);
}
}

@Test
@Order(3)
@Order(4)
public void testBobsConfirmPaymentReceived(final TestInfo testInfo) {
try {
waitForSellerSeesPaymentInitiatedMessage(log, testInfo, bobClient, tradeId);
waitUntilSellerSeesPaymentStartedMessage(log, testInfo, bobClient, tradeId);
var trade = bobClient.getTrade(tradeId);
bobClient.confirmPaymentReceived(trade.getTradeId());
sleep(3_000);
Expand All @@ -131,7 +154,7 @@ public void testBobsConfirmPaymentReceived(final TestInfo testInfo) {
}

@Test
@Order(4)
@Order(5)
public void testCloseTrade(final TestInfo testInfo) {
try {
genBtcBlocksThenWait(1, 1_000);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void testTakeAlicesBuyOffer(final TestInfo testInfo) {
alicesOffers = aliceClient.getMyOffersSortedByDate(BUY.name(), BRL);
assertEquals(0, alicesOffers.size());
genBtcBlocksThenWait(1, 2_500);
waitForDepositConfirmation(log, testInfo, bobClient, trade.getTradeId());
waitForTakerDepositConfirmation(log, testInfo, bobClient, trade.getTradeId());

trade = bobClient.getTrade(tradeId);
verifyTakerDepositConfirmed(trade);
Expand Down Expand Up @@ -182,10 +182,10 @@ public void testBankAcctDetailsIncludedInContracts(final TestInfo testInfo) {
public void testAlicesConfirmPaymentStarted(final TestInfo testInfo) {
try {
var trade = aliceClient.getTrade(tradeId);
waitForDepositConfirmation(log, testInfo, aliceClient, trade.getTradeId());
waitForTakerDepositConfirmation(log, testInfo, aliceClient, trade.getTradeId());
aliceClient.confirmPaymentStarted(trade.getTradeId());
sleep(6_000);
waitForBuyerSeesPaymentInitiatedMessage(log, testInfo, aliceClient, tradeId);
waitUntilBuyerSeesPaymentStartedMessage(log, testInfo, aliceClient, tradeId);
trade = aliceClient.getTrade(tradeId);
assertEquals(OFFER_FEE_PAID.name(), trade.getOffer().getState());
logTrade(log, testInfo, "Alice's Maker/Buyer View (Payment Sent)", aliceClient.getTrade(tradeId));
Expand All @@ -199,7 +199,7 @@ public void testAlicesConfirmPaymentStarted(final TestInfo testInfo) {
@Order(4)
public void testBobsConfirmPaymentReceived(final TestInfo testInfo) {
try {
waitForSellerSeesPaymentInitiatedMessage(log, testInfo, bobClient, tradeId);
waitUntilSellerSeesPaymentStartedMessage(log, testInfo, bobClient, tradeId);
var trade = bobClient.getTrade(tradeId);
bobClient.confirmPaymentReceived(trade.getTradeId());
sleep(3_000);
Expand Down
Loading