diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index 700f0b2ef..c78f377bc 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -57,6 +57,7 @@ extern int RpcDBCount, TxnDBCount, LedgerDBCount, WalletDBCount, HashNodeDBCount void Application::stop() { + cLog(lsINFO) << "Received shutdown request"; mIOService.stop(); mJobQueue.shutdown(); mHashedObjectStore.bulkWrite(); diff --git a/src/cpp/ripple/InstanceCounter.cpp b/src/cpp/ripple/InstanceCounter.cpp index 564010282..8f551dff3 100644 --- a/src/cpp/ripple/InstanceCounter.cpp +++ b/src/cpp/ripple/InstanceCounter.cpp @@ -1,6 +1,7 @@ #include "InstanceCounter.h" InstanceType* InstanceType::sHeadInstance = NULL; +bool InstanceType::sMultiThreaded = false; std::vector InstanceType::getInstanceCounts(int min) { diff --git a/src/cpp/ripple/InstanceCounter.h b/src/cpp/ripple/InstanceCounter.h index ffb3665f5..aaec9efcd 100644 --- a/src/cpp/ripple/InstanceCounter.h +++ b/src/cpp/ripple/InstanceCounter.h @@ -32,6 +32,7 @@ protected: InstanceType* mNextInstance; static InstanceType* sHeadInstance; + static bool sMultiThreaded; public: typedef std::pair InstanceCount; @@ -42,17 +43,32 @@ public: sHeadInstance = this; } + static void multiThread() + { + // We can support global objects and multi-threaded code, but not both + // at the same time. Switch to multi-threaded. + sMultiThreaded = true; + } + void addInstance() { - mLock.lock(); - ++mInstances; - mLock.unlock(); + if (sMultiThreaded) + { + mLock.lock(); + ++mInstances; + mLock.unlock(); + } + else ++mInstances; } void decInstance() { - mLock.lock(); - --mInstances; - mLock.unlock(); + if (sMultiThreaded) + { + mLock.lock(); + --mInstances; + mLock.unlock(); + } + else --mInstances; } int getCount() { diff --git a/src/cpp/ripple/JobQueue.cpp b/src/cpp/ripple/JobQueue.cpp index b029dab5e..5abfbb81a 100644 --- a/src/cpp/ripple/JobQueue.cpp +++ b/src/cpp/ripple/JobQueue.cpp @@ -181,6 +181,7 @@ void JobQueue::shutdown() mJobCond.notify_all(); while (mThreadCount != 0) mJobCond.wait(sl); + cLog(lsDEBUG) << "Job queue has shut down"; } void JobQueue::setThreadCount(int c) diff --git a/src/cpp/ripple/LedgerFormats.cpp b/src/cpp/ripple/LedgerFormats.cpp index 1e553398a..ae443179c 100644 --- a/src/cpp/ripple/LedgerFormats.cpp +++ b/src/cpp/ripple/LedgerFormats.cpp @@ -103,6 +103,13 @@ static bool LEFInit() << SOElement(sfFeatures, SOE_REQUIRED) ; + DECLARE_LEF(FeeSettings, ltFEE_SETTINGS) + << SOElement(sfBaseFee, SOE_REQUIRED) + << SOElement(sfReferenceFeeUnits, SOE_REQUIRED) + << SOElement(sfReserveBase, SOE_REQUIRED) + << SOElement(sfReserveIncrement, SOE_REQUIRED) + ; + return true; } diff --git a/src/cpp/ripple/LedgerFormats.h b/src/cpp/ripple/LedgerFormats.h index 3bc0afb50..e39e7a894 100644 --- a/src/cpp/ripple/LedgerFormats.h +++ b/src/cpp/ripple/LedgerFormats.h @@ -16,6 +16,7 @@ enum LedgerEntryType ltCONTRACT = 'c', ltLEDGER_HASHES = 'h', ltFEATURES = 'f', + ltFEE_SETTINGS = 's', }; // Used as a prefix for computing ledger indexes (keys). @@ -32,6 +33,7 @@ enum LedgerNameSpace spaceContract = 'c', spaceSkipList = 's', spaceFeature = 'f', + spaceFee = 's', }; enum LedgerSpecificFlags diff --git a/src/cpp/ripple/SerializeProto.h b/src/cpp/ripple/SerializeProto.h index 286cf617f..e536f9d19 100644 --- a/src/cpp/ripple/SerializeProto.h +++ b/src/cpp/ripple/SerializeProto.h @@ -60,6 +60,9 @@ FIELD(LastLedgerSequence, UINT32, 27) FIELD(TransactionIndex, UINT32, 28) FIELD(OperationLimit, UINT32, 29) + FIELD(ReferenceFeeUnits, UINT32, 30) + FIELD(ReserveBase, UINT32, 31) + FIELD(ReserveIncrement, UINT32, 32) // 64-bit integers FIELD(IndexNext, UINT64, 1) @@ -69,6 +72,7 @@ FIELD(BaseFee, UINT64, 5) FIELD(ExchangeRate, UINT64, 6) + // 128-bit FIELD(EmailHash, HASH128, 1) diff --git a/src/cpp/ripple/TransactionFormats.cpp b/src/cpp/ripple/TransactionFormats.cpp index 683517892..b428ed764 100644 --- a/src/cpp/ripple/TransactionFormats.cpp +++ b/src/cpp/ripple/TransactionFormats.cpp @@ -76,6 +76,14 @@ static bool TFInit() << SOElement(sfFeature, SOE_REQUIRED) ; + DECLARE_TF(SetFee, ttFEE) + << SOElement(sfFeatures, SOE_REQUIRED) + << SOElement(sfBaseFee, SOE_REQUIRED) + << SOElement(sfReferenceFeeUnits, SOE_REQUIRED) + << SOElement(sfReserveBase, SOE_REQUIRED) + << SOElement(sfReserveIncrement, SOE_REQUIRED) + ; + return true; } diff --git a/src/cpp/ripple/TransactionFormats.h b/src/cpp/ripple/TransactionFormats.h index a9cab9ba8..602b1fb3e 100644 --- a/src/cpp/ripple/TransactionFormats.h +++ b/src/cpp/ripple/TransactionFormats.h @@ -6,6 +6,7 @@ enum TransactionType { ttINVALID = -1, + ttPAYMENT = 0, ttCLAIM = 1, // open ttWALLET_ADD = 2, @@ -21,6 +22,7 @@ enum TransactionType ttTRUST_SET = 20, ttFEATURE = 100, + ttFEE = 101, }; class TransactionFormat diff --git a/src/cpp/ripple/ValidationCollection.cpp b/src/cpp/ripple/ValidationCollection.cpp index 9057bd082..173dc3d65 100644 --- a/src/cpp/ripple/ValidationCollection.cpp +++ b/src/cpp/ripple/ValidationCollection.cpp @@ -260,6 +260,7 @@ void ValidationCollection::flush() { bool anyNew = false; + cLog(lsINFO) << "Flushing validations"; boost::mutex::scoped_lock sl(mValidationLock); BOOST_FOREACH(u160_val_pair& it, mCurrentValidations) { @@ -276,6 +277,7 @@ void ValidationCollection::flush() boost::this_thread::sleep(boost::posix_time::milliseconds(100)); sl.lock(); } + cLog(lsDEBUG) << "Validations flushed"; } void ValidationCollection::condWrite() diff --git a/src/cpp/ripple/main.cpp b/src/cpp/ripple/main.cpp index fa3606777..515d6b6a6 100644 --- a/src/cpp/ripple/main.cpp +++ b/src/cpp/ripple/main.cpp @@ -90,7 +90,7 @@ int main(int argc, char* argv[]) // // Set up option parsing. // - po::options_description desc("Options"); + po::options_description desc("General Options"); desc.add_options() ("help,h", "Display this message.") ("conf", po::value(), "Specify the configuration file.") @@ -99,12 +99,21 @@ int main(int argc, char* argv[]) ("test,t", "Perform unit tests.") ("parameters", po::value< vector >(), "Specify comma separated parameters.") ("quiet,q", "Reduce diagnotics.") - ("verbose,v", "Increase log level.") + ("verbose,v", "Verbose logging.") ("load", "Load the current ledger from the local DB.") ("start", "Start from a fresh Ledger.") ("net", "Get the initial ledger from the network.") ; + po::options_description hidden("Hidden Options"); + hidden.add_options() + ("trace,vvv", "Trace level logging") + ("debug,vv", "Debug level logging") + ; + + po::options_description all("All Options"); + all.add(desc).add(hidden); + // Interpret positional arguments as --parameters. po::positional_options_description p; p.add("parameters", -1); @@ -129,7 +138,7 @@ int main(int argc, char* argv[]) // Parse options, if no error. try { po::store(po::command_line_parser(argc, argv) - .options(desc) // Parse options. + .options(all) // Parse options. .positional(p) // Remainder as --parameters. .run(), vm); @@ -141,11 +150,17 @@ int main(int argc, char* argv[]) } } - if (vm.count("verbose")) + if (vm.count("trace")) Log::setMinSeverity(lsTRACE, true); + else if (vm.count("debug")) + Log::setMinSeverity(lsDEBUG, true); + else if (vm.count("verbose")) + Log::setMinSeverity(lsINFO, true); else Log::setMinSeverity(lsWARNING, true); + InstanceType::multiThread(); + if (vm.count("test")) { unit_test_main(init_unit_test, argc, argv);