Merge pull request #2250 from ManfredKarrer/refactor-trademanager-setup

Refactor balances and trademanager setup
This commit is contained in:
Christoph Atteneder 2019-01-14 14:46:15 +01:00 committed by GitHub
commit ef106858a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 72 deletions

View File

@ -23,9 +23,8 @@ import bisq.core.alert.PrivateNotificationManager;
import bisq.core.alert.PrivateNotificationPayload;
import bisq.core.arbitration.ArbitratorManager;
import bisq.core.arbitration.DisputeManager;
import bisq.core.btc.listeners.BalanceListener;
import bisq.core.btc.Balances;
import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.model.BalanceModel;
import bisq.core.btc.setup.WalletsSetup;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.btc.wallet.WalletsManager;
@ -41,14 +40,12 @@ import bisq.core.notifications.alerts.MyOfferTakenEvents;
import bisq.core.notifications.alerts.TradeEvents;
import bisq.core.notifications.alerts.market.MarketAlerts;
import bisq.core.notifications.alerts.price.PriceAlert;
import bisq.core.offer.OpenOffer;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.Trade;
import bisq.core.trade.TradeManager;
import bisq.core.trade.statistics.AssetTradeActivityCheck;
import bisq.core.trade.statistics.TradeStatisticsManager;
@ -73,7 +70,6 @@ import bisq.common.proto.ProtobufferException;
import bisq.common.util.Utilities;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
import javax.inject.Inject;
@ -125,7 +121,7 @@ public class BisqSetup {
private final WalletsManager walletsManager;
private final WalletsSetup walletsSetup;
private final BtcWalletService btcWalletService;
private final BalanceModel balanceModel;
private final Balances balances;
private final PriceFeedService priceFeedService;
private final ArbitratorManager arbitratorManager;
private final P2PService p2PService;
@ -201,7 +197,7 @@ public class BisqSetup {
WalletsManager walletsManager,
WalletsSetup walletsSetup,
BtcWalletService btcWalletService,
BalanceModel balanceModel,
Balances balances,
PriceFeedService priceFeedService,
ArbitratorManager arbitratorManager,
P2PService p2PService,
@ -239,7 +235,7 @@ public class BisqSetup {
this.walletsManager = walletsManager;
this.walletsSetup = walletsSetup;
this.btcWalletService = btcWalletService;
this.balanceModel = balanceModel;
this.balances = balances;
this.priceFeedService = priceFeedService;
this.arbitratorManager = arbitratorManager;
this.p2PService = p2PService;
@ -588,29 +584,14 @@ public class BisqSetup {
disputeManager.onAllServicesInitialized();
tradeManager.onAllServicesInitialized();
tradeManager.getTradableList().addListener((ListChangeListener<Trade>) change -> balanceModel.updateBalance());
tradeManager.getAddressEntriesForAvailableBalanceStream()
.filter(addressEntry -> addressEntry.getOfferId() != null)
.forEach(addressEntry -> {
log.warn("Swapping pending OFFER_FUNDING entries at startup. offerId={}", addressEntry.getOfferId());
btcWalletService.swapTradeEntryToAvailableEntry(addressEntry.getOfferId(), AddressEntry.Context.OFFER_FUNDING);
});
btcWalletService.addBalanceListener(new BalanceListener() {
@Override
public void onBalanceChanged(Coin balance, Transaction tx) {
balanceModel.updateBalance();
}
});
if (walletsSetup.downloadPercentageProperty().get() == 1)
checkForLockedUpFunds();
balanceModel.updateBalance();
openOfferManager.getObservableList().addListener((ListChangeListener<OpenOffer>) c -> balanceModel.updateBalance());
openOfferManager.onAllServicesInitialized();
balances.onAllServicesInitialized();
arbitratorManager.onAllServicesInitialized();
alertManager.alertMessageProperty().addListener((observable, oldValue, newValue) ->

View File

@ -15,30 +15,38 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.btc.model;
package bisq.core.btc;
import bisq.core.btc.listeners.BalanceListener;
import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.offer.OpenOffer;
import bisq.core.offer.OpenOfferManager;
import bisq.core.trade.Trade;
import bisq.core.trade.TradeManager;
import bisq.core.trade.closed.ClosedTradableManager;
import bisq.core.trade.failed.FailedTradesManager;
import org.bitcoinj.core.Address;
import bisq.common.UserThread;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
import javax.inject.Inject;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ListChangeListener;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
public class BalanceModel {
@Slf4j
public class Balances {
private final TradeManager tradeManager;
private final BtcWalletService btcWalletService;
private final OpenOfferManager openOfferManager;
@ -53,8 +61,11 @@ public class BalanceModel {
private final ObjectProperty<Coin> lockedBalance = new SimpleObjectProperty<>();
@Inject
public BalanceModel(TradeManager tradeManager, BtcWalletService btcWalletService, OpenOfferManager openOfferManager,
ClosedTradableManager closedTradableManager, FailedTradesManager failedTradesManager) {
public Balances(TradeManager tradeManager,
BtcWalletService btcWalletService,
OpenOfferManager openOfferManager,
ClosedTradableManager closedTradableManager,
FailedTradesManager failedTradesManager) {
this.tradeManager = tradeManager;
this.btcWalletService = btcWalletService;
this.openOfferManager = openOfferManager;
@ -62,55 +73,53 @@ public class BalanceModel {
this.failedTradesManager = failedTradesManager;
}
public void updateBalance() {
//TODO check if still needed
/* // Without delaying to the next cycle it does not update.
// Seems order of events we are listening on causes that...
public void onAllServicesInitialized() {
openOfferManager.getObservableList().addListener((ListChangeListener<OpenOffer>) c -> updateBalance());
tradeManager.getTradableList().addListener((ListChangeListener<Trade>) change -> updateBalance());
btcWalletService.addBalanceListener(new BalanceListener() {
@Override
public void onBalanceChanged(Coin balance, Transaction tx) {
updateBalance();
}
});
updateBalance();
}
private void updateBalance() {
// Need to delay a bit to get the balances correct
UserThread.execute(() -> {
updateAvailableBalance();
updateReservedBalance();
updateLockedBalance();
});*/
updateAvailableBalance();
updateReservedBalance();
updateLockedBalance();
// TODO add lockingBalance
});
}
private void updateAvailableBalance() {
Coin totalAvailableBalance = Coin.valueOf(tradeManager.getAddressEntriesForAvailableBalanceStream()
.mapToLong(addressEntry -> btcWalletService.getBalanceForAddress(addressEntry.getAddress()).getValue())
.sum());
availableBalance.set(totalAvailableBalance);
long sum = tradeManager.getAddressEntriesForAvailableBalanceStream()
.mapToLong(addressEntry -> btcWalletService.getBalanceForAddress(addressEntry.getAddress()).value)
.sum();
availableBalance.set(Coin.valueOf(sum));
}
private void updateReservedBalance() {
Coin sum = Coin.valueOf(openOfferManager.getObservableList().stream()
.map(openOffer -> {
final Optional<AddressEntry> addressEntryOptional = btcWalletService.getAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE);
if (addressEntryOptional.isPresent()) {
Address address = addressEntryOptional.get().getAddress();
return btcWalletService.getBalanceForAddress(address);
} else {
return null;
}
})
long sum = openOfferManager.getObservableList().stream()
.map(openOffer -> btcWalletService.getAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE)
.orElse(null))
.filter(Objects::nonNull)
.mapToLong(Coin::getValue)
.sum());
reservedBalance.set(sum);
.mapToLong(addressEntry -> btcWalletService.getBalanceForAddress(addressEntry.getAddress()).value)
.sum();
reservedBalance.set(Coin.valueOf(sum));
}
private void updateLockedBalance() {
Stream<Trade> lockedTrades = Stream.concat(closedTradableManager.getLockedTradesStream(), failedTradesManager.getLockedTradesStream());
lockedTrades = Stream.concat(lockedTrades, tradeManager.getLockedTradesStream());
Coin sum = Coin.valueOf(lockedTrades
.mapToLong(trade -> {
final Optional<AddressEntry> addressEntryOptional = btcWalletService.getAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG);
return addressEntryOptional.map(addressEntry -> addressEntry.getCoinLockedInMultiSig().getValue()).orElse(0L);
})
.sum());
lockedBalance.set(sum);
long sum = lockedTrades.map(trade -> btcWalletService.getAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG)
.orElse(null))
.filter(Objects::nonNull)
.mapToLong(addressEntry -> addressEntry.getCoinLockedInMultiSig().getValue())
.sum();
lockedBalance.set(Coin.valueOf(sum));
}
}

View File

@ -19,7 +19,6 @@ package bisq.core.btc;
import bisq.core.app.AppOptionKeys;
import bisq.core.btc.model.AddressEntryList;
import bisq.core.btc.model.BalanceModel;
import bisq.core.btc.nodes.BtcNodes;
import bisq.core.btc.setup.RegTestHost;
import bisq.core.btc.setup.WalletsSetup;
@ -78,7 +77,7 @@ public class BitcoinModule extends AppModule {
bind(BsqCoinSelector.class).in(Singleton.class);
bind(NonBsqCoinSelector.class).in(Singleton.class);
bind(BtcNodes.class).in(Singleton.class);
bind(BalanceModel.class).in(Singleton.class);
bind(Balances.class).in(Singleton.class);
bind(PriceNodeHttpClient.class).in(Singleton.class);

View File

@ -17,7 +17,7 @@
package bisq.core.presentation;
import bisq.core.btc.model.BalanceModel;
import bisq.core.btc.Balances;
import bisq.core.util.BSFormatter;
import javax.inject.Inject;
@ -26,7 +26,9 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class BalancePresentation {
@Getter
private final StringProperty availableBalance = new SimpleStringProperty();
@ -36,8 +38,8 @@ public class BalancePresentation {
private final StringProperty lockedBalance = new SimpleStringProperty();
@Inject
public BalancePresentation(BalanceModel balanceModel, BSFormatter formatter) {
balanceModel.getAvailableBalance().addListener((observable, oldValue, newValue) -> {
public BalancePresentation(Balances balances, BSFormatter formatter) {
balances.getAvailableBalance().addListener((observable, oldValue, newValue) -> {
String value = formatter.formatCoinWithCode(newValue);
// If we get full precision the BTC postfix breaks layout so we omit it
if (value.length() > 11)
@ -45,10 +47,10 @@ public class BalancePresentation {
availableBalance.set(value);
});
balanceModel.getReservedBalance().addListener((observable, oldValue, newValue) -> {
balances.getReservedBalance().addListener((observable, oldValue, newValue) -> {
reservedBalance.set(formatter.formatCoinWithCode(newValue));
});
balanceModel.getLockedBalance().addListener((observable, oldValue, newValue) -> {
balances.getLockedBalance().addListener((observable, oldValue, newValue) -> {
lockedBalance.set(formatter.formatCoinWithCode(newValue));
});
}

View File

@ -239,6 +239,13 @@ public class TradeManager implements PersistedDataHost {
tradableList.getList().addListener((ListChangeListener<Trade>) change -> onTradesChanged());
onTradesChanged();
getAddressEntriesForAvailableBalanceStream()
.filter(addressEntry -> addressEntry.getOfferId() != null)
.forEach(addressEntry -> {
log.warn("Swapping pending OFFER_FUNDING entries at startup. offerId={}", addressEntry.getOfferId());
btcWalletService.swapTradeEntryToAvailableEntry(addressEntry.getOfferId(), AddressEntry.Context.OFFER_FUNDING);
});
}
public void shutDown() {