Search in sources :

Example 1 with Socks5Proxy

use of com.runjva.sourceforge.jsocks.protocol.Socks5Proxy in project bitsquare by bitsquare.

the class TorNode method setupSocksProxy.

private Socks5Proxy setupSocksProxy(int proxyPort) throws UnknownHostException {
    Socks5Proxy proxy = new Socks5Proxy(PROXY_LOCALHOST, proxyPort);
    proxy.resolveAddrLocally(false);
    return proxy;
}
Also used : Socks5Proxy(com.runjva.sourceforge.jsocks.protocol.Socks5Proxy)

Example 2 with Socks5Proxy

use of com.runjva.sourceforge.jsocks.protocol.Socks5Proxy in project bisq-core by bisq-network.

the class WalletConfig method createPeerGroup.

private PeerGroup createPeerGroup() {
    // no proxy case.
    if (socks5Proxy == null) {
        return new PeerGroup(params, vChain);
    } else {
        // proxy case (tor).
        Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(socks5Proxy.getInetAddress().getHostName(), socks5Proxy.getPort()));
        ProxySocketFactory proxySocketFactory = new ProxySocketFactory(proxy);
        // we dont use tor mode if we have a local node running
        BlockingClientManager blockingClientManager = bisqEnvironment.isBitcoinLocalhostNodeRunning() ? new BlockingClientManager() : new BlockingClientManager(proxySocketFactory);
        PeerGroup peerGroup = new PeerGroup(params, vChain, blockingClientManager);
        blockingClientManager.setConnectTimeoutMillis(TIMEOUT);
        peerGroup.setConnectTimeoutMillis(TIMEOUT);
        return peerGroup;
    }
}
Also used : ProxySocketFactory(bisq.core.btc.ProxySocketFactory) BlockingClientManager(org.bitcoinj.net.BlockingClientManager) Proxy(java.net.Proxy) Socks5Proxy(com.runjva.sourceforge.jsocks.protocol.Socks5Proxy) InetSocketAddress(java.net.InetSocketAddress) PeerGroup(org.bitcoinj.core.PeerGroup)

Example 3 with Socks5Proxy

use of com.runjva.sourceforge.jsocks.protocol.Socks5Proxy in project bitsquare by bitsquare.

the class WalletService method initialize.

///////////////////////////////////////////////////////////////////////////////////////////
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void initialize(@Nullable DeterministicSeed seed, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
    Log.traceCall();
    // Tell bitcoinj to execute event handlers on the JavaFX UI thread. This keeps things simple and means
    // we cannot forget to switch threads when adding event handlers. Unfortunately, the DownloadListener
    // we give to the app kit is currently an exception and runs on a library thread. It'll get fixed in
    // a future version.
    Threading.USER_THREAD = UserThread.getExecutor();
    Timer timeoutTimer = UserThread.runAfter(() -> exceptionHandler.handleException(new TimeoutException("Wallet did not initialize in " + STARTUP_TIMEOUT_SEC + " seconds.")), STARTUP_TIMEOUT_SEC);
    backupWallet();
    final Socks5Proxy socks5Proxy = preferences.getUseTorForBitcoinJ() ? socks5ProxyProvider.getSocks5Proxy() : null;
    log.debug("Use socks5Proxy for bitcoinj: " + socks5Proxy);
    // If seed is non-null it means we are restoring from backup.
    walletAppKit = new WalletAppKitBitSquare(params, socks5Proxy, walletDir, "Bitsquare") {

        @Override
        protected void onSetupCompleted() {
            // Don't make the user wait for confirmations for now, as the intention is they're sending it
            // their own money!
            walletAppKit.wallet().allowSpendingUnconfirmedTransactions();
            final PeerGroup peerGroup = walletAppKit.peerGroup();
            if (params != RegTestParams.get())
                peerGroup.setMaxConnections(11);
            // We don't want to get our node white list polluted with nodes from AddressMessage calls.
            if (preferences.getBitcoinNodes() != null && !preferences.getBitcoinNodes().isEmpty())
                peerGroup.setAddPeersFromAddressMessage(false);
            wallet = walletAppKit.wallet();
            wallet.addEventListener(walletEventListener);
            addressEntryList.onWalletReady(wallet);
            peerGroup.addEventListener(new PeerEventListener() {

                @Override
                public void onPeersDiscovered(Set<PeerAddress> peerAddresses) {
                }

                @Override
                public void onBlocksDownloaded(Peer peer, Block block, FilteredBlock filteredBlock, int blocksLeft) {
                }

                @Override
                public void onChainDownloadStarted(Peer peer, int blocksLeft) {
                }

                @Override
                public void onPeerConnected(Peer peer, int peerCount) {
                    numPeers.set(peerCount);
                    connectedPeers.set(peerGroup.getConnectedPeers());
                }

                @Override
                public void onPeerDisconnected(Peer peer, int peerCount) {
                    numPeers.set(peerCount);
                    connectedPeers.set(peerGroup.getConnectedPeers());
                }

                @Override
                public Message onPreMessageReceived(Peer peer, Message m) {
                    return null;
                }

                @Override
                public void onTransaction(Peer peer, Transaction t) {
                }

                @Nullable
                @Override
                public List<Message> getData(Peer peer, GetDataMessage m) {
                    return null;
                }
            });
            // set after wallet is ready
            tradeWalletService.setWalletAppKit(walletAppKit);
            tradeWalletService.setAddressEntryList(addressEntryList);
            timeoutTimer.stop();
            // onSetupCompleted in walletAppKit is not the called on the last invocations, so we add a bit of delay
            UserThread.runAfter(resultHandler::handleResult, 100, TimeUnit.MILLISECONDS);
        }
    };
    // Bloom filters in BitcoinJ are completely broken
    // See: https://jonasnick.github.io/blog/2015/02/12/privacy-in-bitcoinj/
    // Here are a few improvements to fix a few vulnerabilities.
    // Bitsquare's BitcoinJ fork has added a bloomFilterTweak (nonce) setter to reuse the same seed avoiding the trivial vulnerability
    // by getting the real pub keys by intersections of several filters sent at each startup.
    walletAppKit.setBloomFilterTweak(bloomFilterTweak);
    // Avoid the simple attack (see: https://jonasnick.github.io/blog/2015/02/12/privacy-in-bitcoinj/) due to the 
    // default implementation using both pubkey and hash of pubkey. We have set a insertPubKey flag in BasicKeyChain to default false.
    // Default only 266 keys are generated (2 * 100+33). That would trigger new bloom filters when we are reaching 
    // the threshold. To avoid reaching the threshold we create much more keys which are unlikely to cause update of the
    // filter for most users. With lookaheadSize of 500 we get 1333 keys which should be enough for most users to 
    // never need to update a bloom filter, which would weaken privacy.
    walletAppKit.setLookaheadSize(500);
    // Calculation is derived from: https://www.reddit.com/r/Bitcoin/comments/2vrx6n/privacy_in_bitcoinj_android_wallet_multibit_hive/coknjuz
    // No. of false positives (56M keys in the blockchain): 
    // First attempt for FP rate:
    // FP rate = 0,0001;  No. of false positives: 0,0001 * 56 000 000  = 5600
    // We have 1333keys: 1333 / (5600 + 1333) = 0.19 -> 19 % probability that a pub key is in our wallet
    // After tests I found out that the bandwidth consumption varies widely related to the generated filter.
    // About 20- 40 MB for upload and 30-130 MB for download at first start up (spv chain).
    // Afterwards its about 1 MB for upload and 20-80 MB for download.
    // Probably better then a high FP rate would be to include foreign pubKeyHashes which are tested to not be used 
    // in many transactions. If we had a pool of 100 000 such keys (2 MB data dump) to random select 4000 we could mix it with our
    // 1000 own keys and get a similar probability rate as with the current setup but less variation in bandwidth 
    // consumption.
    // For now to reduce risks with high bandwidth consumption we reduce the FP rate by half.
    // FP rate = 0,00005;  No. of false positives: 0,00005 * 56 000 000  = 2800
    // 1333 / (2800 + 1333) = 0.32 -> 32 % probability that a pub key is in our wallet
    walletAppKit.setBloomFilterFalsePositiveRate(0.00005);
    String btcNodes = preferences.getBitcoinNodes();
    log.debug("btcNodes: " + btcNodes);
    boolean usePeerNodes = false;
    // Pass custom seed nodes if set in options
    if (!btcNodes.isEmpty()) {
        String[] nodes = StringUtils.deleteWhitespace(btcNodes).split(",");
        List<PeerAddress> peerAddressList = new ArrayList<>();
        for (String node : nodes) {
            String[] parts = node.split(":");
            if (parts.length == 1) {
                // port not specified.  Use default port for network.
                parts = new String[] { parts[0], Integer.toString(params.getPort()) };
            }
            if (parts.length == 2) {
                // note: this will cause a DNS request if hostname used.
                // note: DNS requests are routed over socks5 proxy, if used.
                // note: .onion hostnames will be unresolved.
                InetSocketAddress addr;
                if (socks5Proxy != null) {
                    try {
                        // proxy remote DNS request happens here.  blocking.
                        addr = new InetSocketAddress(DnsLookupTor.lookup(socks5Proxy, parts[0]), Integer.parseInt(parts[1]));
                    } catch (Exception e) {
                        log.warn("Dns lookup failed for host: {}", parts[0]);
                        addr = null;
                    }
                } else {
                    // DNS request happens here. if it fails, addr.isUnresolved() == true.
                    addr = new InetSocketAddress(parts[0], Integer.parseInt(parts[1]));
                }
                if (addr != null && !addr.isUnresolved()) {
                    peerAddressList.add(new PeerAddress(addr.getAddress(), addr.getPort()));
                }
            }
        }
        if (peerAddressList.size() > 0) {
            PeerAddress[] peerAddressListFixed = new PeerAddress[peerAddressList.size()];
            log.debug("btcNodes parsed: " + Arrays.toString(peerAddressListFixed));
            walletAppKit.setPeerNodes(peerAddressList.toArray(peerAddressListFixed));
            usePeerNodes = true;
        }
    }
    // or progress widget to keep the user engaged whilst we initialise, but we don't.
    if (params == RegTestParams.get()) {
        if (regTestHost == RegTestHost.REG_TEST_SERVER) {
            try {
                walletAppKit.setPeerNodes(new PeerAddress(InetAddress.getByName(RegTestHost.SERVER_IP), params.getPort()));
                usePeerNodes = true;
            } catch (UnknownHostException e) {
                throw new RuntimeException(e);
            }
        } else if (regTestHost == RegTestHost.LOCALHOST) {
            // You should run a regtest mode bitcoind locally.}
            walletAppKit.connectToLocalHost();
        }
    } else if (params == MainNetParams.get()) {
        // last months worth or more (takes a few seconds).
        try {
            walletAppKit.setCheckpoints(getClass().getResourceAsStream("/wallet/checkpoints"));
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.toString());
        }
    } else if (params == TestNet3Params.get()) {
        walletAppKit.setCheckpoints(getClass().getResourceAsStream("/wallet/checkpoints.testnet"));
    }
    // disable it, but should be made aware of the reduced privacy.
    if (socks5Proxy != null && !usePeerNodes) {
        // SeedPeers uses hard coded stable addresses (from MainNetParams). It should be updated from time to time.
        walletAppKit.setDiscovery(new Socks5MultiDiscovery(socks5Proxy, params, socks5DiscoverMode));
    }
    walletAppKit.setDownloadListener(downloadListener).setBlockingStartup(false).setUserAgent(userAgent.getName(), userAgent.getVersion()).restoreWalletFromSeed(seed);
    walletAppKit.addListener(new Service.Listener() {

        @Override
        public void failed(@NotNull Service.State from, @NotNull Throwable failure) {
            walletAppKit = null;
            log.error("walletAppKit failed");
            timeoutTimer.stop();
            UserThread.execute(() -> exceptionHandler.handleException(failure));
        }
    }, Threading.USER_THREAD);
    walletAppKit.startAsync();
}
Also used : CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) Socks5Proxy(com.runjva.sourceforge.jsocks.protocol.Socks5Proxy) InetSocketAddress(java.net.InetSocketAddress) TimeoutException(java.util.concurrent.TimeoutException) UnknownHostException(java.net.UnknownHostException) Socks5MultiDiscovery(io.bitsquare.network.Socks5MultiDiscovery) Service(com.google.common.util.concurrent.Service) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) Timer(io.bitsquare.common.Timer)

Example 4 with Socks5Proxy

use of com.runjva.sourceforge.jsocks.protocol.Socks5Proxy in project bitsquare by bitsquare.

the class WalletAppKitBitSquare method createPeerGroup.

protected PeerGroup createPeerGroup() throws TimeoutException {
    // no proxy case.
    if (socks5Proxy == null || isLocalHostFullNodeRunning()) {
        return super.createPeerGroup();
    } else {
        // proxy case.
        Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(socks5Proxy.getInetAddress().getHostName(), socks5Proxy.getPort()));
        // same value used in bitcoinj.
        int CONNECT_TIMEOUT_MSEC = 60 * 1000;
        ProxySocketFactory proxySocketFactory = new ProxySocketFactory(proxy);
        BlockingClientManager mgr = new BlockingClientManager(proxySocketFactory);
        PeerGroup peerGroup = new PeerGroup(params, vChain, mgr);
        mgr.setConnectTimeoutMillis(CONNECT_TIMEOUT_MSEC);
        peerGroup.setConnectTimeoutMillis(CONNECT_TIMEOUT_MSEC);
        return peerGroup;
    }
}
Also used : BlockingClientManager(org.bitcoinj.net.BlockingClientManager) Proxy(java.net.Proxy) Socks5Proxy(com.runjva.sourceforge.jsocks.protocol.Socks5Proxy) InetSocketAddress(java.net.InetSocketAddress) PeerGroup(org.bitcoinj.core.PeerGroup)

Example 5 with Socks5Proxy

use of com.runjva.sourceforge.jsocks.protocol.Socks5Proxy in project bitsquare by bitsquare.

the class HttpClient method requestWithGET.

public String requestWithGET(String param, @Nullable String headerKey, @Nullable String headerValue) throws IOException, HttpException {
    checkNotNull(baseUrl, "baseUrl must be set before calling requestWithGET");
    Socks5Proxy socks5Proxy = null;
    if (socks5ProxyProvider != null) {
        // We use the custom socks5ProxyHttp. If not set we request socks5ProxyProvider.getSocks5ProxyBtc()
        // which delivers the btc proxy if set, otherwise the internal proxy.
        socks5Proxy = socks5ProxyProvider.getSocks5ProxyHttp();
        if (socks5Proxy == null)
            socks5Proxy = socks5ProxyProvider.getSocks5Proxy();
    }
    if (ignoreSocks5Proxy) {
        log.debug("Use clear net for HttpClient because ignoreSocks5Proxy is set to true");
        return requestWithGETNoProxy(param, headerKey, headerValue);
    } else if (socks5Proxy == null) {
        log.debug("Use clear net for HttpClient because socks5Proxy is null");
        return requestWithGETNoProxy(param, headerKey, headerValue);
    } else {
        log.debug("Use socks5Proxy for HttpClient: " + socks5Proxy);
        return requestWithGETProxy(param, socks5Proxy, headerKey, headerValue);
    }
}
Also used : Socks5Proxy(com.runjva.sourceforge.jsocks.protocol.Socks5Proxy)

Aggregations

Socks5Proxy (com.runjva.sourceforge.jsocks.protocol.Socks5Proxy)6 InetSocketAddress (java.net.InetSocketAddress)3 PeerGroup (org.bitcoinj.core.PeerGroup)3 Service (com.google.common.util.concurrent.Service)2 IOException (java.io.IOException)2 Proxy (java.net.Proxy)2 UnknownHostException (java.net.UnknownHostException)2 TimeoutException (java.util.concurrent.TimeoutException)2 Timer (bisq.common.Timer)1 UserThread (bisq.common.UserThread)1 Log (bisq.common.app.Log)1 ExceptionHandler (bisq.common.handlers.ExceptionHandler)1 ResultHandler (bisq.common.handlers.ResultHandler)1 FileUtil (bisq.common.storage.FileUtil)1 BisqEnvironment (bisq.core.app.BisqEnvironment)1 AddressEntry (bisq.core.btc.AddressEntry)1 AddressEntryList (bisq.core.btc.AddressEntryList)1 BitcoinNodes (bisq.core.btc.BitcoinNodes)1 BtcNode (bisq.core.btc.BitcoinNodes.BtcNode)1 BtcOptionKeys (bisq.core.btc.BtcOptionKeys)1