diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index d22809ce69..95c0680345 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -1193,6 +1193,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 1) ConvertTo(params[1]); if (strMethod == "signrawtransaction" && n > 1) ConvertTo(params[1], true); if (strMethod == "signrawtransaction" && n > 2) ConvertTo(params[2], true); + if (strMethod == "sendrawtransaction" && n > 1) ConvertTo(params[1], true); if (strMethod == "gettxout" && n > 1) ConvertTo(params[1]); if (strMethod == "gettxout" && n > 2) ConvertTo(params[2]); if (strMethod == "lockunspent" && n > 0) ConvertTo(params[0]); diff --git a/src/main.cpp b/src/main.cpp index 24fd1fadbc..b21e98413d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -787,7 +787,7 @@ void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins) } bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs) + bool* pfMissingInputs, bool fRejectInsaneFee) { if (pfMissingInputs) *pfMissingInputs = false; @@ -921,6 +921,11 @@ bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fL 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 // 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)) diff --git a/src/main.h b/src/main.h index a690a2bc9c..09e4700fbb 100644 --- a/src/main.h +++ b/src/main.h @@ -1082,7 +1082,7 @@ public: std::map mapTx; std::map 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 remove(const CTransaction &tx, bool fRecursive = false); bool removeConflicts(const CTransaction &tx); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 580120f2a2..3359e94cce 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -527,9 +527,9 @@ Value signrawtransaction(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( - "sendrawtransaction \n" + "sendrawtransaction [allowhighfees=false]\n" "Submits raw transaction (serialized, hex-encoded) to local node and network."); // parse hex string from parameter @@ -537,6 +537,10 @@ Value sendrawtransaction(const Array& params, bool fHelp) CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); CTransaction tx; + bool fOverrideFees = false; + if (params.size() > 1) + fOverrideFees = params[1].get_bool(); + // deserialize binary data stream try { ssData >> tx; @@ -554,7 +558,7 @@ Value sendrawtransaction(const Array& params, bool fHelp) if (!fHave) { // push to local node 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 } }