mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-10-10 11:33:46 +02:00
[rpc/net] Introduce addconnection to test outbounds & blockrelay
Add a new RPC endpoint to enable opening outbound connections from the tests. The functional test framework currently uses the addnode RPC, which has different behavior than general outbound peers. These changes enable creating both full-relay and block-relay-only connections. The new RPC endpoint calls through to a newly introduced AddConnection method on CConnman that ensures we stay within the allocated max.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <rpc/server.h>
|
||||
|
||||
#include <banman.h>
|
||||
#include <chainparams.h>
|
||||
#include <clientversion.h>
|
||||
#include <core_io.h>
|
||||
#include <net.h>
|
||||
@@ -314,6 +315,61 @@ static RPCHelpMan addnode()
|
||||
};
|
||||
}
|
||||
|
||||
static RPCHelpMan addconnection()
|
||||
{
|
||||
return RPCHelpMan{"addconnection",
|
||||
"\nOpen an outbound connection to a specified node. This RPC is for testing only.\n",
|
||||
{
|
||||
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address and port to attempt connecting to."},
|
||||
{"connection_type", RPCArg::Type::STR, RPCArg::Optional::NO, "Type of connection to open, either \"outbound-full-relay\" or \"block-relay-only\"."},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::OBJ, "", "",
|
||||
{
|
||||
{ RPCResult::Type::STR, "address", "Address of newly added connection." },
|
||||
{ RPCResult::Type::STR, "connection_type", "Type of connection opened." },
|
||||
}},
|
||||
RPCExamples{
|
||||
HelpExampleCli("addconnection", "\"192.168.0.6:8333\" \"outbound-full-relay\"")
|
||||
+ HelpExampleRpc("addconnection", "\"192.168.0.6:8333\" \"outbound-full-relay\"")
|
||||
},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
if (Params().NetworkIDString() != CBaseChainParams::REGTEST) {
|
||||
throw std::runtime_error("addconnection is for regression testing (-regtest mode) only.");
|
||||
}
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VSTR});
|
||||
const std::string address = request.params[0].get_str();
|
||||
const std::string conn_type_in{TrimString(request.params[1].get_str())};
|
||||
ConnectionType conn_type{};
|
||||
if (conn_type_in == "outbound-full-relay") {
|
||||
conn_type = ConnectionType::OUTBOUND_FULL_RELAY;
|
||||
} else if (conn_type_in == "block-relay-only") {
|
||||
conn_type = ConnectionType::BLOCK_RELAY;
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, self.ToString());
|
||||
}
|
||||
|
||||
NodeContext& node = EnsureNodeContext(request.context);
|
||||
if (!node.connman) {
|
||||
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled.");
|
||||
}
|
||||
|
||||
const bool success = node.connman->AddConnection(address, conn_type);
|
||||
if (!success) {
|
||||
throw JSONRPCError(RPC_CLIENT_NODE_CAPACITY_REACHED, "Error: Already at capacity for specified connection type.");
|
||||
}
|
||||
|
||||
UniValue info(UniValue::VOBJ);
|
||||
info.pushKV("address", address);
|
||||
info.pushKV("connection_type", conn_type_in);
|
||||
|
||||
return info;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static RPCHelpMan disconnectnode()
|
||||
{
|
||||
return RPCHelpMan{"disconnectnode",
|
||||
@@ -900,6 +956,8 @@ static const CRPCCommand commands[] =
|
||||
{ "network", "clearbanned", &clearbanned, {} },
|
||||
{ "network", "setnetworkactive", &setnetworkactive, {"state"} },
|
||||
{ "network", "getnodeaddresses", &getnodeaddresses, {"count"} },
|
||||
|
||||
{ "hidden", "addconnection", &addconnection, {"address", "connection_type"} },
|
||||
{ "hidden", "addpeeraddress", &addpeeraddress, {"address", "port"} },
|
||||
};
|
||||
// clang-format on
|
||||
|
Reference in New Issue
Block a user