mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Add statistics dump for offers
This commit is contained in:
parent
5c86e6ed5d
commit
814bf8d065
@ -76,6 +76,13 @@ public class Storage<T extends Serializable> {
|
||||
this.dir = dir;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public void initWithFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
storageFile = new File(dir, fileName);
|
||||
fileManager = new FileManager<>(dir, storageFile, 300);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T initAndGetPersistedWithFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
|
46
core/src/main/java/io/bitsquare/trade/offer/FlatOffer.java
Normal file
46
core/src/main/java/io/bitsquare/trade/offer/FlatOffer.java
Normal file
@ -0,0 +1,46 @@
|
||||
package io.bitsquare.trade.offer;
|
||||
|
||||
import io.bitsquare.payment.PaymentMethod;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.utils.Fiat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class FlatOffer {
|
||||
public final Offer.Direction direction;
|
||||
public final String currencyCode;
|
||||
public final long minAmount;
|
||||
public final long amount;
|
||||
public final long price;
|
||||
public final long date;
|
||||
public final boolean useMarketBasedPrice;
|
||||
public final double marketPriceMargin;
|
||||
public final String paymentMethod;
|
||||
public final String id;
|
||||
public final String offerFeeTxID;
|
||||
|
||||
public FlatOffer(Offer.Direction direction,
|
||||
String currencyCode,
|
||||
Coin minAmount,
|
||||
Coin amount,
|
||||
Fiat price,
|
||||
Date date,
|
||||
String id,
|
||||
boolean useMarketBasedPrice,
|
||||
double marketPriceMargin,
|
||||
PaymentMethod paymentMethod,
|
||||
String offerFeeTxID) {
|
||||
|
||||
this.direction = direction;
|
||||
this.currencyCode = currencyCode;
|
||||
this.minAmount = minAmount.value;
|
||||
this.amount = amount.value;
|
||||
this.price = price.value;
|
||||
this.date = date.getTime();
|
||||
this.id = id;
|
||||
this.useMarketBasedPrice = useMarketBasedPrice;
|
||||
this.marketPriceMargin = marketPriceMargin;
|
||||
this.paymentMethod = paymentMethod.getId();
|
||||
this.offerFeeTxID = offerFeeTxID;
|
||||
}
|
||||
}
|
@ -17,12 +17,19 @@
|
||||
|
||||
package io.bitsquare.trade.offer;
|
||||
|
||||
import com.google.inject.name.Named;
|
||||
import io.bitsquare.app.CoreOptionKeys;
|
||||
import io.bitsquare.btc.pricefeed.PriceFeedService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.p2p.BootstrapListener;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
import io.bitsquare.p2p.storage.HashMapChangedListener;
|
||||
import io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry;
|
||||
import io.bitsquare.storage.JsonString;
|
||||
import io.bitsquare.storage.Storage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -47,6 +54,7 @@ public class OfferBookService {
|
||||
|
||||
private final P2PService p2PService;
|
||||
private PriceFeedService priceFeedService;
|
||||
private final Storage<JsonString> offersJsonStorage;
|
||||
private final List<OfferBookChangedListener> offerBookChangedListeners = new LinkedList<>();
|
||||
|
||||
|
||||
@ -55,9 +63,13 @@ public class OfferBookService {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public OfferBookService(P2PService p2PService, PriceFeedService priceFeedService) {
|
||||
public OfferBookService(P2PService p2PService,
|
||||
PriceFeedService priceFeedService,
|
||||
Storage<JsonString> offersJsonStorage,
|
||||
@Named(CoreOptionKeys.DUMP_STATISTICS) boolean dumpStatistics) {
|
||||
this.p2PService = p2PService;
|
||||
this.priceFeedService = priceFeedService;
|
||||
this.offersJsonStorage = offersJsonStorage;
|
||||
|
||||
p2PService.addHashSetChangedListener(new HashMapChangedListener() {
|
||||
@Override
|
||||
@ -79,10 +91,28 @@ public class OfferBookService {
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addOfferBookChangedListener(OfferBookChangedListener offerBookChangedListener) {
|
||||
offerBookChangedListeners.add(offerBookChangedListener);
|
||||
if (dumpStatistics) {
|
||||
this.offersJsonStorage.initWithFileName("offers_statistics.json");
|
||||
|
||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||
@Override
|
||||
public void onBootstrapComplete() {
|
||||
addOfferBookChangedListener(new OfferBookChangedListener() {
|
||||
@Override
|
||||
public void onAdded(Offer offer) {
|
||||
doDumpStatistics();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoved(Offer offer) {
|
||||
doDumpStatistics();
|
||||
}
|
||||
});
|
||||
UserThread.runAfter(OfferBookService.this::doDumpStatistics, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -140,4 +170,41 @@ public class OfferBookService {
|
||||
public boolean isBootstrapped() {
|
||||
return p2PService.isBootstrapped();
|
||||
}
|
||||
|
||||
public void addOfferBookChangedListener(OfferBookChangedListener offerBookChangedListener) {
|
||||
offerBookChangedListeners.add(offerBookChangedListener);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void doDumpStatistics() {
|
||||
final List<FlatOffer> flatOffers = getOffers().stream()
|
||||
.filter(offer -> !offer.getUseMarketBasedPrice() || priceFeedService.getMarketPrice(offer.getCurrencyCode()) != null)
|
||||
.map(offer -> {
|
||||
try {
|
||||
return new FlatOffer(offer.getDirection(),
|
||||
offer.getCurrencyCode(),
|
||||
offer.getMinAmount(),
|
||||
offer.getAmount(),
|
||||
offer.getPrice(),
|
||||
offer.getDate(),
|
||||
offer.getId(),
|
||||
offer.getUseMarketBasedPrice(),
|
||||
offer.getMarketPriceMargin(),
|
||||
offer.getPaymentMethod(),
|
||||
offer.getOfferFeePaymentTxID()
|
||||
);
|
||||
} catch (Throwable t) {
|
||||
// In case a offer was corrupted with null values we ignore it
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.filter(e -> e != null)
|
||||
.collect(Collectors.toList());
|
||||
offersJsonStorage.queueUpForSave(new JsonString(Utilities.objectToJson(flatOffers)), 5000);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,15 +47,15 @@ public class TradeStatisticsManager {
|
||||
this.dumpStatistics = dumpStatistics;
|
||||
|
||||
if (dumpStatistics) {
|
||||
this.statisticsJsonStorage.initAndGetPersistedWithFileName("trade_statistics.json");
|
||||
this.statisticsJsonStorage.initWithFileName("trade_statistics.json");
|
||||
|
||||
this.fiatCurrencyListJsonStorage.initAndGetPersistedWithFileName("fiat_currency_list.json");
|
||||
this.fiatCurrencyListJsonStorage.initWithFileName("fiat_currency_list.json");
|
||||
ArrayList<CurrencyTuple> fiatCurrencyList = new ArrayList<>(CurrencyUtil.getAllSortedFiatCurrencies().stream()
|
||||
.map(e -> new CurrencyTuple(e.getCode(), e.getName()))
|
||||
.collect(Collectors.toList()));
|
||||
fiatCurrencyListJsonStorage.queueUpForSave(new JsonString(Utilities.objectToJson(fiatCurrencyList)), 2000);
|
||||
|
||||
this.cryptoCurrencyListJsonStorage.initAndGetPersistedWithFileName("crypto_currency_list.json");
|
||||
this.cryptoCurrencyListJsonStorage.initWithFileName("crypto_currency_list.json");
|
||||
ArrayList<CurrencyTuple> cryptoCurrencyList = new ArrayList<>(CurrencyUtil.getAllSortedCryptoCurrencies().stream()
|
||||
.map(e -> new CurrencyTuple(e.getCode(), e.getName()))
|
||||
.collect(Collectors.toList()));
|
||||
|
@ -13,8 +13,8 @@ import io.bitsquare.common.CommonOptionKeys;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.p2p.BootstrapListener;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
import io.bitsquare.p2p.P2PServiceListener;
|
||||
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||
import io.bitsquare.trade.statistics.TradeStatisticsManager;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
@ -74,49 +74,9 @@ public class SeedNode {
|
||||
injector = Guice.createInjector(seedNodeModule);
|
||||
Version.setBtcNetworkId(injector.getInstance(BitsquareEnvironment.class).getBitcoinNetwork().ordinal());
|
||||
p2pService = injector.getInstance(P2PService.class);
|
||||
p2pService.start(false, new P2PServiceListener() {
|
||||
@Override
|
||||
public void onRequestingDataCompleted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNoSeedNodeAvailable() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNoPeersAvailable() {
|
||||
|
||||
}
|
||||
|
||||
p2pService.start(false, new BootstrapListener() {
|
||||
@Override
|
||||
public void onBootstrapComplete() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTorNodeReady() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHiddenServicePublished() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetupFailed(Throwable throwable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUseDefaultBridges() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestCustomBridges(Runnable resultHandler) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -9,12 +9,15 @@ import io.bitsquare.app.Log;
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.pricefeed.PriceFeedService;
|
||||
import io.bitsquare.common.CommonOptionKeys;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import io.bitsquare.p2p.BootstrapListener;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
import io.bitsquare.p2p.P2PServiceListener;
|
||||
import io.bitsquare.trade.offer.OfferBookService;
|
||||
import io.bitsquare.trade.offer.OpenOfferManager;
|
||||
import io.bitsquare.trade.statistics.TradeStatisticsManager;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
@ -33,6 +36,8 @@ public class Statistics {
|
||||
private final Injector injector;
|
||||
private final StatisticsModule statisticsModule;
|
||||
private final TradeStatisticsManager tradeStatisticsManager;
|
||||
private final OfferBookService offerBookService;
|
||||
private final PriceFeedService priceFeedService;
|
||||
|
||||
private P2PService p2pService;
|
||||
|
||||
@ -74,54 +79,22 @@ public class Statistics {
|
||||
injector = Guice.createInjector(statisticsModule);
|
||||
Version.setBtcNetworkId(injector.getInstance(BitsquareEnvironment.class).getBitcoinNetwork().ordinal());
|
||||
p2pService = injector.getInstance(P2PService.class);
|
||||
p2pService.start(false, new P2PServiceListener() {
|
||||
@Override
|
||||
public void onRequestingDataCompleted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNoSeedNodeAvailable() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNoPeersAvailable() {
|
||||
|
||||
}
|
||||
|
||||
p2pService.start(false, new BootstrapListener() {
|
||||
@Override
|
||||
public void onBootstrapComplete() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTorNodeReady() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHiddenServicePublished() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetupFailed(Throwable throwable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUseDefaultBridges() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestCustomBridges(Runnable resultHandler) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// We want to persist trade statistics so we need to instantiate the tradeStatisticsManager
|
||||
tradeStatisticsManager = injector.getInstance(TradeStatisticsManager.class);
|
||||
offerBookService = injector.getInstance(OfferBookService.class);
|
||||
priceFeedService = injector.getInstance(PriceFeedService.class);
|
||||
|
||||
// We need the price feed for market based offers
|
||||
priceFeedService.setCurrencyCode(CurrencyUtil.getDefaultTradeCurrency().getCode());
|
||||
priceFeedService.setType(PriceFeedService.Type.LAST);
|
||||
priceFeedService.init(price -> log.debug("price " + price),
|
||||
(errorMessage, throwable) -> log.warn(throwable.getMessage()));
|
||||
}
|
||||
|
||||
public void shutDown() {
|
||||
|
Loading…
Reference in New Issue
Block a user