diff options
author | Karl-Johan Alm <karljohan-alm@garage.co.jp> | 2018-06-27 17:21:07 +0900 |
---|---|---|
committer | Karl-Johan Alm <karljohan-alm@garage.co.jp> | 2019-03-14 08:48:46 +0900 |
commit | 6c0a6f73e3672bbec31b63d5046d591599aa21a8 (patch) | |
tree | cfe87fa9f25908a60c4b033b867c240c8ffc0c03 /src | |
parent | e5efacb941f78645462da1237ed04c75082d3aed (diff) |
wallet/rpc: add maxfeerate parameter to sendrawtransaction
Diffstat (limited to 'src')
-rw-r--r-- | src/rpc/client.cpp | 1 | ||||
-rw-r--r-- | src/rpc/rawtransaction.cpp | 30 | ||||
-rw-r--r-- | src/validation.cpp | 20 |
3 files changed, 44 insertions, 7 deletions
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index a266580b3d..c19160d325 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -92,6 +92,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "signrawtransactionwithkey", 2, "prevtxs" }, { "signrawtransactionwithwallet", 1, "prevtxs" }, { "sendrawtransaction", 1, "allowhighfees" }, + { "sendrawtransaction", 1, "maxfeerate" }, { "testmempoolaccept", 0, "rawtxs" }, { "testmempoolaccept", 1, "allowhighfees" }, { "combinerawtransaction", 0, "txs" }, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index d19afaa8a1..fedc30dc35 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -28,6 +28,7 @@ #include <script/standard.h> #include <uint256.h> #include <util/bip32.h> +#include <util/moneystr.h> #include <util/strencodings.h> #include <validation.h> #include <validationinterface.h> @@ -1039,7 +1040,7 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) "\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n", { {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"}, - {"allowhighfees", RPCArg::Type::BOOL, /* default */ "false", "Allow high fees"}, + {"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(maxTxFee), "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kB\n"}, }, RPCResult{ "\"hex\" (string) The transaction hash in hex\n" @@ -1056,7 +1057,10 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) }, }.ToString()); - RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); + RPCTypeCheck(request.params, { + UniValue::VSTR, + UniValueType(), // NUM or BOOL, checked later + }); // parse hex string from parameter CMutableTransaction mtx; @@ -1064,12 +1068,24 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); CTransactionRef tx(MakeTransactionRef(std::move(mtx))); - bool allowhighfees = false; - if (!request.params[1].isNull()) allowhighfees = request.params[1].get_bool(); - const CAmount highfee{allowhighfees ? 0 : ::maxTxFee}; + CAmount max_raw_tx_fee = maxTxFee; + // TODO: temporary migration code for old clients. Remove in v0.20 + if (request.params[1].isBool()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Second argument must be numeric (maxfeerate) and no longer supports a boolean. To allow a transaction with high fees, set maxfeerate to 0."); + } else if (request.params[1].isNum()) { + size_t weight = GetTransactionWeight(*tx); + CFeeRate fr(AmountFromValue(request.params[1])); + // the +3/4 part rounds the value up, and is the same formula used when + // calculating the fee for a transaction + // (see GetVirtualTransactionSize) + max_raw_tx_fee = fr.GetFee((weight+3)/4); + } else if (!request.params[1].isNull()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "second argument (maxfeerate) must be numeric"); + } + uint256 txid; std::string err_string; - const TransactionError err = BroadcastTransaction(tx, txid, err_string, highfee); + const TransactionError err = BroadcastTransaction(tx, txid, err_string, max_raw_tx_fee); if (TransactionError::OK != err) { throw JSONRPCTransactionError(err, err_string); } @@ -2048,7 +2064,7 @@ static const CRPCCommand commands[] = { "rawtransactions", "createrawtransaction", &createrawtransaction, {"inputs","outputs","locktime","replaceable"} }, { "rawtransactions", "decoderawtransaction", &decoderawtransaction, {"hexstring","iswitness"} }, { "rawtransactions", "decodescript", &decodescript, {"hexstring"} }, - { "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees"} }, + { "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees|maxfeerate"} }, { "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} }, { "hidden", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, { "rawtransactions", "signrawtransactionwithkey", &signrawtransactionwithkey, {"hexstring","privkeys","prevtxs","sighashtype"} }, diff --git a/src/validation.cpp b/src/validation.cpp index 358992b74d..e407c082b4 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3130,6 +3130,26 @@ static int GetWitnessCommitmentIndex(const CBlock& block) return commitpos; } +// Compute at which vout of the block's coinbase transaction the signet +// signature occurs, or -1 if not found. +static int GetSignetSignatureIndex(const CBlock& block) +{ + if (!block.vtx.empty()) { + for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) { + if (block.vtx[0]->vout[o].scriptPubKey.size() >= 68 // at minimum 64 byte signature plus script/header data + && block.vtx[0]->vout[o].scriptPubKey[0] == OP_RETURN // unspendable + && block.vtx[0]->vout[o].scriptPubKey[1] == block.vtx[0]->vout[o].scriptPubKey.size() - 1 // push the rest + && block.vtx[0]->vout[o].scriptPubKey[2] == 0xec // 's' ^ 0x9f + && block.vtx[0]->vout[o].scriptPubKey[3] == 0xc7 // 'i' ^ 0xae + && block.vtx[0]->vout[o].scriptPubKey[4] == 0xda // 'g' ^ 0xbd + && block.vtx[0]->vout[o].scriptPubKey[5] == 0xa2) { // 'n' ^ 0xcc + return (int)o; + } + } + } + return -1; +} + void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams) { int commitpos = GetWitnessCommitmentIndex(block); |