mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-29 07:25:51 +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);
|
return theApp->getFeeTrack().scaleFeeBase(fee, mBaseFee, mReferenceFeeUnits);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 Ledger::scaleFeeLoad(uint64 fee)
|
uint64 Ledger::scaleFeeLoad(uint64 fee, bool bAdmin)
|
||||||
{
|
{
|
||||||
if (!mBaseFee)
|
if (!mBaseFee)
|
||||||
updateFees();
|
updateFees();
|
||||||
return theApp->getFeeTrack().scaleFeeLoad(fee, mBaseFee, mReferenceFeeUnits);
|
return theApp->getFeeTrack().scaleFeeLoad(fee, mBaseFee, mReferenceFeeUnits, bAdmin);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint256> Ledger::getNeededTransactionHashes(int max)
|
std::vector<uint256> Ledger::getNeededTransactionHashes(int max)
|
||||||
|
|||||||
@@ -350,7 +350,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64 scaleFeeBase(uint64 fee);
|
uint64 scaleFeeBase(uint64 fee);
|
||||||
uint64 scaleFeeLoad(uint64 fee);
|
uint64 scaleFeeLoad(uint64 fee, bool bAdmin);
|
||||||
|
|
||||||
|
|
||||||
Json::Value getJson(int options);
|
Json::Value getJson(int options);
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ enum TransactionEngineParams
|
|||||||
|
|
||||||
tapRETRY = 0x20, // This is not the transaction's last pass
|
tapRETRY = 0x20, // This is not the transaction's last pass
|
||||||
// Transaction can be retried, soft failures allowed
|
// Transaction can be retried, soft failures allowed
|
||||||
|
|
||||||
|
tapADMIN = 0x40, // Transaction came from a privileged source
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LedgerEntryAction
|
enum LedgerEntryAction
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ uint64 LoadFeeTrack::mulDiv(uint64 value, uint32 mul, uint64 div)
|
|||||||
return (value * mul) / 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);
|
static uint64 midrange(0x00000000FFFFFFFF);
|
||||||
|
|
||||||
@@ -209,9 +209,15 @@ uint64 LoadFeeTrack::scaleFeeLoad(uint64 fee, uint64 baseFee, uint32 referenceFe
|
|||||||
else // normal fee, multiply first for accuracy
|
else // normal fee, multiply first for accuracy
|
||||||
fee *= referenceFeeUnits;
|
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);
|
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
|
if (big) // Fee was big to start, must now multiply
|
||||||
@@ -381,9 +387,9 @@ BOOST_AUTO_TEST_CASE(LoadFeeTrack_test)
|
|||||||
LoadFeeTrack l;
|
LoadFeeTrack l;
|
||||||
|
|
||||||
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(10000, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 10000);
|
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.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
|
// 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);
|
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);
|
uint64 scaleFeeBase(uint64 fee, uint64 baseFee, uint32 referenceFeeUnits);
|
||||||
|
|
||||||
// Scale using load as well as base rate
|
// 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 getRemoteFee();
|
||||||
uint32 getLocalFee();
|
uint32 getLocalFee();
|
||||||
|
|||||||
@@ -212,12 +212,12 @@ void NetworkOPs::submitTransaction(Job&, SerializedTransaction::pointer iTrans,
|
|||||||
|
|
||||||
// FIXME: Should submit to job queue
|
// FIXME: Should submit to job queue
|
||||||
theApp->getIOService().post(boost::bind(&NetworkOPs::processTransaction, this,
|
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.
|
// Sterilize transaction through serialization.
|
||||||
// This is fully synchronous and deprecated
|
// 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;
|
Serializer s;
|
||||||
tpTrans->getSTransaction()->add(s);
|
tpTrans->getSTransaction()->add(s);
|
||||||
@@ -232,7 +232,7 @@ Transaction::pointer NetworkOPs::submitTransactionSync(Transaction::ref tpTrans,
|
|||||||
else if (tpTransNew->getSTransaction()->isEquivalent(*tpTrans->getSTransaction()))
|
else if (tpTransNew->getSTransaction()->isEquivalent(*tpTrans->getSTransaction()))
|
||||||
{
|
{
|
||||||
if (bSubmit)
|
if (bSubmit)
|
||||||
(void) NetworkOPs::processTransaction(tpTransNew);
|
(void) NetworkOPs::processTransaction(tpTransNew, bAdmin);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -326,7 +326,7 @@ void NetworkOPs::runTransactionQueue()
|
|||||||
theApp->getIOService().post(boost::bind(&NetworkOPs::runTransactionQueue, this));
|
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");
|
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());
|
boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock());
|
||||||
Transaction::pointer dbtx = theApp->getMasterTransaction().fetch(trans->getID(), true);
|
Transaction::pointer dbtx = theApp->getMasterTransaction().fetch(trans->getID(), true);
|
||||||
bool didApply;
|
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);
|
trans->setResult(r);
|
||||||
|
|
||||||
if (isTemMalformed(r)) // malformed, cache bad
|
if (isTemMalformed(r)) // malformed, cache bad
|
||||||
|
|||||||
@@ -188,12 +188,12 @@ public:
|
|||||||
//
|
//
|
||||||
typedef FUNCTION_TYPE<void (Transaction::pointer, TER)> stCallback; // must complete immediately
|
typedef FUNCTION_TYPE<void (Transaction::pointer, TER)> stCallback; // must complete immediately
|
||||||
void submitTransaction(Job&, SerializedTransaction::pointer, stCallback callback = stCallback());
|
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();
|
void runTransactionQueue();
|
||||||
Transaction::pointer processTransaction(Transaction::pointer, stCallback);
|
Transaction::pointer processTransaction(Transaction::pointer, bool bAdmin, stCallback);
|
||||||
Transaction::pointer processTransaction(Transaction::pointer transaction)
|
Transaction::pointer processTransaction(Transaction::pointer transaction, bool bAdmin)
|
||||||
{ return processTransaction(transaction, stCallback()); }
|
{ return processTransaction(transaction, bAdmin, stCallback()); }
|
||||||
|
|
||||||
Transaction::pointer findTransactionByID(const uint256& transactionID);
|
Transaction::pointer findTransactionByID(const uint256& transactionID);
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
@@ -850,7 +850,7 @@ static void checkTransaction(Job&, int flags, SerializedTransaction::pointer stx
|
|||||||
else
|
else
|
||||||
tx = boost::make_shared<Transaction>(stx, false);
|
tx = boost::make_shared<Transaction>(stx, false);
|
||||||
|
|
||||||
theApp->getOPs().processTransaction(tx);
|
theApp->getOPs().processTransaction(tx, (flags & SF_TRUSTED) != 0);
|
||||||
|
|
||||||
#ifndef TRUST_NETWORK
|
#ifndef TRUST_NETWORK
|
||||||
}
|
}
|
||||||
@@ -888,6 +888,8 @@ void Peer::recvTransaction(ripple::TMTransaction& packet)
|
|||||||
if ((flags & SF_RETRY) == 0)
|
if ((flags & SF_RETRY) == 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (mCluster)
|
||||||
|
flags |= SF_TRUSTED | SF_SIGGOOD;
|
||||||
|
|
||||||
theApp->getJobQueue().addJob(jtTRANSACTION, "recvTransction->checkTransaction",
|
theApp->getJobQueue().addJob(jtTRANSACTION, "recvTransction->checkTransaction",
|
||||||
BIND_TYPE(&checkTransaction, P_1, flags, stx, boost::weak_ptr<Peer>(shared_from_this())));
|
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,
|
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
|
#ifndef TRUST_NETWORK
|
||||||
try
|
try
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (!val->isValid(signingHash))
|
if (!isCluster && !val->isValid(signingHash))
|
||||||
{
|
{
|
||||||
cLog(lsWARNING) << "Validation is invalid";
|
cLog(lsWARNING) << "Validation is invalid";
|
||||||
Peer::punishPeer(peer, LT_InvalidRequest);
|
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());
|
bool isTrusted = theApp->getUNL().nodeInUNL(val->getSignerPublic());
|
||||||
theApp->getJobQueue().addJob(isTrusted ? jtVALIDATION_t : jtVALIDATION_ut, "recvValidation->checkValidation",
|
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())));
|
boost::weak_ptr<Peer>(shared_from_this())));
|
||||||
}
|
}
|
||||||
#ifndef TRUST_NETWORK
|
#ifndef TRUST_NETWORK
|
||||||
|
|||||||
@@ -324,7 +324,8 @@ Json::Value RPCHandler::transactionSign(Json::Value jvRequest, bool bSubmit)
|
|||||||
|
|
||||||
try
|
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) {
|
if (!tpTrans) {
|
||||||
jvResult["error"] = "invalidTransaction";
|
jvResult["error"] = "invalidTransaction";
|
||||||
@@ -1452,7 +1453,7 @@ Json::Value RPCHandler::doSubmit(Json::Value jvRequest, int& cost)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
(void) mNetOps->processTransaction(tpTrans);
|
(void) mNetOps->processTransaction(tpTrans, mRole == ADMIN);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ DEFINE_INSTANCE(Suppression);
|
|||||||
#define SF_SIGGOOD 0x04 // Signature is good
|
#define SF_SIGGOOD 0x04 // Signature is good
|
||||||
#define SF_SAVED 0x08
|
#define SF_SAVED 0x08
|
||||||
#define SF_RETRY 0x10 // Transaction can be retried
|
#define SF_RETRY 0x10 // Transaction can be retried
|
||||||
|
#define SF_TRUSTED 0x20 // comes from trusted source
|
||||||
|
|
||||||
class Suppression : private IS_INSTANCE(Suppression)
|
class Suppression : private IS_INSTANCE(Suppression)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Transactor::Transactor(const SerializedTransaction& txn,TransactionEngineParams
|
|||||||
|
|
||||||
void Transactor::calculateFee()
|
void Transactor::calculateFee()
|
||||||
{
|
{
|
||||||
mFeeDue = STAmount(mEngine->getLedger()->scaleFeeLoad(calculateBaseFee()));
|
mFeeDue = STAmount(mEngine->getLedger()->scaleFeeLoad(calculateBaseFee(), isSetBit(mParams, tapADMIN)));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 Transactor::calculateBaseFee()
|
uint64 Transactor::calculateBaseFee()
|
||||||
|
|||||||
Reference in New Issue
Block a user