Search in sources :

Example 6 with ProtectedStorageEntry

use of io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry in project bitsquare by bitsquare.

the class RequestDataHandler method onMessage.

///////////////////////////////////////////////////////////////////////////////////////////
// MessageListener implementation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onMessage(Message message, Connection connection) {
    if (connection.getPeersNodeAddressOptional().isPresent() && connection.getPeersNodeAddressOptional().get().equals(peersNodeAddress)) {
        if (message instanceof GetDataResponse) {
            Log.traceCall(message.toString() + "\n\tconnection=" + connection);
            if (!stopped) {
                GetDataResponse getDataResponse = (GetDataResponse) message;
                Map<String, Set<StoragePayload>> payloadByClassName = new HashMap<>();
                final HashSet<ProtectedStorageEntry> dataSet = getDataResponse.dataSet;
                dataSet.stream().forEach(e -> {
                    final StoragePayload storagePayload = e.getStoragePayload();
                    String className = storagePayload.getClass().getSimpleName();
                    if (!payloadByClassName.containsKey(className))
                        payloadByClassName.put(className, new HashSet<>());
                    payloadByClassName.get(className).add(storagePayload);
                });
                StringBuilder sb = new StringBuilder("Received data size: ").append(dataSet.size()).append(", data items: ");
                payloadByClassName.entrySet().stream().forEach(e -> sb.append(e.getValue().size()).append(" items of ").append(e.getKey()).append("; "));
                log.info(sb.toString());
                if (getDataResponse.requestNonce == nonce) {
                    stopTimeoutTimer();
                    checkArgument(connection.getPeersNodeAddressOptional().isPresent(), "RequestDataHandler.onMessage: connection.getPeersNodeAddressOptional() must be present " + "at that moment");
                    final NodeAddress sender = connection.getPeersNodeAddressOptional().get();
                    List<ProtectedStorageEntry> processDelayedItems = new ArrayList<>();
                    dataSet.stream().forEach(e -> {
                        if (e.getStoragePayload() instanceof LazyProcessedStoragePayload)
                            processDelayedItems.add(e);
                        else {
                            dataStorage.add(e, sender, null, false, false);
                        }
                    });
                    // We process the LazyProcessedStoragePayload items (TradeStatistics) in batches with a delay in between.
                    // We want avoid that the UI get stuck when processing many entries.
                    // The dataStorage.add call is a bit expensive as sig checks is done there.
                    // Using a background thread might be an alternative but it would require much more effort and 
                    // it would also decrease user experience if the app gets under heavy load (like at startup with wallet sync).
                    // Beside that we mitigated the problem already as we will not get the whole TradeStatistics as we 
                    // pass the excludeKeys and we pack the latest data dump 
                    // into the resources, so a new user do not need to request all data.
                    // In future we will probably limit by date or load on demand from user intent to not get too much data.
                    // We split the list into sub lists with max 50 items and delay each batch with 200 ms.
                    int size = processDelayedItems.size();
                    int chunkSize = 50;
                    int chunks = 1 + size / chunkSize;
                    int startIndex = 0;
                    for (int i = 0; i < chunks && startIndex < size; i++, startIndex += chunkSize) {
                        long delay = (i + 1) * 200;
                        int endIndex = Math.min(size, startIndex + chunkSize);
                        List<ProtectedStorageEntry> subList = processDelayedItems.subList(startIndex, endIndex);
                        UserThread.runAfter(() -> {
                            subList.stream().forEach(protectedStorageEntry -> dataStorage.add(protectedStorageEntry, sender, null, false, false));
                        }, delay, TimeUnit.MILLISECONDS);
                    }
                    cleanup();
                    listener.onComplete();
                } else {
                    log.debug("Nonce not matching. That can happen rarely if we get a response after a canceled " + "handshake (timeout causes connection close but peer might have sent a msg before " + "connection was closed).\n\t" + "We drop that message. nonce={} / requestNonce={}", nonce, getDataResponse.requestNonce);
                }
            } else {
                log.warn("We have stopped already. We ignore that onDataRequest call.");
            }
        }
    } else {
        log.trace("We got a message from another connection and ignore it.");
    }
}
Also used : LazyProcessedStoragePayload(io.bitsquare.p2p.storage.payload.LazyProcessedStoragePayload) GetDataResponse(io.bitsquare.p2p.peers.getdata.messages.GetDataResponse) NodeAddress(io.bitsquare.p2p.NodeAddress) PersistedStoragePayload(io.bitsquare.p2p.storage.payload.PersistedStoragePayload) StoragePayload(io.bitsquare.p2p.storage.payload.StoragePayload) LazyProcessedStoragePayload(io.bitsquare.p2p.storage.payload.LazyProcessedStoragePayload) ProtectedStorageEntry(io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry)

Example 7 with ProtectedStorageEntry

use of io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry in project bitsquare by bitsquare.

the class P2PService method addData.

///////////////////////////////////////////////////////////////////////////////////////////
// Data storage
///////////////////////////////////////////////////////////////////////////////////////////
public boolean addData(StoragePayload storagePayload, boolean isDataOwner) {
    Log.traceCall();
    checkArgument(optionalKeyRing.isPresent(), "keyRing not set. Seems that is called on a seed node which must not happen.");
    if (isBootstrapped()) {
        try {
            ProtectedStorageEntry protectedStorageEntry = p2PDataStorage.getProtectedData(storagePayload, optionalKeyRing.get().getSignatureKeyPair());
            return p2PDataStorage.add(protectedStorageEntry, networkNode.getNodeAddress(), null, isDataOwner);
        } catch (CryptoException e) {
            log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
            return false;
        }
    } else {
        throw new NetworkNotReadyException();
    }
}
Also used : CryptoException(io.bitsquare.common.crypto.CryptoException) ProtectedStorageEntry(io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry)

Example 8 with ProtectedStorageEntry

use of io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry in project bitsquare by bitsquare.

the class TradeStatisticsManager method init.

private void init(P2PService p2PService) {
    if (dumpStatistics) {
        this.statisticsJsonStorage.initWithFileName("trade_statistics.json");
        this.fiatCurrencyListJsonStorage.initWithFileName("fiat_currency_list.json");
        ArrayList<CurrencyTuple> fiatCurrencyList = new ArrayList<>(CurrencyUtil.getAllSortedFiatCurrencies().stream().map(e -> new CurrencyTuple(e.getCode(), e.getName(), 8)).collect(Collectors.toList()));
        fiatCurrencyListJsonStorage.queueUpForSave(new PlainTextWrapper(Utilities.objectToJson(fiatCurrencyList)), 2000);
        this.cryptoCurrencyListJsonStorage.initWithFileName("crypto_currency_list.json");
        ArrayList<CurrencyTuple> cryptoCurrencyList = new ArrayList<>(CurrencyUtil.getAllSortedCryptoCurrencies().stream().map(e -> new CurrencyTuple(e.getCode(), e.getName(), 8)).collect(Collectors.toList()));
        cryptoCurrencyList.add(0, new CurrencyTuple("BTC", "Bitcoin", 8));
        cryptoCurrencyListJsonStorage.queueUpForSave(new PlainTextWrapper(Utilities.objectToJson(cryptoCurrencyList)), 2000);
    }
    HashSet<TradeStatistics> persisted = statisticsStorage.initAndGetPersistedWithFileName("TradeStatistics");
    if (persisted != null)
        persisted.stream().forEach(e -> add(e, false));
    p2PService.addHashSetChangedListener(new HashMapChangedListener() {

        @Override
        public void onAdded(ProtectedStorageEntry data) {
            final StoragePayload storagePayload = data.getStoragePayload();
            if (storagePayload instanceof TradeStatistics)
                add((TradeStatistics) storagePayload, true);
        }

        @Override
        public void onRemoved(ProtectedStorageEntry data) {
        // We don't remove items
        }
    });
    // At startup the P2PDataStorage inits earlier, otherwise we ge the listener called.
    p2PService.getP2PDataStorage().getMap().values().forEach(e -> {
        final StoragePayload storagePayload = e.getStoragePayload();
        if (storagePayload instanceof TradeStatistics)
            add((TradeStatistics) storagePayload, false);
    });
}
Also used : CurrencyTuple(io.bitsquare.locale.CurrencyTuple) ObservableSet(javafx.collections.ObservableSet) Utilities(io.bitsquare.common.util.Utilities) Logger(org.slf4j.Logger) P2PService(io.bitsquare.p2p.P2PService) Inject(com.google.inject.Inject) ProtectedStorageEntry(io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry) LoggerFactory(org.slf4j.LoggerFactory) FXCollections(javafx.collections.FXCollections) HashMapChangedListener(io.bitsquare.p2p.storage.HashMapChangedListener) StoragePayload(io.bitsquare.p2p.storage.payload.StoragePayload) Collectors(java.util.stream.Collectors) AppOptionKeys(io.bitsquare.app.AppOptionKeys) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) List(java.util.List) PlainTextWrapper(io.bitsquare.storage.PlainTextWrapper) Named(com.google.inject.name.Named) Storage(io.bitsquare.storage.Storage) CurrencyUtil(io.bitsquare.locale.CurrencyUtil) CurrencyTuple(io.bitsquare.locale.CurrencyTuple) HashMapChangedListener(io.bitsquare.p2p.storage.HashMapChangedListener) ArrayList(java.util.ArrayList) PlainTextWrapper(io.bitsquare.storage.PlainTextWrapper) StoragePayload(io.bitsquare.p2p.storage.payload.StoragePayload) ProtectedStorageEntry(io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry)

Example 9 with ProtectedStorageEntry

use of io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry in project bitsquare by bitsquare.

the class P2PService method removeData.

public boolean removeData(StoragePayload storagePayload, boolean isDataOwner) {
    Log.traceCall();
    checkArgument(optionalKeyRing.isPresent(), "keyRing not set. Seems that is called on a seed node which must not happen.");
    if (isBootstrapped()) {
        try {
            ProtectedStorageEntry protectedStorageEntry = p2PDataStorage.getProtectedData(storagePayload, optionalKeyRing.get().getSignatureKeyPair());
            return p2PDataStorage.remove(protectedStorageEntry, networkNode.getNodeAddress(), isDataOwner);
        } catch (CryptoException e) {
            log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
            return false;
        }
    } else {
        throw new NetworkNotReadyException();
    }
}
Also used : CryptoException(io.bitsquare.common.crypto.CryptoException) ProtectedStorageEntry(io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry)

Example 10 with ProtectedStorageEntry

use of io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry in project bitsquare by bitsquare.

the class P2PDataStorage method printData.

private void printData(String info) {
    if (LoggerFactory.getLogger(Log.class).isInfoEnabled() || LoggerFactory.getLogger(Log.class).isDebugEnabled()) {
        StringBuilder sb = new StringBuilder("\n\n------------------------------------------------------------\n");
        sb.append("Data set ").append(info).append(" operation");
        // We print the items sorted by hash with the payload class name and id
        List<Tuple2<String, ProtectedStorageEntry>> tempList = map.values().stream().map(e -> new Tuple2<>(org.bitcoinj.core.Utils.HEX.encode(getHashAsByteArray(e.getStoragePayload()).bytes), e)).collect(Collectors.toList());
        tempList.sort((o1, o2) -> o1.first.compareTo(o2.first));
        tempList.stream().forEach(e -> {
            final ProtectedStorageEntry storageEntry = e.second;
            final StoragePayload storagePayload = storageEntry.getStoragePayload();
            final MapValue mapValue = sequenceNumberMap.get(getHashAsByteArray(storagePayload));
            sb.append("\n").append("Hash=").append(e.first).append("; Class=").append(storagePayload.getClass().getSimpleName()).append("; SequenceNumbers (Object/Stored)=").append(storageEntry.sequenceNumber).append(" / ").append(mapValue != null ? mapValue.sequenceNr : "null").append("; TimeStamp (Object/Stored)=").append(storageEntry.creationTimeStamp).append(" / ").append(mapValue != null ? mapValue.timeStamp : "null").append("; Payload=").append(Utilities.toTruncatedString(storagePayload));
        });
        sb.append("\n------------------------------------------------------------\n");
        log.debug(sb.toString());
        log.debug("Data set " + info + " operation: size=" + map.values().size());
    }
}
Also used : Version(io.bitsquare.app.Version) KeyPair(java.security.KeyPair) java.util(java.util) io.bitsquare.p2p.storage.payload(io.bitsquare.p2p.storage.payload) ProtectedStorageEntry(io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry) Hex(org.spongycastle.util.encoders.Hex) LoggerFactory(org.slf4j.LoggerFactory) Timer(io.bitsquare.common.Timer) Tuple2(io.bitsquare.common.util.Tuple2) CryptoException(io.bitsquare.common.crypto.CryptoException) StringUtils(org.apache.commons.lang3.StringUtils) io.bitsquare.p2p.network(io.bitsquare.p2p.network) ResourceNotFoundException(io.bitsquare.storage.ResourceNotFoundException) Nullable(javax.annotation.Nullable) Log(io.bitsquare.app.Log) Hash(io.bitsquare.common.crypto.Hash) BroadcastHandler(io.bitsquare.p2p.peers.BroadcastHandler) Utilities(io.bitsquare.common.util.Utilities) FileUtil(io.bitsquare.storage.FileUtil) Logger(org.slf4j.Logger) ProtectedMailboxStorageEntry(io.bitsquare.p2p.storage.storageentry.ProtectedMailboxStorageEntry) UserThread(io.bitsquare.common.UserThread) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Message(io.bitsquare.p2p.Message) NodeAddress(io.bitsquare.p2p.NodeAddress) IOException(java.io.IOException) PublicKey(java.security.PublicKey) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) Collectors(java.util.stream.Collectors) File(java.io.File) Sig(io.bitsquare.common.crypto.Sig) Serializable(java.io.Serializable) io.bitsquare.p2p.storage.messages(io.bitsquare.p2p.storage.messages) TimeUnit(java.util.concurrent.TimeUnit) Payload(io.bitsquare.common.wire.Payload) Broadcaster(io.bitsquare.p2p.peers.Broadcaster) Paths(java.nio.file.Paths) Storage(io.bitsquare.storage.Storage) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Persistable(io.bitsquare.common.persistance.Persistable) Tuple2(io.bitsquare.common.util.Tuple2) ProtectedStorageEntry(io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry)

Aggregations

ProtectedStorageEntry (io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry)13 CryptoException (io.bitsquare.common.crypto.CryptoException)4 Utilities (io.bitsquare.common.util.Utilities)3 NodeAddress (io.bitsquare.p2p.NodeAddress)3 StoragePayload (io.bitsquare.p2p.storage.payload.StoragePayload)3 ProtectedMailboxStorageEntry (io.bitsquare.p2p.storage.storageentry.ProtectedMailboxStorageEntry)3 Storage (io.bitsquare.storage.Storage)3 PublicKey (java.security.PublicKey)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 Log (io.bitsquare.app.Log)2 Version (io.bitsquare.app.Version)2 Timer (io.bitsquare.common.Timer)2 UserThread (io.bitsquare.common.UserThread)2 Hash (io.bitsquare.common.crypto.Hash)2 Sig (io.bitsquare.common.crypto.Sig)2 Persistable (io.bitsquare.common.persistance.Persistable)2 Tuple2 (io.bitsquare.common.util.Tuple2)2 Payload (io.bitsquare.common.wire.Payload)2 Message (io.bitsquare.p2p.Message)2 io.bitsquare.p2p.network (io.bitsquare.p2p.network)2