Search in sources :

Example 1 with ResolveDnsTask

use of de.schildbach.wallet.ui.preference.ResolveDnsTask in project bitcoin-wallet by bitcoin-wallet.

the class BlockchainService method observeLiveDatasThatAreDependentOnWalletAndBlockchain.

private void observeLiveDatasThatAreDependentOnWalletAndBlockchain() {
    final NewTransactionLiveData newTransaction = new NewTransactionLiveData(wallet.getValue());
    newTransaction.observe(this, tx -> {
        final Wallet wallet = BlockchainService.this.wallet.getValue();
        postDelayedStopSelf(5 * DateUtils.MINUTE_IN_MILLIS);
        final Coin amount = tx.getValue(wallet);
        if (amount.isPositive()) {
            final Address address = WalletUtils.getWalletAddressOfReceived(tx, wallet);
            final ConfidenceType confidenceType = tx.getConfidence().getConfidenceType();
            final boolean replaying = blockChain.getBestChainHeight() < config.getBestChainHeightEver();
            final boolean isReplayedTx = confidenceType == ConfidenceType.BUILDING && replaying;
            if (!isReplayedTx)
                notifyCoinsReceived(address, amount, tx.getTxId());
        }
    });
    impediments = new ImpedimentsLiveData(application);
    impediments.observe(this, new Observer<Set<Impediment>>() {

        @Override
        public void onChanged(final Set<Impediment> impediments) {
            if (impediments.isEmpty() && peerGroup == null && Constants.ENABLE_BLOCKCHAIN_SYNC)
                startup();
            else if (!impediments.isEmpty() && peerGroup != null)
                shutdown();
            broadcastBlockchainState();
        }

        private void startup() {
            final Wallet wallet = BlockchainService.this.wallet.getValue();
            // consistency check
            final int walletLastBlockSeenHeight = wallet.getLastBlockSeenHeight();
            final int bestChainHeight = blockChain.getBestChainHeight();
            if (walletLastBlockSeenHeight != -1 && walletLastBlockSeenHeight != bestChainHeight) {
                final String message = "wallet/blockchain out of sync: " + walletLastBlockSeenHeight + "/" + bestChainHeight;
                log.error(message);
                CrashReporter.saveBackgroundTrace(new RuntimeException(message), application.packageInfo());
            }
            final Configuration.SyncMode syncMode = config.getSyncMode();
            peerGroup = new PeerGroup(Constants.NETWORK_PARAMETERS, blockChain);
            log.info("creating {}, sync mode: {}", peerGroup, syncMode);
            // recursive implementation causes StackOverflowError
            peerGroup.setDownloadTxDependencies(0);
            peerGroup.addWallet(wallet);
            peerGroup.setBloomFilteringEnabled(syncMode == Configuration.SyncMode.CONNECTION_FILTER);
            peerGroup.setUserAgent(Constants.USER_AGENT, application.packageInfo().versionName);
            peerGroup.addConnectedEventListener(peerConnectivityListener);
            peerGroup.addDisconnectedEventListener(peerConnectivityListener);
            final int maxConnectedPeers = application.maxConnectedPeers();
            final Set<HostAndPort> trustedPeers = config.getTrustedPeers();
            final boolean trustedPeerOnly = config.isTrustedPeersOnly();
            peerGroup.setMaxConnections(trustedPeerOnly ? 0 : maxConnectedPeers);
            peerGroup.setConnectTimeoutMillis(Constants.PEER_TIMEOUT_MS);
            peerGroup.setPeerDiscoveryTimeoutMillis(Constants.PEER_DISCOVERY_TIMEOUT_MS);
            peerGroup.setStallThreshold(20, Block.HEADER_SIZE * 10);
            final ResolveDnsTask resolveDnsTask = new ResolveDnsTask(backgroundHandler) {

                @Override
                protected void onSuccess(final HostAndPort hostAndPort, final InetSocketAddress socketAddress) {
                    log.info("trusted peer '{}' resolved to {}", hostAndPort, socketAddress.getAddress().getHostAddress());
                    if (socketAddress != null) {
                        peerGroup.addAddress(new PeerAddress(Constants.NETWORK_PARAMETERS, socketAddress), 10);
                        if (peerGroup.getMaxConnections() > maxConnectedPeers)
                            peerGroup.setMaxConnections(maxConnectedPeers);
                    }
                }

                @Override
                protected void onUnknownHost(final HostAndPort hostAndPort) {
                    log.info("trusted peer '{}' unknown host", hostAndPort);
                }
            };
            for (final HostAndPort trustedPeer : trustedPeers) resolveDnsTask.resolve(trustedPeer);
            if (trustedPeerOnly) {
                log.info("trusted peers only – not adding any random nodes from the P2P network");
            } else {
                log.info("adding random peers from the P2P network");
                if (syncMode == Configuration.SyncMode.CONNECTION_FILTER)
                    peerGroup.setRequiredServices(VersionMessage.NODE_BLOOM | VersionMessage.NODE_WITNESS);
                else
                    peerGroup.setRequiredServices(VersionMessage.NODE_WITNESS);
            }
            // start peergroup
            log.info("starting {} asynchronously", peerGroup);
            peerGroup.startAsync();
            peerGroup.startBlockChainDownload(blockchainDownloadListener);
            postDelayedStopSelf(DateUtils.MINUTE_IN_MILLIS / 2);
        }

        private void shutdown() {
            final Wallet wallet = BlockchainService.this.wallet.getValue();
            peerGroup.removeDisconnectedEventListener(peerConnectivityListener);
            peerGroup.removeConnectedEventListener(peerConnectivityListener);
            peerGroup.removeWallet(wallet);
            log.info("stopping {} asynchronously", peerGroup);
            peerGroup.stopAsync();
            peerGroup = null;
        }
    });
}
Also used : EnumSet(java.util.EnumSet) Set(java.util.Set) InetSocketAddress(java.net.InetSocketAddress) Address(org.bitcoinj.core.Address) PeerAddress(org.bitcoinj.core.PeerAddress) Wallet(org.bitcoinj.wallet.Wallet) InetSocketAddress(java.net.InetSocketAddress) PeerGroup(org.bitcoinj.core.PeerGroup) ResolveDnsTask(de.schildbach.wallet.ui.preference.ResolveDnsTask) Impediment(de.schildbach.wallet.service.BlockchainState.Impediment) Coin(org.bitcoinj.core.Coin) ConfidenceType(org.bitcoinj.core.TransactionConfidence.ConfidenceType) HostAndPort(com.google.common.net.HostAndPort) PeerAddress(org.bitcoinj.core.PeerAddress)

Aggregations

HostAndPort (com.google.common.net.HostAndPort)1 Impediment (de.schildbach.wallet.service.BlockchainState.Impediment)1 ResolveDnsTask (de.schildbach.wallet.ui.preference.ResolveDnsTask)1 InetSocketAddress (java.net.InetSocketAddress)1 EnumSet (java.util.EnumSet)1 Set (java.util.Set)1 Address (org.bitcoinj.core.Address)1 Coin (org.bitcoinj.core.Coin)1 PeerAddress (org.bitcoinj.core.PeerAddress)1 PeerGroup (org.bitcoinj.core.PeerGroup)1 ConfidenceType (org.bitcoinj.core.TransactionConfidence.ConfidenceType)1 Wallet (org.bitcoinj.wallet.Wallet)1