<p></p>
<h1>Concrete plan</h1>
<p>Note: below text is written in a tree-like fashion, which helps me structure my writing and navigate the text. Hopefully it doesn't look too outlandish.</p>
<ul>
<li>Below algorithm describes a refactoring of BitcoinJ usage in Bisq
<ul>
<li>the goal of the refactoring is to
<ul>
<li>generally speaking, improve maintenance of Bisq's Bitcoin network code</li>
<li>more specifically, lay the foundation for ongoing reduction of the BitcoinJ-Bisq coupling
<ul>
<li>ongoing, because the coupling is too extensive to be safely undone at once</li>
</ul>
</li>
</ul>
</li>
<li>the described refactoring aims to achieve that by
<ul>
<li>introducing a "btc.low" layer that
<ul>
<li>acts as a Bitcoin client API that is implementation agnostic
<ul>
<li>in other words, it would be the only place in Bisq with Bitcoin-client-specific (BitcoinJ-specific) logic</li>
</ul>
</li>
</ul>
</li>
<li>doing it in a way that allows safe incremental changes
<ul>
<li>what will make the process safe is the smallness of the refactoring steps
<ul>
<li>the small steps facilitate audits</li>
<li>further, being able to refactor in small steps will make opportunistic refactoring more common</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>the end product of this initial refactoring
<ul>
<li>a place where we can move BitcoinJ-specific logic</li>
<li>a place where we can see how exactly we're using BitcoinJ (in a much more centralized way)</li>
<li>a clear and simple abstraction and refactoring system for ongoing improvement of our BitcoinJ usage</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>Refactoring steps</h2>
<p>For readability, I've bolded what you'd call the main variable names if this were code:</p>
<ul>
<li>Make an identical <strong>copy</strong> of the BitcoinJ API inside Bisq
<ul>
<li>more specifically, of the subset of bitcoinj api that we use</li>
<li>initially this copy will just redirect all calls to BitcoinJ
<ul>
<li>nothing more than a fully transparent wrap</li>
</ul>
</li>
<li>you call this copy in the same way that you call the original
<ul>
<li>and you get the same results</li>
</ul>
</li>
</ul>
</li>
<li>Designate the <strong>copy</strong> as foundation for Bisq-BitcoinJ separation <strong>layer</strong>
<ul>
<li>Bisq-BitcoinJ separation layer
<ul>
<li>or, in other words, Bitcoin client agnostic layer</li>
</ul>
</li>
<li>the ultimate goal of this abstraction is to be the only repository of BitcoinJ-specific logic in Bisq</li>
</ul>
</li>
<li>Make this <strong>layer</strong> the (only) Bitcoin client used by Bisq
<ul>
<li>as simple as
<ul>
<li>search and replace <code>import org.bitcoinj.PeerGroup</code> for <code>import bisq.core.btc.low.PeerGroup</code></li>
</ul>
</li>
<li>will now refer to this layer as <strong>btc.low</strong>, as in the package bisq.core.btc.low.</li>
</ul>
</li>
<li>Incrementally mutate the <strong>btc.low</strong> abstraction
<ul>
<li>by
<ul>
<li>moving BitcoinJ-specific logic into it (from the rest of Bisq)</li>
<li>generally refactoring it to better match the needs of Bisq</li>
</ul>
</li>
<li>this step is what makes the refactoring ongoing</li>
</ul>
</li>
</ul>
<h2>Illustrative code sketch</h2>
<p>Below sketch illustrates what <code>btc.core.btc.low.PeerGroup</code> could look like.</p>
<pre><code>package bisq.core.btc.low;

import org.bitcoinj.core.BlockChain;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.net.BlockingClientManager;

import bisq.core.btc.nodes.ProxySocketFactory;
import bisq.core.btc.nodes.LocalBitcoinNode;

import java.net.Proxy;
import java.net.InetSocketAddress;

import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;

/* Below code is a sketch of what btc.low can look like.
 * To make it short and simple, it presumes that our BitcoinJ usage is only
 * what is in the bisq.core.btc.WalletConfig::createPeerGroup method.
 * This sketch tries to demonstrate how logic is moved into btc.low: you start
 * out with a lot of BitcoinJ-specific logic, and end up with a
 * BitcoinJ-agnostic endpoint and a clear view of what BitcoinJ endpoints are
 * used under the sheets.
 * The code would definitely be simplified more after moving, but that's
 * outside the scope of this sketch.
 */

public class PeerGroup {

    private final org.bitcoinj.core.PeerGroup bitcoinjPeerGroup;

    private PeerGroup(org.bitcoinj.core.PeerGroup bitcoinjPeerGroup) {
        this.bitcoinjPeerGroup = bitcoinjPeerGroup;
    }

    /* This method is a copy-paste of
     * bisq.core.btc.WalletConfig::createPeerGroup (except for the signature
     * and using locally defined constructors). It serves only demo purposes
     * and code quality inside it not representative of standards set for this
     * project.
     */
    private static PeerGroup createPeerGroup(
            Socks5Proxy socks5Proxy,
            NetworkParameters params,
            BlockChain vChain,
            LocalBitcoinNode localBitcoinNode
    ) {
        PeerGroup peerGroup;
        // no proxy case.
        if (socks5Proxy == null) {
            peerGroup = this(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 don't use tor mode if we have a local node running
            BlockingClientManager blockingClientManager =
                config.ignoreLocalBtcNode ?
                new BlockingClientManager() :
                new BlockingClientManager(proxySocketFactory);

            peerGroup = this(params, vChain, blockingClientManager);

            blockingClientManager.setConnectTimeoutMillis(TOR_SOCKET_TIMEOUT);
            peerGroup.setConnectTimeoutMillis(TOR_VERSION_EXCHANGE_TIMEOUT);
        }

        if (!localBitcoinNode.shouldBeUsed())
            peerGroup.setUseLocalhostPeerWhenPossible(false);

        return peerGroup;
    }

    /* Proxy all PeerGroup methods that Bisq uses.
     * These would probably be "protected" and be in a separate class, which
     * would be subclassed by this one, for the sake of separating the used
     * BitcoinJ endpoints and their usage.
     */

    private PeerGroup(
            NetworkParameters params,
            BlockChain vChain
    ) {
        org.bitcoinj.core.PeerGroup bitcoinjPeerGroup =
            new org.bitcoinj.core.PeerGroup(params, vChain);
        this(bitcoinjPeerGroup);
    }

    private PeerGroup(
            NetworkParameters params,
            BlockChain vChain,
            BlockingClientManager
            blockingClientManager
    ) {
        org.bitcoinj.core.PeerGroup bitcoinjPeerGroup =
            new org.bitcoinj.core.PeerGroup(
                    params, vChain, blockingClientManager);
        this(bitcoinjPeerGroup);
    }

    private void setUseLocalhostPeerWhenPossible(boolean bool) {
        this.bitcoinjPeerGroup.setUseLocalhostPeerWhenPossible(bool);
    }

    private void setConnectTimeoutMillis(int timeout) {
        this.bitcoinjPeerGroup.setConnectTimeoutMillis(timeout);
    }

}

</code></pre>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/bisq-network/projects/issues/30#issuecomment-629840234">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AJFFTNQLNXZD2FK5FM6FPMLRSAT4LANCNFSM4MPSVBDA">unsubscribe</a>.<img src="https://github.com/notifications/beacon/AJFFTNRNCN4A5J4D2SEUTBTRSAT4LA5CNFSM4MPSVBDKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEWFJS2Q.gif" height="1" width="1" alt="" /></p>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/bisq-network/projects/issues/30#issuecomment-629840234",
"url": "https://github.com/bisq-network/projects/issues/30#issuecomment-629840234",
"name": "View Issue"
},
"description": "View this Issue on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>