diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index d8b7b8fa31..700f0b2efd 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -40,7 +40,7 @@ DatabaseCon::~DatabaseCon() Application::Application() : mIOWork(mIOService), mAuxWork(mAuxService), mUNL(mIOService), mNetOps(mIOService, &mLedgerMaster), mTempNodeCache("NodeCache", 16384, 90), mHashedObjectStore(16384, 300), - mSNTPClient(mAuxService), mRPCHandler(&mNetOps), + mSNTPClient(mAuxService), mRPCHandler(&mNetOps), mFeeTrack(theConfig.TRANSACTION_FEE_BASE, theConfig.FEE_DEFAULT), mRpcDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL), mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL), mWSPublicDoor(NULL), mWSPrivateDoor(NULL), mSweepTimer(mAuxService) diff --git a/src/cpp/ripple/Application.h b/src/cpp/ripple/Application.h index 4a2b16e91f..c4af9de38c 100644 --- a/src/cpp/ripple/Application.h +++ b/src/cpp/ripple/Application.h @@ -63,6 +63,7 @@ class Application RPCHandler mRPCHandler; ProofOfWorkGenerator mPOWGen; LoadManager mLoadMgr; + LoadFeeTrack mFeeTrack; DatabaseCon *mRpcDB, *mTxnDB, *mLedgerDB, *mWalletDB, *mHashNodeDB, *mNetNodeDB; @@ -117,6 +118,8 @@ public: bool isNewFlag(const uint256& s, int f) { return mSuppressions.setFlag(s, f); } bool running() { return mTxnDB != NULL; } bool getSystemTimeOffset(int& offset) { return mSNTPClient.getOffset(offset); } + void scaleFeeBase(uint64 fee) { return mFeeTrack.scaleFeeBase(fee); } + void scaleFeeLoad(uint64 fee) { return mFeeTrack.scaleFeeLoad(fee); } DatabaseCon* getRpcDB() { return mRpcDB; } DatabaseCon* getTxnDB() { return mTxnDB; } diff --git a/src/cpp/ripple/Config.cpp b/src/cpp/ripple/Config.cpp index 4fe97a4b82..d60cbc6f9d 100644 --- a/src/cpp/ripple/Config.cpp +++ b/src/cpp/ripple/Config.cpp @@ -130,6 +130,12 @@ void Config::setup(const std::string& strConf, bool bQuiet) // std::cerr << "CONFIG DIR: " << CONFIG_DIR << std::endl; // std::cerr << "DATA DIR: " << DATA_DIR << std::endl; + // Update default values + load(); +} + +Config::Config() +{ // // Defaults // @@ -159,7 +165,7 @@ void Config::setup(const std::string& strConf, bool bQuiet) PEER_PRIVATE = false; - TRANSACTION_FEE_BASE = 1000; + TRANSACTION_FEE_BASE = DEFAULT_FEE_DEFAULT; NETWORK_QUORUM = 0; // Don't need to see other nodes VALIDATION_QUORUM = 1; // Only need one node to vouch @@ -179,8 +185,6 @@ void Config::setup(const std::string& strConf, bool bQuiet) RUN_STANDALONE = false; START_UP = NORMAL; - - load(); } void Config::load() diff --git a/src/cpp/ripple/Config.h b/src/cpp/ripple/Config.h index 570c766bbd..ca575ddf10 100644 --- a/src/cpp/ripple/Config.h +++ b/src/cpp/ripple/Config.h @@ -64,7 +64,7 @@ public: // Network parameters int NETWORK_START_TIME; // The Unix time we start ledger 0. - int TRANSACTION_FEE_BASE; + int TRANSACTION_FEE_BASE; // The number of fee units a reference transaction costs int LEDGER_SECONDS; int LEDGER_PROPOSAL_DELAY_SECONDS; int LEDGER_AVALANCHE_SECONDS; @@ -106,10 +106,10 @@ public: // Validation RippleAddress VALIDATION_SEED, VALIDATION_PUB, VALIDATION_PRIV; - // Fee schedule + // Fee schedule (All below values are in fee units) uint64 FEE_DEFAULT; // Default fee. - uint64 FEE_ACCOUNT_RESERVE; // Amount of XRP not allowed to send. - uint64 FEE_OWNER_RESERVE; // Amount of XRP not allowed to send per owner entry. + uint64 FEE_ACCOUNT_RESERVE; // Amount of units not allowed to send. + uint64 FEE_OWNER_RESERVE; // Amount of units not allowed to send per owner entry. uint64 FEE_NICKNAME_CREATE; // Fee to create a nickname. uint64 FEE_OFFER; // Rate per day. int FEE_CONTRACT_OPERATION; // fee for each contract operation @@ -120,6 +120,7 @@ public: // Client behavior int ACCOUNT_PROBE_MAX; // How far to scan for accounts. + Config(); void setup(const std::string& strConf, bool bQuiet); void load(); }; diff --git a/src/cpp/ripple/Interpreter.cpp b/src/cpp/ripple/Interpreter.cpp index 6fce0827b6..4cde286c53 100644 --- a/src/cpp/ripple/Interpreter.cpp +++ b/src/cpp/ripple/Interpreter.cpp @@ -129,7 +129,7 @@ TER Interpreter::interpret(Contract* contract,const SerializedTransaction& txn,s return(temMALFORMED); // TODO: is this actually what we want to do? } - mTotalFee += mFunctionTable[ fun ]->getFee(); + mTotalFee += mFunctionTable[ fun ]->getFee(); // FIXME: You can't use fees this way, there's no consensus if(mTotalFee>txn.getTransactionFee().getNValue()) { // TODO: log diff --git a/src/cpp/ripple/LoadManager.cpp b/src/cpp/ripple/LoadManager.cpp index 7956ca1410..a538204a56 100644 --- a/src/cpp/ripple/LoadManager.cpp +++ b/src/cpp/ripple/LoadManager.cpp @@ -1,5 +1,12 @@ #include "LoadManager.h" +#include + +#include "Log.h" +#include "Config.h" + +SETUP_LOG(); + LoadManager::LoadManager(int creditRate, int creditLimit, int debitWarn, int debitLimit) : mCreditRate(creditRate), mCreditLimit(creditLimit), mDebitWarn(debitWarn), mDebitLimit(debitLimit), mCosts(LT_MAX) @@ -244,4 +251,30 @@ Json::Value LoadFeeTrack::getJson(int) return j; } +BOOST_AUTO_TEST_SUITE(LoadManager_test) + +BOOST_AUTO_TEST_CASE(LoadFeeTrack_test) +{ + cLog(lsDEBUG) << "Running load fee track test"; + + Config d; // get a default configuration object + LoadFeeTrack l(d.TRANSACTION_FEE_BASE, d.FEE_DEFAULT); + + BOOST_REQUIRE_EQUAL(l.scaleFeeBase(10000), 10000); + BOOST_REQUIRE_EQUAL(l.scaleFeeLoad(10000), 10000); + BOOST_REQUIRE_EQUAL(l.scaleFeeBase(1), 1); + BOOST_REQUIRE_EQUAL(l.scaleFeeLoad(1), 1); + + // Check new default fee values give same fees as old defaults + BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_DEFAULT), 10); + BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_ACCOUNT_RESERVE), 200 * SYSTEM_CURRENCY_PARTS); + BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_OWNER_RESERVE), 50 * SYSTEM_CURRENCY_PARTS); + BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_NICKNAME_CREATE), 1000); + BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_OFFER), 10); + BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_CONTRACT_OPERATION), 1); + +} + +BOOST_AUTO_TEST_SUITE_END() + // vim:ts=4 diff --git a/src/cpp/ripple/LoadManager.h b/src/cpp/ripple/LoadManager.h index c96a8b447b..f6f18274e3 100644 --- a/src/cpp/ripple/LoadManager.h +++ b/src/cpp/ripple/LoadManager.h @@ -134,7 +134,9 @@ protected: public: - LoadFeeTrack() : mLocalTxnLoadFee(lftNormalFee), mRemoteTxnLoadFee(lftNormalFee) { ; } + LoadFeeTrack(uint32 baseRef, uint32 baseFee) : mBaseRef(baseRef), mBaseFee(baseFee), + mLocalTxnLoadFee(lftNormalFee), mRemoteTxnLoadFee(lftNormalFee) + { ; } uint64 scaleFeeBase(uint64 fee); // Scale from fee units to millionths of a ripple uint64 scaleFeeLoad(uint64 fee); // Scale using load as well as base rate diff --git a/src/cpp/ripple/PaymentTransactor.cpp b/src/cpp/ripple/PaymentTransactor.cpp index 50e48501c7..bd6100e10e 100644 --- a/src/cpp/ripple/PaymentTransactor.cpp +++ b/src/cpp/ripple/PaymentTransactor.cpp @@ -83,7 +83,7 @@ TER PaymentTransactor::doApply() return terNO_DST; } else if (isSetBit(mParams, tapOPEN_LEDGER) // Ledger is not final, we can vote. - && saDstAmount.getNValue() < theConfig.FEE_ACCOUNT_RESERVE) // Reserve is not scaled by fee. + && saDstAmount.getNValue() < theApp->scaleFeeBase(theConfig.FEE_ACCOUNT_RESERVE)) // Reserve is not scaled by load. { Log(lsINFO) << "doPayment: Delay transaction: Destination account does not exist. Insufficent payment to create account."; @@ -138,7 +138,7 @@ TER PaymentTransactor::doApply() const STAmount saSrcXRPBalance = mTxnAccount->getFieldAmount(sfBalance); const uint32 uOwnerCount = mTxnAccount->getFieldU32(sfOwnerCount); - const uint64 uReserve = theConfig.FEE_ACCOUNT_RESERVE+uOwnerCount*theConfig.FEE_OWNER_RESERVE; + const uint64 uReserve = theApp->scaleFeeBase(theConfig.FEE_ACCOUNT_RESERVE + uOwnerCount * theConfig.FEE_OWNER_RESERVE); // Make sure have enough reserve to send. if (isSetBit(mParams, tapOPEN_LEDGER) // Ledger is not final, we can vote. @@ -157,7 +157,7 @@ TER PaymentTransactor::doApply() // re-arm the password change fee if we can and need to if ( (sleDst->getFlags() & lsfPasswordSpent) && - (saDstAmount > theConfig.FEE_DEFAULT) ) + (saDstAmount > theConfig.FEE_DEFAULT) ) // FIXME: Can't access FEE_DEFAULT here { sleDst->setFieldAmount(sfBalance, sleDst->getFieldAmount(sfBalance) + saDstAmount-theConfig.FEE_DEFAULT); sleDst->clearFlag(lsfPasswordSpent);