Refactor dependency structure to enable adding dispute managers

If we would add DisputeManager to previous structure it would cause a
circular dependency error from guice. We change dependency structure so
that TradeManager does not know XmrTxProofService but XmrTxProofService
gets an instance of TradeManager. It makes code cleaner in total as well
as responsibility is better defined.

Next commit will contain the DisputeManager addition.
This commit is contained in:
chimp1984 2020-09-03 14:36:28 -05:00 committed by Christoph Atteneder
parent 688bef885a
commit 2da08a5620
No known key found for this signature in database
GPG key ID: CD5DC1C529CDFD3B
7 changed files with 83 additions and 98 deletions

View file

@ -26,6 +26,7 @@ import bisq.core.setup.CorePersistedDataHost;
import bisq.core.setup.CoreSetup; import bisq.core.setup.CoreSetup;
import bisq.core.support.dispute.arbitration.arbitrator.ArbitratorManager; import bisq.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.trade.txproof.xmr.XmrTxProofService;
import bisq.network.p2p.P2PService; import bisq.network.p2p.P2PService;
@ -221,6 +222,7 @@ public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSet
try { try {
injector.getInstance(ArbitratorManager.class).shutDown(); injector.getInstance(ArbitratorManager.class).shutDown();
injector.getInstance(TradeManager.class).shutDown(); injector.getInstance(TradeManager.class).shutDown();
injector.getInstance(XmrTxProofService.class).shutDown();
injector.getInstance(DaoSetup.class).shutDown(); injector.getInstance(DaoSetup.class).shutDown();
injector.getInstance(AvoidStandbyModeService.class).shutDown(); injector.getInstance(AvoidStandbyModeService.class).shutDown();
injector.getInstance(OpenOfferManager.class).shutDown(() -> { injector.getInstance(OpenOfferManager.class).shutDown(() -> {

View file

@ -59,6 +59,7 @@ import bisq.core.support.traderchat.TraderChatManager;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.trade.TradeTxException; import bisq.core.trade.TradeTxException;
import bisq.core.trade.statistics.TradeStatisticsManager; import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.core.trade.txproof.xmr.XmrTxProofService;
import bisq.core.user.Preferences; import bisq.core.user.Preferences;
import bisq.core.user.User; import bisq.core.user.User;
import bisq.core.util.FormattingUtils; import bisq.core.util.FormattingUtils;
@ -167,6 +168,7 @@ public class BisqSetup {
private final PrivateNotificationManager privateNotificationManager; private final PrivateNotificationManager privateNotificationManager;
private final FilterManager filterManager; private final FilterManager filterManager;
private final TradeStatisticsManager tradeStatisticsManager; private final TradeStatisticsManager tradeStatisticsManager;
private final XmrTxProofService xmrTxProofService;
private final ClockWatcher clockWatcher; private final ClockWatcher clockWatcher;
private final FeeService feeService; private final FeeService feeService;
private final DaoSetup daoSetup; private final DaoSetup daoSetup;
@ -263,6 +265,7 @@ public class BisqSetup {
PrivateNotificationManager privateNotificationManager, PrivateNotificationManager privateNotificationManager,
FilterManager filterManager, FilterManager filterManager,
TradeStatisticsManager tradeStatisticsManager, TradeStatisticsManager tradeStatisticsManager,
XmrTxProofService xmrTxProofService,
ClockWatcher clockWatcher, ClockWatcher clockWatcher,
FeeService feeService, FeeService feeService,
DaoSetup daoSetup, DaoSetup daoSetup,
@ -308,6 +311,7 @@ public class BisqSetup {
this.privateNotificationManager = privateNotificationManager; this.privateNotificationManager = privateNotificationManager;
this.filterManager = filterManager; this.filterManager = filterManager;
this.tradeStatisticsManager = tradeStatisticsManager; this.tradeStatisticsManager = tradeStatisticsManager;
this.xmrTxProofService = xmrTxProofService;
this.clockWatcher = clockWatcher; this.clockWatcher = clockWatcher;
this.feeService = feeService; this.feeService = feeService;
this.daoSetup = daoSetup; this.daoSetup = daoSetup;
@ -686,6 +690,7 @@ public class BisqSetup {
traderChatManager.onAllServicesInitialized(); traderChatManager.onAllServicesInitialized();
tradeManager.onAllServicesInitialized(); tradeManager.onAllServicesInitialized();
xmrTxProofService.onAllServicesInitialized();
if (walletsSetup.downloadPercentageProperty().get() == 1) { if (walletsSetup.downloadPercentageProperty().get() == 1) {
checkForLockedUpFunds(); checkForLockedUpFunds();

View file

@ -46,8 +46,6 @@ import bisq.core.trade.messages.PeerPublishedDelayedPayoutTxMessage;
import bisq.core.trade.messages.TradeMessage; import bisq.core.trade.messages.TradeMessage;
import bisq.core.trade.statistics.ReferralIdService; import bisq.core.trade.statistics.ReferralIdService;
import bisq.core.trade.statistics.TradeStatisticsManager; import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.core.trade.txproof.AssetTxProofResult;
import bisq.core.trade.txproof.xmr.XmrTxProofService;
import bisq.core.user.User; import bisq.core.user.User;
import bisq.core.util.Validator; import bisq.core.util.Validator;
@ -59,7 +57,6 @@ import bisq.network.p2p.P2PService;
import bisq.network.p2p.SendMailboxMessageListener; import bisq.network.p2p.SendMailboxMessageListener;
import bisq.common.ClockWatcher; import bisq.common.ClockWatcher;
import bisq.common.UserThread;
import bisq.common.config.Config; import bisq.common.config.Config;
import bisq.common.crypto.KeyRing; import bisq.common.crypto.KeyRing;
import bisq.common.handlers.ErrorMessageHandler; import bisq.common.handlers.ErrorMessageHandler;
@ -111,8 +108,6 @@ import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkArgument;
public class TradeManager implements PersistedDataHost { public class TradeManager implements PersistedDataHost {
private static final Logger log = LoggerFactory.getLogger(TradeManager.class); private static final Logger log = LoggerFactory.getLogger(TradeManager.class);
@ -132,7 +127,6 @@ public class TradeManager implements PersistedDataHost {
private final ReferralIdService referralIdService; private final ReferralIdService referralIdService;
private final AccountAgeWitnessService accountAgeWitnessService; private final AccountAgeWitnessService accountAgeWitnessService;
@Getter @Getter
private final XmrTxProofService xmrTxProofService;
private final ArbitratorManager arbitratorManager; private final ArbitratorManager arbitratorManager;
private final MediatorManager mediatorManager; private final MediatorManager mediatorManager;
private final RefundAgentManager refundAgentManager; private final RefundAgentManager refundAgentManager;
@ -174,7 +168,6 @@ public class TradeManager implements PersistedDataHost {
TradeStatisticsManager tradeStatisticsManager, TradeStatisticsManager tradeStatisticsManager,
ReferralIdService referralIdService, ReferralIdService referralIdService,
AccountAgeWitnessService accountAgeWitnessService, AccountAgeWitnessService accountAgeWitnessService,
XmrTxProofService xmrTxProofService,
ArbitratorManager arbitratorManager, ArbitratorManager arbitratorManager,
MediatorManager mediatorManager, MediatorManager mediatorManager,
RefundAgentManager refundAgentManager, RefundAgentManager refundAgentManager,
@ -197,7 +190,6 @@ public class TradeManager implements PersistedDataHost {
this.tradeStatisticsManager = tradeStatisticsManager; this.tradeStatisticsManager = tradeStatisticsManager;
this.referralIdService = referralIdService; this.referralIdService = referralIdService;
this.accountAgeWitnessService = accountAgeWitnessService; this.accountAgeWitnessService = accountAgeWitnessService;
this.xmrTxProofService = xmrTxProofService;
this.arbitratorManager = arbitratorManager; this.arbitratorManager = arbitratorManager;
this.mediatorManager = mediatorManager; this.mediatorManager = mediatorManager;
this.refundAgentManager = refundAgentManager; this.refundAgentManager = refundAgentManager;
@ -286,7 +278,7 @@ public class TradeManager implements PersistedDataHost {
} }
public void shutDown() { public void shutDown() {
xmrTxProofService.shutDown(); // Do nothing here
} }
private void initPendingTrades() { private void initPendingTrades() {
@ -329,13 +321,6 @@ public class TradeManager implements PersistedDataHost {
addTradeToFailedTradesList.add(trade); addTradeToFailedTradesList.add(trade);
} }
} }
if (trade.getState() == Trade.State.SELLER_RECEIVED_FIAT_PAYMENT_INITIATED_MSG) {
// This state can be only appear at a SellerTrade
checkArgument(trade instanceof SellerTrade, "Trade must be instance of SellerTrade");
// We delay a bit as at startup lots of stuff is happening
UserThread.runAfter(() -> maybeStartXmrTxProofServices((SellerTrade) trade), 1);
}
} }
); );
@ -360,29 +345,8 @@ public class TradeManager implements PersistedDataHost {
pendingTradesInitialized.set(true); pendingTradesInitialized.set(true);
} }
public void maybeStartXmrTxProofServices(SellerTrade sellerTrade) {
xmrTxProofService.maybeStartRequests(sellerTrade, tradableList.getList(),
assetTxProofResult -> {
if (assetTxProofResult == AssetTxProofResult.COMPLETED) {
log.info("###########################################################################################");
log.info("We auto-confirm trade {} as our all our services for the tx proof completed successfully", sellerTrade.getShortId());
log.info("###########################################################################################");
autoConfirmFiatPaymentReceived(sellerTrade);
}
},
(errorMessage, throwable) -> {
log.error(errorMessage);
});
}
private void autoConfirmFiatPaymentReceived(SellerTrade sellerTrade) { public void onUserConfirmedFiatPaymentReceived(SellerTrade sellerTrade,
onFiatPaymentReceived(sellerTrade,
() -> {
}, errorMessage -> {
});
}
public void onFiatPaymentReceived(SellerTrade sellerTrade,
ResultHandler resultHandler, ResultHandler resultHandler,
ErrorMessageHandler errorMessageHandler) { ErrorMessageHandler errorMessageHandler) {
sellerTrade.onFiatPaymentReceived(resultHandler, errorMessageHandler); sellerTrade.onFiatPaymentReceived(resultHandler, errorMessageHandler);

View file

@ -17,7 +17,6 @@
package bisq.core.trade.protocol.tasks.seller; package bisq.core.trade.protocol.tasks.seller;
import bisq.core.trade.SellerTrade;
import bisq.core.trade.Trade; import bisq.core.trade.Trade;
import bisq.core.trade.messages.CounterCurrencyTransferStartedMessage; import bisq.core.trade.messages.CounterCurrencyTransferStartedMessage;
import bisq.core.trade.protocol.tasks.TradeTask; import bisq.core.trade.protocol.tasks.TradeTask;
@ -27,7 +26,6 @@ import bisq.common.taskrunner.TaskRunner;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j @Slf4j
@ -62,10 +60,6 @@ public class SellerProcessCounterCurrencyTransferStartedMessage extends TradeTas
trade.setCounterCurrencyExtraData(counterCurrencyExtraData); trade.setCounterCurrencyExtraData(counterCurrencyExtraData);
} }
checkArgument(trade instanceof SellerTrade, "Trade must be instance of SellerTrade");
// We return early in the service if its not XMR. We prefer to not have additional checks outside...
processModel.getTradeManager().maybeStartXmrTxProofServices((SellerTrade) trade);
processModel.removeMailboxMessageAfterProcessing(trade); processModel.removeMailboxMessageAfterProcessing(trade);
trade.setState(Trade.State.SELLER_RECEIVED_FIAT_PAYMENT_INITIATED_MSG); trade.setState(Trade.State.SELLER_RECEIVED_FIAT_PAYMENT_INITIATED_MSG);

View file

@ -17,18 +17,8 @@
package bisq.core.trade.txproof; package bisq.core.trade.txproof;
import bisq.core.trade.Trade;
import bisq.common.handlers.FaultHandler;
import java.util.List;
import java.util.function.Consumer;
public interface AssetTxProofService { public interface AssetTxProofService {
void maybeStartRequests(Trade trade, void onAllServicesInitialized();
List<Trade> activeTrades,
Consumer<AssetTxProofResult> resultHandler,
FaultHandler faultHandler);
void shutDown(); void shutDown();
} }

View file

@ -23,6 +23,7 @@ import bisq.core.locale.Res;
import bisq.core.payment.payload.AssetsAccountPayload; import bisq.core.payment.payload.AssetsAccountPayload;
import bisq.core.trade.SellerTrade; import bisq.core.trade.SellerTrade;
import bisq.core.trade.Trade; import bisq.core.trade.Trade;
import bisq.core.trade.TradeManager;
import bisq.core.trade.closed.ClosedTradableManager; import bisq.core.trade.closed.ClosedTradableManager;
import bisq.core.trade.failed.FailedTradesManager; import bisq.core.trade.failed.FailedTradesManager;
import bisq.core.trade.txproof.AssetTxProofHttpClient; import bisq.core.trade.txproof.AssetTxProofHttpClient;
@ -34,16 +35,16 @@ import bisq.core.user.Preferences;
import bisq.network.p2p.P2PService; import bisq.network.p2p.P2PService;
import bisq.common.app.DevEnv; import bisq.common.app.DevEnv;
import bisq.common.handlers.FaultHandler;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Stream; import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -59,12 +60,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class XmrTxProofService implements AssetTxProofService { public class XmrTxProofService implements AssetTxProofService {
private final FilterManager filterManager; private final FilterManager filterManager;
private final Preferences preferences; private final Preferences preferences;
private final TradeManager tradeManager;
private final ClosedTradableManager closedTradableManager; private final ClosedTradableManager closedTradableManager;
private final FailedTradesManager failedTradesManager; private final FailedTradesManager failedTradesManager;
private final P2PService p2PService; private final P2PService p2PService;
private final WalletsSetup walletsSetup; private final WalletsSetup walletsSetup;
private final AssetTxProofHttpClient httpClient; private final AssetTxProofHttpClient httpClient;
private final Map<String, XmrTxProofRequestsPerTrade> servicesByTradeId = new HashMap<>(); private final Map<String, XmrTxProofRequestsPerTrade> servicesByTradeId = new HashMap<>();
private AutoConfirmSettings autoConfirmSettings;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -75,6 +78,7 @@ public class XmrTxProofService implements AssetTxProofService {
@Inject @Inject
public XmrTxProofService(FilterManager filterManager, public XmrTxProofService(FilterManager filterManager,
Preferences preferences, Preferences preferences,
TradeManager tradeManager,
ClosedTradableManager closedTradableManager, ClosedTradableManager closedTradableManager,
FailedTradesManager failedTradesManager, FailedTradesManager failedTradesManager,
P2PService p2PService, P2PService p2PService,
@ -82,11 +86,25 @@ public class XmrTxProofService implements AssetTxProofService {
AssetTxProofHttpClient httpClient) { AssetTxProofHttpClient httpClient) {
this.filterManager = filterManager; this.filterManager = filterManager;
this.preferences = preferences; this.preferences = preferences;
this.tradeManager = tradeManager;
this.closedTradableManager = closedTradableManager; this.closedTradableManager = closedTradableManager;
this.failedTradesManager = failedTradesManager; this.failedTradesManager = failedTradesManager;
this.p2PService = p2PService; this.p2PService = p2PService;
this.walletsSetup = walletsSetup; this.walletsSetup = walletsSetup;
this.httpClient = httpClient; this.httpClient = httpClient;
}
///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onAllServicesInitialized() {
if (!preferences.findAutoConfirmSettings("XMR").isPresent()) {
log.error("AutoConfirmSettings is not present");
}
autoConfirmSettings = preferences.findAutoConfirmSettings("XMR").get();
filterManager.filterProperty().addListener((observable, oldValue, newValue) -> { filterManager.filterProperty().addListener((observable, oldValue, newValue) -> {
if (isAutoConfDisabledByFilter()) { if (isAutoConfDisabledByFilter()) {
@ -96,22 +114,39 @@ public class XmrTxProofService implements AssetTxProofService {
shutDown(); shutDown();
} }
}); });
ObservableList<Trade> tradableList = tradeManager.getTradableList();
tradableList.addListener((ListChangeListener<Trade>) c -> {
c.next();
if (c.wasAdded()) {
processTrades(c.getAddedSubList());
}
});
processTrades(tradableList);
} }
///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void maybeStartRequests(Trade trade, public void shutDown() {
List<Trade> activeTrades, servicesByTradeId.values().forEach(XmrTxProofRequestsPerTrade::terminate);
Consumer<AssetTxProofResult> resultHandler, servicesByTradeId.clear();
FaultHandler faultHandler) {
if (!isXmrBuyer(trade)) {
return;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private void processTrades(List<? extends Trade> trades) {
trades.stream()
.filter(trade -> trade instanceof SellerTrade)
.map(trade -> (SellerTrade) trade)
.filter(this::isExpectedTradeState)
.filter(this::isXmrBuyer)
.filter(trade -> networkAndWalletReady())
.forEach(this::processTrade);
}
private void processTrade(SellerTrade trade) {
String txId = trade.getCounterCurrencyTxId(); String txId = trade.getCounterCurrencyTxId();
String txHash = trade.getCounterCurrencyExtraData(); String txHash = trade.getCounterCurrencyExtraData();
if (is32BitHexStringInValid(txId) || is32BitHexStringInValid(txHash)) { if (is32BitHexStringInValid(txId) || is32BitHexStringInValid(txHash)) {
@ -119,25 +154,13 @@ public class XmrTxProofService implements AssetTxProofService {
return; return;
} }
if (!networkAndWalletReady()) {
return;
}
Optional<AutoConfirmSettings> optionalAutoConfirmSettings = preferences.findAutoConfirmSettings("XMR");
if (!optionalAutoConfirmSettings.isPresent()) {
// Not expected
log.error("autoConfirmSettings is not present");
return;
}
AutoConfirmSettings autoConfirmSettings = optionalAutoConfirmSettings.get();
if (isAutoConfDisabledByFilter()) { if (isAutoConfDisabledByFilter()) {
trade.setAssetTxProofResult(AssetTxProofResult.FEATURE_DISABLED trade.setAssetTxProofResult(AssetTxProofResult.FEATURE_DISABLED
.details(Res.get("portfolio.pending.autoConf.state.filterDisabledFeature"))); .details(Res.get("portfolio.pending.autoConf.state.filterDisabledFeature")));
return; return;
} }
if (wasTxKeyReUsed(trade, activeTrades)) { if (wasTxKeyReUsed(trade, tradeManager.getTradableList())) {
trade.setAssetTxProofResult(AssetTxProofResult.INVALID_DATA trade.setAssetTxProofResult(AssetTxProofResult.INVALID_DATA
.details(Res.get("portfolio.pending.autoConf.state.xmr.txKeyReused"))); .details(Res.get("portfolio.pending.autoConf.state.xmr.txKeyReused")));
return; return;
@ -151,19 +174,22 @@ public class XmrTxProofService implements AssetTxProofService {
assetTxProofResult -> { assetTxProofResult -> {
trade.setAssetTxProofResult(assetTxProofResult); trade.setAssetTxProofResult(assetTxProofResult);
if (assetTxProofResult == AssetTxProofResult.COMPLETED) {
log.info("###########################################################################################");
log.info("We auto-confirm trade {} as our all our services for the tx proof completed successfully", trade.getShortId());
log.info("###########################################################################################");
trade.onFiatPaymentReceived(() -> {
}, errorMessage -> {
});
}
if (assetTxProofResult.isTerminal()) { if (assetTxProofResult.isTerminal()) {
servicesByTradeId.remove(trade.getId()); servicesByTradeId.remove(trade.getId());
} }
resultHandler.accept(assetTxProofResult);
}, },
faultHandler); (errorMessage, throwable) -> {
} log.error(errorMessage);
});
@Override
public void shutDown() {
servicesByTradeId.values().forEach(XmrTxProofRequestsPerTrade::terminate);
servicesByTradeId.clear();
} }
@ -171,6 +197,10 @@ public class XmrTxProofService implements AssetTxProofService {
// Validation // Validation
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
private boolean isExpectedTradeState(SellerTrade sellerTrade) {
return sellerTrade.getState() == Trade.State.SELLER_RECEIVED_FIAT_PAYMENT_INITIATED_MSG;
}
private boolean isXmrBuyer(Trade trade) { private boolean isXmrBuyer(Trade trade) {
if (!checkNotNull(trade.getOffer()).getCurrencyCode().equals("XMR")) { if (!checkNotNull(trade.getOffer()).getCurrencyCode().equals("XMR")) {
return false; return false;
@ -183,6 +213,12 @@ public class XmrTxProofService implements AssetTxProofService {
return checkNotNull(trade.getContract()).getSellerPaymentAccountPayload() instanceof AssetsAccountPayload; return checkNotNull(trade.getContract()).getSellerPaymentAccountPayload() instanceof AssetsAccountPayload;
} }
private boolean networkAndWalletReady() {
return p2PService.isBootstrapped() &&
walletsSetup.isDownloadComplete() &&
walletsSetup.hasSufficientPeersForBroadcast();
}
private boolean is32BitHexStringInValid(String hexString) { private boolean is32BitHexStringInValid(String hexString) {
if (hexString == null || hexString.isEmpty() || !hexString.matches("[a-fA-F0-9]{64}")) { if (hexString == null || hexString.isEmpty() || !hexString.matches("[a-fA-F0-9]{64}")) {
log.warn("Invalid hexString: {}", hexString); log.warn("Invalid hexString: {}", hexString);
@ -192,12 +228,6 @@ public class XmrTxProofService implements AssetTxProofService {
return false; return false;
} }
private boolean networkAndWalletReady() {
return p2PService.isBootstrapped() &&
walletsSetup.isDownloadComplete() &&
walletsSetup.hasSufficientPeersForBroadcast();
}
private boolean isAutoConfDisabledByFilter() { private boolean isAutoConfDisabledByFilter() {
return filterManager.getFilter() != null && return filterManager.getFilter() != null &&
filterManager.getFilter().isDisableAutoConf(); filterManager.getFilter().isDisableAutoConf();

View file

@ -194,7 +194,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
public void onFiatPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { public void onFiatPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
checkNotNull(getTrade(), "trade must not be null"); checkNotNull(getTrade(), "trade must not be null");
checkArgument(getTrade() instanceof SellerTrade, "Trade must be instance of SellerTrade"); checkArgument(getTrade() instanceof SellerTrade, "Trade must be instance of SellerTrade");
tradeManager.onFiatPaymentReceived((SellerTrade) getTrade(), resultHandler, errorMessageHandler); tradeManager.onUserConfirmedFiatPaymentReceived((SellerTrade) getTrade(), resultHandler, errorMessageHandler);
} }
public void onWithdrawRequest(String toAddress, public void onWithdrawRequest(String toAddress,