Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: Investigate (re)enabling DNS support #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contrib/seeds/generate-seeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class BIP155Network(Enum):
TORV3 = 4
I2P = 5
CJDNS = 6
HOSTNAME = 1993

def name_to_bip155(addr):
'''Convert address string to BIP155 (networkID, addr) tuple.'''
Expand Down
4 changes: 4 additions & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ class CMainParams : public CChainParams {
pchMessageStart[1] = 0x0c;
pchMessageStart[2] = 0x6b;
pchMessageStart[3] = 0xbd;
// magic numbers and ports here
nDefaultPort = 9999;
nDefaultPlatformP2PPort = 26656;
nDefaultPlatformHTTPPort = 443;
Expand Down Expand Up @@ -431,6 +432,7 @@ class CTestNetParams : public CChainParams {
pchMessageStart[1] = 0xe2;
pchMessageStart[2] = 0xca;
pchMessageStart[3] = 0xff;
// more magic ports
nDefaultPort = 19999;
nDefaultPlatformP2PPort = 22000;
nDefaultPlatformHTTPPort = 22001;
Expand Down Expand Up @@ -603,6 +605,7 @@ class CDevNetParams : public CChainParams {
pchMessageStart[1] = 0xca;
pchMessageStart[2] = 0xff;
pchMessageStart[3] = 0xce;
// more magic ports
nDefaultPort = 19799;
nDefaultPlatformP2PPort = 22100;
nDefaultPlatformHTTPPort = 22101;
Expand Down Expand Up @@ -851,6 +854,7 @@ class CRegTestParams : public CChainParams {
pchMessageStart[1] = 0xc1;
pchMessageStart[2] = 0xb7;
pchMessageStart[3] = 0xdc;
// more magic ports
nDefaultPort = 19899;
nDefaultPlatformP2PPort = 22200;
nDefaultPlatformHTTPPort = 22201;
Expand Down
1 change: 1 addition & 0 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,7 @@ static bool CheckService(const ProTx& proTx, TxValidationState& state)
}

static int mainnetDefaultPort = CreateChainParams(CBaseChainParams::MAIN)->GetDefaultPort();
// DON'T HARD CODE IT, DUH!
if (Params().NetworkIDString() == CBaseChainParams::MAIN) {
if (proTx.addr.GetPort() != mainnetDefaultPort) {
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-ipaddr-port");
Expand Down
1 change: 1 addition & 0 deletions src/evo/providertx.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class CBlockIndex;
class CCoinsViewCache;
class TxValidationState;

// CProRegTx is defined here
class CProRegTx
{
public:
Expand Down
13 changes: 13 additions & 0 deletions src/netaddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ CNetAddr::BIP155Network CNetAddr::GetBIP155Network() const
return BIP155Network::I2P;
case NET_CJDNS:
return BIP155Network::CJDNS;
case NET_HOSTNAME:
return BIP155Network::HOSTNAME;
case NET_INTERNAL: // should have been handled before calling this function
case NET_UNROUTABLE: // m_net is never and should not be set to NET_UNROUTABLE
case NET_MAX: // m_net is never and should not be set to NET_MAX
Expand Down Expand Up @@ -88,6 +90,14 @@ bool CNetAddr::SetNetFromBIP155Network(uint8_t possible_bip155_net, size_t addre
throw std::ios_base::failure(
strprintf("BIP155 CJDNS address with length %u (should be %u)", address_size,
ADDR_CJDNS_SIZE));
case BIP155Network::HOSTNAME:
if (address_size == ADDR_HOSTNAME_SIZE) {
m_net = NET_HOSTNAME;
return true;
}
throw std::ios_base::failure(
strprintf("BIP155 HOSTNAME address with length %u (should be %u)", address_size,
ADDR_HOSTNAME_SIZE));
}

// Don't throw on addresses with unknown network ids (maybe from the future).
Expand Down Expand Up @@ -124,6 +134,9 @@ void CNetAddr::SetIP(const CNetAddr& ipIn)
case NET_CJDNS:
assert(ipIn.m_addr.size() == ADDR_CJDNS_SIZE);
break;
case NET_HOSTNAME:
assert(ipIn.m_addr.size() <= ADDR_HOSTNAME_SIZE);
break;
case NET_INTERNAL:
assert(ipIn.m_addr.size() == ADDR_INTERNAL_SIZE);
break;
Expand Down
17 changes: 17 additions & 0 deletions src/netaddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ enum Network {
/// CJDNS
NET_CJDNS,

/// Hostname
NET_HOSTNAME,

/// A set of addresses that represent the hash of a string or FQDN. We use
/// them in CAddrMan to keep track of which DNS seeds were used.
NET_INTERNAL,
Expand Down Expand Up @@ -105,6 +108,10 @@ static constexpr size_t ADDR_I2P_SIZE = 32;
/// Size of CJDNS address (in bytes).
static constexpr size_t ADDR_CJDNS_SIZE = 16;

/// Size of Hostname (in bytes). This is the maximum length of all labels and
/// dots as per RFC 1035 Size limits (Section 2.3.4.)
static constexpr size_t ADDR_HOSTNAME_SIZE = 255;

/// Size of "internal" (NET_INTERNAL) address (in bytes).
static constexpr size_t ADDR_INTERNAL_SIZE = 10;

Expand All @@ -114,6 +121,7 @@ static constexpr uint16_t I2P_SAM31_PORT{0};
/**
* Network address.
*/
// CNetAddr is defined here for IPv6 or IPv4
class CNetAddr
{
protected:
Expand Down Expand Up @@ -164,8 +172,12 @@ class CNetAddr
* @returns Whether the operation was successful.
* @see CNetAddr::IsTor(), CNetAddr::IsI2P()
*/
// Hmmm... looks like hostnames (DNS) *can* fit after all?
bool SetSpecial(const std::string& addr);

// What might this look like??
bool SetHostname(const std::string& addr);

bool IsBindAny() const; // INADDR_ANY equivalent
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor)
Expand All @@ -187,6 +199,7 @@ class CNetAddr
bool IsTor() const;
bool IsI2P() const;
bool IsCJDNS() const;
bool IsHostname() const;
bool IsLocal() const;
bool IsRoutable() const;
bool IsInternal() const;
Expand Down Expand Up @@ -282,6 +295,8 @@ class CNetAddr
TORV3 = 4,
I2P = 5,
CJDNS = 6,
// add Hostname support here (and rename the enum?)
HOSTNAME = 1993,
};

/**
Expand Down Expand Up @@ -339,6 +354,7 @@ class CNetAddr
case NET_ONION:
case NET_I2P:
case NET_CJDNS:
case NET_HOSTNAME:
break;
case NET_UNROUTABLE:
case NET_MAX:
Expand Down Expand Up @@ -518,6 +534,7 @@ class CSubNet
};

/** A combination of a network address (CNetAddr) and a (TCP) port */
// CService is defined here
class CService : public CNetAddr
{
protected:
Expand Down
4 changes: 3 additions & 1 deletion src/netbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ enum Network ParseNetwork(const std::string& net_in) {
if (net == "ipv4") return NET_IPV4;
if (net == "ipv6") return NET_IPV6;
if (net == "onion") return NET_ONION;
if (net == "hostname") return NET_HOSTNAME;
if (net == "tor") {
LogPrintf("Warning: net name 'tor' is deprecated and will be removed in the future. You should use 'onion' instead.\n");
return NET_ONION;
Expand All @@ -109,6 +110,7 @@ std::string GetNetworkName(enum Network net)
case NET_ONION: return "onion";
case NET_I2P: return "i2p";
case NET_CJDNS: return "cjdns";
case NET_HOSTNAME: return "hostname";
case NET_INTERNAL: return "internal";
case NET_MAX: assert(false);
} // no default case, so the compiler can warn about missing cases
Expand All @@ -121,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_HOSTNAME || network == NET_CJDNS || network == NET_INTERNAL) continue;
names.emplace_back(GetNetworkName(network));
}
if (append_unroutable) {
Expand Down
35 changes: 19 additions & 16 deletions src/rpc/evo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,15 @@ static RPCArg GetRpcArg(const std::string& strParamName)
"If not specified, payoutAddress is the one that is going to be used.\n"
"The private key belonging to this address must be known in your wallet."}
},
{"ipAndPort",
{"ipAndPort", RPCArg::Type::STR, RPCArg::Optional::NO,
"IP and port in the form \"IP:PORT\". Must be unique on the network.\n"
// ip or hostname, and port
{"hostnameAndPort",
{"hostnameAndPort", RPCArg::Type::STR, RPCArg::Optional::NO,
"Host in the form \"HOSTNAME:PORT\". Must be unique on the network.\n"
"Can be set to an empty string, which will require a ProUpServTx afterwards."}
},
{"ipAndPort_update",
{"ipAndPort", RPCArg::Type::STR, RPCArg::Optional::NO,
"IP and port in the form \"IP:PORT\". Must be unique on the network."}
{"hostnameAndPort_update",
{"hostnameAndPort", RPCArg::Type::STR, RPCArg::Optional::NO,
"Host in the form \"HOSTNAME:PORT\". Must be unique on the network."}
},
{"operatorKey",
{"operatorKey", RPCArg::Type::STR, RPCArg::Optional::NO,
Expand Down Expand Up @@ -367,7 +368,7 @@ static void protx_register_fund_help(const JSONRPCRequest& request, bool legacy)
+ HELP_REQUIRING_PASSPHRASE,
{
GetRpcArg("collateralAddress"),
GetRpcArg("ipAndPort"),
GetRpcArg("hostnameAndPort"),
GetRpcArg("ownerAddress"),
legacy ? GetRpcArg("operatorPubKey_register_legacy") : GetRpcArg("operatorPubKey_register"),
GetRpcArg("votingAddress_register"),
Expand Down Expand Up @@ -402,7 +403,7 @@ static void protx_register_help(const JSONRPCRequest& request, bool legacy)
{
GetRpcArg("collateralHash"),
GetRpcArg("collateralIndex"),
GetRpcArg("ipAndPort"),
GetRpcArg("hostnameAndPort"),
GetRpcArg("ownerAddress"),
legacy ? GetRpcArg("operatorPubKey_register_legacy") : GetRpcArg("operatorPubKey_register"),
GetRpcArg("votingAddress_register"),
Expand Down Expand Up @@ -436,7 +437,7 @@ static void protx_register_prepare_help(const JSONRPCRequest& request, bool lega
{
GetRpcArg("collateralHash"),
GetRpcArg("collateralIndex"),
GetRpcArg("ipAndPort"),
GetRpcArg("hostnameAndPort"),
GetRpcArg("ownerAddress"),
legacy ? GetRpcArg("operatorPubKey_register_legacy") : GetRpcArg("operatorPubKey_register"),
GetRpcArg("votingAddress_register"),
Expand Down Expand Up @@ -489,7 +490,7 @@ static void protx_register_fund_evo_help(const JSONRPCRequest& request)
HELP_REQUIRING_PASSPHRASE,
{
GetRpcArg("collateralAddress"),
GetRpcArg("ipAndPort"),
GetRpcArg("hostnameAndPort"),
GetRpcArg("ownerAddress"),
GetRpcArg("operatorPubKey_register"),
GetRpcArg("votingAddress_register"),
Expand Down Expand Up @@ -523,7 +524,7 @@ static void protx_register_evo_help(const JSONRPCRequest& request)
{
GetRpcArg("collateralHash"),
GetRpcArg("collateralIndex"),
GetRpcArg("ipAndPort"),
GetRpcArg("hostnameAndPort"),
GetRpcArg("ownerAddress"),
GetRpcArg("operatorPubKey_register"),
GetRpcArg("votingAddress_register"),
Expand Down Expand Up @@ -556,7 +557,7 @@ static void protx_register_prepare_evo_help(const JSONRPCRequest& request)
{
GetRpcArg("collateralHash"),
GetRpcArg("collateralIndex"),
GetRpcArg("ipAndPort"),
GetRpcArg("hostnameAndPort"),
GetRpcArg("ownerAddress"),
GetRpcArg("operatorPubKey_register"),
GetRpcArg("votingAddress_register"),
Expand Down Expand Up @@ -619,11 +620,12 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
size_t paramIdx = 0;

CMutableTransaction tx;
tx.nVersion = 3;
tx.nVersion = 3; // EVO SEND!!
tx.nType = TRANSACTION_PROVIDER_REGISTER;

const bool use_legacy = isV19active ? specific_legacy_bls_scheme : true;

// This is the type that packs the IP presently
CProRegTx ptx;
ptx.nType = mnType;

Expand Down Expand Up @@ -654,8 +656,9 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
wallet->LockCoin(ptx.collateralOutpoint);
}

// paramIdx is now for hostnameAndPort
if (request.params[paramIdx].get_str() != "") {
if (!Lookup(request.params[paramIdx].get_str().c_str(), ptx.addr, Params().GetDefaultPort(), false)) {
if (!Lookup(request.params[paramIdx].get_str().c_str(), ptx.addr, Params().GetDefaultPort(), g_dns_lookup)) {
throw std::runtime_error(strprintf("invalid network address %s", request.params[paramIdx].get_str()));
}
}
Expand Down Expand Up @@ -856,7 +859,7 @@ static void protx_update_service_help(const JSONRPCRequest& request)
+ HELP_REQUIRING_PASSPHRASE,
{
GetRpcArg("proTxHash"),
GetRpcArg("ipAndPort_update"),
GetRpcArg("hostnameAndPort_update"),
GetRpcArg("operatorKey"),
GetRpcArg("operatorPayoutAddress"),
GetRpcArg("feeSourceAddress"),
Expand All @@ -880,7 +883,7 @@ static void protx_update_service_evo_help(const JSONRPCRequest& request)
HELP_REQUIRING_PASSPHRASE,
{
GetRpcArg("proTxHash"),
GetRpcArg("ipAndPort_update"),
GetRpcArg("hostnameAndPort_update"),
GetRpcArg("operatorKey"),
GetRpcArg("platformNodeID"),
GetRpcArg("platformP2PPort"),
Expand Down
4 changes: 2 additions & 2 deletions src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static UniValue getpeerinfo(const JSONRPCRequest& request)
{
{
{RPCResult::Type::NUM, "id", "Peer index"},
{RPCResult::Type::STR, "addr", "(host:port) The IP address and port of the peer"},
{RPCResult::Type::STR, "addr", "(hostname:port) The Hostname (or IP address) and port of the peer"},
{RPCResult::Type::STR, "addrbind", "(ip:port) Bind address of the connection to the peer"},
{RPCResult::Type::STR, "addrlocal", "(ip:port) Local address as reported by the peer"},
{RPCResult::Type::STR, "network", "Network (" + Join(GetNetworkNames(/* append_unroutable */ true), ", ") + ")"},
Expand Down Expand Up @@ -461,7 +461,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_HOSTNAME || network == NET_CJDNS || network == NET_INTERNAL) continue;
proxyType proxy;
UniValue obj(UniValue::VOBJ);
GetProxy(network, proxy);
Expand Down
4 changes: 2 additions & 2 deletions test/functional/feature_llmq_evo.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,11 +231,11 @@ def test_evo_is_rejected_before_v19(self):
break
assert collateral_vout is not None

ipAndPort = '127.0.0.1:%d' % p2p_port(len(self.nodes))
hostnameAndPort = 'localhost:%d' % p2p_port(len(self.nodes))
operatorReward = len(self.nodes)

try:
self.nodes[0].protx('register_evo', collateral_txid, collateral_vout, ipAndPort, owner_address, bls['public'], voting_address, operatorReward, reward_address, funds_address, True)
self.nodes[0].protx('register_evo', collateral_txid, collateral_vout, hostnameAndPort, owner_address, bls['public'], voting_address, operatorReward, reward_address, funds_address, True)
# this should never succeed
assert False
except:
Expand Down
18 changes: 9 additions & 9 deletions test/functional/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -1223,21 +1223,21 @@ def dynamically_prepare_masternode(self, idx, node_p2p_port, evo=False, rnd=None
break
assert collateral_vout is not None

ipAndPort = '127.0.0.1:%d' % node_p2p_port
hostnameAndPort = 'localhost:%d' % node_p2p_port
operatorReward = idx

protx_result = None
if evo:
protx_result = self.nodes[0].protx("register_evo", collateral_txid, collateral_vout, ipAndPort, owner_address, bls['public'], voting_address, operatorReward, reward_address, platform_node_id, platform_p2p_port, platform_http_port, funds_address, True)
protx_result = self.nodes[0].protx("register_evo", collateral_txid, collateral_vout, hostnameAndPort, owner_address, bls['public'], voting_address, operatorReward, reward_address, platform_node_id, platform_p2p_port, platform_http_port, funds_address, True)
else:
protx_result = self.nodes[0].protx("register", collateral_txid, collateral_vout, ipAndPort, owner_address, bls['public'], voting_address, operatorReward, reward_address, funds_address, True)
protx_result = self.nodes[0].protx("register", collateral_txid, collateral_vout, hostnameAndPort, owner_address, bls['public'], voting_address, operatorReward, reward_address, funds_address, True)

self.wait_for_instantlock(protx_result, self.nodes[0])
tip = self.nodes[0].generate(1)[0]
self.sync_all(self.nodes)

assert_equal(self.nodes[0].getrawtransaction(protx_result, 1, tip)['confirmations'], 1)
mn_info = MasternodeInfo(protx_result, owner_address, voting_address, reward_address, operatorReward, bls['public'], bls['secret'], collateral_address, collateral_txid, collateral_vout, ipAndPort, evo)
mn_info = MasternodeInfo(protx_result, owner_address, voting_address, reward_address, operatorReward, bls['public'], bls['secret'], collateral_address, collateral_txid, collateral_vout, hostnameAndPort, evo)
self.mninfo.append(mn_info)

mn_type_str = "EvoNode" if evo else "MN"
Expand Down Expand Up @@ -1307,16 +1307,16 @@ def prepare_masternode(self, idx):
votingAddr = ownerAddr

port = p2p_port(len(self.nodes) + idx)
ipAndPort = '127.0.0.1:%d' % port
hostnameAndPort = 'localhost:%d' % port
operatorReward = idx

submit = (idx % 4) < 2

if register_fund:
protx_result = self.nodes[0].protx('register_fund', address, ipAndPort, ownerAddr, bls['public'], votingAddr, operatorReward, rewardsAddr, address, submit)
protx_result = self.nodes[0].protx('register_fund', address, hostnameAndPort, ownerAddr, bls['public'], votingAddr, operatorReward, rewardsAddr, address, submit)
else:
self.nodes[0].generate(1)
protx_result = self.nodes[0].protx('register', txid, collateral_vout, ipAndPort, ownerAddr, bls['public'], votingAddr, operatorReward, rewardsAddr, address, submit)
protx_result = self.nodes[0].protx('register', txid, collateral_vout, hostnameAndPort, ownerAddr, bls['public'], votingAddr, operatorReward, rewardsAddr, address, submit)

if submit:
proTxHash = protx_result
Expand All @@ -1326,9 +1326,9 @@ def prepare_masternode(self, idx):
if operatorReward > 0:
self.nodes[0].generate(1)
operatorPayoutAddress = self.nodes[0].getnewaddress()
self.nodes[0].protx('update_service', proTxHash, ipAndPort, bls['secret'], operatorPayoutAddress, address)
self.nodes[0].protx('update_service', proTxHash, hostnameAndPort, bls['secret'], operatorPayoutAddress, address)

self.mninfo.append(MasternodeInfo(proTxHash, ownerAddr, votingAddr, rewardsAddr, operatorReward, bls['public'], bls['secret'], address, txid, collateral_vout, ipAndPort, False))
self.mninfo.append(MasternodeInfo(proTxHash, ownerAddr, votingAddr, rewardsAddr, operatorReward, bls['public'], bls['secret'], address, txid, collateral_vout, hostnameAndPort, False))

self.log.info("Prepared MN %d: collateral_txid=%s, collateral_vout=%d, protxHash=%s" % (idx, txid, collateral_vout, proTxHash))

Expand Down