aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/seeds/generate-seeds.py11
-rw-r--r--src/init.cpp10
-rw-r--r--src/net.cpp32
-rw-r--r--src/netaddress.cpp19
-rw-r--r--src/netaddress.h3
-rw-r--r--src/netbase.cpp5
-rw-r--r--src/rpc/net.cpp2
-rw-r--r--src/test/netbase_tests.cpp2
-rwxr-xr-xtest/functional/feature_proxy.py67
-rwxr-xr-xtest/functional/interface_bitcoin_cli.py2
-rwxr-xr-xtest/functional/rpc_net.py8
11 files changed, 135 insertions, 26 deletions
diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py
index dbecba7d1d..44345e3987 100755
--- a/contrib/seeds/generate-seeds.py
+++ b/contrib/seeds/generate-seeds.py
@@ -61,7 +61,7 @@ def name_to_bip155(addr):
raise ValueError(f'Invalid I2P {vchAddr}')
elif '.' in addr: # IPv4
return (BIP155Network.IPV4, bytes((int(x) for x in addr.split('.'))))
- elif ':' in addr: # IPv6
+ elif ':' in addr: # IPv6 or CJDNS
sub = [[], []] # prefix, suffix
x = 0
addr = addr.split(':')
@@ -77,7 +77,14 @@ def name_to_bip155(addr):
sub[x].append(val & 0xff)
nullbytes = 16 - len(sub[0]) - len(sub[1])
assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0))
- return (BIP155Network.IPV6, bytes(sub[0] + ([0] * nullbytes) + sub[1]))
+ addr_bytes = bytes(sub[0] + ([0] * nullbytes) + sub[1])
+ if addr_bytes[0] == 0xfc:
+ # Assume that seeds with fc00::/8 addresses belong to CJDNS,
+ # not to the publicly unroutable "Unique Local Unicast" network, see
+ # RFC4193: https://datatracker.ietf.org/doc/html/rfc4193#section-8
+ return (BIP155Network.CJDNS, addr_bytes)
+ else:
+ return (BIP155Network.IPV6, addr_bytes)
else:
raise ValueError('Could not parse address %s' % addr)
diff --git a/src/init.cpp b/src/init.cpp
index e554a18fbf..b0335183d6 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -422,6 +422,7 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultBaseParams->OnionServiceTargetPort(), testnetBaseParams->OnionServiceTargetPort(), signetBaseParams->OnionServiceTargetPort(), regtestBaseParams->OnionServiceTargetPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
+ argsman.AddArg("-cjdnsreachable", "If set then this host is configured for CJDNS (connecting to fc00::/8 addresses would lead us to the CJDNS network) (default: 0)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-dns", strprintf("Allow DNS lookups for -addnode, -seednode and -connect (default: %u)", DEFAULT_NAME_LOOKUP), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
@@ -1294,6 +1295,14 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
}
}
+ if (!args.IsArgSet("-cjdnsreachable")) {
+ SetReachable(NET_CJDNS, false);
+ }
+ // Now IsReachable(NET_CJDNS) is true if:
+ // 1. -cjdnsreachable is given and
+ // 2.1. -onlynet is not given or
+ // 2.2. -onlynet=cjdns is given
+
// Check for host lookup allowed before parsing any network related parameters
fNameLookup = args.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP);
@@ -1315,6 +1324,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
SetProxy(NET_IPV4, addrProxy);
SetProxy(NET_IPV6, addrProxy);
SetProxy(NET_ONION, addrProxy);
+ SetProxy(NET_CJDNS, addrProxy);
SetNameProxy(addrProxy);
SetReachable(NET_ONION, true); // by default, -proxy sets onion as reachable, unless -noonion later
}
diff --git a/src/net.cpp b/src/net.cpp
index 8cf59f0b0d..82e55d4189 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -230,9 +230,27 @@ std::optional<CAddress> GetLocalAddrForPeer(CNode *pnode)
return std::nullopt;
}
+/**
+ * If an IPv6 address belongs to the address range used by the CJDNS network and
+ * the CJDNS network is reachable (-cjdnsreachable config is set), then change
+ * the type from NET_IPV6 to NET_CJDNS.
+ * @param[in] service Address to potentially convert.
+ * @return a copy of `service` either unmodified or changed to CJDNS.
+ */
+CService MaybeFlipIPv6toCJDNS(const CService& service)
+{
+ CService ret{service};
+ if (ret.m_net == NET_IPV6 && ret.m_addr[0] == 0xfc && IsReachable(NET_CJDNS)) {
+ ret.m_net = NET_CJDNS;
+ }
+ return ret;
+}
+
// learn a new local address
-bool AddLocal(const CService& addr, int nScore)
+bool AddLocal(const CService& addr_, int nScore)
{
+ CService addr{MaybeFlipIPv6toCJDNS(addr_)};
+
if (!addr.IsRoutable())
return false;
@@ -409,7 +427,8 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
if (pszDest) {
std::vector<CService> resolved;
if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
- addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
+ const CService rnd{resolved[GetRand(resolved.size())]};
+ addrConnect = CAddress{MaybeFlipIPv6toCJDNS(rnd), NODE_NONE};
if (!addrConnect.IsValid()) {
LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest);
return nullptr;
@@ -1092,9 +1111,11 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) {
LogPrintf("Warning: Unknown socket family\n");
+ } else {
+ addr = CAddress{MaybeFlipIPv6toCJDNS(addr), NODE_NONE};
}
- const CAddress addr_bind = GetBindAddress(hSocket);
+ const CAddress addr_bind{MaybeFlipIPv6toCJDNS(GetBindAddress(hSocket)), NODE_NONE};
NetPermissionFlags permissionFlags = NetPermissionFlags::None;
hListenSocket.AddSocketPermissionFlags(permissionFlags);
@@ -2460,7 +2481,10 @@ NodeId CConnman::GetNewNodeId()
}
-bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions) {
+bool CConnman::Bind(const CService& addr_, unsigned int flags, NetPermissionFlags permissions)
+{
+ const CService addr{MaybeFlipIPv6toCJDNS(addr_)};
+
if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) {
return false;
}
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index f9fff5a6d5..7f1dd698b0 100644
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -663,7 +663,7 @@ bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
}
/**
- * Try to get our IPv6 address.
+ * Try to get our IPv6 (or CJDNS) address.
*
* @param[out] pipv6Addr The in6_addr struct to which to copy.
*
@@ -674,7 +674,7 @@ bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
*/
bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
{
- if (!IsIPv6()) {
+ if (!IsIPv6() && !IsCJDNS()) {
return false;
}
assert(sizeof(*pipv6Addr) == m_addr.size());
@@ -794,8 +794,14 @@ std::vector<unsigned char> CNetAddr::GetGroup(const std::vector<bool> &asmap) co
vchRet.push_back((ipv4 >> 24) & 0xFF);
vchRet.push_back((ipv4 >> 16) & 0xFF);
return vchRet;
- } else if (IsTor() || IsI2P() || IsCJDNS()) {
+ } else if (IsTor() || IsI2P()) {
nBits = 4;
+ } else if (IsCJDNS()) {
+ // Treat in the same way as Tor and I2P because the address in all of
+ // them is "random" bytes (derived from a public key). However in CJDNS
+ // the first byte is a constant 0xfc, so the random bytes come after it.
+ // Thus skip the constant 8 bits at the start.
+ nBits = 12;
} else if (IsHeNet()) {
// for he.net, use /36 groups
nBits = 36;
@@ -892,6 +898,11 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
case NET_I2P: return REACH_PRIVATE;
default: return REACH_DEFAULT;
}
+ case NET_CJDNS:
+ switch (ourNet) {
+ case NET_CJDNS: return REACH_PRIVATE;
+ default: return REACH_DEFAULT;
+ }
case NET_TEREDO:
switch(ourNet) {
default: return REACH_DEFAULT;
@@ -993,7 +1004,7 @@ bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
paddrin->sin_port = htons(port);
return true;
}
- if (IsIPv6()) {
+ if (IsIPv6() || IsCJDNS()) {
if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6))
return false;
*addrlen = sizeof(struct sockaddr_in6);
diff --git a/src/netaddress.h b/src/netaddress.h
index 57eb8bc72f..b0b1c5ca9e 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -224,7 +224,7 @@ public:
*/
bool IsRelayable() const
{
- return IsIPv4() || IsIPv6() || IsTor() || IsI2P();
+ return IsIPv4() || IsIPv6() || IsTor() || IsI2P() || IsCJDNS();
}
/**
@@ -550,6 +550,7 @@ public:
}
friend class CServiceHash;
+ friend CService MaybeFlipIPv6toCJDNS(const CService& service);
};
class CServiceHash
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 64d17189a6..6191f25cd9 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -96,6 +96,9 @@ enum Network ParseNetwork(const std::string& net_in) {
if (net == "i2p") {
return NET_I2P;
}
+ if (net == "cjdns") {
+ return NET_CJDNS;
+ }
return NET_UNROUTABLE;
}
@@ -120,7 +123,7 @@ std::vector<std::string> GetNetworkNames(bool append_unroutable)
std::vector<std::string> names;
for (int n = 0; n < NET_MAX; ++n) {
const enum Network network{static_cast<Network>(n)};
- if (network == NET_UNROUTABLE || network == NET_CJDNS || network == NET_INTERNAL) continue;
+ if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue;
names.emplace_back(GetNetworkName(network));
}
if (append_unroutable) {
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index a9bee33c5d..e33f1ce4a3 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -566,7 +566,7 @@ static UniValue GetNetworksInfo()
UniValue networks(UniValue::VARR);
for (int n = 0; n < NET_MAX; ++n) {
enum Network network = static_cast<enum Network>(n);
- if (network == NET_UNROUTABLE || network == NET_CJDNS || network == NET_INTERNAL) continue;
+ if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue;
proxyType proxy;
UniValue obj(UniValue::VOBJ);
GetProxy(network, proxy);
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 687d2f6747..b6d7496cc7 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -339,11 +339,13 @@ BOOST_AUTO_TEST_CASE(netbase_parsenetwork)
BOOST_CHECK_EQUAL(ParseNetwork("ipv6"), NET_IPV6);
BOOST_CHECK_EQUAL(ParseNetwork("onion"), NET_ONION);
BOOST_CHECK_EQUAL(ParseNetwork("tor"), NET_ONION);
+ BOOST_CHECK_EQUAL(ParseNetwork("cjdns"), NET_CJDNS);
BOOST_CHECK_EQUAL(ParseNetwork("IPv4"), NET_IPV4);
BOOST_CHECK_EQUAL(ParseNetwork("IPv6"), NET_IPV6);
BOOST_CHECK_EQUAL(ParseNetwork("ONION"), NET_ONION);
BOOST_CHECK_EQUAL(ParseNetwork("TOR"), NET_ONION);
+ BOOST_CHECK_EQUAL(ParseNetwork("CJDNS"), NET_CJDNS);
BOOST_CHECK_EQUAL(ParseNetwork(":)"), NET_UNROUTABLE);
BOOST_CHECK_EQUAL(ParseNetwork("tÖr"), NET_UNROUTABLE);
diff --git a/test/functional/feature_proxy.py b/test/functional/feature_proxy.py
index 2fb5e328f5..70b9e019c1 100755
--- a/test/functional/feature_proxy.py
+++ b/test/functional/feature_proxy.py
@@ -12,6 +12,7 @@ Test plan:
- `-proxy` (proxy everything)
- `-onion` (proxy just onions)
- `-proxyrandomize` Circuit randomization
+ - `-cjdnsreachable`
- Proxy configurations to test on proxy side,
- support no authentication (other proxy)
- support no authentication + user/pass authentication (Tor)
@@ -26,6 +27,7 @@ addnode connect to IPv4
addnode connect to IPv6
addnode connect to onion
addnode connect to generic DNS name
+addnode connect to a CJDNS address
- Test getnetworkinfo for each node
"""
@@ -50,14 +52,15 @@ NET_IPV4 = "ipv4"
NET_IPV6 = "ipv6"
NET_ONION = "onion"
NET_I2P = "i2p"
+NET_CJDNS = "cjdns"
# Networks returned by RPC getnetworkinfo, defined in src/rpc/net.cpp::GetNetworksInfo()
-NETWORKS = frozenset({NET_IPV4, NET_IPV6, NET_ONION, NET_I2P})
+NETWORKS = frozenset({NET_IPV4, NET_IPV6, NET_ONION, NET_I2P, NET_CJDNS})
class ProxyTest(BitcoinTestFramework):
def set_test_params(self):
- self.num_nodes = 4
+ self.num_nodes = 5
self.setup_clean_chain = True
def setup_nodes(self):
@@ -101,7 +104,9 @@ class ProxyTest(BitcoinTestFramework):
['-listen', f'-proxy={self.conf1.addr[0]}:{self.conf1.addr[1]}',f'-onion={self.conf2.addr[0]}:{self.conf2.addr[1]}',
f'-i2psam={self.i2p_sam[0]}:{self.i2p_sam[1]}', '-i2pacceptincoming=0', '-proxyrandomize=0'],
['-listen', f'-proxy={self.conf2.addr[0]}:{self.conf2.addr[1]}','-proxyrandomize=1'],
- []
+ [],
+ ['-listen', f'-proxy={self.conf1.addr[0]}:{self.conf1.addr[1]}','-proxyrandomize=1',
+ '-cjdnsreachable']
]
if self.have_ipv6:
args[3] = ['-listen', f'-proxy=[{self.conf3.addr[0]}]:{self.conf3.addr[1]}','-proxyrandomize=0', '-noonion']
@@ -113,7 +118,7 @@ class ProxyTest(BitcoinTestFramework):
if peer["addr"] == addr:
assert_equal(peer["network"], network)
- def node_test(self, node, proxies, auth, test_onion=True):
+ def node_test(self, node, *, proxies, auth, test_onion, test_cjdns):
rv = []
addr = "15.61.23.23:1234"
self.log.debug(f"Test: outgoing IPv4 connection through node for address {addr}")
@@ -161,6 +166,21 @@ class ProxyTest(BitcoinTestFramework):
rv.append(cmd)
self.network_test(node, addr, network=NET_ONION)
+ if test_cjdns:
+ addr = "[fc00:1:2:3:4:5:6:7]:8888"
+ self.log.debug(f"Test: outgoing CJDNS connection through node for address {addr}")
+ node.addnode(addr, "onetry")
+ cmd = proxies[1].queue.get()
+ assert isinstance(cmd, Socks5Command)
+ assert_equal(cmd.atyp, AddressType.DOMAINNAME)
+ assert_equal(cmd.addr, b"fc00:1:2:3:4:5:6:7")
+ assert_equal(cmd.port, 8888)
+ if not auth:
+ assert_equal(cmd.username, None)
+ assert_equal(cmd.password, None)
+ rv.append(cmd)
+ self.network_test(node, addr, network=NET_CJDNS)
+
addr = "node.noumenon:8333"
self.log.debug(f"Test: outgoing DNS name connection through node for address {addr}")
node.addnode(addr, "onetry")
@@ -179,20 +199,33 @@ class ProxyTest(BitcoinTestFramework):
def run_test(self):
# basic -proxy
- self.node_test(self.nodes[0], [self.serv1, self.serv1, self.serv1, self.serv1], False)
+ self.node_test(self.nodes[0],
+ proxies=[self.serv1, self.serv1, self.serv1, self.serv1],
+ auth=False, test_onion=True, test_cjdns=False)
# -proxy plus -onion
- self.node_test(self.nodes[1], [self.serv1, self.serv1, self.serv2, self.serv1], False)
+ self.node_test(self.nodes[1],
+ proxies=[self.serv1, self.serv1, self.serv2, self.serv1],
+ auth=False, test_onion=True, test_cjdns=False)
# -proxy plus -onion, -proxyrandomize
- rv = self.node_test(self.nodes[2], [self.serv2, self.serv2, self.serv2, self.serv2], True)
+ rv = self.node_test(self.nodes[2],
+ proxies=[self.serv2, self.serv2, self.serv2, self.serv2],
+ auth=True, test_onion=True, test_cjdns=False)
# Check that credentials as used for -proxyrandomize connections are unique
credentials = set((x.username,x.password) for x in rv)
assert_equal(len(credentials), len(rv))
if self.have_ipv6:
# proxy on IPv6 localhost
- self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False)
+ self.node_test(self.nodes[3],
+ proxies=[self.serv3, self.serv3, self.serv3, self.serv3],
+ auth=False, test_onion=False, test_cjdns=False)
+
+ # -proxy=unauth -proxyrandomize=1 -cjdnsreachable
+ self.node_test(self.nodes[4],
+ proxies=[self.serv1, self.serv1, self.serv1, self.serv1],
+ auth=False, test_onion=True, test_cjdns=True)
def networks_dict(d):
r = {}
@@ -214,6 +247,7 @@ class ProxyTest(BitcoinTestFramework):
assert_equal(n0[net]['proxy_randomize_credentials'], expected_randomize)
assert_equal(n0['onion']['reachable'], True)
assert_equal(n0['i2p']['reachable'], False)
+ assert_equal(n0['cjdns']['reachable'], False)
n1 = networks_dict(self.nodes[1].getnetworkinfo())
assert_equal(NETWORKS, n1.keys())
@@ -240,6 +274,7 @@ class ProxyTest(BitcoinTestFramework):
assert_equal(n2[net]['proxy_randomize_credentials'], expected_randomize)
assert_equal(n2['onion']['reachable'], True)
assert_equal(n2['i2p']['reachable'], False)
+ assert_equal(n2['cjdns']['reachable'], False)
if self.have_ipv6:
n3 = networks_dict(self.nodes[3].getnetworkinfo())
@@ -253,6 +288,22 @@ class ProxyTest(BitcoinTestFramework):
assert_equal(n3[net]['proxy_randomize_credentials'], False)
assert_equal(n3['onion']['reachable'], False)
assert_equal(n3['i2p']['reachable'], False)
+ assert_equal(n3['cjdns']['reachable'], False)
+
+ n4 = networks_dict(self.nodes[4].getnetworkinfo())
+ assert_equal(NETWORKS, n4.keys())
+ for net in NETWORKS:
+ if net == NET_I2P:
+ expected_proxy = ''
+ expected_randomize = False
+ else:
+ expected_proxy = '%s:%i' % (self.conf1.addr)
+ expected_randomize = True
+ assert_equal(n4[net]['proxy'], expected_proxy)
+ assert_equal(n4[net]['proxy_randomize_credentials'], expected_randomize)
+ assert_equal(n4['onion']['reachable'], True)
+ assert_equal(n4['i2p']['reachable'], False)
+ assert_equal(n4['cjdns']['reachable'], True)
if __name__ == '__main__':
diff --git a/test/functional/interface_bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py
index c28186cde7..ae665958b9 100755
--- a/test/functional/interface_bitcoin_cli.py
+++ b/test/functional/interface_bitcoin_cli.py
@@ -136,7 +136,7 @@ class TestBitcoinCli(BitcoinTestFramework):
network_info = self.nodes[0].getnetworkinfo()
cli_get_info_string = self.nodes[0].cli('-getinfo').send_cli()
cli_get_info = cli_get_info_string_to_dict(cli_get_info_string)
- assert_equal(cli_get_info["Proxies"], "127.0.0.1:9050 (ipv4, ipv6, onion), 127.0.0.1:7656 (i2p)")
+ assert_equal(cli_get_info["Proxies"], "127.0.0.1:9050 (ipv4, ipv6, onion, cjdns), 127.0.0.1:7656 (i2p)")
if self.is_wallet_compiled():
self.log.info("Test -getinfo and bitcoin-cli getwalletinfo return expected wallet info")
diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py
index 0f3bbce54c..0857f4e0ca 100755
--- a/test/functional/rpc_net.py
+++ b/test/functional/rpc_net.py
@@ -106,7 +106,7 @@ class NetTest(BitcoinTestFramework):
assert_equal(peer_info[1][1]['connection_type'], 'inbound')
# Check dynamically generated networks list in getpeerinfo help output.
- assert "(ipv4, ipv6, onion, i2p, not_publicly_routable)" in self.nodes[0].help("getpeerinfo")
+ assert "(ipv4, ipv6, onion, i2p, cjdns, not_publicly_routable)" in self.nodes[0].help("getpeerinfo")
def test_getnettotals(self):
self.log.info("Test getnettotals")
@@ -157,7 +157,7 @@ class NetTest(BitcoinTestFramework):
assert_net_servicesnames(int(info["localservices"], 0x10), info["localservicesnames"])
# Check dynamically generated networks list in getnetworkinfo help output.
- assert "(ipv4, ipv6, onion, i2p)" in self.nodes[0].help("getnetworkinfo")
+ assert "(ipv4, ipv6, onion, i2p, cjdns)" in self.nodes[0].help("getnetworkinfo")
def test_getaddednodeinfo(self):
self.log.info("Test getaddednodeinfo")
@@ -228,8 +228,8 @@ class NetTest(BitcoinTestFramework):
assert_equal(res[0]["port"], 8333)
assert_equal(res[0]["services"], P2P_SERVICES)
- # Test for the absence of onion and I2P addresses.
- for network in ["onion", "i2p"]:
+ # Test for the absence of onion, I2P and CJDNS addresses.
+ for network in ["onion", "i2p", "cjdns"]:
assert_equal(self.nodes[0].getnodeaddresses(0, network), [])
# Test invalid arguments.