Skip to content

Commit 1acc61f

Browse files
committed
[build] Move rpc utility methods to rpc/util
Moves the following utility methods to rpc/util and moves that unit to libbitcoin_common so they can be accessed by all libraries. - `RPCTypeCheck` - `RPCTypeCheckArgument` - `RPCTypeCheckObj` - `AmountFromValue` - `ParseHashV``ParseHashO` - `ParseHexV` - `ParseHexO` - `HelpExampleCli` - `HelpExampleRpc`
1 parent 4a75c9d commit 1acc61f

File tree

6 files changed

+148
-148
lines changed

6 files changed

+148
-148
lines changed

src/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ libbitcoin_server_a_SOURCES = \
280280
rpc/net.cpp \
281281
rpc/rawtransaction.cpp \
282282
rpc/server.cpp \
283-
rpc/util.cpp \
284283
script/sigcache.cpp \
285284
shutdown.cpp \
286285
timedata.cpp \
@@ -440,6 +439,7 @@ libbitcoin_common_a_SOURCES = \
440439
policy/policy.cpp \
441440
protocol.cpp \
442441
psbt.cpp \
442+
rpc/util.cpp \
443443
scheduler.cpp \
444444
script/descriptor.cpp \
445445
script/ismine.cpp \

src/rpc/server.cpp

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -77,99 +77,6 @@ void RPCServer::OnStopped(std::function<void ()> slot)
7777
g_rpcSignals.Stopped.connect(slot);
7878
}
7979

80-
void RPCTypeCheck(const UniValue& params,
81-
const std::list<UniValueType>& typesExpected,
82-
bool fAllowNull)
83-
{
84-
unsigned int i = 0;
85-
for (const UniValueType& t : typesExpected) {
86-
if (params.size() <= i)
87-
break;
88-
89-
const UniValue& v = params[i];
90-
if (!(fAllowNull && v.isNull())) {
91-
RPCTypeCheckArgument(v, t);
92-
}
93-
i++;
94-
}
95-
}
96-
97-
void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected)
98-
{
99-
if (!typeExpected.typeAny && value.type() != typeExpected.type) {
100-
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected type %s, got %s", uvTypeName(typeExpected.type), uvTypeName(value.type())));
101-
}
102-
}
103-
104-
void RPCTypeCheckObj(const UniValue& o,
105-
const std::map<std::string, UniValueType>& typesExpected,
106-
bool fAllowNull,
107-
bool fStrict)
108-
{
109-
for (const auto& t : typesExpected) {
110-
const UniValue& v = find_value(o, t.first);
111-
if (!fAllowNull && v.isNull())
112-
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first));
113-
114-
if (!(t.second.typeAny || v.type() == t.second.type || (fAllowNull && v.isNull()))) {
115-
std::string err = strprintf("Expected type %s for %s, got %s",
116-
uvTypeName(t.second.type), t.first, uvTypeName(v.type()));
117-
throw JSONRPCError(RPC_TYPE_ERROR, err);
118-
}
119-
}
120-
121-
if (fStrict)
122-
{
123-
for (const std::string& k : o.getKeys())
124-
{
125-
if (typesExpected.count(k) == 0)
126-
{
127-
std::string err = strprintf("Unexpected key %s", k);
128-
throw JSONRPCError(RPC_TYPE_ERROR, err);
129-
}
130-
}
131-
}
132-
}
133-
134-
CAmount AmountFromValue(const UniValue& value)
135-
{
136-
if (!value.isNum() && !value.isStr())
137-
throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
138-
CAmount amount;
139-
if (!ParseFixedPoint(value.getValStr(), 8, &amount))
140-
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
141-
if (!MoneyRange(amount))
142-
throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
143-
return amount;
144-
}
145-
146-
uint256 ParseHashV(const UniValue& v, std::string strName)
147-
{
148-
std::string strHex(v.get_str());
149-
if (64 != strHex.length())
150-
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d, for '%s')", strName, 64, strHex.length(), strHex));
151-
if (!IsHex(strHex)) // Note: IsHex("") is false
152-
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
153-
return uint256S(strHex);
154-
}
155-
uint256 ParseHashO(const UniValue& o, std::string strKey)
156-
{
157-
return ParseHashV(find_value(o, strKey), strKey);
158-
}
159-
std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName)
160-
{
161-
std::string strHex;
162-
if (v.isStr())
163-
strHex = v.get_str();
164-
if (!IsHex(strHex))
165-
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
166-
return ParseHex(strHex);
167-
}
168-
std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey)
169-
{
170-
return ParseHexV(find_value(o, strKey), strKey);
171-
}
172-
17380
std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& helpreq) const
17481
{
17582
std::string strRet;
@@ -581,17 +488,6 @@ std::vector<std::string> CRPCTable::listCommands() const
581488
return commandList;
582489
}
583490

584-
std::string HelpExampleCli(const std::string& methodname, const std::string& args)
585-
{
586-
return "> bitcoin-cli " + methodname + " " + args + "\n";
587-
}
588-
589-
std::string HelpExampleRpc(const std::string& methodname, const std::string& args)
590-
{
591-
return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
592-
"\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
593-
}
594-
595491
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
596492
{
597493
if (!timerInterface)

src/rpc/server.h

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,6 @@ namespace RPCServer
2727
void OnStopped(std::function<void ()> slot);
2828
}
2929

30-
/** Wrapper for UniValue::VType, which includes typeAny:
31-
* Used to denote don't care type. */
32-
struct UniValueType {
33-
UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
34-
UniValueType() : typeAny(true) {}
35-
bool typeAny;
36-
UniValue::VType type;
37-
};
38-
3930
class JSONRPCRequest
4031
{
4132
public:
@@ -65,26 +56,6 @@ void SetRPCWarmupFinished();
6556
/* returns the current warmup state. */
6657
bool RPCIsInWarmup(std::string *outStatus);
6758

68-
/**
69-
* Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
70-
* the right number of arguments are passed, just that any passed are the correct type.
71-
*/
72-
void RPCTypeCheck(const UniValue& params,
73-
const std::list<UniValueType>& typesExpected, bool fAllowNull=false);
74-
75-
/**
76-
* Type-check one argument; throws JSONRPCError if wrong type given.
77-
*/
78-
void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected);
79-
80-
/*
81-
Check for expected keys/value types in an Object.
82-
*/
83-
void RPCTypeCheckObj(const UniValue& o,
84-
const std::map<std::string, UniValueType>& typesExpected,
85-
bool fAllowNull = false,
86-
bool fStrict = false);
87-
8859
/** Opaque base class for timers returned by NewTimerFunc.
8960
* This provides no methods at the moment, but makes sure that delete
9061
* cleans up the whole state.
@@ -204,19 +175,6 @@ bool IsDeprecatedRPCEnabled(const std::string& method);
204175

205176
extern CRPCTable tableRPC;
206177

207-
/**
208-
* Utilities: convert hex-encoded Values
209-
* (throws error if not hex).
210-
*/
211-
extern uint256 ParseHashV(const UniValue& v, std::string strName);
212-
extern uint256 ParseHashO(const UniValue& o, std::string strKey);
213-
extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
214-
extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
215-
216-
extern CAmount AmountFromValue(const UniValue& value);
217-
extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
218-
extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
219-
220178
void StartRPC();
221179
void InterruptRPC();
222180
void StopRPC();

src/rpc/util.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,110 @@
1010

1111
InitInterfaces* g_rpc_interfaces = nullptr;
1212

13+
void RPCTypeCheck(const UniValue& params,
14+
const std::list<UniValueType>& typesExpected,
15+
bool fAllowNull)
16+
{
17+
unsigned int i = 0;
18+
for (const UniValueType& t : typesExpected) {
19+
if (params.size() <= i)
20+
break;
21+
22+
const UniValue& v = params[i];
23+
if (!(fAllowNull && v.isNull())) {
24+
RPCTypeCheckArgument(v, t);
25+
}
26+
i++;
27+
}
28+
}
29+
30+
void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected)
31+
{
32+
if (!typeExpected.typeAny && value.type() != typeExpected.type) {
33+
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected type %s, got %s", uvTypeName(typeExpected.type), uvTypeName(value.type())));
34+
}
35+
}
36+
37+
void RPCTypeCheckObj(const UniValue& o,
38+
const std::map<std::string, UniValueType>& typesExpected,
39+
bool fAllowNull,
40+
bool fStrict)
41+
{
42+
for (const auto& t : typesExpected) {
43+
const UniValue& v = find_value(o, t.first);
44+
if (!fAllowNull && v.isNull())
45+
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first));
46+
47+
if (!(t.second.typeAny || v.type() == t.second.type || (fAllowNull && v.isNull()))) {
48+
std::string err = strprintf("Expected type %s for %s, got %s",
49+
uvTypeName(t.second.type), t.first, uvTypeName(v.type()));
50+
throw JSONRPCError(RPC_TYPE_ERROR, err);
51+
}
52+
}
53+
54+
if (fStrict)
55+
{
56+
for (const std::string& k : o.getKeys())
57+
{
58+
if (typesExpected.count(k) == 0)
59+
{
60+
std::string err = strprintf("Unexpected key %s", k);
61+
throw JSONRPCError(RPC_TYPE_ERROR, err);
62+
}
63+
}
64+
}
65+
}
66+
67+
CAmount AmountFromValue(const UniValue& value)
68+
{
69+
if (!value.isNum() && !value.isStr())
70+
throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
71+
CAmount amount;
72+
if (!ParseFixedPoint(value.getValStr(), 8, &amount))
73+
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
74+
if (!MoneyRange(amount))
75+
throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
76+
return amount;
77+
}
78+
79+
uint256 ParseHashV(const UniValue& v, std::string strName)
80+
{
81+
std::string strHex(v.get_str());
82+
if (64 != strHex.length())
83+
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d, for '%s')", strName, 64, strHex.length(), strHex));
84+
if (!IsHex(strHex)) // Note: IsHex("") is false
85+
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
86+
return uint256S(strHex);
87+
}
88+
uint256 ParseHashO(const UniValue& o, std::string strKey)
89+
{
90+
return ParseHashV(find_value(o, strKey), strKey);
91+
}
92+
std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName)
93+
{
94+
std::string strHex;
95+
if (v.isStr())
96+
strHex = v.get_str();
97+
if (!IsHex(strHex))
98+
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
99+
return ParseHex(strHex);
100+
}
101+
std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey)
102+
{
103+
return ParseHexV(find_value(o, strKey), strKey);
104+
}
105+
106+
std::string HelpExampleCli(const std::string& methodname, const std::string& args)
107+
{
108+
return "> bitcoin-cli " + methodname + " " + args + "\n";
109+
}
110+
111+
std::string HelpExampleRpc(const std::string& methodname, const std::string& args)
112+
{
113+
return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
114+
"\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
115+
}
116+
13117
// Converts a hex string to a public key if possible
14118
CPubKey HexToPubKey(const std::string& hex_in)
15119
{

src/rpc/util.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,48 @@ struct InitInterfaces;
2626
//! state to RPC method implementations.
2727
extern InitInterfaces* g_rpc_interfaces;
2828

29+
/** Wrapper for UniValue::VType, which includes typeAny:
30+
* Used to denote don't care type. */
31+
struct UniValueType {
32+
UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
33+
UniValueType() : typeAny(true) {}
34+
bool typeAny;
35+
UniValue::VType type;
36+
};
37+
38+
/**
39+
* Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
40+
* the right number of arguments are passed, just that any passed are the correct type.
41+
*/
42+
void RPCTypeCheck(const UniValue& params,
43+
const std::list<UniValueType>& typesExpected, bool fAllowNull=false);
44+
45+
/**
46+
* Type-check one argument; throws JSONRPCError if wrong type given.
47+
*/
48+
void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected);
49+
50+
/*
51+
Check for expected keys/value types in an Object.
52+
*/
53+
void RPCTypeCheckObj(const UniValue& o,
54+
const std::map<std::string, UniValueType>& typesExpected,
55+
bool fAllowNull = false,
56+
bool fStrict = false);
57+
58+
/**
59+
* Utilities: convert hex-encoded Values
60+
* (throws error if not hex).
61+
*/
62+
extern uint256 ParseHashV(const UniValue& v, std::string strName);
63+
extern uint256 ParseHashO(const UniValue& o, std::string strKey);
64+
extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
65+
extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
66+
67+
extern CAmount AmountFromValue(const UniValue& value);
68+
extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
69+
extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
70+
2971
CPubKey HexToPubKey(const std::string& hex_in);
3072
CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in);
3173
CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey>& pubkeys);

src/test/script_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include <util/system.h>
1414
#include <util/strencodings.h>
1515
#include <test/test_bitcoin.h>
16-
#include <rpc/server.h>
16+
#include <rpc/util.h>
1717

1818
#if defined(HAVE_CONSENSUS_LIB)
1919
#include <script/bitcoinconsensus.h>

0 commit comments

Comments
 (0)