Refactored state handling

This commit is contained in:
Manfred Karrer 2015-03-22 00:41:01 +01:00
parent f68030e488
commit 79931b96aa
14 changed files with 184 additions and 146 deletions

View File

@ -87,6 +87,7 @@ lower gradient color on tab: dddddd
#nav-alert-label {
-fx-font-weight: bold;
-fx-alignment: center;
-fx-font-size: 11;
-fx-text-fill: white;
}

View File

@ -61,7 +61,6 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.ListChangeListener;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList;
import javafx.util.StringConverter;
@ -103,7 +102,6 @@ class MainViewModel implements ViewModel {
private final User user;
private final WalletService walletService;
private final ClientNode clientNode;
private MessageService messageService;
private ArbitratorService arbitratorService;
private final TradeManager tradeManager;
private UpdateProcess updateProcess;
@ -119,7 +117,6 @@ class MainViewModel implements ViewModel {
this.user = user;
this.walletService = walletService;
this.clientNode = clientNode;
this.messageService = messageService;
this.arbitratorService = arbitratorService;
this.tradeManager = tradeManager;
this.updateProcess = updateProcess;
@ -210,8 +207,7 @@ class MainViewModel implements ViewModel {
private void onAllServicesInitialized() {
log.trace("backend completed");
tradeManager.getPendingTrades().addListener(
(MapChangeListener<String, Trade>) change -> updateNumPendingTrades());
tradeManager.getPendingTrades().addListener((ListChangeListener<Trade>) change -> updateNumPendingTrades());
updateNumPendingTrades();
showAppScreen.set(true);
@ -333,9 +329,12 @@ class MainViewModel implements ViewModel {
}
private void updateNumPendingTrades() {
int numPendingTrades = tradeManager.getPendingTrades().size();
long numPendingTrades = tradeManager.getPendingTrades().size();
if (numPendingTrades > 0)
numPendingTradesAsString.set(String.valueOf(numPendingTrades));
if (numPendingTrades > 9)
numPendingTradesAsString.set("*");
showPendingTradesNotification.set(numPendingTrades > 0);
}

View File

@ -78,10 +78,12 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
navigation.addListener(navigationListener);
if (tradeManager.getPendingTrades().size() == 0)
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
/* if (tradeManager.getPendingTrades().size() == 0)
navigation.navigateTo(MainView.class, PortfolioView.class, OffersView.class);
else
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);*/
}
@Override

View File

@ -27,8 +27,10 @@ import io.bitsquare.user.User;
import com.google.inject.Inject;
import java.util.stream.Collectors;
import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
class ClosedTradesDataModel implements Activatable, DataModel {
@ -37,36 +39,25 @@ class ClosedTradesDataModel implements Activatable, DataModel {
private final User user;
private final ObservableList<ClosedTradesListItem> list = FXCollections.observableArrayList();
private final MapChangeListener<String, Trade> mapChangeListener;
private final ListChangeListener<Trade> tradesListChangeListener;
@Inject
public ClosedTradesDataModel(TradeManager tradeManager, User user) {
this.tradeManager = tradeManager;
this.user = user;
this.mapChangeListener = change -> {
if (change.wasAdded())
list.add(new ClosedTradesListItem(change.getValueAdded()));
else if (change.wasRemoved())
list.removeIf(e -> e.getTrade().getId().equals(change.getValueRemoved().getId()));
};
tradesListChangeListener = change -> applyList();
}
@Override
public void activate() {
list.clear();
tradeManager.getClosedTrades().values().stream()
.forEach(e -> list.add(new ClosedTradesListItem(e)));
tradeManager.getClosedTrades().addListener(mapChangeListener);
// We sort by date, earliest first
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
applyList();
tradeManager.getClosedTrades().addListener(tradesListChangeListener);
}
@Override
public void deactivate() {
tradeManager.getClosedTrades().removeListener(mapChangeListener);
tradeManager.getClosedTrades().removeListener(tradesListChangeListener);
}
public ObservableList<ClosedTradesListItem> getList() {
@ -78,4 +69,13 @@ class ClosedTradesDataModel implements Activatable, DataModel {
offer.getDirection() : offer.getMirroredDirection();
}
private void applyList() {
list.clear();
list.addAll(tradeManager.getClosedTrades().stream().map(ClosedTradesListItem::new).collect(Collectors.toList()));
// we sort by date, earliest first
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
}
}

View File

@ -41,6 +41,7 @@
<TableColumn text="Price" fx:id="priceColumn" minWidth="100" sortable="false"/>
<TableColumn text="Trade amount in EUR" fx:id="volumeColumn" minWidth="130" sortable="false"/>
<TableColumn text="Trade type" fx:id="directionColumn" minWidth="80" sortable="false"/>
<TableColumn text="State" fx:id="stateColumn" minWidth="80" sortable="false"/>
</columns>
</TableView>

View File

@ -34,7 +34,7 @@ public class ClosedTradesView extends ActivatableViewAndModel<GridPane, ClosedTr
@FXML TableView<ClosedTradesListItem> table;
@FXML TableColumn<ClosedTradesListItem, ClosedTradesListItem> priceColumn, amountColumn, volumeColumn,
directionColumn, dateColumn, tradeIdColumn;
directionColumn, dateColumn, tradeIdColumn, stateColumn;
@Inject
public ClosedTradesView(ClosedTradesViewModel model) {
@ -49,6 +49,7 @@ public class ClosedTradesView extends ActivatableViewAndModel<GridPane, ClosedTr
setPriceColumnCellFactory();
setVolumeColumnCellFactory();
setDateColumnCellFactory();
setStateColumnCellFactory();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setPlaceholder(new Label("No closed trades available"));
@ -121,6 +122,28 @@ public class ClosedTradesView extends ActivatableViewAndModel<GridPane, ClosedTr
});
}
private void setStateColumnCellFactory() {
stateColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
stateColumn.setCellFactory(
new Callback<TableColumn<ClosedTradesListItem, ClosedTradesListItem>, TableCell<ClosedTradesListItem,
ClosedTradesListItem>>() {
@Override
public TableCell<ClosedTradesListItem, ClosedTradesListItem> call(
TableColumn<ClosedTradesListItem, ClosedTradesListItem> column) {
return new TableCell<ClosedTradesListItem, ClosedTradesListItem>() {
@Override
public void updateItem(final ClosedTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
setText(model.getState(item));
else
setText("");
}
};
}
});
}
private void setAmountColumnCellFactory() {
amountColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));

View File

@ -65,4 +65,24 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
return formatter.formatDateTime(item.getTrade().getDate());
}
String getState(ClosedTradesListItem item) {
if (item != null && item.getTrade() != null) {
switch (item.getTrade().getLifeCycleState()) {
case CANCELED:
return "Canceled";
case COMPLETED:
return "Completed";
case FAILED:
return "Failed";
case OPEN_OFFER:
case PENDING:
throw new RuntimeException("Wrong state: " + item.getTrade().getLifeCycleState());
}
return "Undefined";
}
else {
return "";
}
}
}

View File

@ -32,7 +32,7 @@ import com.google.inject.Inject;
import java.util.stream.Collectors;
import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import org.slf4j.Logger;
@ -45,40 +45,29 @@ class OffersDataModel implements Activatable, DataModel {
private final User user;
private final ObservableList<OfferListItem> list = FXCollections.observableArrayList();
private final MapChangeListener<String, Trade> offerMapChangeListener;
private final ListChangeListener<Trade> tradesListChangeListener;
@Inject
public OffersDataModel(TradeManager tradeManager, User user) {
this.tradeManager = tradeManager;
this.user = user;
this.offerMapChangeListener = change -> {
if (change.wasAdded())
list.add(new OfferListItem(change.getValueAdded()));
else if (change.wasRemoved())
list.removeIf(e -> e.getOffer().getId().equals(change.getValueRemoved().getId()));
};
tradesListChangeListener = change -> applyList();
}
@Override
public void activate() {
list.clear();
list.addAll(tradeManager.getOpenOfferTrades().values().stream().map(OfferListItem::new).collect(Collectors.toList()));
// we sort by date, earliest first
list.sort((o1, o2) -> o2.getOffer().getCreationDate().compareTo(o1.getOffer().getCreationDate()));
tradeManager.getOpenOfferTrades().addListener(offerMapChangeListener);
applyList();
tradeManager.getOpenOfferTrades().addListener(tradesListChangeListener);
}
@Override
public void deactivate() {
tradeManager.getOpenOfferTrades().removeListener(offerMapChangeListener);
tradeManager.getOpenOfferTrades().removeListener(tradesListChangeListener);
}
void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
tradeManager.removeOpenOffer(offer, resultHandler, errorMessageHandler);
void cancelOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
tradeManager.cancelOpenOffer(offer, resultHandler, errorMessageHandler);
}
@ -90,4 +79,13 @@ class OffersDataModel implements Activatable, DataModel {
return offer.getP2PSigPubKey().equals(user.getP2PSigPubKey()) ?
offer.getDirection() : offer.getMirroredDirection();
}
private void applyList() {
list.clear();
list.addAll(tradeManager.getOpenOfferTrades().stream().map(OfferListItem::new).collect(Collectors.toList()));
// we sort by date, earliest first
list.sort((o1, o2) -> o2.getOffer().getCreationDate().compareTo(o1.getOffer().getCreationDate()));
}
}

View File

@ -63,8 +63,8 @@ public class OffersView extends ActivatableViewAndModel<GridPane, OffersViewMode
table.setItems(model.getList());
}
private void removeOpenOffer(Offer offer) {
model.removeOpenOffer(offer);
private void cancelOpenOffer(Offer offer) {
model.cancelOpenOffer(offer);
}
private void openOfferDetails(OfferListItem item) {
@ -233,7 +233,7 @@ public class OffersView extends ActivatableViewAndModel<GridPane, OffersViewMode
super.updateItem(item, empty);
if (item != null) {
button.setOnAction(event -> removeOpenOffer(item.getOffer()));
button.setOnAction(event -> cancelOpenOffer(item.getOffer()));
setGraphic(button);
}
else {

View File

@ -44,8 +44,8 @@ class OffersViewModel extends ActivatableWithDataModel<OffersDataModel> implemen
}
void removeOpenOffer(Offer offer) {
dataModel.removeOpenOffer(offer,
void cancelOpenOffer(Offer offer) {
dataModel.cancelOpenOffer(offer,
() -> {
// visual feedback?
log.debug("Remove offer was successful");

View File

@ -37,6 +37,8 @@ import com.google.common.util.concurrent.FutureCallback;
import com.google.inject.Inject;
import java.util.stream.Collectors;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
@ -45,7 +47,7 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import org.jetbrains.annotations.NotNull;
@ -67,7 +69,7 @@ class PendingTradesDataModel implements Activatable, DataModel {
private Trade closedTrade;
private final ChangeListener<Trade.ProcessState> tradeStateChangeListener;
private final MapChangeListener<String, Trade> mapChangeListener;
private final ListChangeListener<Trade> tradesListChangeListener;
final StringProperty txId = new SimpleStringProperty();
final ObjectProperty<Trade.ProcessState> tradeState = new SimpleObjectProperty<>();
@ -80,49 +82,14 @@ class PendingTradesDataModel implements Activatable, DataModel {
this.user = user;
tradeStateChangeListener = (ov, oldValue, newValue) -> tradeState.set(newValue);
mapChangeListener = change -> {
if (change.wasAdded()) {
list.add(new PendingTradesListItem(change.getValueAdded()));
if (list.size() == 1) {
selectTrade(list.get(0));
selectedIndex.set(0);
}
}
else if (change.wasRemoved()) {
closedTrade = change.getValueRemoved();
if (list.size() == 0) {
selectTrade(null);
selectedIndex.set(-1);
}
}
sortList();
};
tradesListChangeListener = change -> applyList();
}
@Override
public void activate() {
list.clear();
// transform trades to list of PendingTradesListItems and keep it updated
tradeManager.getPendingTrades().values().stream().forEach(e -> list.add(new PendingTradesListItem(e)));
tradeManager.getPendingTrades().addListener(mapChangeListener);
applyList();
tradeManager.getPendingTrades().addListener(tradesListChangeListener);
// we sort by date, earliest first
sortList();
// select either currentPendingTrade or first in the list
/*if (tradeManager.getCurrentPendingTrade() != null) {
for (int i = 0; i < list.size(); i++) {
PendingTradesListItem item = list.get(i);
if (tradeManager.getCurrentPendingTrade().getId().equals(item.getTrade().getId())) {
selectedIndex.set(i);
selectTrade(item);
break;
}
}
}
else */
if (list.size() > 0) {
selectTrade(list.get(0));
selectedIndex.set(0);
@ -131,11 +98,17 @@ class PendingTradesDataModel implements Activatable, DataModel {
@Override
public void deactivate() {
tradeManager.getPendingTrades().removeListener(mapChangeListener);
tradeManager.getPendingTrades().removeListener(tradesListChangeListener);
cleanUpSelectedTrade();
}
private void applyList() {
list.clear();
list.addAll(tradeManager.getPendingTrades().stream().map(PendingTradesListItem::new).collect(Collectors.toList()));
// we sort by date, earliest first
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
}
void selectTrade(PendingTradesListItem item) {
// clean up previous selectedItem
@ -282,9 +255,5 @@ class PendingTradesDataModel implements Activatable, DataModel {
}
}
private void sortList() {
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
}
}

View File

@ -471,8 +471,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
if (model.isMyOffer(offer)) {
iconView.setId("image-remove");
title = "Remove";
button.setOnAction(event -> model.cancelOpenOffer(item
.getOffer()));
button.setOnAction(event -> model.cancelOpenOffer(item.getOffer()));
}
else {
if (offer.getDirection() == Direction.SELL)
@ -484,8 +483,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
}
//TODO remove listener
item.bankAccountCountryProperty().addListener((ov, o, n) ->
verifyIfTradable(item));
item.bankAccountCountryProperty().addListener((ov, o, n) -> verifyIfTradable(item));
verifyIfTradable(item);
button.setText(title);

View File

@ -53,14 +53,16 @@ import org.bitcoinj.utils.Fiat;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.inject.Inject;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;
import javafx.collections.ObservableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -84,8 +86,9 @@ public class TradeManager {
private final Map<String, OffererAsBuyerProtocol> offererAsBuyerProtocolMap = new HashMap<>();
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
private final Map<String, Trade> trades = new HashMap<>();
private final ObservableList<Trade> openOfferTrades = FXCollections.observableArrayList();
private final ObservableList<Trade> pendingTrades = FXCollections.observableArrayList();
private final ObservableList<Trade> closedTrades = FXCollections.observableArrayList();
private final Map<String, MailboxMessage> mailboxMessages = new HashMap<>();
@ -110,9 +113,17 @@ public class TradeManager {
this.encryptionService = encryptionService;
this.offerBookService = offerBookService;
Serializable tradesObject = persistence.read(this, "trades");
if (tradesObject instanceof Map<?, ?>) {
trades.putAll((Map<String, Trade>) tradesObject);
Serializable openOffersObject = persistence.read(this, "openOffers");
if (openOffersObject instanceof List<?>) {
openOfferTrades.addAll((List<Trade>) openOffersObject);
}
Serializable pendingTradesObject = persistence.read(this, "pendingTrades");
if (pendingTradesObject instanceof List<?>) {
pendingTrades.addAll((List<Trade>) pendingTradesObject);
}
Serializable closedTradesObject = persistence.read(this, "closedTrades");
if (closedTradesObject instanceof List<?>) {
closedTrades.addAll((List<Trade>) closedTradesObject);
}
}
@ -124,11 +135,13 @@ public class TradeManager {
// When all services are initialized we create the protocols for our open offers and persisted not completed pendingTrades
// BuyerAcceptsOfferProtocol listens for take offer requests, so we need to instantiate it early.
public void onAllServicesInitialized() {
for (Map.Entry<String, Trade> entry : trades.entrySet()) {
for (Trade trade : openOfferTrades) {
createOffererAsBuyerProtocol(trade);
}
for (Trade trade : pendingTrades) {
// We continue an interrupted trade.
// TODO if the peer has changed its IP address, we need to make another findPeer request. At the moment we use the peer stored in trade to
// continue the trade, but that might fail.
Trade trade = entry.getValue();
if (isMyOffer(trade.getOffer())) {
createOffererAsBuyerProtocol(trade);
}
@ -182,8 +195,11 @@ public class TradeManager {
PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol(
model,
(transaction) -> {
Trade trade = createTrade(offer);
Trade trade = new Trade(offer);
trade.setLifeCycleState(Trade.LifeCycleState.OPEN_OFFER);
openOfferTrades.add(trade);
persistOpenOfferTrades();
createOffererAsBuyerProtocol(trade);
resultHandler.handleResult(transaction);
},
@ -194,11 +210,6 @@ public class TradeManager {
}
public void cancelOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
trades.get(offer.getId()).setLifeCycleState(Trade.LifeCycleState.CANCELED);
removeOpenOffer(offer, resultHandler, errorMessageHandler, true);
}
public void removeOpenOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
removeOpenOffer(offer, resultHandler, errorMessageHandler, true);
}
@ -254,7 +265,7 @@ public class TradeManager {
// TODO remove if check when persistence is impl.
if (offererAsBuyerProtocolMap.containsKey(tradeId)) {
offererAsBuyerProtocolMap.get(tradeId).onFiatPaymentStarted();
persistTrades();
persistPendingTrades();
}
}
@ -264,6 +275,10 @@ public class TradeManager {
public void onWithdrawAtTradeCompleted(Trade trade) {
trade.setLifeCycleState(Trade.LifeCycleState.COMPLETED);
pendingTrades.remove(trade);
persistPendingTrades();
closedTrades.add(trade);
persistClosedTrades();
removeFromProtocolMap(trade);
}
@ -277,27 +292,20 @@ public class TradeManager {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public ObservableMap<String, Trade> getOpenOfferTrades() {
ObservableMap<String, Trade> list = FXCollections.observableHashMap();
list.putAll(trades);
return list;
public ObservableList<Trade> getOpenOfferTrades() {
return openOfferTrades;
}
public ObservableMap<String, Trade> getPendingTrades() {
ObservableMap<String, Trade> list = FXCollections.observableHashMap();
list.putAll(trades);
return list;
public ObservableList<Trade> getPendingTrades() {
return pendingTrades;
}
public ObservableMap<String, Trade> getClosedTrades() {
ObservableMap<String, Trade> list = FXCollections.observableHashMap();
list.putAll(trades);
return list;
public ObservableList<Trade> getClosedTrades() {
return closedTrades;
}
@ -312,16 +320,27 @@ public class TradeManager {
private void removeOpenOffer(Offer offer,
ResultHandler resultHandler,
ErrorMessageHandler errorMessageHandler,
boolean removeFromBuyerAcceptsOfferProtocolMap) {
String offerId = offer.getId();
boolean isCancelRequest) {
offerBookService.removeOffer(offer,
() -> {
offer.setState(Offer.State.REMOVED);
trades.remove(offerId);
Optional<Trade> result = openOfferTrades.stream().filter(e -> e.getId().equals(offer.getId())).findAny();
if (result.isPresent()) {
Trade trade = result.get();
openOfferTrades.remove(trade);
persistOpenOfferTrades();
if (isCancelRequest) {
trade.setLifeCycleState(Trade.LifeCycleState.CANCELED);
closedTrades.add(trade);
persistClosedTrades();
}
}
disposeCheckOfferAvailabilityRequest(offer);
persistTrades();
if (removeFromBuyerAcceptsOfferProtocolMap && offererAsBuyerProtocolMap.containsKey(offerId)) {
String offerId = offer.getId();
if (isCancelRequest && offererAsBuyerProtocolMap.containsKey(offerId)) {
offererAsBuyerProtocolMap.get(offerId).cleanup();
offererAsBuyerProtocolMap.remove(offerId);
}
@ -351,21 +370,18 @@ public class TradeManager {
///////////////////////////////////////////////////////////////////////////////////////////
private Trade takeAvailableOffer(Coin amount, Offer offer, Peer peer) {
Trade trade = createTrade(offer);
Trade trade = new Trade(offer);
trade.setTradeAmount(amount);
trade.setTradingPeer(peer);
trade.setLifeCycleState(Trade.LifeCycleState.PENDING);
pendingTrades.add(trade);
persistPendingTrades();
TakerAsSellerProtocol sellerTakesOfferProtocol = createTakerAsSellerProtocol(trade);
sellerTakesOfferProtocol.takeAvailableOffer();
return trade;
}
private Trade createTrade(Offer offer) {
Trade trade = new Trade(offer);
trades.put(trade.getId(), trade);
persistTrades();
return trade;
}
private TakerAsSellerProtocol createTakerAsSellerProtocol(Trade trade) {
trade.processStateProperty().addListener((ov, oldValue, newValue) -> {
@ -379,7 +395,7 @@ public class TradeManager {
case FIAT_PAYMENT_STARTED:
case FIAT_PAYMENT_RECEIVED:
case PAYOUT_PUBLISHED:
persistTrades();
persistPendingTrades();
break;
case MESSAGE_SENDING_FAILED:
case FAULT:
@ -432,19 +448,22 @@ public class TradeManager {
case INIT:
break;
case TAKE_OFFER_FEE_TX_CREATED:
persistTrades();
persistPendingTrades();
break;
case DEPOSIT_PUBLISHED:
removeOpenOffer(trade.getOffer(),
() -> log.debug("remove offer was successful"),
(message) -> log.error(message),
false);
model.trade.setLifeCycleState(Trade.LifeCycleState.PENDING);
pendingTrades.add(trade);
persistPendingTrades();
break;
case DEPOSIT_CONFIRMED:
case FIAT_PAYMENT_STARTED:
case FIAT_PAYMENT_RECEIVED:
case PAYOUT_PUBLISHED:
persistTrades();
persistPendingTrades();
break;
case TAKE_OFFER_FEE_PUBLISH_FAILED:
case MESSAGE_SENDING_FAILED:
@ -520,8 +539,16 @@ public class TradeManager {
});
}
private void persistTrades() {
persistence.write(this, "trades", (Map<String, Trade>) new HashMap<>(trades));
private void persistOpenOfferTrades() {
persistence.write(this, "openOfferTrades", (List<Trade>) new ArrayList<>(openOfferTrades));
}
private void persistPendingTrades() {
persistence.write(this, "pendingTrades", (List<Trade>) new ArrayList<>(pendingTrades));
}
private void persistClosedTrades() {
persistence.write(this, "closedTrades", (List<Trade>) new ArrayList<>(closedTrades));
}
}

View File

@ -133,7 +133,7 @@ public class OffererAsBuyerProtocol {
checkTradeId(model.id, tradeMessage);
model.setTradeMessage(tradeMessage);
model.trade.setTradingPeer(taker);
TaskRunner<OffererAsBuyerModel> taskRunner = new TaskRunner<>(model,
() -> log.debug("taskRunner at handleTakeOfferFeePayedMessage completed"),
(errorMessage) -> handleTaskRunnerFault(errorMessage));