Fix bug in AddressEntryList, add TradeStatisticsList

This commit is contained in:
Manfred Karrer 2017-05-13 23:24:27 +02:00
parent 62f5f3522c
commit c2c64d9e9d
8 changed files with 87 additions and 36 deletions

View File

@ -43,8 +43,7 @@ public final class AddressEntryList implements PersistableEnvelope, PersistedDat
transient private Storage<AddressEntryList> storage;
transient private Wallet wallet;
@Getter
private List<AddressEntry> list = new ArrayList<>();
private List<AddressEntry> persistedList;
private List<AddressEntry> list;
@Inject
public AddressEntryList(Storage<AddressEntryList> storage) {
@ -55,7 +54,7 @@ public final class AddressEntryList implements PersistableEnvelope, PersistedDat
public void readPersisted() {
AddressEntryList persisted = storage.initAndGetPersisted(this);
if (persisted != null)
persistedList = persisted.getList();
list = persisted.getList();
}
@ -89,8 +88,8 @@ public final class AddressEntryList implements PersistableEnvelope, PersistedDat
public void onWalletReady(Wallet wallet) {
this.wallet = wallet;
if (persistedList != null) {
persistedList.stream().forEach(addressEntry -> {
if (list != null) {
list.stream().forEach(addressEntry -> {
DeterministicKey keyFromPubHash = (DeterministicKey) wallet.findKeyFromPubHash(addressEntry.getPubKeyHash());
if (keyFromPubHash != null) {
addressEntry.setDeterministicKey(keyFromPubHash);
@ -99,6 +98,7 @@ public final class AddressEntryList implements PersistableEnvelope, PersistedDat
}
});
} else {
list = new ArrayList<>();
add(new AddressEntry(wallet.freshReceiveKey(), AddressEntry.Context.ARBITRATOR));
persist();
}

View File

@ -282,7 +282,7 @@ public final class OfferPayload implements StoragePayload, RequiresOwnerIsOnline
}
public static OfferPayload fromProto(PB.OfferPayload proto) {
checkArgument(proto.getOfferFeePaymentTxId().isEmpty(), "OfferFeePaymentTxId must be set in PB.OfferPayload");
checkArgument(!proto.getOfferFeePaymentTxId().isEmpty(), "OfferFeePaymentTxId must be set in PB.OfferPayload");
String countryCode = proto.getCountryCode().isEmpty() ? null : proto.getCountryCode();
String bankId = proto.getBankId().isEmpty() ? null : proto.getBankId();
List<String> acceptedBankIds = proto.getAcceptedBankIdsList().isEmpty() ?

View File

@ -4,7 +4,6 @@ import com.google.inject.Provider;
import io.bisq.common.locale.*;
import io.bisq.common.proto.ProtobufferException;
import io.bisq.common.proto.persistable.PersistableEnvelope;
import io.bisq.common.proto.persistable.PersistableList;
import io.bisq.common.proto.persistable.PersistableViewPath;
import io.bisq.common.proto.persistable.PersistenceProtoResolver;
import io.bisq.common.storage.Storage;
@ -15,7 +14,7 @@ import io.bisq.core.offer.OpenOffer;
import io.bisq.core.payment.PaymentAccount;
import io.bisq.core.proto.CoreProtoResolver;
import io.bisq.core.trade.*;
import io.bisq.core.trade.statistics.TradeStatistics;
import io.bisq.core.trade.statistics.TradeStatisticsList;
import io.bisq.core.user.BlockChainExplorer;
import io.bisq.core.user.Preferences;
import io.bisq.core.user.UserPayload;
@ -28,7 +27,6 @@ import javax.inject.Inject;
import javax.inject.Named;
import java.io.File;
import java.util.HashMap;
import java.util.stream.Collectors;
@Slf4j
public class CorePersistenceProtoResolver extends CoreProtoResolver implements PersistenceProtoResolver {
@ -56,7 +54,7 @@ public class CorePersistenceProtoResolver extends CoreProtoResolver implements P
@Override
public PersistableEnvelope fromProto(PB.PersistableEnvelope proto) {
log.debug("Convert protobuffer disk proto: {}", proto.getMessageCase());
log.error("Convert protobuffer disk proto: {}", proto.getMessageCase());
switch (proto.getMessageCase()) {
case ADDRESS_ENTRY_LIST:
@ -77,7 +75,7 @@ public class CorePersistenceProtoResolver extends CoreProtoResolver implements P
case SEQUENCE_NUMBER_MAP:
return SequenceNumberMap.fromProto(proto.getSequenceNumberMap());
case TRADE_STATISTICS_LIST:
return getTradeStatisticsList(proto.getTradeStatisticsList());
return TradeStatisticsList.fromProto(proto.getTradeStatisticsList());
default:
throw new ProtobufferException("Unknown proto message case. messageCase=" + proto.getMessageCase());
}
@ -88,11 +86,6 @@ public class CorePersistenceProtoResolver extends CoreProtoResolver implements P
return TradableList.fromProto(tradableList, openOfferStorage, buyerAsMakerTradeStorage, buyerAsTakerTradeStorage, sellerAsMakerTradeStorage, sellerAsTakerTradeStorage, btcWalletService.get());
}
private PersistableEnvelope getTradeStatisticsList(PB.TradeStatisticsList tradeStatisticsList) {
return new PersistableList<>(tradeStatisticsList.getTradeStatisticsList().stream()
.map(TradeStatistics::fromProto).collect(Collectors.toList()));
}
private Preferences fillPreferences(PB.PersistableEnvelope envelope, Preferences preferences) {
final PB.Preferences env = envelope.getPreferences();
preferences.setUserLanguage(env.getUserLanguage());

View File

@ -143,6 +143,10 @@ public final class TradeStatistics implements LazyProcessedStoragePayload, Persi
return PB.StoragePayload.newBuilder().setTradeStatistics(builder).build();
}
public PB.TradeStatistics toProtoTradeStatistics() {
return toProtoMessage().getTradeStatistics();
}
public static TradeStatistics fromProto(PB.TradeStatistics proto) {
return new TradeStatistics(
OfferPayload.Direction.fromProto(proto.getDirection()),

View File

@ -0,0 +1,46 @@
/*
* 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.statistics;
import com.google.protobuf.Message;
import io.bisq.common.proto.persistable.PersistableEnvelope;
import io.bisq.common.proto.persistable.PersistableList;
import io.bisq.generated.protobuffer.PB;
import java.util.List;
import java.util.stream.Collectors;
public class TradeStatisticsList extends PersistableList<TradeStatistics> {
public TradeStatisticsList(List<TradeStatistics> list) {
super(list);
}
@Override
public Message toProtoMessage() {
return PB.PersistableEnvelope.newBuilder()
.setTradeStatisticsList(PB.TradeStatisticsList.newBuilder()
.addAllTradeStatistics(getList().stream().map(TradeStatistics::toProtoTradeStatistics).collect(Collectors.toList())))
.build();
}
public static PersistableEnvelope fromProto(PB.TradeStatisticsList proto) {
return new TradeStatisticsList(proto.getTradeStatisticsList().stream().map(TradeStatistics::fromProto)
.collect(Collectors.toList()));
}
}

View File

@ -4,13 +4,11 @@ import com.google.inject.Inject;
import com.google.inject.name.Named;
import io.bisq.common.locale.CurrencyTuple;
import io.bisq.common.locale.CurrencyUtil;
import io.bisq.common.proto.ProtoCollectionUtil;
import io.bisq.common.proto.persistable.PersistableList;
import io.bisq.common.proto.persistable.PersistedDataHost;
import io.bisq.common.storage.PlainTextWrapper;
import io.bisq.common.storage.Storage;
import io.bisq.common.util.Utilities;
import io.bisq.core.app.AppOptionKeys;
import io.bisq.generated.protobuffer.PB;
import io.bisq.network.p2p.P2PService;
import io.bisq.network.p2p.storage.HashMapChangedListener;
import io.bisq.network.p2p.storage.payload.ProtectedStorageEntry;
@ -25,19 +23,21 @@ import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
public class TradeStatisticsManager {
public class TradeStatisticsManager implements PersistedDataHost {
private static final Logger log = LoggerFactory.getLogger(TradeStatisticsManager.class);
private final Storage<PersistableList<TradeStatistics>> statisticsStorage;
private final Storage<TradeStatisticsList> statisticsStorage;
private final Storage<PlainTextWrapper> fiatCurrencyListJsonStorage;
private final Storage<PlainTextWrapper> cryptoCurrencyListJsonStorage;
private final Storage<PlainTextWrapper> statisticsJsonStorage;
private P2PService p2PService;
private final boolean dumpStatistics;
private final ObservableSet<TradeStatistics> observableTradeStatisticsSet = FXCollections.observableSet();
private final HashSet<TradeStatistics> tradeStatisticsSet = new HashSet<>();
private List<TradeStatistics> persistedTradeStatisticsList;
@Inject
public TradeStatisticsManager(Storage<PersistableList<TradeStatistics>> statisticsStorage,
public TradeStatisticsManager(Storage<TradeStatisticsList> statisticsStorage,
Storage<PlainTextWrapper> fiatCurrencyListJsonStorage,
Storage<PlainTextWrapper> cryptoCurrencyListJsonStorage,
Storage<PlainTextWrapper> statisticsJsonStorage,
@ -47,13 +47,20 @@ public class TradeStatisticsManager {
this.fiatCurrencyListJsonStorage = fiatCurrencyListJsonStorage;
this.cryptoCurrencyListJsonStorage = cryptoCurrencyListJsonStorage;
this.statisticsJsonStorage = statisticsJsonStorage;
this.p2PService = p2PService;
this.dumpStatistics = dumpStatistics;
init(p2PService);
statisticsStorage.setNumMaxBackupFiles(1);
}
private void init(P2PService p2PService) {
statisticsStorage.setNumMaxBackupFiles(1);
@Override
public void readPersisted() {
TradeStatisticsList persisted = statisticsStorage.initAndGetPersistedWithFileName("TradeStatistics");
if (persisted != null)
persistedTradeStatisticsList = persisted.getList();
}
public void onAllServicesInitialized() {
if (dumpStatistics) {
this.statisticsJsonStorage.initWithFileName("trade_statistics.json");
@ -71,9 +78,8 @@ public class TradeStatisticsManager {
cryptoCurrencyListJsonStorage.queueUpForSave(new PlainTextWrapper(Utilities.objectToJson(cryptoCurrencyList)), 2000);
}
PersistableList<TradeStatistics> persisted = statisticsStorage.initAndGetPersistedWithFileName("TradeStatistics");
if (persisted != null)
persisted.getList().stream().forEach(e -> add(e, false));
if (persistedTradeStatisticsList != null)
persistedTradeStatisticsList.stream().forEach(e -> add(e, false));
p2PService.addHashSetChangedListener(new HashMapChangedListener() {
@Override
@ -104,13 +110,8 @@ public class TradeStatisticsManager {
tradeStatisticsSet.add(tradeStatistics);
observableTradeStatisticsSet.add(tradeStatistics);
if (storeLocally) {
PersistableList<TradeStatistics> serializable = new PersistableList<>(tradeStatisticsSet);
serializable.setToProto((list) -> PB.PersistableEnvelope.newBuilder()
.setTradeStatisticsList(PB.TradeStatisticsList.newBuilder()
.addAllTradeStatistics(ProtoCollectionUtil.collectionToProto(list))).build());
statisticsStorage.queueUpForSave(serializable, 2000);
}
if (storeLocally)
statisticsStorage.queueUpForSave(new TradeStatisticsList(new ArrayList<>(tradeStatisticsSet)), 2000);
dump();
} else {

View File

@ -43,6 +43,7 @@ import io.bisq.core.dao.blockchain.json.JsonChainStateExporter;
import io.bisq.core.filter.FilterManager;
import io.bisq.core.offer.OpenOfferManager;
import io.bisq.core.trade.TradeManager;
import io.bisq.core.trade.statistics.TradeStatisticsManager;
import io.bisq.core.user.Preferences;
import io.bisq.core.user.User;
import io.bisq.gui.Navigation;
@ -179,6 +180,7 @@ public class BisqApp extends Application {
ArrayList<PersistedDataHost> persistedDataHosts = new ArrayList<>();
persistedDataHosts.add(injector.getInstance(Navigation.class));
persistedDataHosts.add(injector.getInstance(AddressEntryList.class));
persistedDataHosts.add(injector.getInstance(TradeStatisticsManager.class));
// we apply at startup the reading of persisted data but don't want to get it triggered in the constructor
persistedDataHosts.stream().forEach(PersistedDataHost::readPersisted);

View File

@ -56,6 +56,7 @@ import io.bisq.core.provider.price.MarketPrice;
import io.bisq.core.provider.price.PriceFeedService;
import io.bisq.core.trade.Trade;
import io.bisq.core.trade.TradeManager;
import io.bisq.core.trade.statistics.TradeStatisticsManager;
import io.bisq.core.user.DontShowAgainLookup;
import io.bisq.core.user.Preferences;
import io.bisq.core.user.User;
@ -117,6 +118,7 @@ public class MainViewModel implements ViewModel {
@SuppressWarnings("unused")
private final FilterManager filterManager;
private final WalletPasswordWindow walletPasswordWindow;
private final TradeStatisticsManager tradeStatisticsManager;
private final NotificationCenter notificationCenter;
private final TacWindow tacWindow;
private final Clock clock;
@ -185,7 +187,7 @@ public class MainViewModel implements ViewModel {
ArbitratorManager arbitratorManager, P2PService p2PService, TradeManager tradeManager,
OpenOfferManager openOfferManager, DisputeManager disputeManager, Preferences preferences,
User user, AlertManager alertManager, PrivateNotificationManager privateNotificationManager,
FilterManager filterManager, WalletPasswordWindow walletPasswordWindow,
FilterManager filterManager, WalletPasswordWindow walletPasswordWindow, TradeStatisticsManager tradeStatisticsManager,
NotificationCenter notificationCenter, TacWindow tacWindow, Clock clock, FeeService feeService,
DaoManager daoManager, EncryptionService encryptionService,
KeyRing keyRing,
@ -205,6 +207,7 @@ public class MainViewModel implements ViewModel {
this.privateNotificationManager = privateNotificationManager;
this.filterManager = filterManager; // Reference so it's initialized and eventListener gets registered
this.walletPasswordWindow = walletPasswordWindow;
this.tradeStatisticsManager = tradeStatisticsManager;
this.notificationCenter = notificationCenter;
this.tacWindow = tacWindow;
this.clock = clock;
@ -554,6 +557,8 @@ public class MainViewModel implements ViewModel {
daoManager.onAllServicesInitialized(errorMessage -> new Popup<>().error(errorMessage).show());
tradeStatisticsManager.onAllServicesInitialized();
priceFeedService.onAllServicesInitialized();
setupBtcNumPeersWatcher();