Disable absurd fee checks when adding to the mempool
To protect users who are not using opreturn we prevent any use of z_sendmany with absurd fees if opreturn is not being used, so this change only affects users who are adding opreturn data. Since there is no way to currently send opreturn data via a GUI this still protects all GUI users from absurd fees while allowing CLI users to decide to use higher fees.
This commit is contained in:
14
src/main.cpp
14
src/main.cpp
@@ -1960,7 +1960,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
dFreeCount += nSize;
|
||||
}
|
||||
|
||||
if (!tx.IsCoinImport() && fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
|
||||
// Disable checks for absurd fees when adding to the mempool. Instead, this check is done
|
||||
// when a user attempts to make a transaction with an absurd fee and only rejects absurd
|
||||
// fees when OP_RETURN data is NOT being used. This means users making normal financial
|
||||
// transactions (z2z) are protected from absurd fees, it is only users who are storing
|
||||
// arbitrary data via a z2t transaction are allowed to (or potentially required) to pay high fees
|
||||
// It would be nice to detect the use of OP_RETURN right here but it seems to only be known
|
||||
// inside of IsStandard() inside of IsStandardTx() and we want to avoid doing expensive checks
|
||||
// multiple times.
|
||||
fRejectAbsurdFee = false;
|
||||
|
||||
if (fRejectAbsurdFee && !tx.IsCoinImport() && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
|
||||
{
|
||||
string errmsg = strprintf("absurdly high fees %s, %d > %d",
|
||||
hash.ToString(),
|
||||
@@ -1968,7 +1978,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
LogPrint("mempool", errmsg.c_str());
|
||||
return state.Error("AcceptToMemoryPool: " + errmsg);
|
||||
}
|
||||
//fprintf(stderr,"addmempool 6\n");
|
||||
//fprintf(stderr,"addmempool 6\n");
|
||||
|
||||
// Check against previous transactions
|
||||
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
|
||||
|
||||
@@ -5155,6 +5155,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
CAmount nTotalOut = 0;
|
||||
// Optional OP_RETURN data
|
||||
CScript opret;
|
||||
// TODO: enforce that only a single opreturn exists
|
||||
UniValue opretValue;
|
||||
|
||||
bool containsSaplingOutput = false;
|
||||
|
||||
@@ -5189,7 +5191,10 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
// throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+address);
|
||||
setAddress.insert(address);
|
||||
|
||||
UniValue opretValue = find_value(o, "opreturn");
|
||||
UniValue this_opret = find_value(o, "opreturn");
|
||||
if (!this_opret.isNull()) {
|
||||
opretValue = this_opret;
|
||||
}
|
||||
|
||||
// Create the CScript representation of the OP_RETURN
|
||||
if (!opretValue.isNull()) {
|
||||
@@ -5342,12 +5347,18 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
// or anything less than nDefaultFee instead of being forced to use a custom fee and leak metadata
|
||||
if (nTotalOut < nDefaultFee) {
|
||||
if (nFee > nDefaultFee) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Small transaction amount %s has fee %s that is greater than the default fee %s", FormatMoney(nTotalOut), FormatMoney(nFee), FormatMoney(nDefaultFee)));
|
||||
// Allow large fees if OP_RETURN is being used
|
||||
if( opretValue.isNull() ) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Small transaction amount %s has fee %s that is greater than the default fee %s", FormatMoney(nTotalOut), FormatMoney(nFee), FormatMoney(nDefaultFee)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check that the user specified fee is not absurd.
|
||||
if (nFee > nTotalOut) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the sum of outputs %s and also greater than the default fee", FormatMoney(nFee), FormatMoney(nTotalOut)));
|
||||
// Allow large fees if OP_RETURN is being used
|
||||
if( opretValue.isNull() ) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the sum of outputs %s and also greater than the default fee", FormatMoney(nFee), FormatMoney(nTotalOut)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user