@@ -69,37 +69,52 @@ void ProcessNetInfoPlatform(ProTx& ptx, const UniValue& input_p2p, const UniValu
6969
7070 auto process_field = [&](uint16_t & maybe_target, const UniValue& input, const NetInfoPurpose purpose,
7171 std::string_view field_name) {
72- if (!input.isNum () && !input.isStr ()) {
72+ if (!input.isArray () && !input. isNum () && !input.isStr ()) {
7373 throw JSONRPCError (RPC_INVALID_PARAMETER,
74- strprintf (" Invalid param for %s, must be number or string" , field_name));
74+ strprintf (" Invalid param for %s, must be array, number or string" , field_name));
7575 }
7676
77- const auto & input_str{input.getValStr ()};
78- if (input_str.empty ()) {
79- if (!optional) {
80- // Mandatory field, cannot specify blank value
81- throw JSONRPCError (RPC_INVALID_PARAMETER, strprintf (" Invalid param for %s, cannot be empty" , field_name));
77+ bool is_empty{input.isArray () ? input.get_array ().empty () : input.getValStr ().empty ()};
78+ bool is_nonnumeric_str{input.isStr () && !IsNumeric (input.getValStr ())};
79+ if (is_empty || is_nonnumeric_str || input.isArray ()) {
80+ if (is_empty) {
81+ if (!optional) {
82+ // Mandatory field, cannot specify blank value
83+ throw JSONRPCError (RPC_INVALID_PARAMETER,
84+ strprintf (" Invalid param for %s, cannot be empty" , field_name));
85+ }
86+ if (!ptx.netInfo ->IsEmpty ()) {
87+ // Blank values are tolerable so long as no other field has been populated.
88+ throw JSONRPCError (RPC_INVALID_PARAMETER,
89+ strprintf (" Invalid param for %s, cannot be empty if other fields populated" ,
90+ field_name));
91+ }
8292 }
8393 if (!ptx.netInfo ->CanStorePlatform ()) {
84- // We can tolerate blank values if netInfo can store platform fields, if it cannot, we are relying
85- // on platform{HTTP,P2P}Port, where it is mandatory even if their netInfo counterpart is optional.
94+ // Arrays: Expected to be address strings, if relying on platform{HTTP,P2P}Port, bail out.
95+ // Empty Input: We can tolerate blank values if netInfo can store platform fields, if it cannot, we are relying
96+ // on platform{HTTP,P2P}Port, where it is mandatory even if their netInfo counterpart is optional.
97+ // String: If not parsable as port and relying on platform{HTTP,P2P}Port, bail out.
8698 throw JSONRPCError (RPC_INVALID_PARAMETER,
8799 strprintf (" Invalid param for %s, ProTx version only supports ports" , field_name));
88100 }
89- if (!ptx.netInfo ->IsEmpty ()) {
90- // Blank values are tolerable so long as no other field has been populated.
91- throw JSONRPCError (RPC_INVALID_PARAMETER,
92- strprintf (" Invalid param for %s, cannot be empty if other fields populated" , field_name));
93- }
94- } else if (!IsNumeric (input_str)) {
95- // Cannot be parsed as a number (port) so must be an addr:port string
96- if (!ptx.netInfo ->CanStorePlatform ()) {
97- throw JSONRPCError (RPC_INVALID_PARAMETER,
98- strprintf (" Invalid param for %s, ProTx version only supports ports" , field_name));
101+ if (input.isArray ()) {
102+ const UniValue& entries = input.get_array ();
103+ for (size_t idx{0 }; idx < entries.size (); idx++) {
104+ const UniValue& entry{entries[idx]};
105+ if (!entry.isStr () || IsNumeric (entry.get_str ())) {
106+ throw JSONRPCError (RPC_INVALID_PARAMETER,
107+ strprintf (" Invalid param for %s[%zu], must be string" , field_name, idx));
108+ }
109+ ParseInput (ptx, field_name, entry.get_str (), purpose, idx, /* optional=*/ false );
110+ }
111+ } else {
112+ CHECK_NONFATAL (is_empty || is_nonnumeric_str);
113+ ParseInput (ptx, field_name, input.get_str (), purpose, /* idx=*/ 0 , /* optional=*/ true );
99114 }
100- ParseInput (ptx, field_name, input.get_str (), purpose, /* idx=*/ 0 , /* optional=*/ false );
101115 } else {
102- if (int32_t port{0 }; ParseInt32 (input_str, &port) && port >= 1 && port <= std::numeric_limits<uint16_t >::max ()) {
116+ if (int32_t port{0 };
117+ ParseInt32 (input.getValStr (), &port) && port >= 1 && port <= std::numeric_limits<uint16_t >::max ()) {
103118 // Valid port
104119 if (!ptx.netInfo ->CanStorePlatform ()) {
105120 maybe_target = static_cast <uint16_t >(port);
@@ -122,5 +137,5 @@ void ProcessNetInfoPlatform(ProTx& ptx, const UniValue& input_p2p, const UniValu
122137 process_field (ptx.platformP2PPort , input_p2p, NetInfoPurpose::PLATFORM_P2P, " platformP2PPort" );
123138 process_field (ptx.platformHTTPPort , input_http, NetInfoPurpose::PLATFORM_HTTPS, " platformHTTPPort" );
124139}
125- template void ProcessNetInfoPlatform (CProRegTx& ptx, const UniValue& input_p2p, const UniValue& input_http);
126- template void ProcessNetInfoPlatform (CProUpServTx& ptx, const UniValue& input_p2p, const UniValue& input_http);
140+ template void ProcessNetInfoPlatform (CProRegTx& ptx, const UniValue& input_p2p, const UniValue& input_http, const bool optional );
141+ template void ProcessNetInfoPlatform (CProUpServTx& ptx, const UniValue& input_p2p, const UniValue& input_http, const bool optional );
0 commit comments