diff options
| author | Gregory Maxwell <[email protected]> | 2013-08-28 15:41:46 -0700 |
|---|---|---|
| committer | Gregory Maxwell <[email protected]> | 2013-08-28 15:49:51 -0700 |
| commit | 9d14e689c86a395c11a530767db4ddf895446ba8 (patch) | |
| tree | b02fee2fa8d600da274cb1871bb7d7e56aad60de /src | |
| parent | Merge pull request #2928 from jgarzik/cnb-txout (diff) | |
| download | discoin-9d14e689c86a395c11a530767db4ddf895446ba8.tar.xz discoin-9d14e689c86a395c11a530767db4ddf895446ba8.zip | |
[raw] reject insanely high fees by default in sendrawtransaction
There have been several incidents where mainnet experimentation with
raw transactions resulted in insane fees. This is hard to prevent
in the raw transaction api because the inputs may not be known.
Since sending doesn't work if the inputs aren't known, we can catch
it there.
This rejects fees > than 10000 * nMinRelayTxFee or 1 BTC with the
defaults and can be overridden with a bool at the rpc.
Diffstat (limited to 'src')
| -rw-r--r-- | src/bitcoinrpc.cpp | 1 | ||||
| -rw-r--r-- | src/main.cpp | 7 | ||||
| -rw-r--r-- | src/main.h | 2 | ||||
| -rw-r--r-- | src/rpcrawtransaction.cpp | 10 |
4 files changed, 15 insertions, 5 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index d22809ce6..95c068034 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -1193,6 +1193,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]); if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], 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 > 2) ConvertTo<bool>(params[2]); if (strMethod == "lockunspent" && n > 0) ConvertTo<bool>(params[0]); diff --git a/src/main.cpp b/src/main.cpp index 24fd1fadb..b21e98413 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 a690a2bc9..09e4700fb 100644 --- a/src/main.h +++ b/src/main.h @@ -1082,7 +1082,7 @@ public: std::map<uint256, CTransaction> mapTx; 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 remove(const CTransaction &tx, bool fRecursive = false); bool removeConflicts(const CTransaction &tx); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 580120f2a..3359e94cc 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 <hex string>\n" + "sendrawtransaction <hex string> [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 } } |