mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-11 07:37:54 +00:00
[rpc] fundrawtransaction feeRate: Use BTC/kB
Also introduce UniValueType UniValueType is a wrapper for UniValue::VType which allows setting a typeAny flag. This flag indicates the type does not matter. (Used by RPCTypeCheckObj)
This commit is contained in:
parent
faf82e8fc8
commit
fa7f4f577c
@ -681,9 +681,9 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||||||
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) # 1000 sat via settxfee
|
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'])
|
||||||
|
|
||||||
|
@ -675,7 +675,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");
|
||||||
|
|
||||||
@ -703,7 +708,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"));
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
@ -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
|
||||||
|
@ -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))
|
||||||
@ -2369,7 +2373,7 @@ 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 not set: makes wallet determine the fee) Set a specific feerate (satoshis 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"
|
||||||
@ -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());
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user