Merge pull request #2949 from gmaxwell/fewer_fee_footguns
[raw] reject insanely high fees by default in sendrawtransaction
This commit is contained in:
commit
ff4e3e63e7
@ -1223,6 +1223,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
|
|||||||
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
|
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
|
||||||
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
|
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
|
||||||
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
|
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
|
||||||
|
if (strMethod == "sendrawtransaction" && n > 1) ConvertTo<bool>(params[1], true);
|
||||||
if (strMethod == "gettxout" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "gettxout" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
if (strMethod == "gettxout" && n > 2) ConvertTo<bool>(params[2]);
|
if (strMethod == "gettxout" && n > 2) ConvertTo<bool>(params[2]);
|
||||||
if (strMethod == "lockunspent" && n > 0) ConvertTo<bool>(params[0]);
|
if (strMethod == "lockunspent" && n > 0) ConvertTo<bool>(params[0]);
|
||||||
|
@ -787,7 +787,7 @@ void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fLimitFree,
|
bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fLimitFree,
|
||||||
bool* pfMissingInputs)
|
bool* pfMissingInputs, bool fRejectInsaneFee)
|
||||||
{
|
{
|
||||||
if (pfMissingInputs)
|
if (pfMissingInputs)
|
||||||
*pfMissingInputs = false;
|
*pfMissingInputs = false;
|
||||||
@ -921,6 +921,11 @@ bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fL
|
|||||||
dFreeCount += nSize;
|
dFreeCount += nSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fRejectInsaneFee && nFees > CTransaction::nMinRelayTxFee * 10000)
|
||||||
|
return error("CTxMemPool::accept() : insane fees %s, %"PRI64d" > %"PRI64d,
|
||||||
|
hash.ToString().c_str(),
|
||||||
|
nFees, CTransaction::nMinRelayTxFee * 10000);
|
||||||
|
|
||||||
// Check against previous transactions
|
// Check against previous transactions
|
||||||
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
|
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
|
||||||
if (!CheckInputs(tx, state, view, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC))
|
if (!CheckInputs(tx, state, view, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC))
|
||||||
|
@ -1086,7 +1086,7 @@ public:
|
|||||||
std::map<uint256, CTransaction> mapTx;
|
std::map<uint256, CTransaction> mapTx;
|
||||||
std::map<COutPoint, CInPoint> mapNextTx;
|
std::map<COutPoint, CInPoint> mapNextTx;
|
||||||
|
|
||||||
bool accept(CValidationState &state, const CTransaction &tx, bool fLimitFree, bool* pfMissingInputs);
|
bool accept(CValidationState &state, const CTransaction &tx, bool fLimitFree, bool* pfMissingInputs, bool fRejectInsaneFee = false);
|
||||||
bool addUnchecked(const uint256& hash, const CTransaction &tx);
|
bool addUnchecked(const uint256& hash, const CTransaction &tx);
|
||||||
bool remove(const CTransaction &tx, bool fRecursive = false);
|
bool remove(const CTransaction &tx, bool fRecursive = false);
|
||||||
bool removeConflicts(const CTransaction &tx);
|
bool removeConflicts(const CTransaction &tx);
|
||||||
|
@ -518,9 +518,9 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
Value sendrawtransaction(const Array& params, bool fHelp)
|
Value sendrawtransaction(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() < 1 || params.size() > 1)
|
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"sendrawtransaction <hex string>\n"
|
"sendrawtransaction <hex string> [allowhighfees=false]\n"
|
||||||
"Submits raw transaction (serialized, hex-encoded) to local node and network.");
|
"Submits raw transaction (serialized, hex-encoded) to local node and network.");
|
||||||
|
|
||||||
// parse hex string from parameter
|
// parse hex string from parameter
|
||||||
@ -528,6 +528,10 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
|||||||
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
CTransaction tx;
|
CTransaction tx;
|
||||||
|
|
||||||
|
bool fOverrideFees = false;
|
||||||
|
if (params.size() > 1)
|
||||||
|
fOverrideFees = params[1].get_bool();
|
||||||
|
|
||||||
// deserialize binary data stream
|
// deserialize binary data stream
|
||||||
try {
|
try {
|
||||||
ssData >> tx;
|
ssData >> tx;
|
||||||
@ -545,7 +549,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
|||||||
if (!fHave) {
|
if (!fHave) {
|
||||||
// push to local node
|
// push to local node
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!mempool.accept(state, tx, false, NULL))
|
if (!mempool.accept(state, tx, false, NULL, !fOverrideFees))
|
||||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); // TODO: report validation state
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); // TODO: report validation state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user