Merge pull request 'OP_RETURN fees' (#429) from opretfees into dev
Reviewed-on: https://git.hush.is/hush/hush3/pulls/429
This commit is contained in:
@@ -479,7 +479,6 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
if (showDebug)
|
||||
strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)",
|
||||
CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK())));
|
||||
strUsage += HelpMessageOpt("-opretmintxfee=<amt>", strprintf(_("Minimum fee (in %s/kB) to allow for OP_RETURN transactions (default: %s)"), CURRENCY_UNIT, 400000 ));
|
||||
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
|
||||
// If this is used incorrectly (-rescanheight too large), then the local wallet may attempt to spend funds which it does not have witness data about
|
||||
// which will cause a "missing inputs" error when added to the mempool. Rescanning from correct height will fix this.
|
||||
|
||||
12
src/main.cpp
12
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(),
|
||||
|
||||
@@ -475,14 +475,10 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
// fprintf(stderr,"%s: nTxSize = %u\n", __func__, nTxSize);
|
||||
|
||||
// Opret spam limits
|
||||
if (mapArgs.count("-opretmintxfee"))
|
||||
const bool opretminfee = true;
|
||||
if (opretminfee)
|
||||
{
|
||||
CAmount n = 0;
|
||||
CFeeRate opretMinFeeRate;
|
||||
if (ParseMoney(mapArgs["-opretmintxfee"], n) && n > 0)
|
||||
opretMinFeeRate = CFeeRate(n);
|
||||
else
|
||||
opretMinFeeRate = CFeeRate(400000); // default opretMinFeeRate (1 HUSH per 250 Kb = 0.004 per 1 Kb = 400000 puposhis per 1 Kb)
|
||||
CFeeRate opretMinFeeRate = CFeeRate(10000000); // default opretMinFeeRate 0.1 HUSH
|
||||
|
||||
bool fSpamTx = false;
|
||||
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||
@@ -501,9 +497,13 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
|
||||
}
|
||||
}
|
||||
|
||||
if ((nTxOpretSize > 256) && (feeRate < opretMinFeeRate)) fSpamTx = true;
|
||||
// std::cerr << tx.GetHash().ToString() << " nTxSize." << nTxSize << " nTxOpretSize." << nTxOpretSize << " feeRate." << feeRate.ToString() << " opretMinFeeRate." << opretMinFeeRate.ToString() << " fSpamTx." << fSpamTx << std::endl;
|
||||
if (fSpamTx) continue;
|
||||
// opreturns of this size or smaller get amnesty and do not have to pay increased fees
|
||||
int amnestySize = 128;
|
||||
if ((nTxOpretSize > amnestySize) && (feeRate < opretMinFeeRate)) {
|
||||
fSpamTx = true;
|
||||
std::cerr << __func__ << ": " << tx.GetHash().ToString() << " nTxSize=" << nTxSize << " nTxOpretSize=" << nTxOpretSize << " feeRate=" << feeRate.ToString() << " opretMinFeeRate=" << opretMinFeeRate.ToString() << " fSpamTx=" << fSpamTx << std::endl;
|
||||
continue;
|
||||
}
|
||||
// std::cerr << tx.GetHash().ToString() << " vecPriority.size() = " << vecPriority.size() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,15 +5347,21 @@ 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) {
|
||||
// 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) {
|
||||
// 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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use input parameters as the optional context info to be returned by z_getoperationstatus and z_getoperationresult.
|
||||
UniValue o(UniValue::VOBJ);
|
||||
|
||||
Reference in New Issue
Block a user