Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
Arthur Britto
2012-10-31 16:43:25 -07:00
29 changed files with 221 additions and 31 deletions

View File

@@ -112,6 +112,7 @@
<ClCompile Include="src\HTTPRequest.cpp" />
<ClCompile Include="src\HttpsClient.cpp" />
<ClCompile Include="src\Interpreter.cpp" />
<ClCompile Include="src\InstanceCounter.cpp" />
<ClCompile Include="src\Ledger.cpp" />
<ClCompile Include="src\LedgerAcquire.cpp" />
<ClCompile Include="src\LedgerConsensus.cpp" />

View File

@@ -42,11 +42,13 @@ Application::Application() :
mNetOps(mIOService, &mMasterLedger), mTempNodeCache(16384, 90), mHashedObjectStore(16384, 300),
mSNTPClient(mAuxService), mRpcDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL),
mHashNodeDB(NULL), mNetNodeDB(NULL),
mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL)
mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL), mSweepTimer(mAuxService)
{
RAND_bytes(mNonce256.begin(), mNonce256.size());
RAND_bytes(reinterpret_cast<unsigned char *>(&mNonceST), sizeof(mNonceST));
mJobQueue.setThreadCount();
mSweepTimer.expires_from_now(boost::posix_time::seconds(60));
mSweepTimer.async_wait(boost::bind(&Application::sweep, this));
}
extern const char *RpcDBInit[], *TxnDBInit[], *LedgerDBInit[], *WalletDBInit[], *HashNodeDBInit[], *NetNodeDBInit[];
@@ -183,6 +185,16 @@ void Application::run()
std::cout << "Done." << std::endl;
}
void Application::sweep()
{
mMasterTransaction.sweep();
mHashedObjectStore.sweep();
mMasterLedger.sweep();
mTempNodeCache.sweep();
mSweepTimer.expires_from_now(boost::posix_time::seconds(60));
mSweepTimer.async_wait(boost::bind(&Application::sweep, this));
}
Application::~Application()
{
delete mTxnDB;

View File

@@ -66,6 +66,8 @@ class Application
uint256 mNonce256;
std::size_t mNonceST;
boost::asio::deadline_timer mSweepTimer;
std::map<std::string, Peer::pointer> mPeerMap;
boost::recursive_mutex mPeerMapLock;
@@ -110,6 +112,7 @@ public:
void run();
void stop();
void sweep();
};
extern Application* theApp;

View File

@@ -9,6 +9,7 @@
#include "Log.h"
SETUP_LOG();
DECLARE_INSTANCE(HashedObject);
HashedObjectStore::HashedObjectStore(int cacheSize, int cacheAge) :
mCache(cacheSize, cacheAge), mWritePending(false)

View File

@@ -10,6 +10,9 @@
#include "uint256.h"
#include "ScopedLock.h"
#include "TaggedCache.h"
#include "InstanceCounter.h"
DEFINE_INSTANCE(HashedObject);
enum HashedObjectType
{
@@ -20,7 +23,7 @@ enum HashedObjectType
hotTRANSACTION_NODE = 4
};
class HashedObject
class HashedObject : private IS_INSTANCE(HashedObject)
{
public:
typedef boost::shared_ptr<HashedObject> pointer;
@@ -61,6 +64,7 @@ public:
void bulkWrite();
void waitWrite();
void sweep() { mCache.sweep(); }
};
#endif

15
src/InstanceCounter.cpp Normal file
View File

@@ -0,0 +1,15 @@
#include "InstanceCounter.h"
InstanceType* InstanceType::sHeadInstance = NULL;
std::vector<InstanceType::InstanceCount> InstanceType::getInstanceCounts(int min)
{
std::vector<InstanceCount> ret;
for (InstanceType* i = sHeadInstance; i != NULL; i = i->mNextInstance)
{
int c = i->getCount();
if (c >= min)
ret.push_back(InstanceCount(i->getName(), c));
}
return ret;
}

80
src/InstanceCounter.h Normal file
View File

@@ -0,0 +1,80 @@
#ifndef INSTANCE_COUNTER__H
#define INSTANCE_COUNTER__H
#include <string>
#include <vector>
#include <boost/thread/mutex.hpp>
#define DEFINE_INSTANCE(x) \
extern InstanceType IT_##x; \
class Instance_##x : private Instance \
{ \
protected: \
Instance_##x() : Instance(IT_##x) { ; } \
Instance_##x(const Instance_##x &) : \
Instance(IT_##x) { ; } \
Instance_##x& operator=(const Instance_##x&) \
{ return *this; } \
}
#define DECLARE_INSTANCE(x) \
InstanceType IT_##x(#x);
#define IS_INSTANCE(x) Instance_##x
class InstanceType
{
protected:
int mInstances;
std::string mName;
boost::mutex mLock;
InstanceType* mNextInstance;
static InstanceType* sHeadInstance;
public:
typedef std::pair<std::string, int> InstanceCount;
InstanceType(const char *n) : mInstances(0), mName(n)
{
mNextInstance = sHeadInstance;
sHeadInstance = this;
}
void addInstance()
{
mLock.lock();
++mInstances;
mLock.unlock();
}
void decInstance()
{
mLock.lock();
--mInstances;
mLock.unlock();
}
int getCount()
{
boost::mutex::scoped_lock(mLock);
return mInstances;
}
const std::string& getName()
{
return mName;
}
static std::vector<InstanceCount> getInstanceCounts(int min = 1);
};
class Instance
{
protected:
InstanceType& mType;
public:
Instance(InstanceType& t) : mType(t) { mType.addInstance(); }
~Instance() { mType.decInstance(); }
};
#endif

View File

@@ -20,6 +20,7 @@
#include "Log.h"
SETUP_LOG();
DECLARE_INSTANCE(Ledger);
Ledger::Ledger(const RippleAddress& masterID, uint64 startAmount) : mTotCoins(startAmount), mLedgerSeq(1),
mCloseTime(0), mParentCloseTime(0), mCloseResolution(LEDGER_TIME_ACCURACY), mCloseFlags(0),

View File

@@ -18,6 +18,7 @@
#include "types.h"
#include "BitcoinUtil.h"
#include "SHAMap.h"
#include "InstanceCounter.h"
enum LedgerStateParms
{
@@ -38,7 +39,9 @@ enum LedgerStateParms
#define LEDGER_JSON_DUMP_STATE 0x20000000
#define LEDGER_JSON_FULL 0x40000000
class Ledger : public boost::enable_shared_from_this<Ledger>
DEFINE_INSTANCE(Ledger);
class Ledger : public boost::enable_shared_from_this<Ledger>, public IS_INSTANCE(Ledger)
{ // The basic Ledger structure, can be opened, closed, or synching
friend class TransactionEngine;
public:

View File

@@ -18,6 +18,7 @@ public:
Ledger::pointer getLedgerBySeq(uint32 index);
Ledger::pointer getLedgerByHash(const uint256& hash);
Ledger::pointer canonicalizeLedger(Ledger::pointer, bool cache);
void sweep() { mLedgersByHash.sweep(); }
};
#endif

View File

@@ -91,6 +91,8 @@ public:
void setLedgerRangePresent(uint32 minV, uint32 maxV) { mCompleteLedgers.setRange(minV, maxV); }
bool addHeldTransaction(const Transaction::pointer& trans);
void sweep(void) { mLedgerHistory.sweep(); }
};
#endif

View File

@@ -16,6 +16,7 @@
#include "Log.h"
SETUP_LOG();
DECLARE_INSTANCE(Peer);
// Don't try to run past receiving nonsense from a peer
#define TRUST_NETWORK

View File

@@ -11,6 +11,7 @@
#include "PackedMessage.h"
#include "Ledger.h"
#include "Transaction.h"
#include "InstanceCounter.h"
enum PeerPunish
{
@@ -21,7 +22,9 @@ enum PeerPunish
typedef std::pair<std::string,int> ipPort;
class Peer : public boost::enable_shared_from_this<Peer>
DEFINE_INSTANCE(Peer);
class Peer : public boost::enable_shared_from_this<Peer>, public IS_INSTANCE(Peer)
{
public:
typedef boost::shared_ptr<Peer> pointer;

View File

@@ -7,6 +7,7 @@
#include "RippleAddress.h"
#include "AccountState.h"
#include "NicknameState.h"
#include "InstanceCounter.h"
#include "Pathfinder.h"
#include <boost/foreach.hpp>
@@ -75,7 +76,7 @@ Json::Value RPCHandler::rpcError(int iError)
for (i=NUMBER(errorInfoA); i-- && errorInfoA[i].iError != iError;)
;
Json::Value jsonResult = Json::Value(Json::objectValue);
Json::Value jsonResult(Json::objectValue);
jsonResult["error"] = i >= 0 ? errorInfoA[i].pToken : lexical_cast_i(iError);
jsonResult["error_message"] = i >= 0 ? errorInfoA[i].pMessage : lexical_cast_i(iError);
@@ -2420,37 +2421,38 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param
bool mAdminRequired;
unsigned int iOptions;
} commandsA[] = {
{ "accept_ledger", &RPCHandler::doAcceptLedger, 0, 0, true },
{ "account_domain_set", &RPCHandler::doAccountDomainSet, 2, 3, false, optCurrent },
{ "accept_ledger", &RPCHandler::doAcceptLedger, 0, 0, true },
{ "account_domain_set", &RPCHandler::doAccountDomainSet, 2, 3, false, optCurrent },
{ "account_email_set", &RPCHandler::doAccountEmailSet, 2, 3, false, optCurrent },
{ "account_info", &RPCHandler::doAccountInfo, 1, 2, false, optCurrent },
{ "account_message_set", &RPCHandler::doAccountMessageSet, 3, 3, false, optCurrent },
{ "account_publish_set", &RPCHandler::doAccountPublishSet, 4, 4, false, optCurrent },
{ "account_rate_set", &RPCHandler::doAccountRateSet, 3, 3, false, optCurrent },
{ "account_tx", &RPCHandler::doAccountTransactions, 2, 3, false, optNetwork },
{ "account_wallet_set", &RPCHandler::doAccountWalletSet, 2, 3, false, optCurrent },
{ "account_wallet_set", &RPCHandler::doAccountWalletSet, 2, 3, false, optCurrent },
{ "connect", &RPCHandler::doConnect, 1, 2, true },
{ "data_delete", &RPCHandler::doDataDelete, 1, 1, true },
{ "data_fetch", &RPCHandler::doDataFetch, 1, 1, true },
{ "data_store", &RPCHandler::doDataStore, 2, 2, true },
{ "get_counts", &RPCHandler::doGetCounts, 0, 1, true },
{ "ledger", &RPCHandler::doLedger, 0, 2, false, optNetwork },
{ "log_level", &RPCHandler::doLogLevel, 0, 2, true },
{ "log_level", &RPCHandler::doLogLevel, 0, 2, true },
{ "logrotate", &RPCHandler::doLogRotate, 0, 0, true },
{ "nickname_info", &RPCHandler::doNicknameInfo, 1, 1, false, optCurrent },
{ "nickname_info", &RPCHandler::doNicknameInfo, 1, 1, false, optCurrent },
{ "nickname_set", &RPCHandler::doNicknameSet, 2, 3, false, optCurrent },
{ "offer_create", &RPCHandler::doOfferCreate, 9, 10, false, optCurrent },
{ "offer_cancel", &RPCHandler::doOfferCancel, 3, 3, false, optCurrent },
{ "owner_info", &RPCHandler::doOwnerInfo, 1, 2, false, optCurrent },
{ "password_fund", &RPCHandler::doPasswordFund, 2, 3, false, optCurrent },
{ "password_fund", &RPCHandler::doPasswordFund, 2, 3, false, optCurrent },
{ "password_set", &RPCHandler::doPasswordSet, 2, 3, false, optNetwork },
{ "peers", &RPCHandler::doPeers, 0, 0, true },
{ "profile", &RPCHandler::doProfile, 1, 9, false, optCurrent },
{ "ripple", &RPCHandler::doRipple, 9, -1, false, optCurrent|optClosed },
{ "ripple_lines_get", &RPCHandler::doRippleLinesGet, 1, 2, false, optCurrent },
{ "ripple_line_set", &RPCHandler::doRippleLineSet, 4, 7, false, optCurrent },
{ "send", &RPCHandler::doSend, 3, 9, false, optCurrent },
{ "send", &RPCHandler::doSend, 3, 9, false, optCurrent },
{ "server_info", &RPCHandler::doServerInfo, 0, 0, true },
{ "stop", &RPCHandler::doStop, 0, 0, true },
{ "stop", &RPCHandler::doStop, 0, 0, true },
{ "tx", &RPCHandler::doTx, 1, 1, true },
{ "tx_history", &RPCHandler::doTxHistory, 1, 1, false, },
@@ -2459,16 +2461,16 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param
{ "unl_list", &RPCHandler::doUnlList, 0, 0, true },
{ "unl_load", &RPCHandler::doUnlLoad, 0, 0, true },
{ "unl_network", &RPCHandler::doUnlNetwork, 0, 0, true },
{ "unl_reset", &RPCHandler::doUnlReset, 0, 0, true },
{ "unl_score", &RPCHandler::doUnlScore, 0, 0, true },
{ "unl_reset", &RPCHandler::doUnlReset, 0, 0, true },
{ "unl_score", &RPCHandler::doUnlScore, 0, 0, true },
{ "validation_create", &RPCHandler::doValidationCreate, 0, 1, false },
{ "validation_create", &RPCHandler::doValidationCreate, 0, 1, false },
{ "validation_seed", &RPCHandler::doValidationSeed, 0, 1, false },
{ "wallet_accounts", &RPCHandler::doWalletAccounts, 1, 1, false, optCurrent },
{ "wallet_add", &RPCHandler::doWalletAdd, 3, 5, false, optCurrent },
{ "wallet_claim", &RPCHandler::doWalletClaim, 2, 4, false, optNetwork },
{ "wallet_create", &RPCHandler::doWalletCreate, 3, 4, false, optCurrent },
{ "wallet_create", &RPCHandler::doWalletCreate, 3, 4, false, optCurrent },
{ "wallet_propose", &RPCHandler::doWalletPropose, 0, 1, false, },
{ "wallet_seed", &RPCHandler::doWalletSeed, 0, 1, false, },
@@ -2603,6 +2605,20 @@ Json::Value RPCHandler::doLogin(const Json::Value& params)
}
}
Json::Value RPCHandler::doGetCounts(const Json::Value& params)
{
int minCount = 1;
if (params.size() > 0)
minCount = params[0u].asInt();
std::vector<InstanceType::InstanceCount> count = InstanceType::getInstanceCounts(minCount);
Json::Value ret(Json::objectValue);
BOOST_FOREACH(InstanceType::InstanceCount& it, count)
ret[it.first] = it.second;
return ret;
}
Json::Value RPCHandler::doLogLevel(const Json::Value& params)
{
if (params.size() == 0)

View File

@@ -1,3 +1,6 @@
#ifndef RPCHANDLER__H
#define RPCHANDLER__H
// used by the RPCServer or WSDoor to carry out these RPC commands
class NetworkOPs;
@@ -37,6 +40,7 @@ class RPCHandler
Json::Value doDataDelete(const Json::Value& params);
Json::Value doDataFetch(const Json::Value& params);
Json::Value doDataStore(const Json::Value& params);
Json::Value doGetCounts(const Json::Value& params);
Json::Value doLedger(const Json::Value& params);
Json::Value doLogRotate(const Json::Value& params);
Json::Value doNicknameInfo(const Json::Value& params);
@@ -156,4 +160,6 @@ public:
Json::Value doCommand(const std::string& command, Json::Value& params,int role);
Json::Value rpcError(int iError);
};
};
#endif

View File

@@ -17,6 +17,10 @@
SETUP_LOG();
DECLARE_INSTANCE(SHAMap);
DECLARE_INSTANCE(SHAMapItem);
DECLARE_INSTANCE(SHAMapTreeNode);
std::size_t hash_value(const SHAMapNode& mn)
{
std::size_t seed = theApp->getNonceST();

View File

@@ -14,6 +14,11 @@
#include "ScopedLock.h"
#include "Serializer.h"
#include "HashedObject.h"
#include "InstanceCounter.h"
DEFINE_INSTANCE(SHAMap);
DEFINE_INSTANCE(SHAMapItem);
DEFINE_INSTANCE(SHAMapTreeNode);
class SHAMap;
@@ -31,7 +36,7 @@ private:
public:
static const int rootDepth=0;
static const int rootDepth = 0;
SHAMapNode() : mDepth(0) { ; }
SHAMapNode(int depth, const uint256& hash);
@@ -77,7 +82,7 @@ extern std::size_t hash_value(const SHAMapNode& mn);
inline std::ostream& operator<<(std::ostream& out, const SHAMapNode& node) { return out << node.getString(); }
class SHAMapItem
class SHAMapItem : public IS_INSTANCE(SHAMapItem)
{ // an item stored in a SHAMap
public:
typedef boost::shared_ptr<SHAMapItem> pointer;
@@ -135,7 +140,7 @@ enum SHAMapType
smtFREE =3, // A tree not part of a ledger
};
class SHAMapTreeNode : public SHAMapNode
class SHAMapTreeNode : public SHAMapNode, public IS_INSTANCE(SHAMapTreeNode)
{
friend class SHAMap;
@@ -276,7 +281,7 @@ public:
extern std::ostream& operator<<(std::ostream&, const SHAMapMissingNode&);
class SHAMap
class SHAMap : public IS_INSTANCE(SHAMap)
{
public:
typedef boost::shared_ptr<SHAMap> pointer;

View File

@@ -5,6 +5,8 @@
#include "Ledger.h"
#include "Log.h"
DECLARE_INSTANCE(SerializedLedgerEntry)
SerializedLedgerEntry::SerializedLedgerEntry(SerializerIterator& sit, const uint256& index)
: STObject(sfLedgerEntry), mIndex(index)
{

View File

@@ -4,8 +4,11 @@
#include "SerializedObject.h"
#include "LedgerFormats.h"
#include "RippleAddress.h"
#include "InstanceCounter.h"
class SerializedLedgerEntry : public STObject
DEFINE_INSTANCE(SerializedLedgerEntry);
class SerializedLedgerEntry : public STObject, private IS_INSTANCE(SerializedLedgerEntry)
{
public:
typedef boost::shared_ptr<SerializedLedgerEntry> pointer;

View File

@@ -14,6 +14,8 @@
#include "SerializedTransaction.h"
SETUP_LOG();
DECLARE_INSTANCE(SerializedObject);
DECLARE_INSTANCE(SerializedArray);
std::auto_ptr<SerializedType> STObject::makeDefaultObject(SerializedTypeID id, SField::ref name)
{

View File

@@ -8,6 +8,10 @@
#include "../json/value.h"
#include "SerializedTypes.h"
#include "InstanceCounter.h"
DEFINE_INSTANCE(SerializedObject);
DEFINE_INSTANCE(SerializedArray);
// Serializable object/array types
@@ -22,7 +26,7 @@ public:
SOElement(SField::ref fi, SOE_Flags fl) : e_field(fi), flags(fl) { ; }
};
class STObject : public SerializedType
class STObject : public SerializedType, private IS_INSTANCE(SerializedObject)
{
protected:
boost::ptr_vector<SerializedType> mData;
@@ -175,7 +179,7 @@ namespace boost
class STArray : public SerializedType
class STArray : public SerializedType, private IS_INSTANCE(SerializedArray)
{
public:
typedef std::vector<STObject> vector;

View File

@@ -8,6 +8,8 @@
#include "Log.h"
#include "HashPrefixes.h"
DECLARE_INSTANCE(SerializedTransaction);
SerializedTransaction::SerializedTransaction(TransactionType type) : STObject(sfTransaction), mType(type)
{
mFormat = TransactionFormat::getTxnFormat(type);

View File

@@ -9,6 +9,7 @@
#include "SerializedObject.h"
#include "TransactionFormats.h"
#include "RippleAddress.h"
#include "InstanceCounter.h"
#define TXN_SQL_NEW 'N'
#define TXN_SQL_CONFLICT 'C'
@@ -17,7 +18,9 @@
#define TXN_SQL_INCLUDED 'I'
#define TXN_SQL_UNKNOWN 'U'
class SerializedTransaction : public STObject
DEFINE_INSTANCE(SerializedTransaction);
class SerializedTransaction : public STObject, private IS_INSTANCE(SerializedTransaction)
{
public:
typedef boost::shared_ptr<SerializedTransaction> pointer;

View File

@@ -14,6 +14,7 @@
#include "TransactionErr.h"
SETUP_LOG();
DECLARE_INSTANCE(SerializedEntry);
STAmount saZero(CURRENCY_ONE, ACCOUNT_ONE, 0);
STAmount saOne(CURRENCY_ONE, ACCOUNT_ONE, 1);

View File

@@ -9,7 +9,7 @@
#include "uint256.h"
#include "Serializer.h"
#include "FieldNames.h"
#include "InstanceCounter.h"
enum PathFlags
{
@@ -30,7 +30,9 @@ enum PathFlags
#define ACCOUNT_XNS uint160(0)
#define ACCOUNT_ONE uint160(1) // Used as a place holder
class SerializedType
DEFINE_INSTANCE(SerializedEntry);
class SerializedType : private IS_INSTANCE(SerializedEntry)
{
protected:
SField::ptr fName;

View File

@@ -44,6 +44,7 @@ public:
int getTargetAge() const;
int getCacheSize();
int getTrackSize();
int getSweepAge();
void setTargetSize(int size);
@@ -78,6 +79,12 @@ template<typename c_Key, typename c_Data> int TaggedCache<c_Key, c_Data>::getCac
return mCache.size();
}
template<typename c_Key, typename c_Data> int TaggedCache<c_Key, c_Data>::getTrackSize()
{
boost::recursive_mutex::scoped_lock sl(mLock);
return mMap.size();
}
template<typename c_Key, typename c_Data> void TaggedCache<c_Key, c_Data>::sweep()
{
boost::recursive_mutex::scoped_lock sl(mLock);
@@ -96,7 +103,7 @@ template<typename c_Key, typename c_Data> void TaggedCache<c_Key, c_Data>::sweep
typename boost::unordered_map<key_type, cache_entry>::iterator cit = mCache.begin();
while (cit != mCache.end())
{
if (cit->second->second.first < target)
if (cit->second.first < target)
mCache.erase(cit++);
else
++cit;
@@ -106,7 +113,7 @@ template<typename c_Key, typename c_Data> void TaggedCache<c_Key, c_Data>::sweep
typename boost::unordered_map<key_type, weak_data_ptr>::iterator mit = mMap.begin();
while (mit != mMap.end())
{
if (mit->second->expired())
if (mit->second.expired())
mMap.erase(mit++);
else
++mit;

View File

@@ -13,6 +13,8 @@
#include "SerializedTransaction.h"
#include "Log.h"
DECLARE_INSTANCE(Transaction);
Transaction::Transaction(SerializedTransaction::ref sit, bool bValidate)
: mInLedger(0), mStatus(INVALID), mResult(temUNCERTAIN), mTransaction(sit)
{

View File

@@ -21,6 +21,7 @@
#include "SHAMap.h"
#include "SerializedTransaction.h"
#include "TransactionErr.h"
#include "InstanceCounter.h"
class Database;
@@ -37,8 +38,10 @@ enum TransStatus
INCOMPLETE = 8 // needs more signatures
};
DEFINE_INSTANCE(Transaction);
// This class is for constructing and examining transactions. Transactions are static so manipulation functions are unnecessary.
class Transaction : public boost::enable_shared_from_this<Transaction>
class Transaction : public boost::enable_shared_from_this<Transaction>, private IS_INSTANCE(Transaction)
{
public:
typedef boost::shared_ptr<Transaction> pointer;

View File

@@ -20,6 +20,7 @@ public:
// return value: true = we had the transaction already
bool canonicalize(Transaction::pointer& txn, bool maybeNew);
void sweep(void) { mCache.sweep(); }
};
#endif