@@ -968,6 +968,54 @@ static RPCHelpMan addpeeraddress()
968
968
};
969
969
}
970
970
971
+ static RPCHelpMan sendmsgtopeer ()
972
+ {
973
+ return RPCHelpMan{
974
+ " sendmsgtopeer" ,
975
+ " Send a p2p message to a peer specified by id.\n "
976
+ " The message type and body must be provided, the message header will be generated.\n "
977
+ " This RPC is for testing only." ,
978
+ {
979
+ {" peer_id" , RPCArg::Type::NUM, RPCArg::Optional::NO, " The peer to send the message to." },
980
+ {" msg_type" , RPCArg::Type::STR, RPCArg::Optional::NO, strprintf (" The message type (maximum length %i)" , CMessageHeader::COMMAND_SIZE)},
981
+ {" msg" , RPCArg::Type::STR_HEX, RPCArg::Optional::NO, " The serialized message body to send, in hex, without a message header" },
982
+ },
983
+ RPCResult{RPCResult::Type::OBJ, " " , " " , std::vector<RPCResult>{}},
984
+ RPCExamples{
985
+ HelpExampleCli (" sendmsgtopeer" , " 0 \" addr\" \" ffffff\" " ) + HelpExampleRpc (" sendmsgtopeer" , " 0 \" addr\" \" ffffff\" " )},
986
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
987
+ const NodeId peer_id{request.params [0 ].getInt <int64_t >()};
988
+ const std::string& msg_type{request.params [1 ].get_str ()};
989
+ if (msg_type.size () > CMessageHeader::COMMAND_SIZE) {
990
+ throw JSONRPCError (RPC_INVALID_PARAMETER, strprintf (" Error: msg_type too long, max length is %i" , CMessageHeader::COMMAND_SIZE));
991
+ }
992
+ auto msg{TryParseHex<unsigned char >(request.params [2 ].get_str ())};
993
+ if (!msg.has_value ()) {
994
+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Error parsing input for msg" );
995
+ }
996
+
997
+ NodeContext& node = EnsureAnyNodeContext (request.context );
998
+ CConnman& connman = EnsureConnman (node);
999
+
1000
+ CSerializedNetMsg msg_ser;
1001
+ msg_ser.data = msg.value ();
1002
+ msg_ser.m_type = msg_type;
1003
+
1004
+ bool success = connman.ForNode (peer_id, [&](CNode* node) {
1005
+ connman.PushMessage (node, std::move (msg_ser));
1006
+ return true ;
1007
+ });
1008
+
1009
+ if (!success) {
1010
+ throw JSONRPCError (RPC_MISC_ERROR, " Error: Could not send message to peer" );
1011
+ }
1012
+
1013
+ UniValue ret{UniValue::VOBJ};
1014
+ return ret;
1015
+ },
1016
+ };
1017
+ }
1018
+
971
1019
void RegisterNetRPCCommands (CRPCTable& t)
972
1020
{
973
1021
static const CRPCCommand commands[]{
@@ -986,6 +1034,7 @@ void RegisterNetRPCCommands(CRPCTable& t)
986
1034
{" network" , &getnodeaddresses},
987
1035
{" hidden" , &addconnection},
988
1036
{" hidden" , &addpeeraddress},
1037
+ {" hidden" , &sendmsgtopeer},
989
1038
};
990
1039
for (const auto & c : commands) {
991
1040
t.appendCommand (c.name , &c);
0 commit comments