mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 18:03:12 +01:00
Merge branch 'master' into Development
# Conflicts: # provider/src/main/java/io/bisq/provider/price/providers/PoloniexProvider.java
This commit is contained in:
commit
e3488184a5
@ -19,8 +19,7 @@ package io.bisq.core.offer.placeoffer;
|
||||
|
||||
import io.bisq.common.handlers.ErrorMessageHandler;
|
||||
import io.bisq.common.taskrunner.TaskRunner;
|
||||
import io.bisq.core.offer.placeoffer.tasks.AddOfferToRemoteOfferBook;
|
||||
import io.bisq.core.offer.placeoffer.tasks.BroadcastMakerFeeTx;
|
||||
import io.bisq.core.offer.placeoffer.tasks.AddOfferOfferBook;
|
||||
import io.bisq.core.offer.placeoffer.tasks.CreateMakerFeeTx;
|
||||
import io.bisq.core.offer.placeoffer.tasks.ValidateOffer;
|
||||
import io.bisq.core.trade.handlers.TransactionResultHandler;
|
||||
@ -76,8 +75,7 @@ public class PlaceOfferProtocol {
|
||||
taskRunner.addTasks(
|
||||
ValidateOffer.class,
|
||||
CreateMakerFeeTx.class,
|
||||
AddOfferToRemoteOfferBook.class,
|
||||
BroadcastMakerFeeTx.class
|
||||
AddOfferOfferBook.class
|
||||
);
|
||||
|
||||
taskRunner.run();
|
||||
|
@ -23,12 +23,12 @@ import io.bisq.core.offer.placeoffer.PlaceOfferModel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AddOfferToRemoteOfferBook extends Task<PlaceOfferModel> {
|
||||
public class AddOfferOfferBook extends Task<PlaceOfferModel> {
|
||||
@SuppressWarnings("unused")
|
||||
private static final Logger log = LoggerFactory.getLogger(AddOfferToRemoteOfferBook.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(AddOfferOfferBook.class);
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public AddOfferToRemoteOfferBook(TaskRunner taskHandler, PlaceOfferModel model) {
|
||||
public AddOfferOfferBook(TaskRunner taskHandler, PlaceOfferModel model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bisq.core.offer.placeoffer.tasks;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import io.bisq.common.Timer;
|
||||
import io.bisq.common.UserThread;
|
||||
import io.bisq.common.taskrunner.Task;
|
||||
import io.bisq.common.taskrunner.TaskRunner;
|
||||
import io.bisq.core.offer.Offer;
|
||||
import io.bisq.core.offer.placeoffer.PlaceOfferModel;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class BroadcastMakerFeeTx extends Task<PlaceOfferModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(BroadcastMakerFeeTx.class);
|
||||
|
||||
private boolean removeOfferFailed;
|
||||
private boolean addOfferFailed;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public BroadcastMakerFeeTx(TaskRunner taskHandler, PlaceOfferModel model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
final Transaction transaction = model.getTransaction();
|
||||
|
||||
// TODO Try to republish tx?
|
||||
Timer timeoutTimer = UserThread.runAfter(() -> {
|
||||
log.warn("Broadcast not completed after 5 sec. We go on with the trade protocol.");
|
||||
model.getOffer().setState(Offer.State.OFFER_FEE_PAID);
|
||||
complete();
|
||||
}, 20);
|
||||
|
||||
model.getTradeWalletService().broadcastTx(model.getTransaction(),
|
||||
new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
public void onSuccess(Transaction tx) {
|
||||
timeoutTimer.stop();
|
||||
if (!completed) {
|
||||
log.debug("Broadcast of offer fee payment succeeded: transaction = " + tx.toString());
|
||||
|
||||
if (transaction.getHashAsString().equals(tx.getHashAsString())) {
|
||||
model.getOffer().setState(Offer.State.OFFER_FEE_PAID);
|
||||
// No tx malleability happened after broadcast (still not in blockchain)
|
||||
complete();
|
||||
} else {
|
||||
log.warn("Tx malleability happened after broadcast. We publish the changed offer to the P2P network again.");
|
||||
// Tx malleability happened after broadcast. We first remove the malleable offer.
|
||||
// Then we publish the changed offer to the P2P network again after setting the new TxId.
|
||||
// Normally we use a delay for broadcasting to the peers, but at shut down we want to get it fast out
|
||||
model.getOfferBookService().removeOffer(model.getOffer().getOfferPayload(),
|
||||
() -> {
|
||||
log.debug("We store now the changed txID to the offer and add that again.");
|
||||
// We store now the changed txID to the offer and add that again.
|
||||
model.getOffer().setOfferFeePaymentTxId(tx.getHashAsString());
|
||||
model.setTransaction(tx);
|
||||
model.getOfferBookService().addOffer(model.getOffer(),
|
||||
BroadcastMakerFeeTx.this::complete,
|
||||
errorMessage -> {
|
||||
log.error("addOffer failed");
|
||||
addOfferFailed = true;
|
||||
updateStateOnFault();
|
||||
model.getOffer().setErrorMessage("An error occurred when adding the offer to the P2P network.\n" +
|
||||
"Error message:\n"
|
||||
+ errorMessage);
|
||||
failed(errorMessage);
|
||||
});
|
||||
},
|
||||
errorMessage -> {
|
||||
log.error("removeOffer failed");
|
||||
removeOfferFailed = true;
|
||||
updateStateOnFault();
|
||||
model.getOffer().setErrorMessage("An error occurred when removing the offer from the P2P network.\n" +
|
||||
"Error message:\n"
|
||||
+ errorMessage);
|
||||
failed(errorMessage);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
log.warn("We got the onSuccess callback called after the timeout has been triggered a complete().");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
if (!completed) {
|
||||
timeoutTimer.stop();
|
||||
updateStateOnFault();
|
||||
model.getOffer().setErrorMessage("An error occurred.\n" +
|
||||
"Error message:\n"
|
||||
+ t.getMessage());
|
||||
failed(t);
|
||||
} else {
|
||||
log.warn("We got the onFailure callback called after the timeout has been triggered a complete().");
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
model.getOffer().setErrorMessage("An error occurred.\n" +
|
||||
"Error message:\n"
|
||||
+ t.getMessage());
|
||||
failed(t);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStateOnFault() {
|
||||
if (!removeOfferFailed && !addOfferFailed) {
|
||||
// If broadcast fails we need to remove offer from offerbook
|
||||
model.getOfferBookService().removeOffer(model.getOffer().getOfferPayload(),
|
||||
() -> log.debug("OfferPayload removed from offerbook because broadcast failed."),
|
||||
errorMessage -> log.error("removeOffer failed. " + errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class CreateMakerFeeTx extends Task<PlaceOfferModel> {
|
||||
@ -92,12 +91,12 @@ public class CreateMakerFeeTx extends Task<PlaceOfferModel> {
|
||||
// returned (tradeFeeTx would be null in that case)
|
||||
UserThread.execute(() -> {
|
||||
if (!completed) {
|
||||
if (tradeFeeTx != null && !tradeFeeTx.getHashAsString().equals(transaction.getHashAsString()))
|
||||
log.warn("The trade fee tx received from the network had another tx ID than the one we publish");
|
||||
|
||||
offer.setOfferFeePaymentTxId(transaction.getHashAsString());
|
||||
model.setTransaction(transaction);
|
||||
walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING);
|
||||
|
||||
model.getOffer().setState(Offer.State.OFFER_FEE_PAID);
|
||||
|
||||
complete();
|
||||
} else {
|
||||
log.warn("We got the onSuccess callback called after the timeout has been triggered a complete().");
|
||||
@ -138,14 +137,15 @@ public class CreateMakerFeeTx extends Task<PlaceOfferModel> {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Transaction transaction) {
|
||||
if (transaction != null) {
|
||||
checkArgument(transaction.equals(signedTx));
|
||||
offer.setOfferFeePaymentTxId(transaction.getHashAsString());
|
||||
model.setTransaction(transaction);
|
||||
log.debug("onSuccess, offerId={}, OFFER_FUNDING", id);
|
||||
walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING);
|
||||
|
||||
complete();
|
||||
log.debug("Successfully sent tx with id " + transaction.getHashAsString());
|
||||
model.getOffer().setState(Offer.State.OFFER_FEE_PAID);
|
||||
|
||||
complete();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,6 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
|
||||
TakerVerifyMakerAccount.class,
|
||||
TakerVerifyMakerFeePayment.class,
|
||||
CreateTakerFeeTx.class,
|
||||
TakerPublishTakerFeeTx.class,
|
||||
BuyerAsTakerCreatesDepositTxInputs.class,
|
||||
TakerSendPayDepositRequest.class
|
||||
);
|
||||
|
@ -91,7 +91,6 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
|
||||
TakerSelectArbitrator.class,
|
||||
TakerSelectMediator.class,
|
||||
CreateTakerFeeTx.class,
|
||||
TakerPublishTakerFeeTx.class,
|
||||
SellerAsTakerCreatesDepositTxInputs.class,
|
||||
TakerSendPayDepositRequest.class
|
||||
);
|
||||
|
@ -38,7 +38,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@Slf4j
|
||||
@ -91,12 +90,10 @@ public class CreateTakerFeeTx extends TradeTask {
|
||||
// returned (tradeFeeTx would be null in that case)
|
||||
UserThread.execute(() -> {
|
||||
if (!completed) {
|
||||
if (tradeFeeTx != null && !tradeFeeTx.getHashAsString().equals(transaction.getHashAsString()))
|
||||
log.warn("The trade fee tx received from the network had another tx ID than the one we publish");
|
||||
|
||||
processModel.setTakeOfferFeeTx(tradeFeeTx);
|
||||
trade.setTakerFeeTxId(tradeFeeTx.getHashAsString());
|
||||
walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING);
|
||||
trade.setState(Trade.State.TAKER_PUBLISHED_TAKER_FEE_TX);
|
||||
|
||||
complete();
|
||||
} else {
|
||||
@ -140,10 +137,10 @@ public class CreateTakerFeeTx extends TradeTask {
|
||||
if (!completed) {
|
||||
if (transaction != null) {
|
||||
log.debug("Successfully sent tx with id " + transaction.getHashAsString());
|
||||
checkArgument(transaction.equals(signedTx));
|
||||
trade.setTakerFeeTxId(transaction.getHashAsString());
|
||||
processModel.setTakeOfferFeeTx(transaction);
|
||||
walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING);
|
||||
trade.setState(Trade.State.TAKER_PUBLISHED_TAKER_FEE_TX);
|
||||
|
||||
complete();
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bisq.core.trade.protocol.tasks.taker;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import io.bisq.common.Timer;
|
||||
import io.bisq.common.UserThread;
|
||||
import io.bisq.common.taskrunner.TaskRunner;
|
||||
import io.bisq.core.trade.Trade;
|
||||
import io.bisq.core.trade.protocol.tasks.TradeTask;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@Slf4j
|
||||
public class TakerPublishTakerFeeTx extends TradeTask {
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public TakerPublishTakerFeeTx(TaskRunner taskHandler, Trade trade) {
|
||||
super(taskHandler, trade);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
try {
|
||||
runInterceptHook();
|
||||
|
||||
Timer timeoutTimer = UserThread.runAfter(() -> {
|
||||
log.warn("Broadcast not completed after 5 sec. We go on with the trade protocol.");
|
||||
trade.setState(Trade.State.TAKER_PUBLISHED_TAKER_FEE_TX);
|
||||
complete();
|
||||
}, 5);
|
||||
|
||||
processModel.getTradeWalletService().broadcastTx(processModel.resolveTakeOfferFeeTx(trade),
|
||||
new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
public void onSuccess(Transaction transaction) {
|
||||
if (!completed) {
|
||||
timeoutTimer.stop();
|
||||
log.debug("Trading fee published successfully. Transaction ID = " + transaction.getHashAsString());
|
||||
trade.setState(Trade.State.TAKER_PUBLISHED_TAKER_FEE_TX);
|
||||
complete();
|
||||
} else {
|
||||
log.warn("We got the onSuccess callback called after the timeout has been triggered a complete().");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
if (!completed) {
|
||||
timeoutTimer.stop();
|
||||
appendToErrorMessage("Trading fee payment failed. Maybe your network connection was lost. Please try again.");
|
||||
failed(t);
|
||||
} else {
|
||||
log.warn("We got the onFailure callback called after the timeout has been triggered a complete().");
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
failed(t);
|
||||
}
|
||||
}
|
||||
}
|
@ -223,7 +223,7 @@ bg color of non edit textFields: fafafa
|
||||
}
|
||||
|
||||
|
||||
.dao-tx-type-unverified-icon,
|
||||
.dao-tx-type-unverified-icon,
|
||||
.dao-tx-type-unverified-icon:hover {
|
||||
-fx-text-fill: -bs-yellow;
|
||||
-fx-cursor: hand;
|
||||
@ -1155,4 +1155,4 @@ textfield */
|
||||
-fx-border-insets: 0 0 0 -2;
|
||||
-fx-background-insets: 0 0 0 -2;
|
||||
-fx-background-radius: 0 4 4 0;
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
|
||||
import io.bisq.gui.components.indicator.TxConfidenceIndicator;
|
||||
import io.bisq.gui.components.indicator.behavior.StaticProgressIndicatorBehavior;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
|
@ -20,8 +20,7 @@ package io.bisq.gui.main.debug;
|
||||
import io.bisq.common.taskrunner.Task;
|
||||
import io.bisq.core.offer.availability.tasks.ProcessOfferAvailabilityResponse;
|
||||
import io.bisq.core.offer.availability.tasks.SendOfferAvailabilityRequest;
|
||||
import io.bisq.core.offer.placeoffer.tasks.AddOfferToRemoteOfferBook;
|
||||
import io.bisq.core.offer.placeoffer.tasks.BroadcastMakerFeeTx;
|
||||
import io.bisq.core.offer.placeoffer.tasks.AddOfferOfferBook;
|
||||
import io.bisq.core.offer.placeoffer.tasks.CreateMakerFeeTx;
|
||||
import io.bisq.core.offer.placeoffer.tasks.ValidateOffer;
|
||||
import io.bisq.core.trade.protocol.tasks.CheckIfPeerIsBanned;
|
||||
@ -79,8 +78,7 @@ public class DebugView extends InitializableView<GridPane, Void> {
|
||||
FXCollections.observableArrayList(Arrays.asList(
|
||||
ValidateOffer.class,
|
||||
CreateMakerFeeTx.class,
|
||||
AddOfferToRemoteOfferBook.class,
|
||||
BroadcastMakerFeeTx.class)
|
||||
AddOfferOfferBook.class)
|
||||
));
|
||||
|
||||
addGroup("BuyerAsMakerProtocol: ",
|
||||
@ -115,7 +113,6 @@ public class DebugView extends InitializableView<GridPane, Void> {
|
||||
TakerSelectArbitrator.class,
|
||||
TakerSelectMediator.class,
|
||||
CreateTakerFeeTx.class,
|
||||
TakerPublishTakerFeeTx.class,
|
||||
SellerAsTakerCreatesDepositTxInputs.class,
|
||||
TakerSendPayDepositRequest.class,
|
||||
|
||||
@ -145,7 +142,6 @@ public class DebugView extends InitializableView<GridPane, Void> {
|
||||
TakerVerifyMakerAccount.class,
|
||||
TakerVerifyMakerFeePayment.class,
|
||||
CreateTakerFeeTx.class,
|
||||
TakerPublishTakerFeeTx.class,
|
||||
BuyerAsTakerCreatesDepositTxInputs.class,
|
||||
TakerSendPayDepositRequest.class,
|
||||
|
||||
|
@ -19,7 +19,6 @@ package io.bisq.provider.price;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
@Value
|
||||
public class PriceData {
|
||||
private final String currencyCode;
|
||||
|
@ -54,7 +54,8 @@ public class PoloniexProvider {
|
||||
marketPriceMap.put(altcoinCurrency,
|
||||
new PriceData(altcoinCurrency,
|
||||
parseDouble((String) data.get("last")),
|
||||
ts, PriceRequestService.POLO_PROVIDER)
|
||||
ts,
|
||||
PriceRequestService.POLO_PROVIDER)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user