mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-27 22:45:52 +00:00
Allow administrators to submit transactions that don't meet the local load fee.
This commit is contained in:
@@ -1618,11 +1618,11 @@ uint64 Ledger::scaleFeeBase(uint64 fee)
|
||||
return theApp->getFeeTrack().scaleFeeBase(fee, mBaseFee, mReferenceFeeUnits);
|
||||
}
|
||||
|
||||
uint64 Ledger::scaleFeeLoad(uint64 fee)
|
||||
uint64 Ledger::scaleFeeLoad(uint64 fee, bool bAdmin)
|
||||
{
|
||||
if (!mBaseFee)
|
||||
updateFees();
|
||||
return theApp->getFeeTrack().scaleFeeLoad(fee, mBaseFee, mReferenceFeeUnits);
|
||||
return theApp->getFeeTrack().scaleFeeLoad(fee, mBaseFee, mReferenceFeeUnits, bAdmin);
|
||||
}
|
||||
|
||||
std::vector<uint256> Ledger::getNeededTransactionHashes(int max)
|
||||
|
||||
@@ -350,7 +350,7 @@ public:
|
||||
}
|
||||
|
||||
uint64 scaleFeeBase(uint64 fee);
|
||||
uint64 scaleFeeLoad(uint64 fee);
|
||||
uint64 scaleFeeLoad(uint64 fee, bool bAdmin);
|
||||
|
||||
|
||||
Json::Value getJson(int options);
|
||||
|
||||
@@ -24,6 +24,8 @@ enum TransactionEngineParams
|
||||
|
||||
tapRETRY = 0x20, // This is not the transaction's last pass
|
||||
// Transaction can be retried, soft failures allowed
|
||||
|
||||
tapADMIN = 0x40, // Transaction came from a privileged source
|
||||
};
|
||||
|
||||
enum LedgerEntryAction
|
||||
|
||||
@@ -199,7 +199,7 @@ uint64 LoadFeeTrack::mulDiv(uint64 value, uint32 mul, uint64 div)
|
||||
return (value * mul) / div;
|
||||
}
|
||||
|
||||
uint64 LoadFeeTrack::scaleFeeLoad(uint64 fee, uint64 baseFee, uint32 referenceFeeUnits)
|
||||
uint64 LoadFeeTrack::scaleFeeLoad(uint64 fee, uint64 baseFee, uint32 referenceFeeUnits, bool bAdmin)
|
||||
{
|
||||
static uint64 midrange(0x00000000FFFFFFFF);
|
||||
|
||||
@@ -209,9 +209,15 @@ uint64 LoadFeeTrack::scaleFeeLoad(uint64 fee, uint64 baseFee, uint32 referenceFe
|
||||
else // normal fee, multiply first for accuracy
|
||||
fee *= referenceFeeUnits;
|
||||
|
||||
uint32 feeFactor = std::max(mLocalTxnLoadFee, mRemoteTxnLoadFee);
|
||||
|
||||
// Let admins pay the normal fee until the local load exceeds four times the remote
|
||||
if (bAdmin && (feeFactor > mRemoteTxnLoadFee) && (feeFactor < (4 * mRemoteTxnLoadFee)))
|
||||
feeFactor = mRemoteTxnLoadFee;
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mLock);
|
||||
fee = mulDiv(fee, std::max(mLocalTxnLoadFee, mRemoteTxnLoadFee), lftNormalFee);
|
||||
fee = mulDiv(fee, feeFactor, lftNormalFee);
|
||||
}
|
||||
|
||||
if (big) // Fee was big to start, must now multiply
|
||||
@@ -381,9 +387,9 @@ BOOST_AUTO_TEST_CASE(LoadFeeTrack_test)
|
||||
LoadFeeTrack l;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(10000, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 10000);
|
||||
BOOST_REQUIRE_EQUAL(l.scaleFeeLoad(10000, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 10000);
|
||||
BOOST_REQUIRE_EQUAL(l.scaleFeeLoad(10000, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE, false), 10000);
|
||||
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(1, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 1);
|
||||
BOOST_REQUIRE_EQUAL(l.scaleFeeLoad(1, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 1);
|
||||
BOOST_REQUIRE_EQUAL(l.scaleFeeLoad(1, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE, false), 1);
|
||||
|
||||
// Check new default fee values give same fees as old defaults
|
||||
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_DEFAULT, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 10);
|
||||
|
||||
@@ -169,7 +169,7 @@ public:
|
||||
uint64 scaleFeeBase(uint64 fee, uint64 baseFee, uint32 referenceFeeUnits);
|
||||
|
||||
// Scale using load as well as base rate
|
||||
uint64 scaleFeeLoad(uint64 fee, uint64 baseFee, uint32 referenceFeeUnits);
|
||||
uint64 scaleFeeLoad(uint64 fee, uint64 baseFee, uint32 referenceFeeUnits, bool bAdmin);
|
||||
|
||||
uint32 getRemoteFee();
|
||||
uint32 getLocalFee();
|
||||
|
||||
@@ -212,12 +212,12 @@ void NetworkOPs::submitTransaction(Job&, SerializedTransaction::pointer iTrans,
|
||||
|
||||
// FIXME: Should submit to job queue
|
||||
theApp->getIOService().post(boost::bind(&NetworkOPs::processTransaction, this,
|
||||
boost::make_shared<Transaction>(trans, false), callback));
|
||||
boost::make_shared<Transaction>(trans, false), false, callback));
|
||||
}
|
||||
|
||||
// Sterilize transaction through serialization.
|
||||
// This is fully synchronous and deprecated
|
||||
Transaction::pointer NetworkOPs::submitTransactionSync(Transaction::ref tpTrans, bool bSubmit)
|
||||
Transaction::pointer NetworkOPs::submitTransactionSync(Transaction::ref tpTrans, bool bAdmin, bool bSubmit)
|
||||
{
|
||||
Serializer s;
|
||||
tpTrans->getSTransaction()->add(s);
|
||||
@@ -232,7 +232,7 @@ Transaction::pointer NetworkOPs::submitTransactionSync(Transaction::ref tpTrans,
|
||||
else if (tpTransNew->getSTransaction()->isEquivalent(*tpTrans->getSTransaction()))
|
||||
{
|
||||
if (bSubmit)
|
||||
(void) NetworkOPs::processTransaction(tpTransNew);
|
||||
(void) NetworkOPs::processTransaction(tpTransNew, bAdmin);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -326,7 +326,7 @@ void NetworkOPs::runTransactionQueue()
|
||||
theApp->getIOService().post(boost::bind(&NetworkOPs::runTransactionQueue, this));
|
||||
}
|
||||
|
||||
Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, stCallback callback)
|
||||
Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, bool bAdmin, stCallback callback)
|
||||
{
|
||||
LoadEvent::autoptr ev = theApp->getJobQueue().getLoadEventAP(jtTXN_PROC, "ProcessTXN");
|
||||
|
||||
@@ -352,7 +352,8 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
|
||||
boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock());
|
||||
Transaction::pointer dbtx = theApp->getMasterTransaction().fetch(trans->getID(), true);
|
||||
bool didApply;
|
||||
TER r = mLedgerMaster->doTransaction(trans->getSTransaction(), tapOPEN_LEDGER | tapNO_CHECK_SIGN, didApply);
|
||||
TER r = mLedgerMaster->doTransaction(trans->getSTransaction(),
|
||||
bAdmin ? (tapOPEN_LEDGER | tapNO_CHECK_SIGN | tapADMIN) : (tapOPEN_LEDGER | tapNO_CHECK_SIGN), didApply);
|
||||
trans->setResult(r);
|
||||
|
||||
if (isTemMalformed(r)) // malformed, cache bad
|
||||
|
||||
@@ -188,12 +188,12 @@ public:
|
||||
//
|
||||
typedef FUNCTION_TYPE<void (Transaction::pointer, TER)> stCallback; // must complete immediately
|
||||
void submitTransaction(Job&, SerializedTransaction::pointer, stCallback callback = stCallback());
|
||||
Transaction::pointer submitTransactionSync(Transaction::ref tpTrans, bool bSubmit=true);
|
||||
Transaction::pointer submitTransactionSync(Transaction::ref tpTrans, bool bAdmin, bool bSubmit);
|
||||
|
||||
void runTransactionQueue();
|
||||
Transaction::pointer processTransaction(Transaction::pointer, stCallback);
|
||||
Transaction::pointer processTransaction(Transaction::pointer transaction)
|
||||
{ return processTransaction(transaction, stCallback()); }
|
||||
Transaction::pointer processTransaction(Transaction::pointer, bool bAdmin, stCallback);
|
||||
Transaction::pointer processTransaction(Transaction::pointer transaction, bool bAdmin)
|
||||
{ return processTransaction(transaction, bAdmin, stCallback()); }
|
||||
|
||||
Transaction::pointer findTransactionByID(const uint256& transactionID);
|
||||
#if 0
|
||||
|
||||
@@ -850,7 +850,7 @@ static void checkTransaction(Job&, int flags, SerializedTransaction::pointer stx
|
||||
else
|
||||
tx = boost::make_shared<Transaction>(stx, false);
|
||||
|
||||
theApp->getOPs().processTransaction(tx);
|
||||
theApp->getOPs().processTransaction(tx, (flags & SF_TRUSTED) != 0);
|
||||
|
||||
#ifndef TRUST_NETWORK
|
||||
}
|
||||
@@ -888,6 +888,8 @@ void Peer::recvTransaction(ripple::TMTransaction& packet)
|
||||
if ((flags & SF_RETRY) == 0)
|
||||
return;
|
||||
}
|
||||
if (mCluster)
|
||||
flags |= SF_TRUSTED | SF_SIGGOOD;
|
||||
|
||||
theApp->getJobQueue().addJob(jtTRANSACTION, "recvTransction->checkTransaction",
|
||||
BIND_TYPE(&checkTransaction, P_1, flags, stx, boost::weak_ptr<Peer>(shared_from_this())));
|
||||
@@ -1043,13 +1045,13 @@ void Peer::recvHaveTxSet(ripple::TMHaveTransactionSet& packet)
|
||||
}
|
||||
|
||||
static void checkValidation(Job&, SerializedValidation::pointer val, uint256 signingHash,
|
||||
bool isTrusted, boost::shared_ptr<ripple::TMValidation> packet, boost::weak_ptr<Peer> peer)
|
||||
bool isTrusted, bool isCluster, boost::shared_ptr<ripple::TMValidation> packet, boost::weak_ptr<Peer> peer)
|
||||
{
|
||||
#ifndef TRUST_NETWORK
|
||||
try
|
||||
#endif
|
||||
{
|
||||
if (!val->isValid(signingHash))
|
||||
if (!isCluster && !val->isValid(signingHash))
|
||||
{
|
||||
cLog(lsWARNING) << "Validation is invalid";
|
||||
Peer::punishPeer(peer, LT_InvalidRequest);
|
||||
@@ -1106,7 +1108,7 @@ void Peer::recvValidation(const boost::shared_ptr<ripple::TMValidation>& packet)
|
||||
|
||||
bool isTrusted = theApp->getUNL().nodeInUNL(val->getSignerPublic());
|
||||
theApp->getJobQueue().addJob(isTrusted ? jtVALIDATION_t : jtVALIDATION_ut, "recvValidation->checkValidation",
|
||||
BIND_TYPE(&checkValidation, P_1, val, signingHash, isTrusted, packet,
|
||||
BIND_TYPE(&checkValidation, P_1, val, signingHash, isTrusted, mCluster, packet,
|
||||
boost::weak_ptr<Peer>(shared_from_this())));
|
||||
}
|
||||
#ifndef TRUST_NETWORK
|
||||
|
||||
@@ -324,7 +324,8 @@ Json::Value RPCHandler::transactionSign(Json::Value jvRequest, bool bSubmit)
|
||||
|
||||
try
|
||||
{
|
||||
tpTrans = mNetOps->submitTransactionSync(tpTrans, bSubmit); // FIXME: For performance, should use asynch interface
|
||||
// FIXME: For performance, should use asynch interface
|
||||
tpTrans = mNetOps->submitTransactionSync(tpTrans, mRole == ADMIN, bSubmit);
|
||||
|
||||
if (!tpTrans) {
|
||||
jvResult["error"] = "invalidTransaction";
|
||||
@@ -1452,7 +1453,7 @@ Json::Value RPCHandler::doSubmit(Json::Value jvRequest, int& cost)
|
||||
|
||||
try
|
||||
{
|
||||
(void) mNetOps->processTransaction(tpTrans);
|
||||
(void) mNetOps->processTransaction(tpTrans, mRole == ADMIN);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ DEFINE_INSTANCE(Suppression);
|
||||
#define SF_SIGGOOD 0x04 // Signature is good
|
||||
#define SF_SAVED 0x08
|
||||
#define SF_RETRY 0x10 // Transaction can be retried
|
||||
#define SF_TRUSTED 0x20 // comes from trusted source
|
||||
|
||||
class Suppression : private IS_INSTANCE(Suppression)
|
||||
{
|
||||
|
||||
@@ -42,7 +42,7 @@ Transactor::Transactor(const SerializedTransaction& txn,TransactionEngineParams
|
||||
|
||||
void Transactor::calculateFee()
|
||||
{
|
||||
mFeeDue = STAmount(mEngine->getLedger()->scaleFeeLoad(calculateBaseFee()));
|
||||
mFeeDue = STAmount(mEngine->getLedger()->scaleFeeLoad(calculateBaseFee(), isSetBit(mParams, tapADMIN)));
|
||||
}
|
||||
|
||||
uint64 Transactor::calculateBaseFee()
|
||||
|
||||
Reference in New Issue
Block a user