Skip to content

Commit

Permalink
Merge #8153: [rpc] fundrawtransaction feeRate: Use BTC/kB
Browse files Browse the repository at this point in the history
fa7f4f5 [rpc] fundrawtransaction feeRate: Use BTC/kB (MarcoFalke)
faf82e8 [rpc] fundrawtransaction: Fix help text and interface (MarcoFalke)
  • Loading branch information
laanwj committed Jun 8, 2016
2 parents a7c41f2 + fa7f4f5 commit 75ec320
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 21 deletions.
6 changes: 3 additions & 3 deletions qa/rpc-tests/fundrawtransaction.py
Expand Up @@ -681,9 +681,9 @@ def run_test(self):
inputs = [] inputs = []
outputs = {self.nodes[2].getnewaddress() : 1} outputs = {self.nodes[2].getnewaddress() : 1}
rawtx = self.nodes[3].createrawtransaction(inputs, outputs) rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
result = self.nodes[3].fundrawtransaction(rawtx, ) result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee)
result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2000}) result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee})
result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10000}) result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10*min_relay_tx_fee})
assert_equal(result['fee']*2, result2['fee']) assert_equal(result['fee']*2, result2['fee'])
assert_equal(result['fee']*10, result3['fee']) assert_equal(result['fee']*10, result3['fee'])


Expand Down
15 changes: 13 additions & 2 deletions src/rpc/rawtransaction.cpp
Expand Up @@ -682,7 +682,12 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)


UniValue prevOut = p.get_obj(); UniValue prevOut = p.get_obj();


RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)); RPCTypeCheckObj(prevOut,
{
{"txid", UniValueType(UniValue::VSTR)},
{"vout", UniValueType(UniValue::VNUM)},
{"scriptPubKey", UniValueType(UniValue::VSTR)},
});


uint256 txid = ParseHashO(prevOut, "txid"); uint256 txid = ParseHashO(prevOut, "txid");


Expand Down Expand Up @@ -710,7 +715,13 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
// if redeemScript given and not using the local wallet (private keys // if redeemScript given and not using the local wallet (private keys
// given), add redeemScript to the tempKeystore so it can be signed: // given), add redeemScript to the tempKeystore so it can be signed:
if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) { if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR)); RPCTypeCheckObj(prevOut,
{
{"txid", UniValueType(UniValue::VSTR)},
{"vout", UniValueType(UniValue::VNUM)},
{"scriptPubKey", UniValueType(UniValue::VSTR)},
{"redeemScript", UniValueType(UniValue::VSTR)},
});
UniValue v = find_value(prevOut, "redeemScript"); UniValue v = find_value(prevOut, "redeemScript");
if (!v.isNull()) { if (!v.isNull()) {
vector<unsigned char> rsData(ParseHexV(v, "redeemScript")); vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
Expand Down
14 changes: 6 additions & 8 deletions src/rpc/server.cpp
Expand Up @@ -88,20 +88,18 @@ void RPCTypeCheck(const UniValue& params,
} }


void RPCTypeCheckObj(const UniValue& o, void RPCTypeCheckObj(const UniValue& o,
const map<string, UniValue::VType>& typesExpected, const map<string, UniValueType>& typesExpected,
bool fAllowNull, bool fAllowNull,
bool fStrict) bool fStrict)
{ {
BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected) for (const auto& t : typesExpected) {
{
const UniValue& v = find_value(o, t.first); const UniValue& v = find_value(o, t.first);
if (!fAllowNull && v.isNull()) if (!fAllowNull && v.isNull())
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first)); throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first));


if (!((v.type() == t.second) || (fAllowNull && (v.isNull())))) if (!(t.second.typeAny || v.type() == t.second.type || (fAllowNull && v.isNull()))) {
{
string err = strprintf("Expected type %s for %s, got %s", string err = strprintf("Expected type %s for %s, got %s",
uvTypeName(t.second), t.first, uvTypeName(v.type())); uvTypeName(t.second.type), t.first, uvTypeName(v.type()));
throw JSONRPCError(RPC_TYPE_ERROR, err); throw JSONRPCError(RPC_TYPE_ERROR, err);
} }
} }
Expand Down
15 changes: 12 additions & 3 deletions src/rpc/server.h
Expand Up @@ -32,6 +32,15 @@ namespace RPCServer
class CBlockIndex; class CBlockIndex;
class CNetAddr; class CNetAddr;


/** Wrapper for UniValue::VType, which includes typeAny:
* Used to denote don't care type. Only used by RPCTypeCheckObj */
struct UniValueType {
UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
UniValueType() : typeAny(true) {}
bool typeAny;
UniValue::VType type;
};

class JSONRequest class JSONRequest
{ {
public: public:
Expand Down Expand Up @@ -60,17 +69,17 @@ bool RPCIsInWarmup(std::string *statusOut);
/** /**
* Type-check arguments; throws JSONRPCError if wrong type given. Does not check that * Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
* the right number of arguments are passed, just that any passed are the correct type. * the right number of arguments are passed, just that any passed are the correct type.
* Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type));
*/ */
void RPCTypeCheck(const UniValue& params, void RPCTypeCheck(const UniValue& params,
const std::list<UniValue::VType>& typesExpected, bool fAllowNull=false); const std::list<UniValue::VType>& typesExpected, bool fAllowNull=false);


/* /*
Check for expected keys/value types in an Object. Check for expected keys/value types in an Object.
Use like: RPCTypeCheckObj(object, boost::assign::map_list_of("name", str_type)("value", int_type));
*/ */
void RPCTypeCheckObj(const UniValue& o, void RPCTypeCheckObj(const UniValue& o,
const std::map<std::string, UniValue::VType>& typesExpected, bool fAllowNull=false, bool fStrict=false); const std::map<std::string, UniValueType>& typesExpected,
bool fAllowNull = false,
bool fStrict = false);


/** Opaque base class for timers returned by NewTimerFunc. /** Opaque base class for timers returned by NewTimerFunc.
* This provides no methods at the moment, but makes sure that delete * This provides no methods at the moment, but makes sure that delete
Expand Down
22 changes: 17 additions & 5 deletions src/wallet/rpcwallet.cpp
Expand Up @@ -2069,7 +2069,11 @@ UniValue lockunspent(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
const UniValue& o = output.get_obj(); const UniValue& o = output.get_obj();


RPCTypeCheckObj(o, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)); RPCTypeCheckObj(o,
{
{"txid", UniValueType(UniValue::VSTR)},
{"vout", UniValueType(UniValue::VNUM)},
});


string txid = find_value(o, "txid").get_str(); string txid = find_value(o, "txid").get_str();
if (!IsHex(txid)) if (!IsHex(txid))
Expand Down Expand Up @@ -2369,13 +2373,13 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
" \"changePosition\" (numeric, optional, default random) The index of the change output\n" " \"changePosition\" (numeric, optional, default random) The index of the change output\n"
" \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
" \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
" \"feeRate\" (numeric, optional, default 0=estimate) Set a specific feerate (fee per KB)\n" " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n"
" }\n" " }\n"
" for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n" " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
"\nResult:\n" "\nResult:\n"
"{\n" "{\n"
" \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n" " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n"
" \"fee\": n, (numeric) Fee the resulting transaction pays\n" " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n"
" \"changepos\": n (numeric) The position of the added change output, or -1\n" " \"changepos\": n (numeric) The position of the added change output, or -1\n"
"}\n" "}\n"
"\"hex\" \n" "\"hex\" \n"
Expand Down Expand Up @@ -2409,7 +2413,15 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)


UniValue options = params[1]; UniValue options = params[1];


RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL)("feeRate", UniValue::VNUM), true, true); RPCTypeCheckObj(options,
{
{"changeAddress", UniValueType(UniValue::VSTR)},
{"changePosition", UniValueType(UniValue::VNUM)},
{"includeWatching", UniValueType(UniValue::VBOOL)},
{"lockUnspents", UniValueType(UniValue::VBOOL)},
{"feeRate", UniValueType()}, // will be checked below
},
true, true);


if (options.exists("changeAddress")) { if (options.exists("changeAddress")) {
CBitcoinAddress address(options["changeAddress"].get_str()); CBitcoinAddress address(options["changeAddress"].get_str());
Expand All @@ -2431,7 +2443,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)


if (options.exists("feeRate")) if (options.exists("feeRate"))
{ {
feeRate = CFeeRate(options["feeRate"].get_real()); feeRate = CFeeRate(AmountFromValue(options["feeRate"]));
overrideEstimatedFeerate = true; overrideEstimatedFeerate = true;
} }
} }
Expand Down

0 comments on commit 75ec320

Please sign in to comment.